Skip to content

Commit 4a0c3b6

Browse files
authored
Merge pull request #3331 from shadowofsilicon/CE_Context_Menu
Code Explorer improvements
2 parents 912f682 + a0a2e46 commit 4a0c3b6

File tree

14 files changed

+493
-185
lines changed

14 files changed

+493
-185
lines changed

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerItemViewModel.cs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,20 @@ public class CompareByType : Comparer<CodeExplorerItemViewModel>
3131
{
3232
private static readonly Dictionary<DeclarationType, int> SortOrder = new Dictionary<DeclarationType, int>
3333
{
34+
// Some DeclarationTypes we want to treat the same, like Subs and Functions.
35+
// Give them the same number.
3436
{DeclarationType.LibraryFunction, 0},
35-
{DeclarationType.LibraryProcedure, 1},
36-
{DeclarationType.UserDefinedType, 2},
37-
{DeclarationType.Enumeration, 3},
38-
{DeclarationType.Event, 4},
39-
{DeclarationType.Constant, 5},
40-
{DeclarationType.Variable, 6},
41-
{DeclarationType.PropertyGet, 7},
42-
{DeclarationType.PropertyLet, 8},
43-
{DeclarationType.PropertySet, 9},
44-
{DeclarationType.Function, 10},
45-
{DeclarationType.Procedure, 11}
37+
{DeclarationType.LibraryProcedure, 0},
38+
{DeclarationType.UserDefinedType, 1},
39+
{DeclarationType.Enumeration, 2},
40+
{DeclarationType.Event, 3},
41+
{DeclarationType.Constant, 4},
42+
{DeclarationType.Variable, 5},
43+
{DeclarationType.PropertyGet, 6},
44+
{DeclarationType.PropertyLet, 7},
45+
{DeclarationType.PropertySet, 8},
46+
{DeclarationType.Function, 9},
47+
{DeclarationType.Procedure, 9}
4648
};
4749

4850
public override int Compare(CodeExplorerItemViewModel x, CodeExplorerItemViewModel y)
@@ -69,17 +71,21 @@ public override int Compare(CodeExplorerItemViewModel x, CodeExplorerItemViewMod
6971
if (SortOrder.TryGetValue(xNode.Declaration.DeclarationType, out xValue) &&
7072
SortOrder.TryGetValue(yNode.Declaration.DeclarationType, out yValue))
7173
{
72-
return xValue < yValue ? -1 : 1;
74+
if (xValue != yValue)
75+
{ return xValue < yValue ? -1 : 1; }
7376
}
74-
75-
return xNode.Declaration.DeclarationType < yNode.Declaration.DeclarationType ? -1 : 1;
7677
}
7778

78-
if (xNode.Declaration.Accessibility != yNode.Declaration.Accessibility)
79+
// The Tree shows Public and Private Subs/Functions with a seperate icon.
80+
// But Public and Implicit Subs/Functions appear the same, so treat Implicts like Publics.
81+
var xNodeAcc = xNode.Declaration.Accessibility == Accessibility.Implicit ? Accessibility.Public : xNode.Declaration.Accessibility;
82+
var yNodeAcc = yNode.Declaration.Accessibility == Accessibility.Implicit ? Accessibility.Public : yNode.Declaration.Accessibility;
83+
84+
if (xNodeAcc != yNodeAcc)
7985
{
80-
return xNode.Declaration.Accessibility < yNode.Declaration.Accessibility ? -1 : 1;
86+
return xNodeAcc < yNodeAcc ? -1 : 1;
8187
}
82-
88+
8389
if (x.ExpandedIcon != y.ExpandedIcon)
8490
{
8591
// ReSharper disable PossibleInvalidOperationException - this will have a component
@@ -121,12 +127,12 @@ public override int Compare(CodeExplorerItemViewModel x, CodeExplorerItemViewMod
121127
return x.QualifiedSelection.HasValue ? -1 : 1;
122128
}
123129

124-
if (x.QualifiedSelection.Value.Selection == y.QualifiedSelection.Value.Selection)
130+
if (x.QualifiedSelection.Value.Selection.StartLine == y.QualifiedSelection.Value.Selection.StartLine)
125131
{
126132
return 0;
127133
}
128134

129-
return x.QualifiedSelection.Value.Selection < y.QualifiedSelection.Value.Selection ? -1 : 1;
135+
return x.QualifiedSelection.Value.Selection.StartLine < y.QualifiedSelection.Value.Selection.StartLine ? -1 : 1;
130136
}
131137
}
132138

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using Rubberduck.Parsing.Annotations;
1010
using Rubberduck.Parsing.Symbols;
1111
using Rubberduck.Parsing.VBA;
12+
using Rubberduck.Settings;
13+
using Rubberduck.SettingsProvider;
1214
using Rubberduck.UI;
1315
using Rubberduck.UI.CodeExplorer.Commands;
1416
using Rubberduck.UI.Command;
@@ -26,29 +28,46 @@ public sealed class CodeExplorerViewModel : ViewModelBase, IDisposable
2628
{
2729
private readonly FolderHelper _folderHelper;
2830
private readonly RubberduckParserState _state;
31+
private IConfigProvider<GeneralSettings> _generalSettingsProvider;
32+
private IConfigProvider<WindowSettings> _windowSettingsProvider;
33+
private GeneralSettings _generalSettings;
34+
private WindowSettings _windowSettings;
2935

30-
public CodeExplorerViewModel(FolderHelper folderHelper, RubberduckParserState state, List<CommandBase> commands)
36+
public CodeExplorerViewModel(FolderHelper folderHelper, RubberduckParserState state, List<CommandBase> commands,
37+
IConfigProvider<GeneralSettings> generalSettingsProvider, IConfigProvider<WindowSettings> windowSettingsProvider)
3138
{
3239
_folderHelper = folderHelper;
3340
_state = state;
3441
_state.StateChanged += HandleStateChanged;
3542
_state.ModuleStateChanged += ParserState_ModuleStateChanged;
43+
_generalSettingsProvider = generalSettingsProvider;
44+
_windowSettingsProvider = windowSettingsProvider;
45+
46+
if (generalSettingsProvider != null)
47+
{
48+
_generalSettings = generalSettingsProvider.Create();
49+
}
50+
51+
if (windowSettingsProvider != null)
52+
{
53+
_windowSettings = windowSettingsProvider.Create();
54+
}
3655

3756
var reparseCommand = commands.OfType<ReparseCommand>().SingleOrDefault();
3857

3958
RefreshCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(),
4059
reparseCommand == null ? (Action<object>)(o => { }) :
4160
o => reparseCommand.Execute(o),
4261
o => !IsBusy && reparseCommand != null && reparseCommand.CanExecute(o));
43-
44-
NavigateCommand = commands.OfType<UI.CodeExplorer.Commands.NavigateCommand>().SingleOrDefault();
62+
63+
OpenCommand = commands.OfType<UI.CodeExplorer.Commands.OpenCommand>().SingleOrDefault();
64+
OpenDesignerCommand = commands.OfType<OpenDesignerCommand>().SingleOrDefault();
4565

4666
AddTestModuleCommand = commands.OfType<UI.CodeExplorer.Commands.AddTestModuleCommand>().SingleOrDefault();
4767
AddStdModuleCommand = commands.OfType<AddStdModuleCommand>().SingleOrDefault();
4868
AddClassModuleCommand = commands.OfType<AddClassModuleCommand>().SingleOrDefault();
4969
AddUserFormCommand = commands.OfType<AddUserFormCommand>().SingleOrDefault();
5070

51-
OpenDesignerCommand = commands.OfType<OpenDesignerCommand>().SingleOrDefault();
5271
OpenProjectPropertiesCommand = commands.OfType<OpenProjectPropertiesCommand>().SingleOrDefault();
5372
RenameCommand = commands.OfType<RenameCommand>().SingleOrDefault();
5473
IndenterCommand = commands.OfType<IndentCommand>().SingleOrDefault();
@@ -111,36 +130,38 @@ public CodeExplorerItemViewModel SelectedItem
111130
}
112131
}
113132

114-
private bool _sortByName = true;
115133
public bool SortByName
116134
{
117-
get { return _sortByName; }
135+
get { return _windowSettings.CodeExplorer_SortByName; }
118136
set
119137
{
120-
if (_sortByName == value)
138+
if (_windowSettings.CodeExplorer_SortByName == value)
121139
{
122140
return;
123141
}
124142

125-
_sortByName = value;
143+
_windowSettings.CodeExplorer_SortByName = value;
144+
_windowSettings.CodeExplorer_SortByLocation = !value;
145+
_windowSettingsProvider.Save(_windowSettings);
126146
OnPropertyChanged();
127147

128148
ReorderChildNodes(Projects);
129149
}
130150
}
131151

132-
private bool _sortBySelection;
133152
public bool SortBySelection
134153
{
135-
get { return _sortBySelection; }
154+
get { return _windowSettings.CodeExplorer_SortByLocation; }
136155
set
137156
{
138-
if (_sortBySelection == value)
157+
if (_windowSettings.CodeExplorer_SortByLocation == value)
139158
{
140159
return;
141160
}
142161

143-
_sortBySelection = value;
162+
_windowSettings.CodeExplorer_SortByLocation = value;
163+
_windowSettings.CodeExplorer_SortByName = !value;
164+
_windowSettingsProvider.Save(_windowSettings);
144165
OnPropertyChanged();
145166

146167
ReorderChildNodes(Projects);
@@ -153,15 +174,16 @@ public bool SortBySelection
153174

154175
public CommandBase SetSelectionSortCommand { get; }
155176

156-
private bool _sortByType = true;
157177
public bool SortByType
158178
{
159-
get { return _sortByType; }
179+
get { return _windowSettings.CodeExplorer_GroupByType; }
160180
set
161181
{
162-
if (_sortByType != value)
182+
if (_windowSettings.CodeExplorer_GroupByType != value)
163183
{
164-
_sortByType = value;
184+
_windowSettings.CodeExplorer_GroupByType = value;
185+
_windowSettingsProvider.Save(_windowSettings);
186+
165187
OnPropertyChanged();
166188

167189
ReorderChildNodes(Projects);
@@ -177,6 +199,8 @@ public bool IsBusy
177199
{
178200
_isBusy = value;
179201
OnPropertyChanged();
202+
// If the window is "busy" then hide the Refresh message
203+
OnPropertyChanged("EmptyTreeMessageVisibility");
180204
}
181205
}
182206

@@ -244,6 +268,8 @@ public ObservableCollection<CodeExplorerItemViewModel> Projects
244268
_projects = new ObservableCollection<CodeExplorerItemViewModel>(value.OrderBy(o => o.NameWithSignature));
245269

246270
OnPropertyChanged();
271+
// Once a Project has been set, show the TreeView
272+
OnPropertyChanged("TreeViewVisibility");
247273
}
248274
}
249275

@@ -254,7 +280,8 @@ private void HandleStateChanged(object sender, ParserStateEventArgs e)
254280
Projects = new ObservableCollection<CodeExplorerItemViewModel>();
255281
}
256282

257-
IsBusy = _state.Status != ParserState.Pending && _state.Status < ParserState.ResolvedDeclarations;
283+
IsBusy = _state.Status != ParserState.Pending && _state.Status <= ParserState.ResolvedDeclarations;
284+
258285
if (e.State != ParserState.ResolvedDeclarations)
259286
{
260287
return;
@@ -447,7 +474,7 @@ private void SwitchNodeState(CodeExplorerItemViewModel node, bool expandedState)
447474

448475
public CommandBase RefreshCommand { get; }
449476

450-
public CommandBase NavigateCommand { get; }
477+
public CommandBase OpenCommand { get; }
451478

452479
public CommandBase AddTestModuleCommand { get; }
453480
public CommandBase AddStdModuleCommand { get; }
@@ -512,6 +539,27 @@ public Visibility ExportAllVisibility
512539
}
513540
}
514541

542+
public bool IsSourceControlEnabled
543+
{
544+
get { return _generalSettings.SourceControlEnabled; }
545+
}
546+
547+
public Visibility TreeViewVisibility
548+
{
549+
get
550+
{
551+
return Projects == null || Projects.Count == 0 ? Visibility.Collapsed : Visibility.Visible;
552+
}
553+
}
554+
555+
public Visibility EmptyTreeMessageVisibility
556+
{
557+
get
558+
{
559+
return _isBusy ? Visibility.Hidden : Visibility.Visible;
560+
}
561+
}
562+
515563
public void Dispose()
516564
{
517565
if (_state != null)

RetailCoder.VBE/Rubberduck.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@
402402
<Compile Include="UI\CodeExplorer\Commands\FindAllReferencesCommand.cs" />
403403
<Compile Include="UI\CodeExplorer\Commands\FindAllImplementationsCommand.cs" />
404404
<Compile Include="UI\CodeExplorer\Commands\IndentCommand.cs" />
405-
<Compile Include="UI\CodeExplorer\Commands\NavigateCommand.cs" />
405+
<Compile Include="UI\CodeExplorer\Commands\OpenCommand.cs" />
406406
<Compile Include="UI\CodeExplorer\Commands\RemoveCommand.cs" />
407407
<Compile Include="UI\CodeExplorer\Commands\ExportCommand.cs" />
408408
<Compile Include="UI\CodeExplorer\Commands\ImportCommand.cs" />

RetailCoder.VBE/Settings/WindowSettings.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,34 @@ public interface IWindowSettings
1717
bool TestExplorerVisibleOnStartup { get; set; }
1818
bool TodoExplorerVisibleOnStartup { get; set; }
1919

20+
bool CodeExplorer_SortByName { get; set; }
21+
bool CodeExplorer_SortByLocation { get; set; }
22+
bool CodeExplorer_GroupByType { get; set; }
23+
2024
bool IsWindowVisible(DockableToolwindowPresenter candidate);
2125
}
2226

2327
[XmlType(AnonymousType = true)]
2428
public class WindowSettings : IWindowSettings, IEquatable<WindowSettings>
2529
{
2630
public WindowSettings()
27-
: this(false, false, false, false, false)
31+
: this(false, false, false, false, false, true, false, false)
32+
// SortByName and SortByLocation are opposites; SortByName should start as True.
2833
{
2934
//empty constructor needed for serialization
3035
}
3136

32-
public WindowSettings(bool codeExplorerVisibleOnStartup, bool codeInspectionsVisibleOnStartup, bool sourceControlVisibleOnStartup, bool testExplorerVisibleOnStartup, bool todoExplorerVisibleOnStartup)
37+
public WindowSettings(bool codeExplorerVisibleOnStartup, bool codeInspectionsVisibleOnStartup, bool sourceControlVisibleOnStartup, bool testExplorerVisibleOnStartup, bool todoExplorerVisibleOnStartup, bool codeExplorer_SortByName, bool codeExplorer_SortByLocation, bool codeExplorer_GroupByType)
3338
{
3439
CodeExplorerVisibleOnStartup = codeExplorerVisibleOnStartup;
3540
CodeInspectionsVisibleOnStartup = codeInspectionsVisibleOnStartup;
3641
SourceControlVisibleOnStartup = sourceControlVisibleOnStartup;
3742
TestExplorerVisibleOnStartup = testExplorerVisibleOnStartup;
3843
TodoExplorerVisibleOnStartup = todoExplorerVisibleOnStartup;
44+
45+
CodeExplorer_SortByName = codeExplorer_SortByName;
46+
CodeExplorer_SortByLocation = codeExplorer_SortByLocation;
47+
CodeExplorer_GroupByType = codeExplorer_GroupByType;
3948
}
4049

4150
public bool CodeExplorerVisibleOnStartup { get; set; }
@@ -44,6 +53,10 @@ public WindowSettings(bool codeExplorerVisibleOnStartup, bool codeInspectionsVis
4453
public bool TestExplorerVisibleOnStartup { get; set; }
4554
public bool TodoExplorerVisibleOnStartup { get; set; }
4655

56+
public bool CodeExplorer_SortByName { get; set; }
57+
public bool CodeExplorer_SortByLocation { get; set; }
58+
public bool CodeExplorer_GroupByType { get; set; }
59+
4760
public bool IsWindowVisible(DockableToolwindowPresenter candidate)
4861
{
4962
//I'm sure there's a better way to do this, because this is a lazy-ass way to do it.
@@ -79,7 +92,10 @@ public bool Equals(WindowSettings other)
7992
CodeInspectionsVisibleOnStartup == other.CodeInspectionsVisibleOnStartup &&
8093
SourceControlVisibleOnStartup == other.SourceControlVisibleOnStartup &&
8194
TestExplorerVisibleOnStartup == other.TestExplorerVisibleOnStartup &&
82-
TodoExplorerVisibleOnStartup == other.TodoExplorerVisibleOnStartup;
95+
TodoExplorerVisibleOnStartup == other.TodoExplorerVisibleOnStartup &&
96+
CodeExplorer_SortByName == other.CodeExplorer_SortByName &&
97+
CodeExplorer_SortByLocation == other.CodeExplorer_SortByLocation &&
98+
CodeExplorer_GroupByType == other.CodeExplorer_GroupByType;
8399
}
84100
}
85101
}

0 commit comments

Comments
 (0)