Index: Core/Common/src/Core.Common.Base/Data/Project.cs =================================================================== diff -u -rad6f88d1d7b21f950588f6109b79fe007aab0c9e -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/src/Core.Common.Base/Data/Project.cs (.../Project.cs) (revision ad6f88d1d7b21f950588f6109b79fe007aab0c9e) +++ Core/Common/src/Core.Common.Base/Data/Project.cs (.../Project.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -1,3 +1,5 @@ +using System.Collections.Generic; + using Core.Common.Base.Properties; using Core.Common.Utils.Collections.Generic; @@ -22,7 +24,7 @@ Name = name; Description = ""; - Items = new EventedList(); + Items = new List(); } /// @@ -38,6 +40,6 @@ /// /// Gets or sets the items of the . /// - public IEventedList Items { get; private set; } + public IList Items { get; private set; } } } \ No newline at end of file Index: Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeView.cs =================================================================== diff -u -rc3dd2497d527a0d8f1e7d974f601903d2e426331 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeView.cs (.../TreeView.cs) (revision c3dd2497d527a0d8f1e7d974f601903d2e426331) +++ Core/Common/src/Core.Common.Controls.Swf/TreeViewControls/TreeView.cs (.../TreeView.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -24,6 +24,11 @@ public event Action BeforeWaitUntilAllEventsAreProcessed; + /// + /// Occurs when a node with data has been deleted from the tree view. + /// + public event EventHandler DataDeleted; + private const int TV_FIRST = 0x1100; private const int TVM_SETBKCOLOR = TV_FIRST + 29; private const int TVM_SETEXTENDEDSTYLE = TV_FIRST + 44; @@ -336,7 +341,12 @@ { var presenter = GetTreeViewNodePresenter(node.Tag, node); presenter.RemoveNodeData(node.Parent.Tag, node.Tag); + SelectedNode = SelectedNode ?? Nodes.FirstOrDefault(); + if (DataDeleted != null) + { + DataDeleted(this, new TreeViewDataDeletedEventArgs(node.Tag)); + } } public override void Refresh() @@ -1101,7 +1111,7 @@ } } - internal class NativeInterop + private static class NativeInterop { public const int WM_PRINTCLIENT = 0x0318; public const int PRF_CLIENT = 0x00000004; @@ -1128,5 +1138,25 @@ [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); } + + /// + /// Event arguments to be used in the event that data has been deleted from a . + /// + public class TreeViewDataDeletedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The deleted data instance. + public TreeViewDataDeletedEventArgs(object deletedDataInstance) + { + DeletedDataInstance = deletedDataInstance; + } + + /// + /// Gets the data instance deleted from the . + /// + public object DeletedDataInstance { get; private set; } + } } } \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/GuiCommandHandler.cs =================================================================== diff -u -r0c09106be1dfa0dad80232e39fea48b274ecdf37 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/src/Core.Common.Gui/GuiCommandHandler.cs (.../GuiCommandHandler.cs) (revision 0c09106be1dfa0dad80232e39fea48b274ecdf37) +++ Core/Common/src/Core.Common.Gui/GuiCommandHandler.cs (.../GuiCommandHandler.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -16,7 +16,6 @@ using Core.Common.Gui.Forms.ViewManager; using Core.Common.Gui.Properties; using Core.Common.Utils; -using Core.Common.Utils.Collections; using log4net; using log4net.Appender; using MainWindow = Core.Common.Gui.Forms.MainWindow.MainWindow; @@ -273,9 +272,11 @@ { return; } - - gui.DocumentViewsResolver.CloseAllViewsFor(dataObject); - RemoveViewsAndData(gui.ToolWindowViews.Where(v => v.Data == dataObject)); + foreach (var data in gui.GetAllDataWithViewDefinitionsRecursively(dataObject)) + { + gui.DocumentViewsResolver.CloseAllViewsFor(data); + RemoveViewsAndData(gui.ToolWindowViews.Where(v => v.Data == data).ToArray()); + } } public void Dispose() @@ -311,25 +312,15 @@ } project.Detach(this); - project.Items.CollectionChanged -= ProjectCollectionChanged; } private void ApplicationProjectOpened(Project project) { gui.Selection = project; project.Attach(this); - project.Items.CollectionChanged += ProjectCollectionChanged; } - private void ProjectCollectionChanged(object sender, NotifyCollectionChangingEventArgs e) - { - if (e.Action == NotifyCollectionChangeAction.Remove) - { - RemoveAllViewsForItem(e.Item); - } - } - private void AddProjectToMruList() { var mruList = (StringCollection) Settings.Default["mruList"]; Index: Core/Common/src/Core.Common.Gui/GuiPlugin.cs =================================================================== diff -u -r44fce3b0d8942914f2678d8e33ca99646cf8062f -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/src/Core.Common.Gui/GuiPlugin.cs (.../GuiPlugin.cs) (revision 44fce3b0d8942914f2678d8e33ca99646cf8062f) +++ Core/Common/src/Core.Common.Gui/GuiPlugin.cs (.../GuiPlugin.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -73,5 +73,10 @@ { Gui = null; } + + public virtual IEnumerable GetChildDataWithViewDefinitions(object dataObject) + { + yield break; + } } } \ No newline at end of file Index: Core/Common/src/Core.Common.Gui/IGui.cs =================================================================== diff -u -r83aacc6578d82137751a7d28f691e8b3d02312f1 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/src/Core.Common.Gui/IGui.cs (.../IGui.cs) (revision 83aacc6578d82137751a7d28f691e8b3d02312f1) +++ Core/Common/src/Core.Common.Gui/IGui.cs (.../IGui.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -6,9 +6,9 @@ // -------------------------------------------------------------------------------------------------------------------- using System; +using System.Collections; using System.Collections.Generic; using System.Configuration; -using Core.Common.Base; using Core.Common.Base.Data; using Core.Common.Base.Plugin; using Core.Common.Gui.Forms.MainWindow; @@ -133,6 +133,14 @@ GuiPlugin GetPluginGuiForType(Type type); /// + /// Queries the plugins to get all data with view definitions recursively given a + /// piece of hierarchical data. + /// + /// The root data object. + /// An enumeration of all (child)data that have view definitions declared. + IEnumerable GetAllDataWithViewDefinitionsRecursively(object rootDataObject); + + /// /// Runs gui. Internally it runs , initializes all user interface components, including /// those loaded from plugins. After that it creates and shows main window. /// Index: Core/Common/src/Core.Common.Gui/RingtoetsGui.cs =================================================================== diff -u -r0c09106be1dfa0dad80232e39fea48b274ecdf37 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/src/Core.Common.Gui/RingtoetsGui.cs (.../RingtoetsGui.cs) (revision 0c09106be1dfa0dad80232e39fea48b274ecdf37) +++ Core/Common/src/Core.Common.Gui/RingtoetsGui.cs (.../RingtoetsGui.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -8,9 +8,9 @@ using System.Linq; using System.Reflection; using System.Windows.Forms; + using Core.Common.Base.Data; using Core.Common.Base.Plugin; -using Core.Common.Controls; using Core.Common.Controls.Swf.TreeViewControls; using Core.Common.Controls.Views; using Core.Common.Gui.ContextMenu; @@ -24,6 +24,7 @@ using Core.Common.Utils.Collections; using Core.Common.Utils.Reflection; using Core.GIS.SharpMap.UI.Helpers; + using log4net; using log4net.Appender; using log4net.Repository.Hierarchy; @@ -212,7 +213,7 @@ } set { - mainWindow = (MainWindow) value; + mainWindow = (MainWindow)value; mainWindow.Gui = this; } } @@ -260,6 +261,24 @@ return new ContextMenuBuilder(CommandHandler, treeNode); } + public IEnumerable GetAllDataWithViewDefinitionsRecursively(object rootDataObject) + { + var resultSet = new HashSet(); + foreach (var childDataInstance in Plugins.SelectMany(p => p.GetChildDataWithViewDefinitions(rootDataObject)).Distinct()) + { + resultSet.Add(childDataInstance); + + if (!ReferenceEquals(rootDataObject, childDataInstance)) + { + foreach (var dataWithViewDefined in GetAllDataWithViewDefinitionsRecursively(childDataInstance)) + { + resultSet.Add(dataWithViewDefined); + } + } + } + return resultSet; + } + public void Dispose() { Dispose(true); @@ -471,7 +490,7 @@ var propertyCacheInfo = reflectTypeDescriptionProviderType.GetField("_propertyCache", BindingFlags.Static | BindingFlags.NonPublic); - var propertyCache = (Hashtable) propertyCacheInfo.GetValue(null); + var propertyCache = (Hashtable)propertyCacheInfo.GetValue(null); if (propertyCache != null) { propertyCache.Clear(); @@ -586,7 +605,7 @@ private void ConfigureLogging() { // configure logging - var rootLogger = ((Hierarchy) LogManager.GetRepository()).Root; + var rootLogger = ((Hierarchy)LogManager.GetRepository()).Root; if (!rootLogger.Appenders.Cast().Any(a => a is MessageWindowLogAppender)) { @@ -597,7 +616,7 @@ private void RemoveLogging() { - var rootLogger = ((Hierarchy) LogManager.GetRepository()).Root; + var rootLogger = ((Hierarchy)LogManager.GetRepository()).Root; var messageWindowLogAppender = rootLogger.Appenders.Cast().OfType().FirstOrDefault(); if (messageWindowLogAppender != null) { @@ -912,8 +931,8 @@ StringCollection defaultViewDataTypes; if (UserSettings["defaultViews"] != null) { - defaultViews = (StringCollection) UserSettings["defaultViews"]; - defaultViewDataTypes = (StringCollection) UserSettings["defaultViewDataTypes"]; + defaultViews = (StringCollection)UserSettings["defaultViews"]; + defaultViewDataTypes = (StringCollection)UserSettings["defaultViewDataTypes"]; } else { Index: Core/Common/test/Core.Common.Controls.Swf.Test/TreeViewControls/TreeViewTest.cs =================================================================== diff -u -ref35125104cc8b0201f9c961049cc6c8a30fb74d -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/test/Core.Common.Controls.Swf.Test/TreeViewControls/TreeViewTest.cs (.../TreeViewTest.cs) (revision ef35125104cc8b0201f9c961049cc6c8a30fb74d) +++ Core/Common/test/Core.Common.Controls.Swf.Test/TreeViewControls/TreeViewTest.cs (.../TreeViewTest.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -308,6 +308,21 @@ [Test] public void DeletedNodeMovesSelectionToItsParentNode() { + var parent = new Parent + { + Name = "Parent" + }; + var child = new Child + { + Name = "Child" + }; + var grandchild = new Child + { + Name = "GrandChild" + }; + parent.Children.Add(child); + child.Children.Add(grandchild); + DialogBoxHandler = (name, wnd) => { var messageBox = new MessageBoxTester(wnd); @@ -316,26 +331,18 @@ messageBox.ClickOk(); }; + int dataDeletedCallCount = 0; using (var treeView = new TreeView()) { + treeView.DataDeleted += (sender, args) => + { + Assert.AreSame(treeView, sender); + Assert.AreSame(grandchild, args.DeletedDataInstance); + dataDeletedCallCount++; + }; treeView.RegisterNodePresenter(new ParentNodePresenter()); treeView.RegisterNodePresenter(new ChildNodePresenter()); - var parent = new Parent() - { - Name = "Parent" - }; - var child = new Child() - { - Name = "Child" - }; - var grandchild = new Child() - { - Name = "GrandChild" - }; - parent.Children.Add(child); - child.Children.Add(grandchild); - treeView.Data = parent; try @@ -355,6 +362,7 @@ { WindowsFormsTestHelper.CloseAll(); } + Assert.AreEqual(1, dataDeletedCallCount); } } Index: Core/Common/test/Core.Common.Gui.Test/Core.Common.Gui.Test.csproj =================================================================== diff -u -r75aa4fefacf584d5172dc3bdffd348b0aacb05a4 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/test/Core.Common.Gui.Test/Core.Common.Gui.Test.csproj (.../Core.Common.Gui.Test.csproj) (revision 75aa4fefacf584d5172dc3bdffd348b0aacb05a4) +++ Core/Common/test/Core.Common.Gui.Test/Core.Common.Gui.Test.csproj (.../Core.Common.Gui.Test.csproj) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -84,6 +84,10 @@ {30e4c2ae-719e-4d70-9fa9-668a9767fbfa} Core.Common.Gui + + {f49bd8b2-332a-4c91-a196-8cce0a2c7d98} + Core.Common.Utils + {26214BD0-DAFB-4CFC-8EB2-80C5D53C859E} Core.Common.Gui.TestUtil Index: Core/Common/test/Core.Common.Gui.Test/GuiCommandHandlerTest.cs =================================================================== diff -u -r8d069bd17ce1b0f7ec017385f9f4e5fd84ed1f6f -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/test/Core.Common.Gui.Test/GuiCommandHandlerTest.cs (.../GuiCommandHandlerTest.cs) (revision 8d069bd17ce1b0f7ec017385f9f4e5fd84ed1f6f) +++ Core/Common/test/Core.Common.Gui.Test/GuiCommandHandlerTest.cs (.../GuiCommandHandlerTest.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -1,4 +1,6 @@ using System.Collections.Generic; + +using Core.Common.Controls.Views; using Core.Common.Gui.Forms.PropertyGridView; using NUnit.Framework; using Rhino.Mocks; @@ -62,6 +64,56 @@ mocks.VerifyAll(); } + + [Test] + public void RemoveAllViewsForItem_GuiHasDocumentViews_CloseViewForDataAndChildren() + { + // Setup + var data = new object(); + var childData = new object(); + + var documentViewsResolver = mocks.StrictMock(); + documentViewsResolver.Expect(vr => vr.CloseAllViewsFor(data)); + documentViewsResolver.Expect(vr => vr.CloseAllViewsFor(childData)); + + var dataView = mocks.Stub(); + dataView.Data = data; + var childDataView = mocks.Stub(); + childDataView.Data = childData; + + var viewsArray = new List + { + dataView, + childDataView + }; + var toolWindows = mocks.StrictMock(); + toolWindows.Stub(ws => ws.GetEnumerator()).WhenCalled(invocation => invocation.ReturnValue = viewsArray.GetEnumerator()).Return(null); + toolWindows.Expect(ws => ws.Count).Return(viewsArray.Count); + + var gui = mocks.Stub(); + gui.Expect(g => g.GetAllDataWithViewDefinitionsRecursively(data)).Return(new[] + { + data, + childData + }); + gui.Expect(g => g.DocumentViews).Return(toolWindows).Repeat.AtLeastOnce(); + gui.Expect(g => g.DocumentViewsResolver).Return(documentViewsResolver).Repeat.AtLeastOnce(); + gui.Expect(g => g.ToolWindowViews).Return(toolWindows).Repeat.AtLeastOnce(); + gui.Stub(g => g.ProjectOpened += null).IgnoreArguments(); + gui.Stub(g => g.ProjectClosing += null).IgnoreArguments(); + gui.Stub(g => g.MainWindow).Return(null); + mocks.ReplayAll(); + + var guiCommandHandler = new GuiCommandHandler(gui); + + // Call + guiCommandHandler.RemoveAllViewsForItem(data); + + // Assert + Assert.IsNull(dataView.Data); + Assert.IsNull(childDataView.Data); + mocks.VerifyAll(); + } } public class TestGuiPlugin : GuiPlugin Index: Core/Common/test/Core.Common.Test/Gui/RingtoetsGuiTests.cs =================================================================== diff -u -rad6f88d1d7b21f950588f6109b79fe007aab0c9e -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Common/test/Core.Common.Test/Gui/RingtoetsGuiTests.cs (.../RingtoetsGuiTests.cs) (revision ad6f88d1d7b21f950588f6109b79fe007aab0c9e) +++ Core/Common/test/Core.Common.Test/Gui/RingtoetsGuiTests.cs (.../RingtoetsGuiTests.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -1,4 +1,5 @@ -using Core.Common.Base; +using System.Linq; + using Core.Common.Base.Plugin; using Core.Common.Gui; using NUnit.Framework; @@ -37,5 +38,112 @@ Assert.NotNull(ViewPropertyEditor.Gui); } } + + [Test] + public void GetAllDataWithViewDefinitionsRecursively_DataHasNoViewDefinitions_ReturnEmpty() + { + // Setup + using (var ringtoetsGui = new RingtoetsGui()) + { + var rootData = new object(); + + // Call + var dataInstancesWithViewDefinitions = ringtoetsGui.GetAllDataWithViewDefinitionsRecursively(rootData); + + // Assert + CollectionAssert.IsEmpty(dataInstancesWithViewDefinitions); + } + } + + [Test] + public void GetAllDataWithViewDefinitionsRecursively_MultiplePluginsHaveViewDefinitionsForRoot_ReturnRootObject() + { + // Setup + var rootData = new object(); + + var mocks = new MockRepository(); + var plugin1 = mocks.StrictMock(); + plugin1.Expect(p => p.GetChildDataWithViewDefinitions(rootData)).Return(new[] + { + rootData + }); + plugin1.Stub(p => p.Dispose()); + plugin1.Stub(p => p.Deactivate()); + var plugin2 = mocks.StrictMock(); + plugin2.Expect(p => p.GetChildDataWithViewDefinitions(rootData)).Return(new[] + { + rootData + }); + plugin2.Stub(p => p.Dispose()); + plugin2.Stub(p => p.Deactivate()); + mocks.ReplayAll(); + + using (var ringtoetsGui = new RingtoetsGui()) + { + ringtoetsGui.Plugins.Add(plugin1); + ringtoetsGui.Plugins.Add(plugin2); + + // Call + var dataInstancesWithViewDefinitions = ringtoetsGui.GetAllDataWithViewDefinitionsRecursively(rootData).OfType().ToArray(); + + // Assert + var expectedDataDefinitions = new[] + { + rootData + }; + CollectionAssert.AreEquivalent(expectedDataDefinitions, dataInstancesWithViewDefinitions); + } + mocks.VerifyAll(); + } + + [Test] + public void GetAllDataWithViewDefinitionsRecursively_MultiplePluginsHaveViewDefinitionsForRootAndChild_ReturnRootAndChild() + { + // Setup + object rootData = 1; + object rootChild = 2; + + var mocks = new MockRepository(); + var plugin1 = mocks.StrictMock(); + plugin1.Expect(p => p.GetChildDataWithViewDefinitions(rootData)).Return(new[] + { + rootData, rootChild + }); + plugin1.Expect(p => p.GetChildDataWithViewDefinitions(rootChild)).Return(new[] + { + rootChild + }); + plugin1.Stub(p => p.Dispose()); + plugin1.Stub(p => p.Deactivate()); + var plugin2 = mocks.StrictMock(); + plugin2.Expect(p => p.GetChildDataWithViewDefinitions(rootData)).Return(new[] + { + rootChild, rootData + }); + plugin2.Expect(p => p.GetChildDataWithViewDefinitions(rootChild)).Return(new[] + { + rootChild + }); + plugin2.Stub(p => p.Dispose()); + plugin2.Stub(p => p.Deactivate()); + mocks.ReplayAll(); + + using (var ringtoetsGui = new RingtoetsGui()) + { + ringtoetsGui.Plugins.Add(plugin1); + ringtoetsGui.Plugins.Add(plugin2); + + // Call + var dataInstancesWithViewDefinitions = ringtoetsGui.GetAllDataWithViewDefinitionsRecursively(rootData).OfType().ToArray(); + + // Assert + var expectedDataDefinitions = new[] + { + rootData, rootChild + }; + CollectionAssert.AreEquivalent(expectedDataDefinitions, dataInstancesWithViewDefinitions); + } + mocks.VerifyAll(); + } } } \ No newline at end of file Index: Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectExplorerGuiPlugin.cs =================================================================== diff -u -r65c12731b5bc4f7dd185b779c801b9ee319e4e3a -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectExplorerGuiPlugin.cs (.../ProjectExplorerGuiPlugin.cs) (revision 65c12731b5bc4f7dd185b779c801b9ee319e4e3a) +++ Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectExplorerGuiPlugin.cs (.../ProjectExplorerGuiPlugin.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Core.Common.Base.Data; -using Core.Common.Controls; using Core.Common.Controls.Swf.TreeViewControls; using Core.Common.Gui; using Core.Common.Gui.Forms; @@ -45,6 +44,18 @@ yield return new ProjectNodePresenter(Gui.ContextMenuProvider, Gui.CommandHandler); } + public override IEnumerable GetChildDataWithViewDefinitions(object dataObject) + { + var project = dataObject as Project; + if (project != null) + { + foreach (var item in project.Items) + { + yield return item; + } + } + } + public static ProjectExplorerGuiPlugin Instance { get; private set; } public ProjectExplorer ProjectExplorer { get; private set; } Index: Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectTreeView.cs =================================================================== diff -u -rc3dd2497d527a0d8f1e7d974f601903d2e426331 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectTreeView.cs (.../ProjectTreeView.cs) (revision c3dd2497d527a0d8f1e7d974f601903d2e426331) +++ Core/Plugins/src/Core.Plugins.ProjectExplorer/ProjectTreeView.cs (.../ProjectTreeView.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -35,6 +35,7 @@ { AllowDrop = true }; + treeView.DataDeleted += ProjectDataDeleted; treeView.NodeMouseClick += TreeViewNodeMouseClick; treeView.DoubleClick += TreeViewDoubleClick; @@ -231,6 +232,11 @@ gui.CommandHandler.OpenViewForSelection(); } + private void ProjectDataDeleted(object sender, TreeView.TreeViewDataDeletedEventArgs e) + { + gui.CommandHandler.RemoveAllViewsForItem(e.DeletedDataInstance); + } + ~ProjectTreeView() { if (gui == null) Index: Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/Core.Plugins.ProjectExplorer.Test.csproj =================================================================== diff -u -r257d05c151e5c8e1f661870752d8a3783633924b -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/Core.Plugins.ProjectExplorer.Test.csproj (.../Core.Plugins.ProjectExplorer.Test.csproj) (revision 257d05c151e5c8e1f661870752d8a3783633924b) +++ Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/Core.Plugins.ProjectExplorer.Test.csproj (.../Core.Plugins.ProjectExplorer.Test.csproj) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -65,6 +65,9 @@ ..\..\..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll True + + ..\..\..\..\lib\NUnitForms.dll + @@ -83,7 +86,7 @@ - + Index: Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectExplorerGuiPluginTest.cs =================================================================== diff -u --- Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectExplorerGuiPluginTest.cs (revision 0) +++ Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectExplorerGuiPluginTest.cs (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Core.Common.Base.Data; +using Core.Common.Base.Plugin; +using Core.Common.Controls.Swf.TreeViewControls; +using Core.Common.Gui; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Plugins.ProjectExplorer.Test +{ + [TestFixture] + public class ProjectExplorerGuiPluginTest + { + private IGui gui; + private MockRepository mocks; + private ApplicationCore applicationCore; + private ITreeNodePresenter mockNodePresenter; + private ProjectExplorerGuiPlugin projectExplorerPluginGui; + + [SetUp] + public void SetUp() + { + mocks = new MockRepository(); + gui = mocks.Stub(); + + var project = new Project(); + var plugin = mocks.Stub(); + var pluginGui = mocks.Stub(); + projectExplorerPluginGui = new ProjectExplorerGuiPlugin + { + Gui = gui + }; + + gui.Expect(g => g.SelectionChanged += Arg>.Is.Anything).Repeat.Any(); + gui.Expect(g => g.SelectionChanged -= Arg>.Is.Anything).Repeat.Any(); + gui.Expect(g => g.ProjectOpened += Arg>.Is.Anything).Repeat.Any(); + gui.Expect(g => g.ProjectOpened -= Arg>.Is.Anything).Repeat.Any(); + gui.Expect(g => g.ProjectClosing += Arg>.Is.Anything).Repeat.Any(); + gui.Expect(g => g.ProjectClosing -= Arg>.Is.Anything).Repeat.Any(); + gui.Expect(g => g.ToolWindowViews).Return(mocks.Stub()).Repeat.Any(); + gui.Expect(g => g.DocumentViews).Return(mocks.Stub()).Repeat.Any(); + gui.Expect(g => g.Plugins).Return(new List + { + projectExplorerPluginGui, pluginGui + }).Repeat.Any(); + gui.Expect(g => g.ContextMenuProvider).Return(mocks.StrictMock()).Repeat.Any(); + gui.CommandHandler = mocks.StrictMock(); + + gui.Project = project; + + //create and register a custom np + mockNodePresenter = mocks.Stub(); + pluginGui.Expect(g => g.GetProjectTreeViewNodePresenters()).Return(new[] + { + mockNodePresenter + }); + + applicationCore = new ApplicationCore(); + gui.Expect(g => g.ApplicationCore).Return(applicationCore).Repeat.Any(); + + mocks.ReplayAll(); + + gui.ApplicationCore.AddPlugin(plugin); + } + + [Test] + public void RegisteringTreeNodeAddsToTreeView() + { + projectExplorerPluginGui.Activate(); //this will create the projecttreeview. + + var projectTreeView = projectExplorerPluginGui.ProjectExplorer.TreeView; + Assert.IsTrue(projectTreeView.NodePresenters.Contains(mockNodePresenter)); + + mocks.VerifyAll(); + } + + [Test] + public void ReopeningProjectExplorerKeepsCustomNodePresenter() + { + projectExplorerPluginGui.Activate(); //this will create the projecttreeview. + + //this is somewhat similar to closing the treeview.. + projectExplorerPluginGui.ProjectExplorer.Dispose(); + + //this is what the show command does + projectExplorerPluginGui.InitializeProjectTreeView(); + + //assert all is well again + var projectTreeView = projectExplorerPluginGui.ProjectExplorer.TreeView; + Assert.IsTrue(projectTreeView.NodePresenters.Contains(mockNodePresenter)); + + mocks.VerifyAll(); + } + + [Test] + public void GetChildDataWithViewDefinitions_DataIsProjectWithChildren_ReturnChildren() + { + // Setup + var project = new Project(); + project.Items.Add(1); + project.Items.Add(2); + project.Items.Add(3); + + var plugin = new ProjectExplorerGuiPlugin(); + + // Call + var childrenWithViewDefinitions = plugin.GetChildDataWithViewDefinitions(project); + + // Assert + var expectedResult = project.Items; + CollectionAssert.AreEquivalent(expectedResult, childrenWithViewDefinitions); + } + + [Test] + public void GetChildDataWithViewDefinitions_UnsupportedDataType_ReturnEmpty() + { + // Setup + var plugin = new ProjectExplorerGuiPlugin(); + + // Call + var childrenWithViewDefinitions = plugin.GetChildDataWithViewDefinitions(2); + + // Assert + CollectionAssert.IsEmpty(childrenWithViewDefinitions); + } + } +} \ No newline at end of file Fisheye: Tag 25019cc752a91361f32968c26d48064ed35a916c refers to a dead (removed) revision in file `Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectExplorerPluginGuiTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectTreeViewTest.cs =================================================================== diff -u -r1f79b34c12554e2b9878f6296168d18232cc9852 -r25019cc752a91361f32968c26d48064ed35a916c --- Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectTreeViewTest.cs (.../ProjectTreeViewTest.cs) (revision 1f79b34c12554e2b9878f6296168d18232cc9852) +++ Core/Plugins/test/Core.Plugins.ProjectExplorer.Test/ProjectTreeViewTest.cs (.../ProjectTreeViewTest.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -1,16 +1,22 @@ using System.Configuration; -using Core.Common.Base; +using System.Linq; + +using Core.Common.Base.Data; using Core.Common.Base.Plugin; +using Core.Common.Controls.Swf.TreeViewControls; using Core.Common.Gui; +using Core.Plugins.ProjectExplorer.NodePresenters; + +using NUnit.Extensions.Forms; using NUnit.Framework; using Rhino.Mocks; namespace Core.Plugins.ProjectExplorer.Test { [TestFixture] - public class ProjectTreeViewTest + public class ProjectTreeViewTest : NUnitFormTest { - [Test] + [Test] public void Init() { var mocks = new MockRepository(); @@ -36,5 +42,57 @@ mocks.VerifyAll(); } + + [Test] + public void WhenRemovingNodeFromProjectTree_ThenCommandHandlerRemovesAllViewsForRemovedItems() + { + // Setup + DialogBoxHandler = (name, wnd) => + { + var messageBox = new MessageBoxTester(wnd); + StringAssert.StartsWith("Weet u zeker dat u het volgende item wilt verwijderen:", messageBox.Text); + Assert.AreEqual("Bevestigen", messageBox.Title); + messageBox.ClickOk(); + }; + + object item = 1; + + var project = new Project(); + project.Items.Add(item); + + var mocks = new MockRepository(); + var menuBuilderProvider = mocks.Stub(); + + var integerNodePresenter = mocks.Stub(); + integerNodePresenter.Expect(np => np.CanRemove(project, item)).Return(true); + integerNodePresenter.Expect(np => np.RemoveNodeData(project, item)).Return(true); + integerNodePresenter.Stub(np => np.NodeTagType).Return(typeof(int)); + integerNodePresenter.Stub(np => np.UpdateNode(null, null, null)).IgnoreArguments(); + integerNodePresenter.Stub(np => np.GetChildNodeObjects(item)).Return(new object[0]); + + var commandHandler = mocks.Stub(); + commandHandler.Expect(ch => ch.RemoveAllViewsForItem(item)); + + var gui = mocks.Stub(); + gui.CommandHandler = commandHandler; + mocks.ReplayAll(); + + var guiPlugin = new ProjectExplorerGuiPlugin + { + Gui = gui + }; + + var projectTree = new ProjectTreeView(guiPlugin); + projectTree.TreeView.RegisterNodePresenter(new ProjectNodePresenter(menuBuilderProvider, commandHandler)); + projectTree.TreeView.RegisterNodePresenter(integerNodePresenter); + projectTree.Project = project; + + // Call + projectTree.TreeView.SelectedNode = projectTree.TreeView.Nodes[0].Nodes.First(); + projectTree.TreeView.TryDeleteSelectedNodeData(); + + // Assert + mocks.VerifyAll(); + } } } \ No newline at end of file Index: Ringtoets/Integration/src/Ringtoets.Integration.Plugin/RingtoetsGuiPlugin.cs =================================================================== diff -u -r75aa4fefacf584d5172dc3bdffd348b0aacb05a4 -r25019cc752a91361f32968c26d48064ed35a916c --- Ringtoets/Integration/src/Ringtoets.Integration.Plugin/RingtoetsGuiPlugin.cs (.../RingtoetsGuiPlugin.cs) (revision 75aa4fefacf584d5172dc3bdffd348b0aacb05a4) +++ Ringtoets/Integration/src/Ringtoets.Integration.Plugin/RingtoetsGuiPlugin.cs (.../RingtoetsGuiPlugin.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -48,6 +48,15 @@ }; } + public override IEnumerable GetChildDataWithViewDefinitions(object dataObject) + { + var assessmentSection = dataObject as AssessmentSectionBase; + if (assessmentSection != null) + { + yield return assessmentSection.FailureMechanismContribution; + } + } + /// /// Get the defined for the . /// Index: Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/RingtoetsGuiPluginTest.cs =================================================================== diff -u -r6fc99be8198e5795ca4be54719dab3d1be3c6299 -r25019cc752a91361f32968c26d48064ed35a916c --- Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/RingtoetsGuiPluginTest.cs (.../RingtoetsGuiPluginTest.cs) (revision 6fc99be8198e5795ca4be54719dab3d1be3c6299) +++ Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/RingtoetsGuiPluginTest.cs (.../RingtoetsGuiPluginTest.cs) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -83,5 +83,36 @@ } mocks.VerifyAll(); } + + [Test] + public void GetChildDataWithViewDefinitions_AssessmentSectionBase_ReturnFailureMechanismContribution() + { + // Setup + var mocks = new MockRepository(); + var assessmentSectionBase = mocks.Stub(); + mocks.ReplayAll(); + + var guiPlugin = new RingtoetsGuiPlugin(); + + // Call + var childrenWithViewDefinitions = guiPlugin.GetChildDataWithViewDefinitions(assessmentSectionBase); + + // Assert + CollectionAssert.AreEqual(new[] { assessmentSectionBase.FailureMechanismContribution }, childrenWithViewDefinitions); + mocks.VerifyAll(); + } + + [Test] + public void GetChildDataWithViewDefinitions_UnsupportedData_ReturnEmpty() + { + // Setup + var guiPlugin = new RingtoetsGuiPlugin(); + + // Call + var childrenWithViewDefinitions = guiPlugin.GetChildDataWithViewDefinitions(1); + + // Assert + CollectionAssert.IsEmpty(childrenWithViewDefinitions); + } } } \ No newline at end of file Index: packages/repositories.config =================================================================== diff -u -rde55a69b451ac05927b17902e9f750855605e3ed -r25019cc752a91361f32968c26d48064ed35a916c --- packages/repositories.config (.../repositories.config) (revision de55a69b451ac05927b17902e9f750855605e3ed) +++ packages/repositories.config (.../repositories.config) (revision 25019cc752a91361f32968c26d48064ed35a916c) @@ -30,6 +30,7 @@ +