Skip to content

Commit 64ae145

Browse files
authored
Merge pull request #4718 from comintern/next
Code Explorer folder hotfix.
2 parents f0d4885 + 8ab45d8 commit 64ae145

File tree

9 files changed

+695
-480
lines changed

9 files changed

+695
-480
lines changed

Rubberduck.Core/CodeAnalysis/CodeMetrics/CodeMetricsViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ private void Synchronize(List<Declaration> declarations)
8484

8585
foreach (var project in adding)
8686
{
87-
var model = new CodeExplorerProjectViewModel(project, declarations, _state, _vbe, false);
87+
var model = new CodeExplorerProjectViewModel(project, declarations.Where(proj => proj.ProjectId.Equals(project.ProjectId)).ToList(), _state, _vbe, false);
8888
Projects.Add(model);
8989
model.IsExpanded = true;
9090
}

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Diagnostics;
23
using System.Linq;
34
using Rubberduck.Navigation.Folders;
45
using Rubberduck.Parsing.Symbols;
@@ -7,6 +8,7 @@
78

89
namespace Rubberduck.Navigation.CodeExplorer
910
{
11+
[DebuggerDisplay("{Name}")]
1012
public sealed class CodeExplorerCustomFolderViewModel : CodeExplorerItemViewModel
1113
{
1214
private static readonly DeclarationType[] ComponentTypes =
@@ -27,8 +29,8 @@ public CodeExplorerCustomFolderViewModel(
2729
IEnumerable<Declaration> declarations) : base(parent, parent?.Declaration)
2830
{
2931
_vbe = vbe;
30-
31-
FullPath = fullPath ?? string.Empty;
32+
FolderDepth = parent is CodeExplorerCustomFolderViewModel folder ? folder.FolderDepth + 1 : 1;
33+
FullPath = fullPath?.Trim('"') ?? string.Empty;
3234
Name = name.Replace("\"", string.Empty);
3335

3436
AddNewChildren(declarations.ToList());
@@ -44,6 +46,11 @@ public CodeExplorerCustomFolderViewModel(
4446

4547
public string FolderAttribute => $"@Folder(\"{FullPath.Replace("\"", string.Empty)}\")";
4648

49+
/// <summary>
50+
/// One-based depth in the folder hierarchy.
51+
/// </summary>
52+
public int FolderDepth { get; }
53+
4754
public override QualifiedSelection? QualifiedSelection => null;
4855

4956
public override bool IsErrorState
@@ -58,18 +65,20 @@ public override bool IsErrorState
5865

5966
protected override void AddNewChildren(List<Declaration> declarations)
6067
{
61-
var subfolders = declarations.Where(declaration => declaration.IsInSubFolder(FullPath)).ToList();
68+
var children = declarations.Where(declaration => declaration.IsInSubFolder(FullPath)).ToList();
6269

63-
foreach (var folder in subfolders.GroupBy(declaration => declaration.CustomFolder))
70+
foreach (var folder in children.GroupBy(declaration => declaration.CustomFolder.SubFolderRoot(FullPath)))
6471
{
65-
AddChild(new CodeExplorerCustomFolderViewModel(this, folder.Key.SubFolderRoot(Name), folder.Key, _vbe, folder));
72+
AddChild(new CodeExplorerCustomFolderViewModel(this, folder.Key, $"{FullPath}.{folder.Key}", _vbe, folder));
73+
foreach (var declaration in folder)
74+
{
75+
declarations.Remove(declaration);
76+
}
6677
}
6778

68-
var components = declarations.Except(subfolders).ToList();
69-
70-
foreach (var component in components.GroupBy(item => item.ComponentName))
79+
foreach (var declaration in declarations.GroupBy(item => item.ComponentName))
7180
{
72-
var moduleName = component.Key;
81+
var moduleName = declaration.Key;
7382
var parent = declarations.SingleOrDefault(item =>
7483
ComponentTypes.Contains(item.DeclarationType) && item.ComponentName == moduleName);
7584

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,15 @@
1919
using Rubberduck.UI.UnitTesting.Commands;
2020
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
2121

22-
// ReSharper disable ExplicitCallerInfoArgument
23-
2422
namespace Rubberduck.Navigation.CodeExplorer
2523
{
2624
[Flags]
2725
public enum CodeExplorerSortOrder
2826
{
2927
Undefined = 0,
3028
Name = 1,
31-
CodeLine = 1 << 2,
32-
DeclarationType = 1 << 3,
29+
CodeLine = 1 << 1,
30+
DeclarationType = 1 << 2,
3331
DeclarationTypeThenName = DeclarationType | Name,
3432
DeclarationTypeThenCodeLine = DeclarationType | CodeLine
3533
}
@@ -76,11 +74,11 @@ public CodeExplorerViewModel(
7674
RemoveCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteRemoveCommand, _externalRemoveCommand.CanExecute);
7775
}
7876

79-
OnPropertyChanged("Projects");
77+
OnPropertyChanged(nameof(Projects));
8078

8179
SyncCodePaneCommand = syncProvider.GetSyncCommand(this);
8280
// Force a call to EvaluateCanExecute
83-
OnPropertyChanged("SyncCodePaneCommand");
81+
OnPropertyChanged(nameof(SyncCodePaneCommand));
8482
}
8583

8684
public ObservableCollection<ICodeExplorerNode> Projects { get; } = new ObservableCollection<ICodeExplorerNode>();
@@ -109,8 +107,8 @@ public ICodeExplorerNode SelectedItem
109107

110108
OnPropertyChanged();
111109

112-
OnPropertyChanged("ExportVisibility");
113-
OnPropertyChanged("ExportAllVisibility");
110+
OnPropertyChanged(nameof(ExportVisibility));
111+
OnPropertyChanged(nameof(ExportAllVisibility));
114112
}
115113
}
116114

@@ -266,9 +264,8 @@ private void Synchronize(List<Declaration> declarations)
266264

267265
foreach (var project in adding)
268266
{
269-
var model = new CodeExplorerProjectViewModel(project, declarations, _state, _vbe);
267+
var model = new CodeExplorerProjectViewModel(project, declarations.Where(proj => proj.ProjectId.Equals(project.ProjectId)).ToList(), _state, _vbe);
270268
Projects.Add(model);
271-
//model.IsExpanded = true;
272269
}
273270

274271
CanSearch = Projects.Any();

Rubberduck.Core/Navigation/Folders/FolderExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Rubberduck.Navigation.Folders
66
{
77
public static class FolderExtensions
88
{
9-
private const char FolderDelimiter = '.';
9+
public const char FolderDelimiter = '.';
1010

1111
public static string RootFolder(this Declaration declaration)
1212
{
@@ -17,12 +17,12 @@ public static string RootFolder(this Declaration declaration)
1717

1818
public static string SubFolderRoot(this string folder, string subfolder)
1919
{
20-
if (folder is null || subfolder is null || !subfolder.Trim('"').StartsWith(folder.Trim('"')))
20+
if (folder is null || subfolder is null || !folder.Trim('"').StartsWith(subfolder.Trim('"')))
2121
{
2222
return string.Empty;
2323
}
2424

25-
var subPath = subfolder.Trim('"').Substring(folder.Length - 1);
25+
var subPath = folder.Trim('"').Substring(subfolder.Length + 1);
2626
return subPath.Split(FolderDelimiter).FirstOrDefault() ?? string.Empty;
2727
}
2828

@@ -51,7 +51,7 @@ public static bool IsInSubFolder(this Declaration declaration, string folder)
5151
return false;
5252
}
5353

54-
return declarationPath.Take(declarationPath.Length).SequenceEqual(folderPath, StringComparer.Ordinal);
54+
return declarationPath.Take(folderPath.Length).SequenceEqual(folderPath, StringComparer.Ordinal);
5555
}
5656

5757
public static bool IsInFolderOrSubFolder(this Declaration declaration, string folder)

Rubberduck.Core/UI/CodeExplorer/Commands/AddTemplateCommand.cs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using Rubberduck.Navigation.CodeExplorer;
34
using Rubberduck.Templates;
@@ -28,24 +29,49 @@ public bool CanExecuteForNode(ICodeExplorerNode model)
2829

2930
protected override bool EvaluateCanExecute(object parameter)
3031
{
31-
// TODO this cast needs to be safer.
32-
var data = ((string templateName, CodeExplorerItemViewModel model)) parameter;
32+
if (parameter is null)
33+
{
34+
return false;
35+
}
36+
37+
try
38+
{
39+
// TODO this cast needs to be safer.
40+
var data = ((string templateName, ICodeExplorerNode model))parameter;
3341

34-
return base.EvaluateCanExecute(data.model);
42+
return base.EvaluateCanExecute(data.model);
43+
}
44+
catch (Exception ex)
45+
{
46+
Logger.Trace(ex);
47+
return false;
48+
}
3549
}
3650

3751
protected override void OnExecute(object parameter)
3852
{
39-
// TODO this cast needs to be safer.
40-
var data = ((string templateName, CodeExplorerItemViewModel model)) parameter;
41-
42-
if (string.IsNullOrWhiteSpace(data.templateName))
53+
if (parameter is null)
4354
{
4455
return;
4556
}
4657

47-
var moduleText = GetTemplate(data.templateName);
48-
AddComponent(data.model, moduleText);
58+
try
59+
{
60+
// TODO this cast needs to be safer.
61+
var data = ((string templateName, ICodeExplorerNode node))parameter;
62+
63+
if (string.IsNullOrWhiteSpace(data.templateName) || !(data.node is CodeExplorerItemViewModel model))
64+
{
65+
return;
66+
}
67+
68+
var moduleText = GetTemplate(data.templateName);
69+
AddComponent(model, moduleText);
70+
}
71+
catch (Exception ex)
72+
{
73+
Logger.Trace(ex);
74+
}
4975
}
5076

5177
private string GetTemplate(string name)

Rubberduck.Core/UI/Converters/TemplateCommandParameterToTupleConverter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ public class TemplateCommandParameterToTupleConverter : IMultiValueConverter
99
{
1010
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
1111
{
12-
(string templateName, CodeExplorerItemViewModel model) data = (
12+
(string templateName, ICodeExplorerNode model) data = (
1313
values[0] as string,
14-
values[1] as CodeExplorerItemViewModel);
14+
values[1] as ICodeExplorerNode);
1515
return data;
1616
}
1717

1818
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
1919
{
20-
var data = ((string templateName, CodeExplorerItemViewModel model))value;
20+
var data = ((string templateName, ICodeExplorerNode model))value;
2121
return new[] {(object) data.templateName, data.model};
2222
}
2323
}

0 commit comments

Comments
 (0)