Skip to content

Commit db39996

Browse files
Modern UI: pin toggle for symbol paths, modal download overlay, rename to UpdatePdbPath
- Add pin button to save/restore PDB paths across sessions (PinPdbPaths setting) - Replace ProgressBar with modal ProgressRing overlay + cancel in SQL Builds dialog - Symbol path buttons now replace instead of append
1 parent 1296471 commit db39996

10 files changed

Lines changed: 153 additions & 65 deletions

Modern/Converters.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
2424
value is bool b ? !b : value;
2525
}
2626

27+
internal class BoolToOpacityConverter : IValueConverter {
28+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
29+
value is bool b && b ? 1.0 : 0.35;
30+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
31+
throw new NotSupportedException();
32+
}
33+
2734
internal class StepToBoldConverter : IValueConverter {
2835
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
2936
if (value is int current && parameter is string stepStr && int.TryParse(stepStr, out int step))

Modern/Dialogs/SQLBuildsDialog.xaml

Lines changed: 64 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,53 +11,74 @@
1111
<Window.CommandBindings>
1212
<CommandBinding Command="Find" Executed="Find_Executed"/>
1313
</Window.CommandBindings>
14-
<Grid Margin="10">
15-
<Grid.RowDefinitions>
16-
<RowDefinition Height="Auto"/>
17-
<RowDefinition Height="*"/>
18-
<RowDefinition Height="Auto"/>
19-
<RowDefinition Height="Auto"/>
20-
</Grid.RowDefinitions>
14+
<Grid>
15+
<!-- Main content -->
16+
<Grid x:Name="mainContent" Margin="10">
17+
<Grid.RowDefinitions>
18+
<RowDefinition Height="Auto"/>
19+
<RowDefinition Height="*"/>
20+
<RowDefinition Height="Auto"/>
21+
<RowDefinition Height="Auto"/>
22+
</Grid.RowDefinitions>
2123

22-
<Border x:Name="findBarBorder" Grid.Row="0" Visibility="Collapsed"
23-
Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
24-
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
25-
BorderThickness="1" CornerRadius="4" Padding="6,4" Margin="0,0,0,8">
26-
<DockPanel>
27-
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" Margin="6,0,0,0">
28-
<TextBlock x:Name="matchInfo" VerticalAlignment="Center" FontSize="11" Opacity="0.6" Margin="0,0,8,0"/>
29-
<Button Click="FindPrev_Click" Padding="4,2" ToolTip="Previous match (Shift+F3)"
30-
Background="Transparent" BorderThickness="0">
31-
<TextBlock Text="&#xE70E;" FontFamily="Segoe MDL2 Assets" FontSize="12"/>
32-
</Button>
33-
<Button Click="FindNext_Click" Padding="4,2" ToolTip="Next match (F3)"
34-
Background="Transparent" BorderThickness="0">
35-
<TextBlock Text="&#xE70D;" FontFamily="Segoe MDL2 Assets" FontSize="12"/>
36-
</Button>
37-
<Button Click="FindClose_Click" Padding="4,2" Margin="4,0,0,0" ToolTip="Close (Esc)"
38-
Background="Transparent" BorderThickness="0">
39-
<TextBlock Text="&#xE711;" FontFamily="Segoe MDL2 Assets" FontSize="12"/>
40-
</Button>
41-
</StackPanel>
42-
<TextBox x:Name="searchText" VerticalAlignment="Center" FontSize="13"
43-
KeyDown="SearchBox_KeyDown"/>
44-
</DockPanel>
45-
</Border>
24+
<Border x:Name="findBarBorder" Grid.Row="0" Visibility="Collapsed"
25+
Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
26+
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
27+
BorderThickness="1" CornerRadius="4" Padding="6,4" Margin="0,0,0,8">
28+
<DockPanel>
29+
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" Margin="6,0,0,0">
30+
<TextBlock x:Name="matchInfo" VerticalAlignment="Center" FontSize="11" Opacity="0.6" Margin="0,0,8,0"/>
31+
<Button Click="FindPrev_Click" Padding="4,2" ToolTip="Previous match (Shift+F3)"
32+
Background="Transparent" BorderThickness="0">
33+
<TextBlock Text="&#xE70E;" FontFamily="Segoe MDL2 Assets" FontSize="12"/>
34+
</Button>
35+
<Button Click="FindNext_Click" Padding="4,2" ToolTip="Next match (F3)"
36+
Background="Transparent" BorderThickness="0">
37+
<TextBlock Text="&#xE70D;" FontFamily="Segoe MDL2 Assets" FontSize="12"/>
38+
</Button>
39+
<Button Click="FindClose_Click" Padding="4,2" Margin="4,0,0,0" ToolTip="Close (Esc)"
40+
Background="Transparent" BorderThickness="0">
41+
<TextBlock Text="&#xE711;" FontFamily="Segoe MDL2 Assets" FontSize="12"/>
42+
</Button>
43+
</StackPanel>
44+
<TextBox x:Name="searchText" VerticalAlignment="Center" FontSize="13"
45+
KeyDown="SearchBox_KeyDown"/>
46+
</DockPanel>
47+
</Border>
4648

47-
<TreeView Grid.Row="1" x:Name="treeviewSyms" Margin="0,0,0,8"/>
49+
<TreeView Grid.Row="1" x:Name="treeviewSyms" Margin="0,0,0,8"/>
4850

49-
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,0,0,8">
50-
<Button Content="Check PDB availability" Width="150" Margin="0,0,8,0" Click="CheckPDBAvail_Click"/>
51-
<Button x:Name="dnldButton" Content="Download PDBs" Width="120" Margin="0,0,8,0" Click="DownloadPDBs_Click"/>
52-
</StackPanel>
51+
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,0,0,8">
52+
<Button Content="Check PDB availability" Width="150" Margin="0,0,8,0" Click="CheckPDBAvail_Click"/>
53+
<Button x:Name="dnldButton" Content="Download PDBs" Width="120" Margin="0,0,8,0" Click="DownloadPDBs_Click"/>
54+
</StackPanel>
5355

54-
<Grid Grid.Row="3">
55-
<Grid.ColumnDefinitions>
56-
<ColumnDefinition Width="*"/>
57-
<ColumnDefinition Width="Auto"/>
58-
</Grid.ColumnDefinitions>
59-
<TextBlock x:Name="downloadStatus" Grid.Column="0" TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
60-
<ProgressBar x:Name="downloadProgress" Grid.Column="1" Width="150" Height="18" Margin="8,0,0,0"/>
56+
<TextBlock x:Name="downloadStatus" Grid.Row="3" TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
6157
</Grid>
58+
59+
<!-- Modal processing overlay -->
60+
<Border x:Name="processingOverlay" Visibility="Collapsed"
61+
Background="#80000000" Panel.ZIndex="50">
62+
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
63+
CornerRadius="12" Padding="40,32"
64+
HorizontalAlignment="Center" VerticalAlignment="Center"
65+
MinWidth="280"
66+
BorderThickness="1" BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}">
67+
<Border.Effect>
68+
<DropShadowEffect BlurRadius="24" ShadowDepth="4" Opacity="0.3"/>
69+
</Border.Effect>
70+
<StackPanel HorizontalAlignment="Center">
71+
<ui:ProgressRing IsActive="True" Width="40" Height="40" Margin="0,0,0,14"/>
72+
<TextBlock x:Name="overlayStatus" FontSize="13" TextAlignment="Center"
73+
TextWrapping="Wrap" MaxWidth="240" Margin="0,0,0,14"/>
74+
<Button Click="CancelDownload_Click" HorizontalAlignment="Center" Padding="20,6">
75+
<StackPanel Orientation="Horizontal">
76+
<TextBlock Text="&#xE711;" FontFamily="Segoe MDL2 Assets" FontSize="13" VerticalAlignment="Center" Margin="0,0,6,0"/>
77+
<TextBlock Text="Cancel"/>
78+
</StackPanel>
79+
</Button>
80+
</StackPanel>
81+
</Border>
82+
</Border>
6283
</Grid>
6384
</Window>

Modern/Dialogs/SQLBuildsDialog.xaml.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,9 @@ private async void DownloadPDBs_Click(object sender, RoutedEventArgs e) {
4040
var selectedItem = treeviewSyms.SelectedItem as TreeViewItem;
4141
if (selectedItem?.Tag is not SQLBuildInfo bld || bld.SymbolDetails.Count <= 0) return;
4242

43-
if (_dnldTask != null) {
44-
_cts?.Cancel();
45-
return;
46-
}
47-
4843
var statusMsg = new StringBuilder();
49-
dnldButton.Content = "Cancel download";
44+
dnldButton.IsEnabled = false;
45+
processingOverlay.Visibility = Visibility.Visible;
5046
LastDownloadedSymFolder = $@"{PathToPDBs}\{bld.BuildNumber}.{bld.MachineType}";
5147
Directory.CreateDirectory(LastDownloadedSymFolder);
5248
var urls = bld.SymbolDetails.Select(s => s.DownloadURL);
@@ -58,7 +54,7 @@ private async void DownloadPDBs_Click(object sender, RoutedEventArgs e) {
5854
var filename = Path.GetFileName(uri.LocalPath);
5955
if (File.Exists($@"{LastDownloadedSymFolder}\{filename}")) continue;
6056

61-
downloadStatus.Text = filename;
57+
overlayStatus.Text = $"Downloading {filename}...";
6258
var prog = new DownloadProgress();
6359
_dnldTask = Task.Run(async () => {
6460
var res = await Utils.DownloadFromUrl(url, $@"{LastDownloadedSymFolder}\{filename}", prog, _cts);
@@ -67,13 +63,12 @@ private async void DownloadPDBs_Click(object sender, RoutedEventArgs e) {
6763

6864
while (!_dnldTask.IsCompleted) {
6965
await Task.Delay(StackResolver.OperationWaitIntervalMilliseconds);
70-
downloadProgress.Value = prog.Percent;
7166
}
7267
_dnldTask = null;
7368
}
7469

75-
dnldButton.Content = "Download PDBs";
76-
downloadProgress.Value = 0;
70+
dnldButton.IsEnabled = true;
71+
processingOverlay.Visibility = Visibility.Collapsed;
7772
downloadStatus.Text = string.Empty;
7873

7974
if (statusMsg.Length > 0) {
@@ -97,12 +92,16 @@ private async void CheckPDBAvail_Click(object sender, RoutedEventArgs e) {
9792
List<string> failedUrls = new();
9893
var urls = bld.SymbolDetails.Select(s => s.DownloadURL);
9994
foreach (var url in urls) {
100-
downloadStatus.Text = url;
95+
downloadStatus.Text = $"Checking {url}...";
10196
if (!(await Symbol.IsURLValid(new Uri(url)))) failedUrls.Add(url);
10297
}
10398
downloadStatus.Text = failedUrls.Count > 0 ? string.Join(",", failedUrls) : "All PDBs for this build are available!";
10499
}
105100

101+
private void CancelDownload_Click(object sender, RoutedEventArgs e) {
102+
_cts?.Cancel();
103+
}
104+
106105
private void FindNext_Click(object sender, RoutedEventArgs e) => FindInTree(forward: true);
107106
private void FindPrev_Click(object sender, RoutedEventArgs e) => FindInTree(forward: false);
108107

Modern/Pages/SymbolConfigPage.xaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
xmlns:local="clr-namespace:Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver.Modern">
55
<UserControl.Resources>
66
<local:BoolToVisibilityConverter x:Key="BoolToVis"/>
7+
<local:BoolToOpacityConverter x:Key="BoolToOpacityConverter"/>
78
</UserControl.Resources>
89
<Grid>
910
<Grid.RowDefinitions>
@@ -109,10 +110,17 @@
109110
<Grid.ColumnDefinitions>
110111
<ColumnDefinition Width="*"/>
111112
<ColumnDefinition Width="Auto"/>
113+
<ColumnDefinition Width="Auto"/>
112114
</Grid.ColumnDefinitions>
113115
<TextBox Grid.Column="0" Text="{Binding PdbPaths, UpdateSourceTrigger=PropertyChanged}"
114116
Margin="0,0,4,0" ToolTip="Semicolon-separated paths to PDB files"/>
115117
<Button Grid.Column="1" Content="Browse..." Width="80" Click="BrowsePdbPath_Click"/>
118+
<ToggleButton Grid.Column="2" IsChecked="{Binding PinPdbPaths}" Margin="4,0,0,0"
119+
Padding="4,2" Background="Transparent" BorderThickness="0"
120+
ToolTip="Pin to remember this path for next session">
121+
<TextBlock Text="&#xE718;" FontFamily="Segoe MDL2 Assets" FontSize="14"
122+
Opacity="{Binding PinPdbPaths, Converter={StaticResource BoolToOpacityConverter}}"/>
123+
</ToggleButton>
116124
</Grid>
117125
</GroupBox>
118126

Modern/Pages/SymbolConfigPage.xaml.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public SymbolConfigPage() {
99
}
1010

1111
private void UseSymbolServer_Click(object sender, RoutedEventArgs e) {
12-
ViewModel.AppendPdbPath(@"SRV*c:\temp\symcache*https://msdl.microsoft.com/download/symbols");
12+
ViewModel.UpdatePdbPath(@"SRV*c:\temp\symcache*https://msdl.microsoft.com/download/symbols");
1313
ViewModel.StatusMessage = "Symbol server path added. Ready to resolve!";
1414
ViewModel.HighlightResolve = true;
1515
}
@@ -27,7 +27,7 @@ private void BrowsePdbPath_Click(object sender, RoutedEventArgs e) {
2727
Title = "Select FOLDER path to your PDBs"
2828
};
2929
if (dlg.ShowDialog(Window.GetWindow(this)) == true) {
30-
ViewModel.AppendPdbPath(Path.GetDirectoryName(dlg.FileName));
30+
ViewModel.UpdatePdbPath(Path.GetDirectoryName(dlg.FileName));
3131
}
3232
}
3333

@@ -56,7 +56,7 @@ private void SelectSQLPDB_Click(object sender, RoutedEventArgs e) {
5656
Owner = Window.GetWindow(this)
5757
};
5858
if (dialog.ShowDialog() == true) {
59-
ViewModel.AppendPdbPath(dialog.LastDownloadedSymFolder);
59+
ViewModel.UpdatePdbPath(dialog.LastDownloadedSymFolder);
6060
}
6161
}
6262

Modern/Properties/Settings.Designer.cs

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modern/Properties/Settings.settings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,11 @@
1414
<Setting Name="AcceptedSplashVersion" Type="System.String" Scope="User">
1515
<Value Profile="(Default)" />
1616
</Setting>
17+
<Setting Name="LastPdbPaths" Type="System.String" Scope="User">
18+
<Value Profile="(Default)" />
19+
</Setting>
20+
<Setting Name="PinPdbPaths" Type="System.Boolean" Scope="User">
21+
<Value Profile="(Default)">False</Value>
22+
</Setting>
1723
</Settings>
1824
</SettingsFile>

Modern/ResolverViewModel.cs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,32 @@ private void DetectSqlBuildVersion() {
189189
public string BaseAddressesString { get => _baseAddressesString; set => SetField(ref _baseAddressesString, value, nameof(BaseAddressesString)); }
190190

191191
// -- Symbol Config --
192-
private string _pdbPaths = string.Empty;
193-
public string PdbPaths { get => _pdbPaths; set => SetField(ref _pdbPaths, value, nameof(PdbPaths)); }
192+
private string _pdbPaths = Properties.Settings.Default.PinPdbPaths ? (Properties.Settings.Default.LastPdbPaths ?? string.Empty) : string.Empty;
193+
public string PdbPaths {
194+
get => _pdbPaths;
195+
set {
196+
if (SetField(ref _pdbPaths, value, nameof(PdbPaths)) && _pinPdbPaths) {
197+
Properties.Settings.Default.LastPdbPaths = value;
198+
Properties.Settings.Default.Save();
199+
}
200+
}
201+
}
202+
203+
private bool _pinPdbPaths = Properties.Settings.Default.PinPdbPaths;
204+
public bool PinPdbPaths {
205+
get => _pinPdbPaths;
206+
set {
207+
if (SetField(ref _pinPdbPaths, value, nameof(PinPdbPaths))) {
208+
Properties.Settings.Default.PinPdbPaths = value;
209+
if (value) {
210+
Properties.Settings.Default.LastPdbPaths = _pdbPaths;
211+
} else {
212+
Properties.Settings.Default.LastPdbPaths = string.Empty;
213+
}
214+
Properties.Settings.Default.Save();
215+
}
216+
}
217+
}
194218

195219
private bool _pdbRecurse = true;
196220
public bool PdbRecurse { get => _pdbRecurse; set => SetField(ref _pdbRecurse, value, nameof(PdbRecurse)); }
@@ -539,9 +563,9 @@ await MainWindow.ShowContentDialogAsync(
539563
} catch { /* best effort update check */ }
540564
}
541565

542-
internal void AppendPdbPath(string path) {
566+
internal void UpdatePdbPath(string path) {
543567
if (string.IsNullOrEmpty(path)) return;
544-
PdbPaths = string.IsNullOrEmpty(PdbPaths) ? path : PdbPaths + ";" + path;
568+
PdbPaths = path;
545569
}
546570

547571
internal void AppendBinaryPath(string path) {
@@ -591,7 +615,7 @@ internal async Task DownloadSymbolsForDetectedBuildAsync() {
591615
} else if (_cts?.IsCancellationRequested == true) {
592616
StatusMessage = StackResolver.OperationCanceled;
593617
} else {
594-
AppendPdbPath(destFolder);
618+
UpdatePdbPath(destFolder);
595619
StatusMessage = $"Symbols for {bld.BuildNumber} downloaded. Ready to resolve!";
596620
HighlightResolve = true;
597621
}

Modern/Views/ClassicView.xaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
FontSize="12">
66
<UserControl.Resources>
77
<local:BoolToVisibilityConverter x:Key="BoolToVis"/>
8+
<local:BoolToOpacityConverter x:Key="BoolToOpacityConverter"/>
89
</UserControl.Resources>
910
<UserControl.InputBindings>
1011
<KeyBinding Gesture="Ctrl+F" Command="Find"/>
@@ -182,6 +183,12 @@
182183
</StackPanel>
183184
<TextBlock Text="PDB search paths:" Foreground="Gray" Margin="0,0,0,2"/>
184185
<DockPanel Margin="0,0,0,4">
186+
<ToggleButton DockPanel.Dock="Right" IsChecked="{Binding PinPdbPaths}"
187+
Padding="2,2" Background="Transparent" BorderThickness="0" Margin="2,0,0,0"
188+
ToolTip="Pin to remember this path for next session">
189+
<TextBlock Text="&#xE718;" FontFamily="Segoe MDL2 Assets" FontSize="12"
190+
Opacity="{Binding PinPdbPaths, Converter={StaticResource BoolToOpacityConverter}}"/>
191+
</ToggleButton>
185192
<Button DockPanel.Dock="Right" Content="..." Width="30" Click="BrowsePdbPath_Click"
186193
ToolTip="Browse for PDB folder"/>
187194
<TextBox Text="{Binding PdbPaths, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,2,0"

0 commit comments

Comments
 (0)