Skip to content

Commit 4098165

Browse files
author
Andrew Mansell
committed
Enforce maximum 1 MDI Form per project
1 parent 2b521b7 commit 4098165

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

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

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,54 @@
22
using Rubberduck.Navigation.CodeExplorer;
33
using Rubberduck.UI.Command;
44
using Rubberduck.VBEditor.SafeComWrappers;
5+
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
56

67
namespace Rubberduck.UI.CodeExplorer.Commands
78
{
89
[CodeExplorerCommand]
910
public class AddMDIFormCommand : CommandBase
1011
{
12+
private readonly IVBE _vbe;
1113
private readonly AddComponentCommand _addComponentCommand;
1214

13-
public AddMDIFormCommand(AddComponentCommand addComponentCommand) : base(LogManager.GetCurrentClassLogger())
15+
public AddMDIFormCommand(IVBE vbe, AddComponentCommand addComponentCommand) : base(LogManager.GetCurrentClassLogger())
1416
{
17+
_vbe = vbe;
1518
_addComponentCommand = addComponentCommand;
1619
}
1720

1821
protected override bool EvaluateCanExecute(object parameter)
1922
{
20-
return _addComponentCommand.CanAddComponent(parameter as CodeExplorerItemViewModel, new[] {ProjectType.StandardExe, ProjectType.ActiveXExe});
23+
var node = parameter as CodeExplorerItemViewModel;
24+
while (node != null && !(node is ICodeExplorerDeclarationViewModel))
25+
{
26+
node = node.Parent;
27+
}
28+
var project = (node as ICodeExplorerDeclarationViewModel)?.Declaration?.Project;
29+
30+
if (project == null && _vbe.ProjectsCount == 1)
31+
{
32+
project = _vbe.VBProjects[1];
33+
}
34+
35+
if (project == null)
36+
{
37+
return false;
38+
}
39+
40+
foreach (var component in project.VBComponents)
41+
{
42+
using (component)
43+
{
44+
if (component.Type == ComponentType.MDIForm)
45+
{
46+
// Only one MDI Form allowed per project
47+
return false;
48+
}
49+
}
50+
}
51+
52+
return _addComponentCommand.CanAddComponent(parameter as CodeExplorerItemViewModel, new[] { ProjectType.StandardExe, ProjectType.ActiveXExe });
2153
}
2254

2355
protected override void OnExecute(object parameter)

RubberduckTests/CodeExplorer/CodeExplorerTests.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ public void AddMDIForm()
337337
var vbe = builder.AddProject(project.Build()).Build();
338338
var vbeEvents = MockVbeEvents.CreateMockVbeEvents(vbe);
339339

340-
var commands = new List<CommandBase> { new AddMDIFormCommand(new AddComponentCommand(vbe.Object)) };
340+
var commands = new List<CommandBase> { new AddMDIFormCommand(vbe.Object, new AddComponentCommand(vbe.Object)) };
341341

342342
var projectRepository = new ProjectsRepository(vbe.Object);
343343
var uiDispatcher = new Mock<IUiDispatcher>();
@@ -375,7 +375,7 @@ public bool AddMDIForm_CanExecuteBasedOnProjectType(ProjectType projectType)
375375
var vbe = builder.AddProject(project.Build()).Build();
376376
var vbeEvents = MockVbeEvents.CreateMockVbeEvents(vbe);
377377

378-
var commands = new List<CommandBase> { new AddMDIFormCommand(new AddComponentCommand(vbe.Object)) };
378+
var commands = new List<CommandBase> { new AddMDIFormCommand(vbe.Object, new AddComponentCommand(vbe.Object)) };
379379

380380
var projectRepository = new ProjectsRepository(vbe.Object);
381381
var uiDispatcher = new Mock<IUiDispatcher>();
@@ -394,6 +394,37 @@ public bool AddMDIForm_CanExecuteBasedOnProjectType(ProjectType projectType)
394394
}
395395
}
396396

397+
[Category("Code Explorer")]
398+
[Test]
399+
public void AddMDIForm_CannotExecuteIfProjectAlreadyHasMDIForm()
400+
{
401+
var builder = new MockVbeBuilder();
402+
var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected, ProjectType.StandardExe)
403+
.AddComponent("MDIForm1", ComponentType.MDIForm, "");
404+
405+
406+
var vbe = builder.AddProject(project.Build()).Build();
407+
var vbeEvents = MockVbeEvents.CreateMockVbeEvents(vbe);
408+
409+
var commands = new List<CommandBase> { new AddMDIFormCommand(vbe.Object, new AddComponentCommand(vbe.Object)) };
410+
411+
var projectRepository = new ProjectsRepository(vbe.Object);
412+
var uiDispatcher = new Mock<IUiDispatcher>();
413+
414+
using (var state = new RubberduckParserState(vbe.Object, projectRepository, new DeclarationFinderFactory(), vbeEvents.Object))
415+
{
416+
var vm = new CodeExplorerViewModel(new FolderHelper(state), state, commands, _generalSettingsProvider.Object, _windowSettingsProvider.Object, uiDispatcher.Object, vbe.Object);
417+
418+
var parser = MockParser.Create(vbe.Object, state, projectRepository);
419+
parser.Parse(new CancellationTokenSource());
420+
if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
421+
422+
vm.SelectedItem = vm.Projects.First().Items.First().Items.First();
423+
424+
Assert.IsFalse(vm.AddMDIFormCommand.CanExecute(vm.SelectedItem));
425+
}
426+
}
427+
397428
[Category("Code Explorer")]
398429
[Test]
399430
public void AddUserControlForm()

0 commit comments

Comments
 (0)