Index: Ringtoets/Common/src/Ringtoets.Common.Forms/TreeNodeInfos/CalculationTreeNodeInfoFactory.cs =================================================================== diff -u -r6f20aae03e9fecf0d90cf930d06ed72bc4633749 -r3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356 --- Ringtoets/Common/src/Ringtoets.Common.Forms/TreeNodeInfos/CalculationTreeNodeInfoFactory.cs (.../CalculationTreeNodeInfoFactory.cs) (revision 6f20aae03e9fecf0d90cf930d06ed72bc4633749) +++ Ringtoets/Common/src/Ringtoets.Common.Forms/TreeNodeInfos/CalculationTreeNodeInfoFactory.cs (.../CalculationTreeNodeInfoFactory.cs) (revision 3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356) @@ -207,6 +207,23 @@ builder.AddCustomItem(performAllItem); } + /// + /// This method adds a context menu item for performing a calculation. + /// + /// The builder to add the context menu item to. + /// The calculation involved. + /// The action that performs the calculation. + public static void AddPerformCalculationItem(IContextMenuBuilder builder, ICalculation calculation, Action calculate) + { + var calculateItem = new StrictContextMenuItem( + Resources.Calculate, + Resources.Calculate_ToolTip, + Resources.CalculateIcon, + (o, args) => { calculate(calculation); }); + + builder.AddCustomItem(calculateItem); + } + # region Helper methods for CreateCalculationGroupContextTreeNodeInfo private static bool IsNestedGroup(object parentData) Index: Ringtoets/Common/test/Ringtoets.Common.Forms.Test/TreeNodeInfos/CalculationTreeNodeInfoFactoryTest.cs =================================================================== diff -u -r97517f6a66f66d512315618a08fa21a9999624a1 -r3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356 --- Ringtoets/Common/test/Ringtoets.Common.Forms.Test/TreeNodeInfos/CalculationTreeNodeInfoFactoryTest.cs (.../CalculationTreeNodeInfoFactoryTest.cs) (revision 97517f6a66f66d512315618a08fa21a9999624a1) +++ Ringtoets/Common/test/Ringtoets.Common.Forms.Test/TreeNodeInfos/CalculationTreeNodeInfoFactoryTest.cs (.../CalculationTreeNodeInfoFactoryTest.cs) (revision 3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356) @@ -428,6 +428,60 @@ Assert.AreEqual(1, counter); } + [Test] + public void AddPerformCalculationItem_Always_CreatesPerformItem() + { + // Setup + var mocks = new MockRepository(); + var applicationFeatureCommandHandler = mocks.Stub(); + var exportImportHandler = mocks.Stub(); + var viewCommandsHandler = mocks.StrictMock(); + var treeViewControl = mocks.StrictMock(); + var calculation = mocks.StrictMock(); + + mocks.ReplayAll(); + + var menubuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculation, treeViewControl); + + // Call + CalculationTreeNodeInfoFactory.AddPerformCalculationItem(menubuilder, calculation, null); + + // Assert + TestHelper.AssertContextMenuStripContainsItem(menubuilder.Build(), 0, + RingtoetsFormsResources.Calculate, + RingtoetsFormsResources.Calculate_ToolTip, + RingtoetsFormsResources.CalculateIcon); + + mocks.VerifyAll(); + } + + [Test] + public void AddPerformCalculationItem_PerformClickOnCreatedItem_PerformCalculationMethod() + { + // Setup + var mocks = new MockRepository(); + var applicationFeatureCommandHandler = mocks.Stub(); + var exportImportHandler = mocks.Stub(); + var viewCommandsHandler = mocks.StrictMock(); + var treeViewControl = mocks.StrictMock(); + var calculation = mocks.StrictMock(); + + mocks.ReplayAll(); + + var counter = 0; + + var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculation, treeViewControl); + + CalculationTreeNodeInfoFactory.AddPerformCalculationItem(menuBuilder, calculation, context => counter++); + var contextMenuItem = menuBuilder.Build().Items[0]; + + // Call + contextMenuItem.PerformClick(); + + // Assert + Assert.AreEqual(1, counter); + } + # region CreateCalculationGroupContextTreeNodeInfo [Test] Index: Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Plugin/GrassCoverErosionInwardsGuiPlugin.cs =================================================================== diff -u -r6f20aae03e9fecf0d90cf930d06ed72bc4633749 -r3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356 --- Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Plugin/GrassCoverErosionInwardsGuiPlugin.cs (.../GrassCoverErosionInwardsGuiPlugin.cs) (revision 6f20aae03e9fecf0d90cf930d06ed72bc4633749) +++ Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Plugin/GrassCoverErosionInwardsGuiPlugin.cs (.../GrassCoverErosionInwardsGuiPlugin.cs) (revision 3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356) @@ -78,7 +78,7 @@ yield return CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo( GrassCoverErosionInwardsFormsResources.CalculationIcon, CalculationContextChildNodeObjects, - null, + CalculationContextContextmenuStrip, null); yield return new TreeNodeInfo @@ -106,25 +106,6 @@ }; } - private static object[] CalculationContextChildNodeObjects(GrassCoverErosionInwardsCalculationContext calculationContext) - { - var childNodes = new List - { - new CommentContext(calculationContext.WrappedData), - new GrassCoverErosionInwardsInputContext(calculationContext.WrappedData.InputParameters, - calculationContext.WrappedData, - calculationContext.FailureMechanism, - calculationContext.AssessmentSection) - }; - - if (!calculationContext.WrappedData.HasOutput) - { - childNodes.Add(new EmptyGrassCoverErosionInwardsOutput()); - } - - return childNodes.ToArray(); - } - private static ExceedanceProbabilityCalculationActivity CreateHydraRingTargetProbabilityCalculationActivity(HydraulicBoundaryLocation hydraulicBoundaryLocation, string hlcdDirectory, GrassCoverErosionInwardsInput inwardsInput, @@ -353,5 +334,62 @@ } #endregion + + #region CalculationContext TreeNodeInfo + + private static object[] CalculationContextChildNodeObjects(GrassCoverErosionInwardsCalculationContext calculationContext) + { + var childNodes = new List + { + new CommentContext(calculationContext.WrappedData), + new GrassCoverErosionInwardsInputContext(calculationContext.WrappedData.InputParameters, + calculationContext.WrappedData, + calculationContext.FailureMechanism, + calculationContext.AssessmentSection) + }; + + if (!calculationContext.WrappedData.HasOutput) + { + childNodes.Add(new EmptyGrassCoverErosionInwardsOutput()); + } + + return childNodes.ToArray(); + } + + private ContextMenuStrip CalculationContextContextmenuStrip(GrassCoverErosionInwardsCalculationContext nodeData, object parentData, TreeViewControl treeViewControl) + { + var builder = Gui.Get(nodeData, treeViewControl); + + GrassCoverErosionInwardsCalculation calculation = nodeData.WrappedData; + + CalculationTreeNodeInfoFactory.AddPerformCalculationItem(builder, calculation, null); + builder.AddSeparator(); +// var clearOutputItem = new StrictContextMenuItem(PipingFormsResources.Clear_output, +// PipingFormsResources.Clear_output_ToolTip, +// RingtoetsCommonFormsResources.ClearIcon, +// (o, args) => ClearOutput(calculation)); +// +// if (!calculation.HasOutput) +// { +// clearOutputItem.Enabled = false; +// clearOutputItem.ToolTipText = PipingFormsResources.ClearOutput_No_output_to_clear; +// } + + return builder +// .AddCustomItem(clearOutputItem) + .AddRenameItem() + .AddDeleteItem() + .AddSeparator() + .AddImportItem() + .AddExportItem() + .AddSeparator() + .AddExpandAllItem() + .AddCollapseAllItem() + .AddSeparator() + .AddPropertiesItem() + .Build(); + } + + #endregion } } \ No newline at end of file Index: Ringtoets/GrassCoverErosionInwards/test/Ringtoets.GrassCoverErosionInwards.Forms.Test/TreeNodeInfos/GrassCoverErosionInwardsCalculationContextTreeNodeInfoTest.cs =================================================================== diff -u -r7343a55e81349863d0e5d7bec5c7f0b3577adf65 -r3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356 --- Ringtoets/GrassCoverErosionInwards/test/Ringtoets.GrassCoverErosionInwards.Forms.Test/TreeNodeInfos/GrassCoverErosionInwardsCalculationContextTreeNodeInfoTest.cs (.../GrassCoverErosionInwardsCalculationContextTreeNodeInfoTest.cs) (revision 7343a55e81349863d0e5d7bec5c7f0b3577adf65) +++ Ringtoets/GrassCoverErosionInwards/test/Ringtoets.GrassCoverErosionInwards.Forms.Test/TreeNodeInfos/GrassCoverErosionInwardsCalculationContextTreeNodeInfoTest.cs (.../GrassCoverErosionInwardsCalculationContextTreeNodeInfoTest.cs) (revision 3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356) @@ -21,6 +21,8 @@ using System.Linq; using Core.Common.Controls.TreeView; +using Core.Common.Gui; +using Core.Common.Gui.ContextMenu; using Core.Common.TestUtil; using NUnit.Framework; using Rhino.Mocks; @@ -37,14 +39,14 @@ [TestFixture] public class GrassCoverErosionInwardsCalculationContextTreeNodeInfoTest { - private MockRepository mocksRepository; + private MockRepository mocks; private GrassCoverErosionInwardsGuiPlugin plugin; private TreeNodeInfo info; [SetUp] public void SetUp() { - mocksRepository = new MockRepository(); + mocks = new MockRepository(); plugin = new GrassCoverErosionInwardsGuiPlugin(); info = plugin.GetTreeNodeInfos().First(tni => tni.TagType == typeof(GrassCoverErosionInwardsCalculationContext)); } @@ -76,11 +78,11 @@ [Test] public void ChildNodeObjects_WithOutputData_ReturnOutputChildNode() { - var calculation = mocksRepository.StrictMock(new GeneralGrassCoverErosionInwardsInput()); - var failureMechanism = mocksRepository.StrictMock(); - var assessmentSectionMock = mocksRepository.StrictMock(); - mocksRepository.ReplayAll(); + var calculation = mocks.StrictMock(new GeneralGrassCoverErosionInwardsInput()); + var assessmentSectionMock = mocks.StrictMock(); + mocks.ReplayAll(); + var failureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var calculationContext = new GrassCoverErosionInwardsCalculationContext(calculation, failureMechanism, assessmentSectionMock); // Call @@ -98,5 +100,46 @@ var emptyOutput = (EmptyGrassCoverErosionInwardsOutput) children[2]; Assert.IsNotNull(emptyOutput); } + + [Test] + public void ContextMenuStrip_Always_CallsContextMenuBuilderMethods() + { + // Setup + var gui = mocks.StrictMock(); + var treeViewControlMock = mocks.StrictMock(); + + var menuBuilderMock = mocks.Stub(); + menuBuilderMock.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddRenameItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddDeleteItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddImportItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddExportItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddExpandAllItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddCollapseAllItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddSeparator()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.AddPropertiesItem()).Return(menuBuilderMock); + menuBuilderMock.Expect(mb => mb.Build()).Return(null); + + var failureMechanism = new GrassCoverErosionInwardsFailureMechanism(); + var assessmentSectionMock = mocks.StrictMock(); + var calculation = mocks.StrictMock(new GeneralGrassCoverErosionInwardsInput()); + + var nodeData = new GrassCoverErosionInwardsCalculationContext(calculation, failureMechanism, assessmentSectionMock); + + gui.Expect(cmp => cmp.Get(nodeData, treeViewControlMock)).Return(menuBuilderMock); + + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + info.ContextMenuStrip(nodeData, null, treeViewControlMock); + + // Assert + mocks.VerifyAll(); // Expect no calls on arguments + } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingGuiPlugin.cs =================================================================== diff -u -r6b43c39e0f54d1054729aaed5aa6dc19149ef72a -r3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356 --- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingGuiPlugin.cs (.../PipingGuiPlugin.cs) (revision 6b43c39e0f54d1054729aaed5aa6dc19149ef72a) +++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/PipingGuiPlugin.cs (.../PipingGuiPlugin.cs) (revision 3bd79dc878fa0b81b1ebb5c35dd5612f2bfed356) @@ -423,16 +423,17 @@ private ContextMenuStrip PipingCalculationContextContextMenuStrip(PipingCalculationScenarioContext nodeData, object parentData, TreeViewControl treeViewControl) { + var builder = Gui.Get(nodeData, treeViewControl); + PipingCalculation calculation = nodeData.WrappedData; var validateItem = new StrictContextMenuItem(RingtoetsCommonFormsResources.Validate, RingtoetsCommonFormsResources.Validate_ToolTip, RingtoetsCommonFormsResources.ValidateIcon, (o, args) => { PipingCalculationService.Validate(calculation); }); - var calculateItem = new StrictContextMenuItem(RingtoetsCommonFormsResources.Calculate, - RingtoetsCommonFormsResources.Calculate_ToolTip, - RingtoetsCommonFormsResources.CalculateIcon, - (o, args) => { ActivityProgressDialogRunner.Run(Gui.MainWindow, new PipingCalculationActivity(calculation)); }); + builder.AddCustomItem(validateItem); + CalculationTreeNodeInfoFactory.AddPerformCalculationItem(builder, calculation, PerformCalculation); + var clearOutputItem = new StrictContextMenuItem(PipingFormsResources.Clear_output, PipingFormsResources.Clear_output_ToolTip, RingtoetsCommonFormsResources.ClearIcon, @@ -444,11 +445,11 @@ clearOutputItem.ToolTipText = PipingFormsResources.ClearOutput_No_output_to_clear; } - return Gui.Get(nodeData, treeViewControl) - .AddCustomItem(validateItem) - .AddCustomItem(calculateItem) - .AddCustomItem(clearOutputItem) - .AddSeparator() + builder + .AddCustomItem(clearOutputItem) + .AddSeparator(); + + return builder .AddRenameItem() .AddDeleteItem() .AddSeparator() @@ -514,6 +515,11 @@ calculation.NotifyObservers(); } + private void PerformCalculation(ICalculation calculation) + { + ActivityProgressDialogRunner.Run(Gui.MainWindow, new PipingCalculationActivity((PipingCalculation)calculation)); + } + # endregion # region PipingCalculationGroupContext TreeNodeInfo