Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/ClosingStructuresPlugin.cs =================================================================== diff -u -rada94ef2b6943fb9a2d8e59256871205a7d4c4ee -r2982a33466b6b47205d8ecf7faab23c362a36596 --- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/ClosingStructuresPlugin.cs (.../ClosingStructuresPlugin.cs) (revision ada94ef2b6943fb9a2d8e59256871205a7d4c4ee) +++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Plugin/ClosingStructuresPlugin.cs (.../ClosingStructuresPlugin.cs) (revision 2982a33466b6b47205d8ecf7faab23c362a36596) @@ -497,11 +497,18 @@ return childNodeObjects.ToArray(); } - private ContextMenuStrip CalculationGroupContextContextMenuStrip(ClosingStructuresCalculationGroupContext context, object parentData, TreeViewControl treeViewControl) + private ContextMenuStrip CalculationGroupContextContextMenuStrip(ClosingStructuresCalculationGroupContext context, + object parentData, + TreeViewControl treeViewControl) { CalculationGroup group = context.WrappedData; var builder = new RingtoetsContextMenuBuilder(Gui.Get(context, treeViewControl)); + var inquiryHelper = new DialogBasedInquiryHelper(Gui.MainWindow); bool isNestedGroup = parentData is ClosingStructuresCalculationGroupContext; + + StructuresCalculation[] calculations = group + .GetCalculations() + .OfType>().ToArray(); builder.AddImportItem() .AddExportItem() @@ -522,7 +529,10 @@ builder.AddRenameItem(); } - builder.AddCustomItem(CreateUpdateStructureItem(context)) + builder.AddUpdateForeshoreProfileOfCalculationsItem(calculations, + inquiryHelper, + SynchronizeCalculationWithForeshoreProfileHelper.UpdateForeshoreProfileDerivedCalculationInput) + .AddCustomItem(CreateUpdateStructureItem(calculations)) .AddSeparator() .AddValidateAllCalculationsInGroupItem( context, @@ -553,12 +563,8 @@ .Build(); } - private StrictContextMenuItem CreateUpdateStructureItem(ClosingStructuresCalculationGroupContext nodeData) + private StrictContextMenuItem CreateUpdateStructureItem(StructuresCalculation[] calculations) { - IEnumerable> calculations = nodeData.WrappedData - .GetCalculations() - .OfType>(); - var contextMenuEnabled = true; string toolTipText = RingtoetsCommonFormsResources.StructuresPlugin_CreateUpdateStructureItem_Update_all_calculations_with_Structure_Tooltip; if (!calculations.Any()) Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Plugin.Test/TreeNodeInfos/ClosingStructuresCalculationGroupContextTreeNodeInfoTest.cs =================================================================== diff -u -rdad191ad1ec7648b4ead227124aa1df4b612bd45 -r2982a33466b6b47205d8ecf7faab23c362a36596 --- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Plugin.Test/TreeNodeInfos/ClosingStructuresCalculationGroupContextTreeNodeInfoTest.cs (.../ClosingStructuresCalculationGroupContextTreeNodeInfoTest.cs) (revision dad191ad1ec7648b4ead227124aa1df4b612bd45) +++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Plugin.Test/TreeNodeInfos/ClosingStructuresCalculationGroupContextTreeNodeInfoTest.cs (.../ClosingStructuresCalculationGroupContextTreeNodeInfoTest.cs) (revision 2982a33466b6b47205d8ecf7faab23c362a36596) @@ -62,17 +62,19 @@ private const int contextMenuGenerateCalculationsIndexRootGroup = 3; private const int contextMenuAddCalculationGroupIndexRootGroup = 5; private const int contextMenuAddCalculationIndexRootGroup = 6; - private const int contextMenuUpdateStructureAllIndexRootGroup = 8; - private const int contextMenuValidateAllIndexRootGroup = 10; - private const int contextMenuCalculateAllIndexRootGroup = 11; - private const int contextMenuClearAllIndexRootGroup = 13; + private const int contextMenuUpdateForeshoreProfileAllIndexRootGroup = 8; + private const int contextMenuUpdateStructureAllIndexRootGroup = 9; + private const int contextMenuValidateAllIndexRootGroup = 11; + private const int contextMenuCalculateAllIndexRootGroup = 12; + private const int contextMenuClearAllIndexRootGroup = 14; private const int contextMenuAddCalculationGroupIndexNestedGroup = 3; private const int contextMenuAddCalculationIndexNestedGroup = 4; - private const int contextMenuUpdateStructureAllIndexNestedGroup = 7; - private const int contextMenuValidateAllIndexNestedGroup = 9; - private const int contextMenuCalculateAllIndexNestedGroup = 10; - private const int contextMenuClearAllIndexNestedGroup = 12; + private const int contextMenuUpdateForeshoreProfileAllIndexNestedGroup = 7; + private const int contextMenuUpdateStructureAllIndexNestedGroup = 8; + private const int contextMenuValidateAllIndexNestedGroup = 10; + private const int contextMenuCalculateAllIndexNestedGroup = 11; + private const int contextMenuClearAllIndexNestedGroup = 13; private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "HydraulicBoundaryDatabaseImporter"); @@ -207,6 +209,7 @@ menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); @@ -225,7 +228,7 @@ { gui.Stub(cmp => cmp.Get(groupContext, treeViewControl)).Return(menuBuilderMock); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -252,14 +255,14 @@ { gui.Stub(g => g.Get(groupContext, treeViewControl)).Return(menuBuilder); gui.Stub(g => g.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call using (ContextMenuStrip menu = info.ContextMenuStrip(groupContext, null, treeViewControl)) { // Assert - Assert.AreEqual(20, menu.Items.Count); + Assert.AreEqual(21, menu.Items.Count); TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuGenerateCalculationsIndexRootGroup, "Genereer &berekeningen...", @@ -275,6 +278,11 @@ "Voeg een nieuwe berekening toe aan deze berekeningsmap.", RingtoetsCommonFormsResources.FailureMechanismIcon); + TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuUpdateForeshoreProfileAllIndexRootGroup, + "&Bijwerken voorlandprofielen...", + "De geselecteerde voorlandprofielen hebben geen wijzigingen om bij te werken.", + RingtoetsCommonFormsResources.UpdateItemIcon, + false); TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuUpdateStructureAllIndexRootGroup, "&Bijwerken kunstwerken", "Er zijn geen berekeningen om bij te werken.", @@ -321,15 +329,13 @@ { gui.Stub(g => g.Get(groupContext, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call using (ContextMenuStrip menu = info.ContextMenuStrip(groupContext, null, treeViewControl)) { // Assert - Assert.AreEqual(20, menu.Items.Count); - TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuGenerateCalculationsIndexRootGroup, "Genereer &berekeningen...", "Genereer berekeningen op basis van geselecteerde kunstwerken.", @@ -364,6 +370,7 @@ menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddRenameItem()).Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); @@ -381,7 +388,7 @@ using (var treeViewControl = new TreeViewControl()) { gui.Stub(cmp => cmp.Get(groupContext, treeViewControl)).Return(menuBuilderMock); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -410,13 +417,14 @@ using (var treeViewControl = new TreeViewControl()) { gui.Stub(g => g.Get(groupContext, treeViewControl)).Return(menuBuilder); + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call using (ContextMenuStrip menu = info.ContextMenuStrip(groupContext, parentGroupContext, treeViewControl)) { // Assert - Assert.AreEqual(19, menu.Items.Count); + Assert.AreEqual(20, menu.Items.Count); TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuAddCalculationGroupIndexNestedGroup, "&Map toevoegen", @@ -427,6 +435,11 @@ "Voeg een nieuwe berekening toe aan deze berekeningsmap.", RingtoetsCommonFormsResources.FailureMechanismIcon); + TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuUpdateForeshoreProfileAllIndexNestedGroup, + "&Bijwerken voorlandprofielen...", + "De geselecteerde voorlandprofielen hebben geen wijzigingen om bij te werken.", + RingtoetsCommonFormsResources.UpdateItemIcon, + false); TestHelper.AssertContextMenuStripContainsItem(menu, contextMenuUpdateStructureAllIndexNestedGroup, "&Bijwerken kunstwerken", "Er zijn geen berekeningen om bij te werken.", @@ -479,7 +492,7 @@ { gui.Stub(g => g.Get(nodeData, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -529,7 +542,7 @@ { gui.Stub(g => g.Get(nodeData, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -587,7 +600,7 @@ { gui.Stub(g => g.Get(nodeData, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -642,8 +655,8 @@ using (var treeViewControl = new TreeViewControl()) { gui.Stub(g => g.Get(nodeData, treeViewControl)).Return(menuBuilder); - gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.ViewCommands).Return(mocks.Stub()); + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -664,6 +677,113 @@ } [Test] + public void ContextMenuStrip_WithForeshoreProfileAndChanges_ContextMenuItemUpdateAllForeshoreProfilesEnabled() + { + // Setup + var assessmentSectionStub = mocks.Stub(); + var failureMechanism = new TestClosingStructuresFailureMechanism(); + var calculation = new StructuresCalculation + { + InputParameters = + { + ForeshoreProfile = new TestForeshoreProfile() + } + }; + calculation.InputParameters.UseBreakWater = true; + + var nodeData = new ClosingStructuresCalculationGroupContext( + new CalculationGroup + { + Children = + { + calculation + } + }, + failureMechanism, + assessmentSectionStub); + + using (var treeViewControl = new TreeViewControl()) + { + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(cmp => cmp.MainWindow).Return(mocks.Stub()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip menu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(menu, + contextMenuUpdateForeshoreProfileAllIndexRootGroup, + "&Bijwerken voorlandprofielen...", + "Berekeningen bijwerken waar een voorlandprofiel geselecteerd is.", + RingtoetsCommonFormsResources.UpdateItemIcon); + } + } + } + + [Test] + public void GivenCalculationWithForeshoreProfileSet_WhenUpdatingForeshoreProfileFromContextMenu_ThenCalculationUpdatedAndUpdateObserver() + { + // Given + var calculationObserver = mocks.StrictMock(); + var calculationInputObserver = mocks.StrictMock(); + calculationInputObserver.Expect(o => o.UpdateObserver()); + + var assessmentSectionStub = mocks.Stub(); + var failureMechanism = new TestClosingStructuresFailureMechanism(); + + var calculation = new StructuresCalculation + { + InputParameters = + { + ForeshoreProfile = new TestForeshoreProfile(true) + } + }; + calculation.InputParameters.UseBreakWater = false; + + var nodeData = new ClosingStructuresCalculationGroupContext( + new CalculationGroup + { + Children = + { + calculation + } + }, + failureMechanism, + assessmentSectionStub); + + calculation.Attach(calculationObserver); + calculation.InputParameters.Attach(calculationInputObserver); + + using (var treeViewControl = new TreeViewControl()) + { + gui.Stub(g => g.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(cmp => cmp.MainWindow).Return(mocks.Stub()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + using (ContextMenuStrip contextMenuStrip = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Precondition + TestHelper.AssertContextMenuStripContainsItem(contextMenuStrip, + contextMenuUpdateForeshoreProfileAllIndexRootGroup, + "&Bijwerken voorlandprofielen...", + "Berekeningen bijwerken waar een voorlandprofiel geselecteerd is.", + RingtoetsCommonFormsResources.UpdateItemIcon); + + // When + contextMenuStrip.Items[contextMenuUpdateForeshoreProfileAllIndexRootGroup].PerformClick(); + + // Then + Assert.IsTrue(calculation.InputParameters.UseBreakWater); + } + } + } + + [Test] public void ContextMenuStrip_ClickOnCalculateAllItem_ScheduleAllChildCalculations() { // Setup @@ -707,7 +827,7 @@ gui.Stub(g => g.Get(groupContext, treeViewControl)).Return(menuBuilder); gui.Stub(g => g.MainWindow).Return(mainWindow); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); DialogBoxHandler = (name, wnd) => @@ -782,7 +902,7 @@ { gui.Stub(g => g.Get(groupContext, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); using (ContextMenuStrip contextMenu = info.ContextMenuStrip(groupContext, null, treeViewControl)) @@ -826,7 +946,7 @@ { gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); group.Children.Add(calculationGroup); @@ -872,7 +992,7 @@ { gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(menuBuilder); gui.Stub(cmp => cmp.ViewCommands).Return(mocks.Stub()); - + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); group.Children.Add(calculation); @@ -897,7 +1017,7 @@ } [Test] - public void ContextMenuStrip_CalculationGroupWithoutCalculations_ContextMenuItemUpdateStructureAllDisabledAndToolTipSet() + public void ContextMenuStrip_CalculationGroupWithoutCalculations_ContextMenuItemUpdateDisabledAndToolTipSet() { // Setup var group = new CalculationGroup(); @@ -911,12 +1031,19 @@ using (var treeViewControl = new TreeViewControl()) { gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) { // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, contextMenuUpdateForeshoreProfileAllIndexRootGroup, + "&Bijwerken voorlandprofielen...", + "De geselecteerde voorlandprofielen hebben geen wijzigingen om bij te werken.", + RingtoetsCommonFormsResources.UpdateItemIcon, + false); + TestHelper.AssertContextMenuStripContainsItem(contextMenu, contextMenuUpdateStructureAllIndexRootGroup, "&Bijwerken kunstwerken", "Er zijn geen berekeningen om bij te werken.", @@ -947,6 +1074,7 @@ using (var treeViewControl = new TreeViewControl()) { gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -989,6 +1117,7 @@ using (var treeViewControl = new TreeViewControl()) { gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mocks.Stub()); mocks.ReplayAll(); // Call @@ -1061,7 +1190,7 @@ gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); gui.Stub(g => g.MainWindow).Return(mainWindow); mocks.ReplayAll(); - + using (ContextMenuStrip menu = info.ContextMenuStrip(nodeData, assessmentSection, treeViewControl)) { // When