Skip to content

Commit 5cf6423

Browse files
committed
Apply CE refactoring to CodeMetrics window.
1 parent 4ad676e commit 5cf6423

File tree

4 files changed

+157
-325
lines changed

4 files changed

+157
-325
lines changed

Rubberduck.Core/CodeAnalysis/CodeMetrics/CodeMetricsViewModel.cs

Lines changed: 66 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -6,140 +6,93 @@
66
using System.Collections.Generic;
77
using System.Collections.ObjectModel;
88
using Rubberduck.Navigation.CodeExplorer;
9-
using System.Windows;
10-
using Rubberduck.Navigation.Folders;
9+
using Rubberduck.Parsing.UIContext;
1110
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
1211

1312
namespace Rubberduck.CodeAnalysis.CodeMetrics
1413
{
15-
public class CodeMetricsViewModel : ViewModelBase, IDisposable
14+
public sealed class CodeMetricsViewModel : ViewModelBase, IDisposable
1615
{
1716
private readonly RubberduckParserState _state;
1817
private readonly ICodeMetricsAnalyst _analyst;
19-
//private readonly FolderHelper _folderHelper;
2018
private readonly IVBE _vbe;
19+
private readonly IUiDispatcher _uiDispatcher;
2120

2221
public CodeMetricsViewModel(
2322
RubberduckParserState state,
2423
ICodeMetricsAnalyst analyst,
25-
//FolderHelper folderHelper,
26-
IVBE vbe)
24+
IVBE vbe,
25+
IUiDispatcher uiDispatcher)
2726
{
2827
_state = state;
29-
_analyst = analyst;
30-
//_folderHelper = folderHelper;
3128
_state.StateChanged += OnStateChanged;
29+
30+
_analyst = analyst;
3231
_vbe = vbe;
33-
}
34-
35-
private void OnStateChanged(object sender, ParserStateEventArgs e)
36-
{
37-
if (e.State != ParserState.Ready && e.State != ParserState.Error && e.State != ParserState.ResolverError && e.State != ParserState.UnexpectedError)
38-
{
39-
IsBusy = true;
40-
}
32+
_uiDispatcher = uiDispatcher;
4133

42-
if (e.State == ParserState.Ready)
43-
{
44-
UpdateData();
45-
IsBusy = false;
46-
}
34+
OnPropertyChanged(nameof(Projects));
35+
}
4736

48-
if (e.State == ParserState.Error || e.State == ParserState.ResolverError || e.State == ParserState.UnexpectedError)
37+
private bool _unparsed = true;
38+
public bool Unparsed
39+
{
40+
get => _unparsed;
41+
set
4942
{
50-
IsBusy = false;
43+
if (_unparsed == value)
44+
{
45+
return;
46+
}
47+
_unparsed = value;
48+
OnPropertyChanged();
5149
}
5250
}
5351

54-
private void UpdateData()
52+
private void OnStateChanged(object sender, ParserStateEventArgs e)
5553
{
56-
IsBusy = true;
57-
58-
var metricResults = _analyst.GetMetrics(_state);
59-
resultsByDeclaration = metricResults.GroupBy(r => r.Declaration).ToDictionary(g => g.Key, g => g.ToList());
54+
Unparsed = false;
55+
IsBusy = _state.Status != ParserState.Pending && _state.Status <= ParserState.ResolvedDeclarations;
6056

61-
if (Projects == null)
57+
if (e.State != ParserState.ResolvedDeclarations)
6258
{
63-
Projects = new ObservableCollection<CodeExplorerItemViewModel>();
59+
return;
6460
}
6561

66-
IsBusy = _state.Status != ParserState.Pending && _state.Status <= ParserState.ResolvedDeclarations;
67-
68-
var userDeclarations = _state.DeclarationFinder.AllUserDeclarations
69-
.GroupBy(declaration => declaration.ProjectId)
70-
.ToList();
71-
72-
//var newProjects = userDeclarations
73-
// .Where(grouping => grouping.Any(declaration => declaration.DeclarationType == DeclarationType.Project))
74-
// .Select(grouping =>
75-
// new CodeExplorerProjectViewModel(_folderHelper,
76-
// grouping.SingleOrDefault(declaration => declaration.DeclarationType == DeclarationType.Project),
77-
// grouping,
78-
// _vbe)).ToList();
79-
80-
//UpdateNodes(Projects, newProjects);
81-
82-
//Projects = new ObservableCollection<CodeExplorerItemViewModel>(newProjects);
83-
84-
IsBusy = false;
62+
Synchronize(_state.DeclarationFinder.AllUserDeclarations.ToList());
8563
}
8664

87-
private void UpdateNodes(IEnumerable<CodeExplorerItemViewModel> oldList, IEnumerable<CodeExplorerItemViewModel> newList)
65+
private void Synchronize(List<Declaration> declarations)
8866
{
89-
foreach (var item in newList)
67+
var metricResults = _analyst.GetMetrics(_state);
68+
_resultsByDeclaration = metricResults.GroupBy(r => r.Declaration).ToDictionary(g => g.Key, g => g.ToList());
69+
70+
_uiDispatcher.Invoke(() =>
9071
{
91-
CodeExplorerItemViewModel oldItem;
72+
var existing = Projects.OfType<CodeExplorerProjectViewModel>().ToList();
9273

93-
if (item is CodeExplorerCustomFolderViewModel)
94-
{
95-
oldItem = oldList.FirstOrDefault(i => i.Name == item.Name);
96-
}
97-
else
74+
foreach (var project in existing)
9875
{
99-
oldItem = oldList.FirstOrDefault(i =>
100-
item.QualifiedSelection != null && i.QualifiedSelection != null &&
101-
i.QualifiedSelection.Value.QualifiedName.ProjectId ==
102-
item.QualifiedSelection.Value.QualifiedName.ProjectId &&
103-
i.QualifiedSelection.Value.QualifiedName.ComponentName ==
104-
item.QualifiedSelection.Value.QualifiedName.ComponentName &&
105-
i.QualifiedSelection.Value.Selection == item.QualifiedSelection.Value.Selection);
76+
project.Synchronize(declarations);
77+
if (project.Declaration is null)
78+
{
79+
Projects.Remove(project);
80+
}
10681
}
10782

108-
//if (oldItem != null)
109-
//{
110-
// item.IsExpanded = oldItem.IsExpanded;
111-
// item.IsSelected = oldItem.IsSelected;
112-
113-
// if (oldItem.Items.Any() && item.Items.Any())
114-
// {
115-
// UpdateNodes(oldItem.Items, item.Items);
116-
// }
117-
//}
118-
}
119-
}
120-
121-
public void Dispose()
122-
{
123-
Dispose(true);
124-
GC.SuppressFinalize(this);
125-
}
126-
127-
private bool _isDisposed;
128-
protected virtual void Dispose(bool disposing)
129-
{
130-
if (_isDisposed || !disposing)
131-
{
132-
return;
133-
}
134-
_isDisposed = true;
83+
var adding = declarations.OfType<ProjectDeclaration>().ToList();
13584

136-
_state.StateChanged -= OnStateChanged;
85+
foreach (var project in adding)
86+
{
87+
var model = new CodeExplorerProjectViewModel(project, declarations, _state, _vbe, false);
88+
Projects.Add(model);
89+
model.IsExpanded = true;
90+
}
91+
});
13792
}
13893

139-
private Dictionary<Declaration, List<ICodeMetricResult>> resultsByDeclaration;
140-
141-
private CodeExplorerItemViewModel _selectedItem;
142-
public CodeExplorerItemViewModel SelectedItem
94+
private ICodeExplorerNode _selectedItem;
95+
public ICodeExplorerNode SelectedItem
14396
{
14497
get => _selectedItem;
14598
set
@@ -154,26 +107,14 @@ public CodeExplorerItemViewModel SelectedItem
154107
}
155108
}
156109

157-
private ObservableCollection<CodeExplorerItemViewModel> _projects;
158-
public ObservableCollection<CodeExplorerItemViewModel> Projects
159-
{
160-
get => _projects;
161-
set
162-
{
163-
_projects = new ObservableCollection<CodeExplorerItemViewModel>(value.OrderBy(o => o.NameWithSignature));
164-
165-
OnPropertyChanged();
166-
OnPropertyChanged(nameof(TreeViewVisibility));
167-
}
168-
}
110+
public ObservableCollection<ICodeExplorerNode> Projects { get; } = new ObservableCollection<ICodeExplorerNode>();
169111

170-
public Visibility TreeViewVisibility => Projects == null || Projects.Count == 0 ? Visibility.Collapsed : Visibility.Visible;
171-
112+
private Dictionary<Declaration, List<ICodeMetricResult>> _resultsByDeclaration;
172113
public ObservableCollection<ICodeMetricResult> Metrics
173114
{
174115
get
175116
{
176-
var results = resultsByDeclaration?.FirstOrDefault(f => ReferenceEquals(f.Key, SelectedItem.Declaration));
117+
var results = _resultsByDeclaration?.FirstOrDefault(f => ReferenceEquals(f.Key, SelectedItem.Declaration));
177118
return results?.Value == null ? new ObservableCollection<ICodeMetricResult>() : new ObservableCollection<ICodeMetricResult>(results.Value.Value);
178119
}
179120
}
@@ -185,23 +126,27 @@ public bool IsBusy
185126
set
186127
{
187128
_isBusy = value;
188-
EmptyUIRefreshMessageVisibility = false;
189129
OnPropertyChanged();
190130
}
191131
}
192132

193-
private bool _emptyUIRefreshMessageVisibility = true;
194-
public bool EmptyUIRefreshMessageVisibility
133+
public void Dispose()
195134
{
196-
get => _emptyUIRefreshMessageVisibility;
197-
set
135+
Dispose(true);
136+
GC.SuppressFinalize(this);
137+
}
138+
139+
private bool _isDisposed;
140+
141+
private void Dispose(bool disposing)
142+
{
143+
if (_isDisposed || !disposing)
198144
{
199-
if (_emptyUIRefreshMessageVisibility != value)
200-
{
201-
_emptyUIRefreshMessageVisibility = value;
202-
OnPropertyChanged();
203-
}
145+
return;
204146
}
147+
_isDisposed = true;
148+
149+
_state.StateChanged -= OnStateChanged;
205150
}
206151
}
207152
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerProjectViewModel.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,25 @@ public class CodeExplorerProjectViewModel : CodeExplorerItemViewModel
2222

2323
private readonly IVBE _vbe;
2424

25-
public CodeExplorerProjectViewModel(Declaration declaration, IEnumerable<Declaration> declarations, RubberduckParserState state, IVBE vbe) : base(null, declaration)
25+
public CodeExplorerProjectViewModel(Declaration declaration, IEnumerable<Declaration> declarations, RubberduckParserState state, IVBE vbe, bool references = true) : base(null, declaration)
2626
{
27-
State = state;
27+
State = state;
2828
_vbe = vbe;
29+
ShowReferences = references;
30+
2931
SetName();
3032
AddNewChildren(declarations.ToList());
3133
}
3234

3335
private string _displayName;
3436
private string _name;
3537

36-
public override string Name => string.IsNullOrEmpty(_displayName) ? _name : $"{_name} ({_displayName})";
37-
3838
public RubberduckParserState State { get; }
3939

40+
public bool ShowReferences { get; }
41+
42+
public override string Name => string.IsNullOrEmpty(_displayName) ? _name : $"{_name} ({_displayName})";
43+
4044
public override FontWeight FontWeight
4145
{
4246
get
@@ -99,6 +103,11 @@ protected sealed override void AddNewChildren(List<Declaration> updated)
99103

100104
private void SynchronizeReferences()
101105
{
106+
if (!ShowReferences)
107+
{
108+
return;
109+
}
110+
102111
var references = GetProjectReferenceModels();
103112
foreach (var child in Children.OfType<CodeExplorerReferenceFolderViewModel>())
104113
{

0 commit comments

Comments
 (0)