Skip to content

Commit

Permalink
Apply CE refactoring to CodeMetrics window.
Browse files Browse the repository at this point in the history
  • Loading branch information
comintern committed Jan 14, 2019
1 parent 4ad676e commit 5cf6423
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 325 deletions.
187 changes: 66 additions & 121 deletions Rubberduck.Core/CodeAnalysis/CodeMetrics/CodeMetricsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,140 +6,93 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Rubberduck.Navigation.CodeExplorer;
using System.Windows;
using Rubberduck.Navigation.Folders;
using Rubberduck.Parsing.UIContext;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;

namespace Rubberduck.CodeAnalysis.CodeMetrics
{
public class CodeMetricsViewModel : ViewModelBase, IDisposable
public sealed class CodeMetricsViewModel : ViewModelBase, IDisposable
{
private readonly RubberduckParserState _state;
private readonly ICodeMetricsAnalyst _analyst;
//private readonly FolderHelper _folderHelper;
private readonly IVBE _vbe;
private readonly IUiDispatcher _uiDispatcher;

public CodeMetricsViewModel(
RubberduckParserState state,
ICodeMetricsAnalyst analyst,
//FolderHelper folderHelper,
IVBE vbe)
IVBE vbe,
IUiDispatcher uiDispatcher)
{
_state = state;
_analyst = analyst;
//_folderHelper = folderHelper;
_state.StateChanged += OnStateChanged;

_analyst = analyst;
_vbe = vbe;
}

private void OnStateChanged(object sender, ParserStateEventArgs e)
{
if (e.State != ParserState.Ready && e.State != ParserState.Error && e.State != ParserState.ResolverError && e.State != ParserState.UnexpectedError)
{
IsBusy = true;
}
_uiDispatcher = uiDispatcher;

if (e.State == ParserState.Ready)
{
UpdateData();
IsBusy = false;
}
OnPropertyChanged(nameof(Projects));
}

if (e.State == ParserState.Error || e.State == ParserState.ResolverError || e.State == ParserState.UnexpectedError)
private bool _unparsed = true;
public bool Unparsed
{
get => _unparsed;
set
{
IsBusy = false;
if (_unparsed == value)
{
return;
}
_unparsed = value;
OnPropertyChanged();
}
}

private void UpdateData()
private void OnStateChanged(object sender, ParserStateEventArgs e)
{
IsBusy = true;

var metricResults = _analyst.GetMetrics(_state);
resultsByDeclaration = metricResults.GroupBy(r => r.Declaration).ToDictionary(g => g.Key, g => g.ToList());
Unparsed = false;
IsBusy = _state.Status != ParserState.Pending && _state.Status <= ParserState.ResolvedDeclarations;

if (Projects == null)
if (e.State != ParserState.ResolvedDeclarations)
{
Projects = new ObservableCollection<CodeExplorerItemViewModel>();
return;
}

IsBusy = _state.Status != ParserState.Pending && _state.Status <= ParserState.ResolvedDeclarations;

var userDeclarations = _state.DeclarationFinder.AllUserDeclarations
.GroupBy(declaration => declaration.ProjectId)
.ToList();

//var newProjects = userDeclarations
// .Where(grouping => grouping.Any(declaration => declaration.DeclarationType == DeclarationType.Project))
// .Select(grouping =>
// new CodeExplorerProjectViewModel(_folderHelper,
// grouping.SingleOrDefault(declaration => declaration.DeclarationType == DeclarationType.Project),
// grouping,
// _vbe)).ToList();

//UpdateNodes(Projects, newProjects);

//Projects = new ObservableCollection<CodeExplorerItemViewModel>(newProjects);

IsBusy = false;
Synchronize(_state.DeclarationFinder.AllUserDeclarations.ToList());
}

private void UpdateNodes(IEnumerable<CodeExplorerItemViewModel> oldList, IEnumerable<CodeExplorerItemViewModel> newList)
private void Synchronize(List<Declaration> declarations)
{
foreach (var item in newList)
var metricResults = _analyst.GetMetrics(_state);
_resultsByDeclaration = metricResults.GroupBy(r => r.Declaration).ToDictionary(g => g.Key, g => g.ToList());

_uiDispatcher.Invoke(() =>
{
CodeExplorerItemViewModel oldItem;
var existing = Projects.OfType<CodeExplorerProjectViewModel>().ToList();
if (item is CodeExplorerCustomFolderViewModel)
{
oldItem = oldList.FirstOrDefault(i => i.Name == item.Name);
}
else
foreach (var project in existing)
{
oldItem = oldList.FirstOrDefault(i =>
item.QualifiedSelection != null && i.QualifiedSelection != null &&
i.QualifiedSelection.Value.QualifiedName.ProjectId ==
item.QualifiedSelection.Value.QualifiedName.ProjectId &&
i.QualifiedSelection.Value.QualifiedName.ComponentName ==
item.QualifiedSelection.Value.QualifiedName.ComponentName &&
i.QualifiedSelection.Value.Selection == item.QualifiedSelection.Value.Selection);
project.Synchronize(declarations);
if (project.Declaration is null)
{
Projects.Remove(project);
}
}
//if (oldItem != null)
//{
// item.IsExpanded = oldItem.IsExpanded;
// item.IsSelected = oldItem.IsSelected;

// if (oldItem.Items.Any() && item.Items.Any())
// {
// UpdateNodes(oldItem.Items, item.Items);
// }
//}
}
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private bool _isDisposed;
protected virtual void Dispose(bool disposing)
{
if (_isDisposed || !disposing)
{
return;
}
_isDisposed = true;
var adding = declarations.OfType<ProjectDeclaration>().ToList();
_state.StateChanged -= OnStateChanged;
foreach (var project in adding)
{
var model = new CodeExplorerProjectViewModel(project, declarations, _state, _vbe, false);
Projects.Add(model);
model.IsExpanded = true;
}
});
}

private Dictionary<Declaration, List<ICodeMetricResult>> resultsByDeclaration;

private CodeExplorerItemViewModel _selectedItem;
public CodeExplorerItemViewModel SelectedItem
private ICodeExplorerNode _selectedItem;
public ICodeExplorerNode SelectedItem
{
get => _selectedItem;
set
Expand All @@ -154,26 +107,14 @@ public CodeExplorerItemViewModel SelectedItem
}
}

private ObservableCollection<CodeExplorerItemViewModel> _projects;
public ObservableCollection<CodeExplorerItemViewModel> Projects
{
get => _projects;
set
{
_projects = new ObservableCollection<CodeExplorerItemViewModel>(value.OrderBy(o => o.NameWithSignature));

OnPropertyChanged();
OnPropertyChanged(nameof(TreeViewVisibility));
}
}
public ObservableCollection<ICodeExplorerNode> Projects { get; } = new ObservableCollection<ICodeExplorerNode>();

public Visibility TreeViewVisibility => Projects == null || Projects.Count == 0 ? Visibility.Collapsed : Visibility.Visible;

private Dictionary<Declaration, List<ICodeMetricResult>> _resultsByDeclaration;
public ObservableCollection<ICodeMetricResult> Metrics
{
get
{
var results = resultsByDeclaration?.FirstOrDefault(f => ReferenceEquals(f.Key, SelectedItem.Declaration));
var results = _resultsByDeclaration?.FirstOrDefault(f => ReferenceEquals(f.Key, SelectedItem.Declaration));
return results?.Value == null ? new ObservableCollection<ICodeMetricResult>() : new ObservableCollection<ICodeMetricResult>(results.Value.Value);
}
}
Expand All @@ -185,23 +126,27 @@ public bool IsBusy
set
{
_isBusy = value;
EmptyUIRefreshMessageVisibility = false;
OnPropertyChanged();
}
}

private bool _emptyUIRefreshMessageVisibility = true;
public bool EmptyUIRefreshMessageVisibility
public void Dispose()
{
get => _emptyUIRefreshMessageVisibility;
set
Dispose(true);
GC.SuppressFinalize(this);
}

private bool _isDisposed;

private void Dispose(bool disposing)
{
if (_isDisposed || !disposing)
{
if (_emptyUIRefreshMessageVisibility != value)
{
_emptyUIRefreshMessageVisibility = value;
OnPropertyChanged();
}
return;
}
_isDisposed = true;

_state.StateChanged -= OnStateChanged;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,25 @@ public class CodeExplorerProjectViewModel : CodeExplorerItemViewModel

private readonly IVBE _vbe;

public CodeExplorerProjectViewModel(Declaration declaration, IEnumerable<Declaration> declarations, RubberduckParserState state, IVBE vbe) : base(null, declaration)
public CodeExplorerProjectViewModel(Declaration declaration, IEnumerable<Declaration> declarations, RubberduckParserState state, IVBE vbe, bool references = true) : base(null, declaration)
{
State = state;
State = state;
_vbe = vbe;
ShowReferences = references;

SetName();
AddNewChildren(declarations.ToList());
}

private string _displayName;
private string _name;

public override string Name => string.IsNullOrEmpty(_displayName) ? _name : $"{_name} ({_displayName})";

public RubberduckParserState State { get; }

public bool ShowReferences { get; }

public override string Name => string.IsNullOrEmpty(_displayName) ? _name : $"{_name} ({_displayName})";

public override FontWeight FontWeight
{
get
Expand Down Expand Up @@ -99,6 +103,11 @@ protected sealed override void AddNewChildren(List<Declaration> updated)

private void SynchronizeReferences()
{
if (!ShowReferences)
{
return;
}

var references = GetProjectReferenceModels();
foreach (var child in Children.OfType<CodeExplorerReferenceFolderViewModel>())
{
Expand Down

0 comments on commit 5cf6423

Please sign in to comment.