Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 35 additions & 37 deletions Dashboard/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,6 @@ private void OpenPlanViewerTab()
}

_mainPlanTabControl = new TabControl

{
Background = System.Windows.Media.Brushes.Transparent,
BorderThickness = new Thickness(0)
Expand Down Expand Up @@ -1867,18 +1866,25 @@ private TabItem AddNewEmptyPlanSubTab()
var dialog = new Microsoft.Win32.OpenFileDialog
{
Filter = "SQL Plan Files (*.sqlplan)|*.sqlplan|XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
DefaultExt = ".sqlplan"
DefaultExt = ".sqlplan",
Multiselect = true
};
if (dialog.ShowDialog() != true) return;
try
{
var xml = System.IO.File.ReadAllText(dialog.FileName);
LoadPlanIntoSubTab(subTab, xml, System.IO.Path.GetFileName(dialog.FileName));
}
catch (Exception ex)
var isFirst = true;
foreach (var fileName in dialog.FileNames)
{
MessageBox.Show($"Failed to open file:\n\n{ex.Message}", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
try
{
var xml = System.IO.File.ReadAllText(fileName);
var targetTab = isFirst ? subTab : AddNewEmptyPlanSubTab();
LoadPlanIntoSubTab(targetTab, xml, System.IO.Path.GetFileName(fileName));
}
catch (Exception ex)
{
MessageBox.Show($"Failed to open file:\n\n{ex.Message}", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
isFirst = false;
}
};

Expand Down Expand Up @@ -1985,35 +1991,12 @@ subTab.Header is StackPanel sp &&
return _mainPlanTabControl.SelectedItem as TabItem;
}

public void OpenMainWindowPlanTab(string planXml, string label, string? queryText = null)
{
if (_planViewerTab == null || !ServerTabControl.Items.Contains(_planViewerTab))
OpenPlanViewerTab();

var activeSubTab = GetActivePlanSubTab();
if (activeSubTab?.Content is Grid g &&
g.Children.Count >= 2 &&
g.Children[1] is Controls.PlanViewerControl { Visibility: Visibility.Collapsed })
{
// Active sub-tab is empty — load into it
LoadPlanIntoSubTab(activeSubTab, planXml, label, queryText);
}
else
{
// Active sub-tab already has a plan — open a new one
var newSubTab = AddNewEmptyPlanSubTab();
LoadPlanIntoSubTab(newSubTab, planXml, label, queryText);
}

ServerTabControl.SelectedItem = _planViewerTab;
}

private void MainWindowPlanViewer_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files?.Length > 0 && IsPlanFile(files[0]))
if (files?.Any(IsPlanFile) == true)
{
e.Effects = DragDropEffects.Copy;
e.Handled = true;
Expand All @@ -2027,9 +2010,24 @@ private void MainWindowPlanViewer_DragOver(object sender, DragEventArgs e)
private void MainWindowPlanViewer_Drop(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
var files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files?.Length > 0 && IsPlanFile(files[0]))
LoadMainWindowPlanFromFileIntoActiveTab(files[0]);
var planFiles = (e.Data.GetData(DataFormats.FileDrop) as string[])
?.Where(IsPlanFile).ToArray();
if (planFiles == null || planFiles.Length == 0) return;
LoadMainWindowPlanFromFileIntoActiveTab(planFiles[0]);
for (var i = 1; i < planFiles.Length; i++)
{
var newTab = AddNewEmptyPlanSubTab();
try
{
var xml = System.IO.File.ReadAllText(planFiles[i]);
LoadPlanIntoSubTab(newTab, xml, System.IO.Path.GetFileName(planFiles[i]));
}
catch (Exception ex)
{
MessageBox.Show($"Failed to open file:\n\n{ex.Message}", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}

private void MainWindowPlanViewer_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
Expand Down
20 changes: 20 additions & 0 deletions Lite/Controls/ServerTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,26 @@ public ServerTab(ServerConnection server, DuckDbInitializer duckDb, CredentialSe

/* Initial load is triggered by MainWindow.ConnectToServer calling RefreshData()
after collectors finish - no Loaded handler needed */

KeyDown += ServerTab_KeyDown;
Focusable = true;
}

private void ServerTab_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.V &&
System.Windows.Input.Keyboard.Modifiers == System.Windows.Input.ModifierKeys.Control &&
e.OriginalSource is not System.Windows.Controls.TextBox &&
PlanViewerTabItem.IsSelected)
{
var xml = System.Windows.Clipboard.GetText();
if (!string.IsNullOrWhiteSpace(xml))
{
e.Handled = true;
OpenPlanTab(xml, "Pasted Plan");
PlanViewerTabItem.IsSelected = true;
}
}
}

private void InitializeTimeComboBoxes()
Expand Down
70 changes: 35 additions & 35 deletions Lite/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,18 +1630,25 @@ private TabItem AddNewEmptyPlanSubTab()
var dialog = new Microsoft.Win32.OpenFileDialog
{
Filter = "SQL Plan Files (*.sqlplan)|*.sqlplan|XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
DefaultExt = ".sqlplan"
DefaultExt = ".sqlplan",
Multiselect = true
};
if (dialog.ShowDialog() != true) return;
try
var isFirst = true;
foreach (var fileName in dialog.FileNames)
{
var xml = System.IO.File.ReadAllText(dialog.FileName);
LoadPlanIntoSubTab(subTab, xml, System.IO.Path.GetFileName(dialog.FileName));
}
catch (Exception ex)
{
MessageBox.Show($"Failed to open file:\n\n{ex.Message}", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
try
{
var xml = System.IO.File.ReadAllText(fileName);
var targetTab = isFirst ? subTab : AddNewEmptyPlanSubTab();
LoadPlanIntoSubTab(targetTab, xml, System.IO.Path.GetFileName(fileName));
}
catch (Exception ex)
{
MessageBox.Show($"Failed to open file:\n\n{ex.Message}", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
isFirst = false;
}
};

Expand Down Expand Up @@ -1745,34 +1752,12 @@ subTab.Header is StackPanel sp &&
return MainWindowPlanTabControl.SelectedItem as TabItem;
}

public void OpenMainWindowPlanTab(string planXml, string label, string? queryText = null)
{
EnsurePlanTabControlInitialized();
MainWindowPlanViewerTab.Visibility = Visibility.Visible;

var activeSubTab = GetActivePlanSubTab();
if (activeSubTab?.Content is Grid g &&
g.Children.Count >= 2 &&
g.Children[1] is Controls.PlanViewerControl { Visibility: Visibility.Collapsed })
{
LoadPlanIntoSubTab(activeSubTab, planXml, label, queryText);
}
else
{
var newSubTab = AddNewEmptyPlanSubTab();
LoadPlanIntoSubTab(newSubTab, planXml, label, queryText);
}

MainWindowPlanViewerTab.IsSelected = true;
ServerTabControl.Visibility = Visibility.Visible;
}

private void MainWindowPlanViewer_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files?.Length > 0 && IsPlanFile(files[0]))
if (files?.Any(IsPlanFile) == true)
{
e.Effects = DragDropEffects.Copy;
e.Handled = true;
Expand All @@ -1786,9 +1771,24 @@ private void MainWindowPlanViewer_DragOver(object sender, DragEventArgs e)
private void MainWindowPlanViewer_Drop(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
var files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files?.Length > 0 && IsPlanFile(files[0]))
LoadMainWindowPlanFromFileIntoActiveTab(files[0]);
var planFiles = (e.Data.GetData(DataFormats.FileDrop) as string[])
?.Where(IsPlanFile).ToArray();
if (planFiles == null || planFiles.Length == 0) return;
LoadMainWindowPlanFromFileIntoActiveTab(planFiles[0]);
for (var i = 1; i < planFiles.Length; i++)
{
var newTab = AddNewEmptyPlanSubTab();
try
{
var xml = System.IO.File.ReadAllText(planFiles[i]);
LoadPlanIntoSubTab(newTab, xml, System.IO.Path.GetFileName(planFiles[i]));
}
catch (Exception ex)
{
MessageBox.Show($"Failed to load plan file:\n{ex.Message}", "Load Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}

private void MainWindowPlanViewer_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
Expand Down
Loading