rubberduck-vba / Rubberduck

Compare 99e9094 ... +4 ... ed717df

Missing base report.

Unable to compare commits because the base of the compare did not upload a coverage report.

Learn more here.

Showing 2 of 4 files from the diff.

@@ -80,7 +80,7 @@
Loading
80 80
            INavigateCommand navigateCommand, 
81 81
            ReparseCommand reparseCommand,
82 82
            IClipboardWriter clipboard,
83 -
            IConfigurationService<Configuration> configService, 
83 +
            IConfigurationService<Configuration> configService,
84 84
            ISettingsFormFactory settingsFormFactory,
85 85
            IUiDispatcher uiDispatcher)
86 86
        {
@@ -96,8 +96,8 @@
Loading
96 96
            RefreshCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(),
97 97
                o =>
98 98
                {
99 -
                    IsRefreshing = true;
100 99
                    IsBusy = true;
100 +
                    _forceRefreshResults = true;
101 101
                    var cancellation = new ReparseCancellationFlag();
102 102
                    reparseCommand.Execute(cancellation);
103 103
                    if (cancellation.Canceled)
@@ -136,11 +136,6 @@
Loading
136 136
            _state.StateChanged += HandleStateChanged;
137 137
        }
138 138
139 -
        /// <summary>
140 -
        /// Gets/sets a flag indicating whether the parser state changes are a result of our RefreshCommand.
141 -
        /// </summary>
142 -
        private bool IsRefreshing { get; set; }
143 -
144 139
        private void _configService_SettingsChanged(object sender, ConfigurationChangedEventArgs e)
145 140
        {            
146 141
            if (e.InspectionSettingsChanged)
@@ -235,9 +230,12 @@
Loading
235 230
                }
236 231
237 232
                _grouping = value;
238 -
                Results.GroupDescriptions.Clear();
239 -
                Results.GroupDescriptions.Add(GroupDescriptions[_grouping]);
240 -
                Results.Refresh();
233 +
                // Deferring refresh to avoid a rerendering without grouping
234 +
                using (Results.DeferRefresh())
235 +
                {
236 +
                    Results.GroupDescriptions.Clear();
237 +
                    Results.GroupDescriptions.Add(GroupDescriptions[_grouping]);
238 +
                }
241 239
                OnPropertyChanged();
242 240
            }
243 241
        }
@@ -255,7 +253,9 @@
Loading
255 253
256 254
                _filters = value;
257 255
                OnPropertyChanged();
258 -
                Results.Refresh();
256 +
257 +
                // updating Filter forces a Refresh
258 +
                Results.Filter = i => InspectionFilter((IInspectionResult)i);
259 259
            }
260 260
        }
261 261
@@ -311,7 +311,6 @@
Loading
311 311
        }
312 312
313 313
        private bool _canQuickFix;
314 -
315 314
        public bool CanQuickFix
316 315
        {
317 316
            get => _canQuickFix;
@@ -333,6 +332,12 @@
Loading
333 332
            } 
334 333
        }
335 334
335 +
        /// <summary>
336 +
        /// A boolean indicating that a local refresh was triggered.
337 +
        /// When this is set to true, InspectionResults are refreshed, even when inspecting after successful parsing is disabled.
338 +
        /// </summary>
339 +
        private bool _forceRefreshResults = false;
340 +
336 341
        private bool _unparsed = true;
337 342
        public bool Unparsed
338 343
        {
@@ -362,14 +367,17 @@
Loading
362 367
        private bool _runInspectionsOnReparse;
363 368
        private void HandleStateChanged(object sender, ParserStateEventArgs e)
364 369
        {
365 -
            if (!IsRefreshing && (_state.Status == ParserState.Pending || _state.Status == ParserState.Error || _state.Status == ParserState.ResolverError))
370 +
            if (_state.Status == ParserState.Pending || _state.Status == ParserState.Error || _state.Status == ParserState.ResolverError)
366 371
            {
372 +
                // an error in parser state resets the busy state
367 373
                IsBusy = false;
368 374
                return;
369 375
            }
370 376
371 377
            if(_state.Status != ParserState.Ready)
372 378
            {
379 +
                // not an error, but also not finished -> We're busy
380 +
                IsBusy = true;
373 381
                return;
374 382
            }
375 383
@@ -378,7 +386,9 @@
Loading
378 386
                return;
379 387
            }
380 388
381 -
            if (_runInspectionsOnReparse || IsRefreshing)
389 +
            // push Unparsed to false on the first successful parse
390 +
            Unparsed = false;
391 +
            if (_runInspectionsOnReparse || _forceRefreshResults)
382 392
            {
383 393
                RefreshInspections(e.Token);
384 394
            }
@@ -388,6 +398,7 @@
Loading
388 398
                var modifiedModules = _state.DeclarationFinder.AllModules.ToHashSet();
389 399
                InvalidateStaleInspectionResults(modifiedModules);
390 400
            }
401 +
            IsBusy = false;
391 402
        }
392 403
393 404
        private async void RefreshInspections(CancellationToken token)
@@ -409,9 +420,7 @@
Loading
409 420
            }
410 421
411 422
            stopwatch.Stop();
412 -
            LogManager.GetCurrentClassLogger().Trace("Inspection results returned in {0}ms", stopwatch.ElapsedMilliseconds);
413 -
414 -
            Unparsed = false;
423 +
            Logger.Trace("Inspection results returned in {0}ms", stopwatch.ElapsedMilliseconds);
415 424
416 425
            _uiDispatcher.Invoke(() =>
417 426
            {
@@ -423,28 +432,27 @@
Loading
423 432
                    {
424 433
                        _results.Add(result);
425 434
                    }
426 -
427 435
                    Results.Refresh();
428 -
                    SelectedItem = null;
429 436
                }
430 437
                catch (Exception exception)
431 438
                {
432 -
                    Logger.Error(exception, "Exception thrown trying to refresh the inspection results view on th UI thread.");
439 +
                    Logger.Error(exception, "Exception thrown trying to refresh the inspection results view on the UI thread.");
433 440
                }
434 441
                finally
435 442
                {
436 443
                    IsBusy = false;
437 -
                    IsRefreshing = false;
444 +
                    // refreshing results is only disabled when successful
445 +
                    // It's basically a "refresh on success once".
446 +
                    _forceRefreshResults = false;
438 447
                }
439 448
440 449
                stopwatch.Stop();
441 -
                LogManager.GetCurrentClassLogger().Trace("Inspection results rendered in {0}ms", stopwatch.ElapsedMilliseconds);
450 +
                Logger.Trace("Inspection results rendered in {0}ms", stopwatch.ElapsedMilliseconds);
442 451
            });
443 452
        }
444 453
445 -
        private void InvalidateStaleInspectionResults(ICollection<QualifiedModuleName> modifiedModules)
454 +
        private void InvalidateUIStaleInspectionResults(ICollection<IInspectionResult> staleResults)
446 455
        {
447 -
            var staleResults = _results.Where(result => result.ChangesInvalidateResult(modifiedModules)).ToList();
448 456
            _uiDispatcher.Invoke(() =>
449 457
            {
450 458
                foreach (var staleResult in staleResults)
@@ -455,6 +463,13 @@
Loading
455 463
            });
456 464
        }
457 465
466 +
        private void InvalidateStaleInspectionResults(ICollection<QualifiedModuleName> modifiedModules)
467 +
        {
468 +
            // materialize the collection to take work off of the UI thread
469 +
            var staleResults = _results.Where(result => result.ChangesInvalidateResult(modifiedModules)).ToList();
470 +
            InvalidateUIStaleInspectionResults(staleResults);
471 +
        }
472 +
458 473
        private void ExecuteQuickFixCommand(object parameter)
459 474
        {
460 475
            var quickFix = parameter as IQuickFix;
@@ -547,14 +562,12 @@
Loading
547 562
548 563
            Task.Run(() => _configService.Save(config));
549 564
550 -
            _uiDispatcher.Invoke(() =>
551 -
            {
552 -
                RefreshCommand.Execute(null);
553 -
            });
565 +
            // remove inspection results of the selected inspection from the UI
566 +
            // collection is materialized to take work off of the UI thread
567 +
            InvalidateUIStaleInspectionResults(_results.Where(i => i.Inspection == _selectedInspection).ToList());
554 568
        }
555 569
556 570
        private bool _canDisableInspection;
557 -
558 571
        public bool CanDisableInspection
559 572
        {
560 573
            get => _canDisableInspection;

@@ -17,7 +17,7 @@
Loading
17 17
            <ResourceDictionary.MergedDictionaries>
18 18
                <ResourceDictionary Source="../Controls/ToolBar.xaml"/>
19 19
            </ResourceDictionary.MergedDictionaries>
20 -
20 +
            
21 21
            <codeInspections:InspectionSeverityImageSourceConverter x:Key="SeverityIconConverter" />
22 22
            <codeInspections:InspectionImageSourceConverter x:Key="InspectionIconConverter" />
23 23
            <codeInspections:QuickFixImageSourceConverter x:Key="QuickFixIconConverter" />
@@ -26,24 +26,6 @@
Loading
26 26
                <Setter Property="Margin" Value="4" />
27 27
            </Style>
28 28
29 -
            <BitmapImage x:Key="CopyResultsImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/document-copy.png" />
30 -
            <BitmapImage x:Key="SettingsImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/gear.png" />
31 -
            <BitmapImage x:Key="RefreshImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/arrow-circle-double.png" />
32 -
            <BitmapImage x:Key="FixImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/tick.png" />
33 -
34 -
            <BitmapImage x:Key="GroupByInspectionTypeImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/block.png" />
35 -
            <BitmapImage x:Key="GroupByInspectionImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/light-bulb-code.png" />
36 -
            <BitmapImage x:Key="GroupByLocationImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/ObjectClass.png" />
37 -
            <BitmapImage x:Key="GroupBySeverityImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/Severity.png" />
38 -
39 -
            <BitmapImage x:Key="FilterByHintImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/information-white.png" />
40 -
            <BitmapImage x:Key="FilterBySuggestionImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/information.png" />
41 -
            <BitmapImage x:Key="FilterByWarningImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/exclamation.png" />
42 -
            <BitmapImage x:Key="FilterByErrorImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/cross-circle.png" />
43 -
44 -
            <BitmapImage x:Key="ExpandAllImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/expand-all.png" />
45 -
            <BitmapImage x:Key="CollapseAllImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/collapse-all.png" />
46 -
47 29
            <Style TargetType="Image">
48 30
                <Setter Property="Height" Value="16"/>
49 31
                <Setter Property="Width" Value="16" />
@@ -63,18 +45,29 @@
Loading
63 45
64 46
            <ToolBar Style="{StaticResource ToolBarWithOverflowOnlyShowingWhenNeededStyle}">
65 47
                <ToolBar.Resources>
66 -
                    <codeInspections:InspectionFilterToBooleanConverter x:Key="ErrorFlagConverter" />
67 -
                    <codeInspections:InspectionFilterToBooleanConverter x:Key="WarningFlagConverter" />
68 -
                    <codeInspections:InspectionFilterToBooleanConverter x:Key="SuggestionFlagConverter" />
69 -
                    <codeInspections:InspectionFilterToBooleanConverter x:Key="HintFlagConverter" />
70 -
                    <codeInspections:InspectionResultGroupingToBooleanConverter x:Key="GroupByTypeConverter" />
71 -
                    <codeInspections:InspectionResultGroupingToBooleanConverter x:Key="GroupByNameConverter" />
72 -
                    <codeInspections:InspectionResultGroupingToBooleanConverter x:Key="GroupByLocationConverter" />
73 -
                    <codeInspections:InspectionResultGroupingToBooleanConverter x:Key="GroupBySeverityConverter" />
48 +
                    <codeInspections:InspectionFilterToBooleanConverter x:Key="InspectionTypeToBooleanConverter" />
49 +
                    <codeInspections:InspectionResultGroupingToBooleanConverter x:Key="GroupingToBooleanConverter" />
74 50
                    <Style x:Key="ToolBarToggleStyle" TargetType="ToggleButton">
75 51
                        <Setter Property="Margin" Value="2" />
76 52
                        <Setter Property="BorderBrush" Value="{x:Static SystemColors.ActiveBorderBrush}" />
77 53
                    </Style>
54 +
                    <BitmapImage x:Key="CopyResultsImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/document-copy.png" />
55 +
                    <BitmapImage x:Key="SettingsImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/gear.png" />
56 +
                    <BitmapImage x:Key="RefreshImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/arrow-circle-double.png" />
57 +
                    <BitmapImage x:Key="FixImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/tick.png" />
58 +
59 +
                    <BitmapImage x:Key="GroupByInspectionTypeImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/block.png" />
60 +
                    <BitmapImage x:Key="GroupByInspectionImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/light-bulb-code.png" />
61 +
                    <BitmapImage x:Key="GroupByLocationImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/ObjectClass.png" />
62 +
                    <BitmapImage x:Key="GroupBySeverityImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/Severity.png" />
63 +
64 +
                    <BitmapImage x:Key="FilterByHintImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/information-white.png" />
65 +
                    <BitmapImage x:Key="FilterBySuggestionImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/information.png" />
66 +
                    <BitmapImage x:Key="FilterByWarningImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/exclamation.png" />
67 +
                    <BitmapImage x:Key="FilterByErrorImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/cross-circle.png" />
68 +
69 +
                    <BitmapImage x:Key="ExpandAllImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/expand-all.png" />
70 +
                    <BitmapImage x:Key="CollapseAllImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/collapse-all.png" />
78 71
                </ToolBar.Resources>
79 72
80 73
                <Button Command="{Binding RefreshCommand}">
@@ -114,25 +107,25 @@
Loading
114 107
115 108
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
116 109
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=GroupingStyle_ByInspectionType}"
117 -
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupByTypeConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Type}}">
110 +
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupingToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Type}}">
118 111
                    <Image Source="{StaticResource GroupByInspectionTypeImage}" />
119 112
                </ToggleButton>
120 113
121 114
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
122 115
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=GroupingStyle_ByName}"
123 -
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupByNameConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Name}}">
116 +
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupingToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Name}}">
124 117
                    <Image Source="{StaticResource GroupByInspectionImage}" />
125 118
                </ToggleButton>
126 119
127 120
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
128 121
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=GroupingStyle_ByLocation}"
129 -
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupByLocationConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Location}}">
122 +
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupingToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Location}}">
130 123
                    <Image Source="{StaticResource GroupByLocationImage}" />
131 124
                </ToggleButton>
132 125
133 126
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
134 127
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=GroupingStyle_BySeverity}"
135 -
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupBySeverityConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Severity}}">
128 +
                              IsChecked="{Binding Path=Grouping, Converter={StaticResource GroupingToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultGrouping.Severity}}">
136 129
                    <Image Source="{StaticResource GroupBySeverityImage}" />
137 130
                </ToggleButton>
138 131
@@ -142,25 +135,25 @@
Loading
142 135
143 136
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
144 137
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=InspectionResults_FilterByError}"
145 -
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource ErrorFlagConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Error}}">
138 +
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource InspectionTypeToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Error}}">
146 139
                    <Image Source="{StaticResource FilterByErrorImage}" />
147 140
                </ToggleButton>
148 141
149 142
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
150 143
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=InspectionResults_FilterByWarning}"
151 -
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource WarningFlagConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Warning}}">
144 +
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource InspectionTypeToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Warning}}">
152 145
                    <Image Source="{StaticResource FilterByWarningImage}" />
153 146
                </ToggleButton>
154 147
155 148
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
156 149
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=InspectionResults_FilterBySuggestion}"
157 -
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource SuggestionFlagConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Suggestion}}">
150 +
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource InspectionTypeToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Suggestion}}">
158 151
                    <Image Source="{StaticResource FilterBySuggestionImage}" />
159 152
                </ToggleButton>
160 153
161 154
                <ToggleButton Style="{StaticResource ToolBarToggleStyle}"
162 155
                              ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=InspectionResults_FilterByHint}"
163 -
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource HintFlagConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Hint}}">
156 +
                              IsChecked="{Binding Path=SelectedFilters, Converter={StaticResource InspectionTypeToBooleanConverter}, ConverterParameter={x:Static codeInspections:InspectionResultsFilter.Hint}}">
164 157
                    <Image Source="{StaticResource FilterByHintImage}" />
165 158
                </ToggleButton>
166 159
@@ -199,7 +192,7 @@
Loading
199 192
                               SelectedItem="{Binding SelectedItem}"
200 193
                               SelectionUnit="FullRow"
201 194
                               ItemsSource="{Binding Results, NotifyOnSourceUpdated=True}"
202 -
                               VirtualizingPanel.IsVirtualizingWhenGrouping="False">
195 +
                               VirtualizingPanel.IsVirtualizingWhenGrouping="True">
203 196
            <DataGrid.RowDetailsTemplate>
204 197
                <DataTemplate>
205 198
                    <Grid>
@@ -242,8 +235,6 @@
Loading
242 235
        </controls:GroupingGrid>
243 236
244 237
        <controls:EmptyUIRefresh Grid.Row="1" Visibility="{Binding Unparsed, Converter={StaticResource BoolToVisibility}}" />
245 -
246 -
247 238
        <controls:BusyIndicator Grid.Row="1" Width="120" Height="120" Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}" />
248 239
249 240
        <GridSplitter Grid.Row="2" Height="5" ShowsPreview="True" Cursor="SizeNS" HorizontalAlignment="Stretch"/>

Unable to process changes.

No base report to compare against.

Files Coverage
ComClientLibrary 8.97%
Root 96.67%
Extension.cs 0.00%
VbeProvider.cs 0.00%
Folder Totals (4 files) 46.71%
Project Totals (1079 files) 64.23%
Loading