Skip to content

Commit 7b2b173

Browse files
committed
Add MoveContainingFolderRefactoring
It moves the containing folder into another folder. Also fixes ToVbaStringLiteral. (It was missing the surrounding quotes.)
1 parent 213822f commit 7b2b173

File tree

37 files changed

+1095
-95
lines changed

37 files changed

+1095
-95
lines changed

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Collections.Generic;
22
using System.Diagnostics;
33
using System.Linq;
4+
using Rubberduck.Common;
5+
using Rubberduck.JunkDrawer.Extensions;
46
using Rubberduck.Navigation.Folders;
57
using Rubberduck.Parsing.Symbols;
68
using Rubberduck.VBEditor;
@@ -30,7 +32,7 @@ public CodeExplorerCustomFolderViewModel(
3032
{
3133
_vbe = vbe;
3234
FolderDepth = parent is CodeExplorerCustomFolderViewModel folder ? folder.FolderDepth + 1 : 1;
33-
FullPath = fullPath?.Trim('"') ?? string.Empty;
35+
FullPath = fullPath?.FromVbaStringLiteral() ?? string.Empty;
3436
Name = name.Replace("\"", string.Empty);
3537

3638
AddNewChildren(ref declarations);
@@ -44,7 +46,7 @@ public CodeExplorerCustomFolderViewModel(
4446

4547
public string FullPath { get; }
4648

47-
public string FolderAttribute => $"'@Folder(\"{FullPath.Replace("\"", string.Empty)}\")";
49+
public string FolderAttribute => $"'@Folder({FullPath.ToVbaStringLiteral()})";
4850

4951
/// <summary>
5052
/// One-based depth in the folder hierarchy.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using Rubberduck.Parsing.Symbols;
3+
using Rubberduck.JunkDrawer.Extensions;
4+
5+
namespace Rubberduck.Navigation.Folders
6+
{
7+
public static class DeclarationFolderExtensions
8+
{
9+
public static string RootFolder(this Declaration declaration)
10+
{
11+
return declaration?.CustomFolder?.RootFolder()
12+
?? declaration?.ProjectName
13+
?? string.Empty;
14+
}
15+
16+
public static bool IsInFolder(this Declaration declaration, string folder)
17+
{
18+
if (declaration?.CustomFolder is null || folder is null)
19+
{
20+
return false;
21+
}
22+
23+
return declaration.CustomFolder.Equals(folder, StringComparison.Ordinal);
24+
}
25+
26+
public static bool IsInSubFolder(this Declaration declaration, string folder)
27+
{
28+
var declarationFolder = declaration?.CustomFolder;
29+
if (declarationFolder is null || folder is null)
30+
{
31+
return false;
32+
}
33+
34+
return declarationFolder.IsSubFolderOf(folder);
35+
}
36+
37+
public static bool IsInFolderOrSubFolder(this Declaration declaration, string folder)
38+
{
39+
var declarationFolder = declaration?.CustomFolder;
40+
if (declarationFolder is null || folder is null)
41+
{
42+
return false;
43+
}
44+
45+
return declaration.IsInFolder(folder)
46+
|| declarationFolder.IsSubFolderOf(folder);
47+
}
48+
}
49+
}

Rubberduck.Core/Navigation/Folders/FolderExtensions.cs

Lines changed: 0 additions & 78 deletions
This file was deleted.

Rubberduck.Core/Rubberduck.Core.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@
117117
<DesignTime>True</DesignTime>
118118
<AutoGen>True</AutoGen>
119119
</Compile>
120+
<Compile Update="UI\Refactorings\MoveFolder\MoveMultipleFoldersView.xaml.cs">
121+
<DependentUpon>MoveMultipleFoldersView.xaml</DependentUpon>
122+
</Compile>
120123
<Compile Update="UI\Refactorings\MoveToFolder\MoveMultipleToFolderView.xaml.cs">
121124
<DependentUpon>MoveMultipleToFolderView.xaml</DependentUpon>
122125
</Compile>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Rubberduck.Parsing.VBA;
2+
using Rubberduck.UI.Command.MenuItems.ParentMenus;
3+
using Rubberduck.UI.Command.Refactorings;
4+
5+
namespace Rubberduck.UI.Command.MenuItems
6+
{
7+
public class CodePaneRefactorMoveContainingFolderCommandMenuItem : CommandMenuItemBase
8+
{
9+
public CodePaneRefactorMoveContainingFolderCommandMenuItem(CodePaneRefactorMoveContainingFolderCommand command)
10+
: base(command)
11+
{}
12+
13+
public override string Key => "RefactorMenu_MoveContainingFolder";
14+
public override int DisplayOrder => (int)RefactoringsMenuItemDisplayOrder.MoveContainingFolder;
15+
public override bool BeginGroup => false;
16+
17+
public override bool EvaluateCanExecute(RubberduckParserState state)
18+
{
19+
return state != null && Command.CanExecute(null);
20+
}
21+
}
22+
}

Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RefactoringsParentMenu.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public enum RefactoringsMenuItemDisplayOrder
2525
IntroduceParameter,
2626
IntroduceField,
2727
MoveToFolder,
28+
MoveContainingFolder,
2829
AddRemoveReferences
2930
}
3031
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using Rubberduck.Parsing.Symbols;
2+
using Rubberduck.Parsing.VBA;
3+
using Rubberduck.Refactorings.MoveFolder;
4+
using Rubberduck.UI.Command.Refactorings.Notifiers;
5+
using Rubberduck.VBEditor.Utility;
6+
7+
namespace Rubberduck.UI.Command.Refactorings
8+
{
9+
public class CodePaneRefactorMoveContainingFolderCommand : RefactorCodePaneCommandBase
10+
{
11+
private readonly RubberduckParserState _state;
12+
private readonly ISelectedDeclarationProvider _selectedDeclarationProvider;
13+
14+
public CodePaneRefactorMoveContainingFolderCommand(
15+
MoveContainingFolderRefactoring refactoring,
16+
MoveContainingFolderRefactoringFailedNotifier failureNotifier,
17+
ISelectionProvider selectionProvider,
18+
RubberduckParserState state,
19+
ISelectedDeclarationProvider selectedDeclarationProvider)
20+
: base(refactoring, failureNotifier, selectionProvider, state)
21+
{
22+
_selectedDeclarationProvider = selectedDeclarationProvider;
23+
_state = state;
24+
25+
AddToCanExecuteEvaluation(SpecializedEvaluateCanExecute);
26+
}
27+
28+
private bool SpecializedEvaluateCanExecute(object parameter)
29+
{
30+
var target = GetTarget();
31+
32+
return target != null
33+
&& target is ModuleDeclaration
34+
&& !_state.IsNewOrModified(target.QualifiedModuleName);
35+
}
36+
37+
private Declaration GetTarget()
38+
{
39+
return _selectedDeclarationProvider.SelectedModule();
40+
}
41+
}
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Rubberduck.Interaction;
2+
using Rubberduck.Parsing.Symbols;
3+
using Rubberduck.Refactorings.Exceptions;
4+
using Rubberduck.Refactorings.Exceptions.MoveToFolder;
5+
6+
namespace Rubberduck.UI.Command.Refactorings.Notifiers
7+
{
8+
public class MoveContainingFolderRefactoringFailedNotifier : RefactoringFailureNotifierBase
9+
{
10+
public MoveContainingFolderRefactoringFailedNotifier(IMessageBox messageBox)
11+
: base(messageBox)
12+
{}
13+
14+
protected override string Caption => Resources.RubberduckUI.MoveToFolderDialog_Caption;
15+
16+
protected override string Message(RefactoringException exception)
17+
{
18+
switch (exception)
19+
{
20+
case InvalidDeclarationTypeException invalidDeclarationType:
21+
Logger.Warn(invalidDeclarationType);
22+
return string.Format(
23+
Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType,
24+
invalidDeclarationType.TargetDeclaration.QualifiedName,
25+
invalidDeclarationType.TargetDeclaration.DeclarationType,
26+
DeclarationType.Module);
27+
case NoTargetFolderException noTargetFolder:
28+
return Resources.RubberduckUI.RefactoringFailure_NoTargetFolder;
29+
case AffectedModuleIsStaleException affectedModuleIsStale:
30+
return string.Format(
31+
Resources.RubberduckUI.RefactoringFailure_AffectedModuleIsStale,
32+
affectedModuleIsStale.StaleModule.ToString());
33+
default:
34+
return base.Message(exception);
35+
}
36+
}
37+
}
38+
}

Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveToFolderRefactoringFailedNotifier.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Rubberduck.Interaction;
22
using Rubberduck.Parsing.Symbols;
33
using Rubberduck.Refactorings.Exceptions;
4+
using Rubberduck.Refactorings.Exceptions.MoveToFolder;
45

56
namespace Rubberduck.UI.Command.Refactorings.Notifiers
67
{
@@ -18,10 +19,17 @@ protected override string Message(RefactoringException exception)
1819
{
1920
case InvalidDeclarationTypeException invalidDeclarationType:
2021
Logger.Warn(invalidDeclarationType);
21-
return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType,
22+
return string.Format(
23+
Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType,
2224
invalidDeclarationType.TargetDeclaration.QualifiedName,
2325
invalidDeclarationType.TargetDeclaration.DeclarationType,
2426
DeclarationType.Module);
27+
case NoTargetFolderException noTargetFolder:
28+
return Resources.RubberduckUI.RefactoringFailure_NoTargetFolder;
29+
case AffectedModuleIsStaleException affectedModuleIsStale:
30+
return string.Format(
31+
Resources.RubberduckUI.RefactoringFailure_AffectedModuleIsStale,
32+
affectedModuleIsStale.StaleModule.ToString());
2533
default:
2634
return base.Message(exception);
2735
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Rubberduck.Refactorings.MoveFolder;
2+
using Rubberduck.Resources;
3+
4+
namespace Rubberduck.UI.Refactorings.MoveFolder
5+
{
6+
internal class MoveMultipleFoldersPresenter : RefactoringPresenterBase<MoveMultipleFoldersModel>, IMoveMultipleFoldersPresenter
7+
{
8+
private static readonly DialogData DialogData = DialogData.Create(RubberduckUI.MoveToFolderDialog_Caption, 164, 684);
9+
10+
public MoveMultipleFoldersPresenter(MoveMultipleFoldersModel model, IRefactoringDialogFactory dialogFactory) :
11+
base(DialogData, model, dialogFactory)
12+
{}
13+
}
14+
}
15+

0 commit comments

Comments
 (0)