Skip to content

Commit 5774bc4

Browse files
Hosch250retailcoder
authored andcommitted
Close #1334 (#1679)
* Refresh parser errors view on state changed. * Tweak the implementation * Update all search tab results on parse. No more clunky adding/removing tabs. * Remove dead code and make resolver run on non-UI thread. * Close #1334
1 parent 8242ad4 commit 5774bc4

File tree

7 files changed

+171
-50
lines changed

7 files changed

+171
-50
lines changed

RetailCoder.VBE/UI/Command/FindAllImplementationsCommand.cs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.Linq;
54
using System.Runtime.InteropServices;
65
using System.Windows.Forms;
@@ -9,6 +8,7 @@
98
using Rubberduck.Parsing.Grammar;
109
using Rubberduck.Parsing.Symbols;
1110
using Rubberduck.Parsing.VBA;
11+
using Rubberduck.UI.Command.MenuItems;
1212
using Rubberduck.UI.Controls;
1313

1414
namespace Rubberduck.UI.Command
@@ -17,7 +17,7 @@ namespace Rubberduck.UI.Command
1717
/// A command that finds all implementations of a specified method, or of the active interface module.
1818
/// </summary>
1919
[ComVisible(false)]
20-
public class FindAllImplementationsCommand : CommandBase
20+
public class FindAllImplementationsCommand : CommandBase, IDisposable
2121
{
2222
private readonly INavigateCommand _navigateCommand;
2323
private readonly IMessageBox _messageBox;
@@ -26,14 +26,64 @@ public class FindAllImplementationsCommand : CommandBase
2626
private readonly SearchResultPresenterInstanceManager _presenterService;
2727
private readonly VBE _vbe;
2828

29-
public FindAllImplementationsCommand(INavigateCommand navigateCommand, IMessageBox messageBox, RubberduckParserState state, VBE vbe, ISearchResultsWindowViewModel viewModel, SearchResultPresenterInstanceManager presenterService)
29+
public FindAllImplementationsCommand(INavigateCommand navigateCommand, IMessageBox messageBox,
30+
RubberduckParserState state, VBE vbe, ISearchResultsWindowViewModel viewModel,
31+
SearchResultPresenterInstanceManager presenterService)
3032
{
3133
_navigateCommand = navigateCommand;
3234
_messageBox = messageBox;
3335
_state = state;
3436
_vbe = vbe;
3537
_viewModel = viewModel;
3638
_presenterService = presenterService;
39+
40+
_state.StateChanged += _state_StateChanged;
41+
}
42+
43+
private Declaration FindNewDeclaration(Declaration declaration)
44+
{
45+
return _state.AllUserDeclarations.SingleOrDefault(item =>
46+
item.ProjectId == declaration.ProjectId &&
47+
item.ComponentName == declaration.ComponentName &&
48+
item.ParentScope == declaration.ParentScope &&
49+
item.IdentifierName == declaration.IdentifierName &&
50+
item.DeclarationType == declaration.DeclarationType);
51+
}
52+
53+
private void _state_StateChanged(object sender, ParserStateEventArgs e)
54+
{
55+
if (e.State != ParserState.Ready) { return; }
56+
57+
if (_viewModel == null) { return; }
58+
59+
UiDispatcher.InvokeAsync(UpdateTab);
60+
}
61+
62+
private void UpdateTab()
63+
{
64+
var findImplementationsTabs = _viewModel.Tabs.Where(
65+
t => t.Header.StartsWith(RubberduckUI.AllImplementations_Caption.Replace("'{0}'", ""))).ToList();
66+
67+
foreach (var tab in findImplementationsTabs)
68+
{
69+
var newTarget = FindNewDeclaration(tab.Target);
70+
if (newTarget == null)
71+
{
72+
tab.CloseCommand.Execute(null);
73+
return;
74+
}
75+
76+
var vm = CreateViewModel(newTarget);
77+
if (vm.SearchResults.Any())
78+
{
79+
tab.SearchResults = vm.SearchResults;
80+
tab.Target = vm.Target;
81+
}
82+
else
83+
{
84+
tab.CloseCommand.Execute(null);
85+
}
86+
}
3787
}
3888

3989
public override bool CanExecute(object parameter)
@@ -170,5 +220,13 @@ private IEnumerable<Declaration> FindAllImplementationsOfMember(Declaration targ
170220
return items.FindInterfaceImplementationMembers(member.IdentifierName)
171221
.Where(item => item.IdentifierName == member.ComponentName + "_" + member.IdentifierName);
172222
}
223+
224+
public void Dispose()
225+
{
226+
if (_state != null)
227+
{
228+
_state.StateChanged += _state_StateChanged;
229+
}
230+
}
173231
}
174232
}

RetailCoder.VBE/UI/Command/FindAllReferencesCommand.cs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using System;
2-
using System.Diagnostics;
32
using System.Linq;
43
using System.Runtime.InteropServices;
54
using System.Windows.Forms;
65
using Microsoft.Vbe.Interop;
76
using Rubberduck.Parsing.Symbols;
87
using Rubberduck.Parsing.VBA;
8+
using Rubberduck.UI.Command.MenuItems;
99
using Rubberduck.UI.Controls;
1010

1111
namespace Rubberduck.UI.Command
@@ -14,7 +14,7 @@ namespace Rubberduck.UI.Command
1414
/// A command that locates all references to a specified identifier, or of the active code module.
1515
/// </summary>
1616
[ComVisible(false)]
17-
public class FindAllReferencesCommand : CommandBase
17+
public class FindAllReferencesCommand : CommandBase, IDisposable
1818
{
1919
private readonly INavigateCommand _navigateCommand;
2020
private readonly IMessageBox _messageBox;
@@ -23,14 +23,64 @@ public class FindAllReferencesCommand : CommandBase
2323
private readonly SearchResultPresenterInstanceManager _presenterService;
2424
private readonly VBE _vbe;
2525

26-
public FindAllReferencesCommand(INavigateCommand navigateCommand, IMessageBox messageBox, RubberduckParserState state, VBE vbe, ISearchResultsWindowViewModel viewModel, SearchResultPresenterInstanceManager presenterService)
26+
public FindAllReferencesCommand(INavigateCommand navigateCommand, IMessageBox messageBox,
27+
RubberduckParserState state, VBE vbe, ISearchResultsWindowViewModel viewModel,
28+
SearchResultPresenterInstanceManager presenterService)
2729
{
2830
_navigateCommand = navigateCommand;
2931
_messageBox = messageBox;
3032
_state = state;
3133
_vbe = vbe;
3234
_viewModel = viewModel;
3335
_presenterService = presenterService;
36+
37+
_state.StateChanged += _state_StateChanged;
38+
}
39+
40+
private Declaration FindNewDeclaration(Declaration declaration)
41+
{
42+
return _state.AllUserDeclarations.SingleOrDefault(item =>
43+
item.ProjectId == declaration.ProjectId &&
44+
item.ComponentName == declaration.ComponentName &&
45+
item.ParentScope == declaration.ParentScope &&
46+
item.IdentifierName == declaration.IdentifierName &&
47+
item.DeclarationType == declaration.DeclarationType);
48+
}
49+
50+
private void _state_StateChanged(object sender, ParserStateEventArgs e)
51+
{
52+
if (e.State != ParserState.Ready) { return; }
53+
54+
if (_viewModel == null) { return; }
55+
56+
UiDispatcher.InvokeAsync(UpdateTab);
57+
}
58+
59+
private void UpdateTab()
60+
{
61+
var findReferenceTabs = _viewModel.Tabs.Where(
62+
t => t.Header.StartsWith(RubberduckUI.AllReferences_Caption.Replace("'{0}'", ""))).ToList();
63+
64+
foreach (var tab in findReferenceTabs)
65+
{
66+
var newTarget = FindNewDeclaration(tab.Target);
67+
if (newTarget == null)
68+
{
69+
tab.CloseCommand.Execute(null);
70+
return;
71+
}
72+
73+
var vm = CreateViewModel(newTarget);
74+
if (vm.SearchResults.Any())
75+
{
76+
tab.SearchResults = vm.SearchResults;
77+
tab.Target = vm.Target;
78+
}
79+
else
80+
{
81+
tab.CloseCommand.Execute(null);
82+
}
83+
}
3484
}
3585

3686
public override bool CanExecute(object parameter)
@@ -110,5 +160,13 @@ private Declaration FindTarget(object parameter)
110160

111161
return _state.FindSelectedDeclaration(_vbe.ActiveCodePane);
112162
}
163+
164+
public void Dispose()
165+
{
166+
if (_state != null)
167+
{
168+
_state.StateChanged += _state_StateChanged;
169+
}
170+
}
113171
}
114172
}

RetailCoder.VBE/UI/Command/ShowParserErrorsCommand.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@ public interface IShowParserErrorsCommand : ICommand, IDisposable { }
1717
[ComVisible(false)]
1818
public class ShowParserErrorsCommand : CommandBase, IShowParserErrorsCommand
1919
{
20-
private readonly VBE _vbe;
2120
private readonly INavigateCommand _navigateCommand;
2221
private readonly RubberduckParserState _state;
2322
private readonly ISearchResultsWindowViewModel _viewModel;
2423
private readonly SearchResultPresenterInstanceManager _presenterService;
2524

26-
public ShowParserErrorsCommand(VBE vbe, INavigateCommand navigateCommand, RubberduckParserState state, ISearchResultsWindowViewModel viewModel, SearchResultPresenterInstanceManager presenterService)
25+
public ShowParserErrorsCommand(INavigateCommand navigateCommand, RubberduckParserState state, ISearchResultsWindowViewModel viewModel, SearchResultPresenterInstanceManager presenterService)
2726
{
28-
_vbe = vbe;
2927
_navigateCommand = navigateCommand;
3028
_state = state;
3129
_viewModel = viewModel;
@@ -50,17 +48,24 @@ private void UpdateTab()
5048
return;
5149
}
5250

53-
var oldTab = _viewModel.Tabs.FirstOrDefault(tab => tab.Header == RubberduckUI.Parser_ParserError);
54-
if (_state.Status == ParserState.Error)
51+
var vm = CreateViewModel();
52+
53+
var tab = _viewModel.Tabs.FirstOrDefault(t => t.Header == RubberduckUI.Parser_ParserError);
54+
if (tab != null)
5555
{
56-
var viewModel = CreateViewModel();
57-
_viewModel.AddTab(viewModel);
58-
_viewModel.SelectedTab = viewModel;
56+
if (_state.Status != ParserState.Error)
57+
{
58+
tab.CloseCommand.Execute(null);
59+
}
60+
else
61+
{
62+
tab.SearchResults = vm.SearchResults;
63+
}
5964
}
60-
61-
if (oldTab != null)
65+
else if (_state.Status == ParserState.Error)
6266
{
63-
oldTab.CloseCommand.Execute(null);
67+
_viewModel.AddTab(vm);
68+
_viewModel.SelectedTab = vm;
6469
}
6570
}
6671

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
using System;
2-
using System.Collections.Generic;
2+
using System.Collections.ObjectModel;
33

44
namespace Rubberduck.UI.Controls
55
{
66
public interface ISearchResultsWindowViewModel
77
{
88
void AddTab(SearchResultsViewModel viewModel);
99
event EventHandler LastTabClosed;
10-
IEnumerable<SearchResultsViewModel> Tabs { get; }
10+
ObservableCollection<SearchResultsViewModel> Tabs { get; }
1111
SearchResultsViewModel SelectedTab { get; set; }
1212
}
1313
}

RetailCoder.VBE/UI/Controls/SearchResultsViewModel.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,46 @@ public class SearchResultsViewModel : ViewModelBase, INavigateSelection
1313
{
1414
private readonly INavigateCommand _navigateCommand;
1515
private readonly string _header;
16-
private readonly Declaration _target;
1716

1817
public SearchResultsViewModel(INavigateCommand navigateCommand, string header, Declaration target, IEnumerable<SearchResultItem> searchResults)
1918
{
2019
_navigateCommand = navigateCommand;
2120
_header = header;
22-
_target = target;
23-
_searchResults = new ObservableCollection<SearchResultItem>(searchResults);
24-
_searchResultsSource = new CollectionViewSource();
25-
_searchResultsSource.Source = _searchResults;
26-
_searchResultsSource.GroupDescriptions.Add(new PropertyGroupDescription("ParentScope.QualifiedName.QualifiedModuleName.Name"));
27-
_searchResultsSource.SortDescriptions.Add(new SortDescription("ParentScope.QualifiedName.QualifiedModuleName.Name", ListSortDirection.Ascending));
28-
_searchResultsSource.SortDescriptions.Add(new SortDescription("Selection.StartLine", ListSortDirection.Ascending));
29-
_searchResultsSource.SortDescriptions.Add(new SortDescription("Selection.StartColumn", ListSortDirection.Ascending));
21+
Target = target;
22+
SearchResultsSource = new CollectionViewSource();
23+
SearchResultsSource.GroupDescriptions.Add(new PropertyGroupDescription("ParentScope.QualifiedName.QualifiedModuleName.Name"));
24+
SearchResultsSource.SortDescriptions.Add(new SortDescription("ParentScope.QualifiedName.QualifiedModuleName.Name", ListSortDirection.Ascending));
25+
SearchResultsSource.SortDescriptions.Add(new SortDescription("Selection.StartLine", ListSortDirection.Ascending));
26+
SearchResultsSource.SortDescriptions.Add(new SortDescription("Selection.StartColumn", ListSortDirection.Ascending));
27+
28+
SearchResults = new ObservableCollection<SearchResultItem>(searchResults);
29+
3030
_closeCommand = new DelegateCommand(ExecuteCloseCommand);
3131
}
3232

33-
private readonly ObservableCollection<SearchResultItem> _searchResults;
34-
public ObservableCollection<SearchResultItem> SearchResults { get { return _searchResults; } }
33+
private ObservableCollection<SearchResultItem> _searchResults;
34+
public ObservableCollection<SearchResultItem> SearchResults
35+
{
36+
get { return _searchResults; }
37+
set
38+
{
39+
_searchResults = value;
40+
41+
SearchResultsSource.Source = _searchResults;
42+
43+
OnPropertyChanged();
44+
OnPropertyChanged("SearchResultsSource");
45+
}
46+
}
3547

36-
private readonly CollectionViewSource _searchResultsSource;
37-
public CollectionViewSource SearchResultsSource { get { return _searchResultsSource; } }
48+
public CollectionViewSource SearchResultsSource { get; private set; }
3849

3950
public string Header { get { return _header; } }
4051

4152
private readonly ICommand _closeCommand;
4253
public ICommand CloseCommand { get { return _closeCommand; } }
4354

44-
public Declaration Target { get {return _target; } }
55+
public Declaration Target { get; set; }
4556

4657
private SearchResultItem _selectedItem;
4758
public SearchResultItem SelectedItem

RetailCoder.VBE/UI/Controls/SearchResultsWindowViewModel.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Collections.ObjectModel;
43
using System.Linq;
54

@@ -21,10 +20,9 @@ void viewModel_Close(object sender, EventArgs e)
2120
RemoveTab(sender as SearchResultsViewModel);
2221
}
2322

24-
public IEnumerable<SearchResultsViewModel> Tabs { get { return _tabs; } }
23+
public ObservableCollection<SearchResultsViewModel> Tabs { get { return _tabs; } }
2524

2625
private SearchResultsViewModel _selectedTab;
27-
2826
public SearchResultsViewModel SelectedTab
2927
{
3028
get { return _selectedTab; }

0 commit comments

Comments
 (0)