Skip to content

Commit d9e4a3c

Browse files
authored
Merge pull request #4717 from comintern/inspections
Inspection Result window performance overhaul (Round 1)
2 parents f480325 + 5ad9a1c commit d9e4a3c

22 files changed

+876
-356
lines changed

Rubberduck.Core/UI/Command/ReparseCommand.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515

1616
namespace Rubberduck.UI.Command
1717
{
18+
[ComVisible(false)]
19+
public class ReparseCancellationFlag
20+
{
21+
public bool Canceled { get; set; }
22+
}
23+
1824
[ComVisible(false)]
1925
public class ReparseCommand : CommandBase
2026
{
@@ -58,13 +64,21 @@ protected override void OnExecute(object parameter)
5864
{
5965
if (!VerifyCompileOnDemand())
6066
{
67+
if (parameter is ReparseCancellationFlag cancellation)
68+
{
69+
cancellation.Canceled = true;
70+
}
6171
return;
6272
}
6373

6474
if (AreAllProjectsCompiled(out var failedNames))
6575
{
6676
if (!PromptUserToContinue(failedNames))
6777
{
78+
if (parameter is ReparseCancellationFlag cancellation)
79+
{
80+
cancellation.Canceled = true;
81+
}
6882
return;
6983
}
7084
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
using System.Windows.Interactivity;
4+
using GongSolutions.Wpf.DragDrop.Utilities;
5+
6+
namespace Rubberduck.UI.Controls
7+
{
8+
public class GroupItemExpandedBehavior : Behavior<DataGrid>
9+
{
10+
public object ExpandedState
11+
{
12+
get => GetValue(ExpandedStateProperty);
13+
set => SetValue(ExpandedStateProperty, value);
14+
}
15+
16+
public static readonly DependencyProperty ExpandedStateProperty =
17+
DependencyProperty.Register("ExpandedState", typeof(object), typeof(GroupItemExpandedBehavior), new UIPropertyMetadata(null, OnExpandedStateChanged));
18+
19+
private static void OnExpandedStateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
20+
{
21+
if (!(sender is GroupItemExpandedBehavior data) ||
22+
!(data.AssociatedObject is DataGrid grid) ||
23+
!grid.IsGrouping ||
24+
!(e.NewValue is bool))
25+
{
26+
return;
27+
}
28+
29+
foreach (var expander in grid.GetVisualDescendents<Expander>())
30+
{
31+
expander.IsExpanded = (bool)e.NewValue;
32+
}
33+
}
34+
}
35+
}

Rubberduck.Core/UI/Controls/GroupingGrid.xaml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
<Setter Property="Template">
6161
<Setter.Value>
6262
<ControlTemplate>
63-
<Expander Background="WhiteSmoke" Foreground="Black" FontWeight="SemiBold" IsExpanded="True">
63+
<Expander Background="WhiteSmoke" Foreground="Black" FontWeight="SemiBold">
6464
<Expander.Header>
6565
<StackPanel Orientation="Horizontal">
6666
<TextBlock Margin="4"
@@ -107,7 +107,6 @@
107107
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled" />
108108
<Setter Property="ItemContainerStyle" Value="{StaticResource PrettifyRow}" />
109109
<Setter Property="ColumnHeaderHeight" Value="22" />
110-
<Setter Property="SelectionMode" Value="Single" />
111110
</Style>
112111
</DataGrid.Style>
113112
<DataGrid.CellStyle>
@@ -116,7 +115,16 @@
116115
<Setter Property="Background" Value="Transparent" />
117116
<Setter Property="Padding" Value="0" />
118117
<Setter Property="VerticalContentAlignment" Value="Stretch" />
119-
<Setter Property="VerticalAlignment" Value="Center" />
118+
<Setter Property="VerticalAlignment" Value="Stretch" />
119+
<Setter Property="Template">
120+
<Setter.Value>
121+
<ControlTemplate TargetType="{x:Type DataGridCell}">
122+
<Grid Background="{TemplateBinding Background}">
123+
<ContentPresenter VerticalAlignment="Center" />
124+
</Grid>
125+
</ControlTemplate>
126+
</Setter.Value>
127+
</Setter>
120128
</Style>
121129
</DataGrid.CellStyle>
122130
</DataGrid>

Rubberduck.Core/UI/Controls/GroupingGrid.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Rubberduck.UI.Controls
77
public partial class GroupingGrid
88
{
99
public static readonly DependencyProperty ShowGroupingItemCountProperty =
10-
DependencyProperty.Register("ShowGroupingItemCount", typeof (bool), typeof (GroupingGrid));
10+
DependencyProperty.Register("ShowGroupingItemCount", typeof (bool), typeof(GroupingGrid));
1111

1212
public bool ShowGroupingItemCount
1313
{
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows.Data;
4+
5+
namespace Rubberduck.UI.Inspections
6+
{
7+
internal class InspectionFilterToBooleanConverter : IValueConverter
8+
{
9+
private InspectionResultsFilter _state;
10+
11+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12+
{
13+
if (!(parameter is InspectionResultsFilter flag) ||
14+
!(value is InspectionResultsFilter bound))
15+
{
16+
return _state;
17+
}
18+
19+
_state = bound;
20+
return _state.HasFlag(flag);
21+
}
22+
23+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
24+
{
25+
if (!(parameter is InspectionResultsFilter flag) ||
26+
!(value is bool isSet))
27+
{
28+
return _state;
29+
}
30+
31+
_state ^= flag;
32+
return _state;
33+
}
34+
}
35+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using Rubberduck.Parsing.Inspections.Abstract;
2+
using System.Collections.Generic;
3+
4+
namespace Rubberduck.UI.Inspections
5+
{
6+
public static class InspectionResultComparer
7+
{
8+
public static Comparer<IInspectionResult> InspectionType { get; } = new CompareByInspectionType();
9+
10+
public static Comparer<IInspectionResult> Name { get; } = new CompareByInspectionName();
11+
12+
public static Comparer<IInspectionResult> Location { get; } = new CompareByLocation();
13+
14+
public static Comparer<IInspectionResult> Severity { get; } = new CompareBySeverity();
15+
}
16+
17+
public class CompareByInspectionType : Comparer<IInspectionResult>
18+
{
19+
public override int Compare(IInspectionResult x, IInspectionResult y)
20+
{
21+
if (x == y)
22+
{
23+
return 0;
24+
}
25+
26+
if (x?.Inspection?.InspectionType is null)
27+
{
28+
return -1;
29+
}
30+
31+
return x.Inspection.InspectionType.CompareTo(y?.Inspection?.InspectionType);
32+
}
33+
}
34+
35+
public class CompareByInspectionName : Comparer<IInspectionResult>
36+
{
37+
public override int Compare(IInspectionResult x, IInspectionResult y)
38+
{
39+
if (x == y)
40+
{
41+
return 0;
42+
}
43+
44+
if (x?.Inspection?.Name is null)
45+
{
46+
return -1;
47+
}
48+
49+
return x.Inspection.Name.CompareTo(y?.Inspection?.Name);
50+
}
51+
}
52+
53+
public class CompareByLocation : Comparer<IInspectionResult>
54+
{
55+
public override int Compare(IInspectionResult x, IInspectionResult y)
56+
{
57+
if (x == y)
58+
{
59+
return 0;
60+
}
61+
62+
var first = x?.QualifiedSelection.QualifiedName;
63+
64+
if (first is null)
65+
{
66+
return -1;
67+
}
68+
69+
var second = y?.QualifiedSelection.QualifiedName;
70+
71+
if (second is null)
72+
{
73+
return 1;
74+
}
75+
76+
var nameComparison = first.Value.Name.CompareTo(second.Value.Name);
77+
if (nameComparison != 0)
78+
{
79+
return nameComparison;
80+
}
81+
82+
return x.QualifiedSelection.CompareTo(y.QualifiedSelection);
83+
}
84+
}
85+
86+
public class CompareBySeverity : Comparer<IInspectionResult>
87+
{
88+
public override int Compare(IInspectionResult x, IInspectionResult y)
89+
{
90+
if (x == y)
91+
{
92+
return 0;
93+
}
94+
95+
if (y?.Inspection is null)
96+
{
97+
return 1;
98+
}
99+
100+
// The CodeInspectionSeverity enum is ordered least severe to most. We want the opposite.
101+
return y.Inspection.Severity.CompareTo(x?.Inspection?.Severity);
102+
}
103+
}
104+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows.Data;
4+
5+
namespace Rubberduck.UI.Inspections
6+
{
7+
/// <summary>
8+
/// Provides a mutally exclusive binding between an InspectionResultGrouping and a boolean.
9+
/// Note: This is a stateful converter, so each bound control requires its own converter instance.
10+
/// </summary>
11+
public class InspectionResultGroupingToBooleanConverter : IValueConverter
12+
{
13+
private InspectionResultGrouping _state;
14+
15+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
16+
{
17+
if (!(parameter is InspectionResultGrouping governing) ||
18+
!(value is InspectionResultGrouping bound))
19+
{
20+
return false;
21+
}
22+
23+
_state = bound;
24+
return _state == governing;
25+
}
26+
27+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
28+
{
29+
if (!(parameter is InspectionResultGrouping governing) ||
30+
!(value is bool isSet))
31+
{
32+
return _state;
33+
}
34+
35+
_state = isSet ? governing : _state;
36+
return _state;
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)