Index: Core/Gui/src/Core.Gui/Commands/MainWindowCommands.cs =================================================================== diff -u -r577bf2384ad70fef1d46fe46c399fee1a3401718 -rb441bd9ffa8a255a522abceffd49201e96808502 --- Core/Gui/src/Core.Gui/Commands/MainWindowCommands.cs (.../MainWindowCommands.cs) (revision 577bf2384ad70fef1d46fe46c399fee1a3401718) +++ Core/Gui/src/Core.Gui/Commands/MainWindowCommands.cs (.../MainWindowCommands.cs) (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -20,12 +20,11 @@ // All rights reserved. using System.Windows.Input; -using Core.Gui.Forms.MainWindow; namespace Core.Gui.Commands { /// - /// This class defines members for the custom commands of . + /// Provides a set of commands for the main window. /// public static class MainWindowCommands { @@ -48,18 +47,13 @@ /// The command for opening a project. /// public static readonly ICommand OpenProjectCommand = new RoutedCommand(); - + /// /// The command for closing the application. /// public static readonly ICommand CloseApplicationCommand = new RoutedCommand(); /// - /// The command for closing the current active view. - /// - public static readonly ICommand CloseViewTabCommand = new RoutedCommand(); - - /// /// The command for toggling the backstage. /// public static readonly ICommand ToggleBackstageCommand = new RoutedCommand(); Index: Core/Gui/src/Core.Gui/Commands/RelayCommand.cs =================================================================== diff -u -r577bf2384ad70fef1d46fe46c399fee1a3401718 -rb441bd9ffa8a255a522abceffd49201e96808502 --- Core/Gui/src/Core.Gui/Commands/RelayCommand.cs (.../RelayCommand.cs) (revision 577bf2384ad70fef1d46fe46c399fee1a3401718) +++ Core/Gui/src/Core.Gui/Commands/RelayCommand.cs (.../RelayCommand.cs) (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -1,4 +1,25 @@ -using System; +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; using System.Windows.Input; namespace Core.Gui.Commands Index: Core/Gui/src/Core.Gui/Commands/RoutedCommandHandler.cs =================================================================== diff -u -r577bf2384ad70fef1d46fe46c399fee1a3401718 -rb441bd9ffa8a255a522abceffd49201e96808502 --- Core/Gui/src/Core.Gui/Commands/RoutedCommandHandler.cs (.../RoutedCommandHandler.cs) (revision 577bf2384ad70fef1d46fe46c399fee1a3401718) +++ Core/Gui/src/Core.Gui/Commands/RoutedCommandHandler.cs (.../RoutedCommandHandler.cs) (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -1,4 +1,25 @@ -using System.Windows; +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System.Windows; using System.Windows.Input; namespace Core.Gui.Commands Index: Core/Gui/src/Core.Gui/Commands/RoutedCommandHandlers.cs =================================================================== diff -u -r577bf2384ad70fef1d46fe46c399fee1a3401718 -rb441bd9ffa8a255a522abceffd49201e96808502 --- Core/Gui/src/Core.Gui/Commands/RoutedCommandHandlers.cs (.../RoutedCommandHandlers.cs) (revision 577bf2384ad70fef1d46fe46c399fee1a3401718) +++ Core/Gui/src/Core.Gui/Commands/RoutedCommandHandlers.cs (.../RoutedCommandHandlers.cs) (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -1,4 +1,25 @@ -using System.Collections; +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System.Collections; using System.Collections.Specialized; using System.Windows; Index: Core/Gui/src/Core.Gui/Forms/MainWindow/MainWindow.xaml.cs =================================================================== diff -u -r577bf2384ad70fef1d46fe46c399fee1a3401718 -rb441bd9ffa8a255a522abceffd49201e96808502 --- Core/Gui/src/Core.Gui/Forms/MainWindow/MainWindow.xaml.cs (.../MainWindow.xaml.cs) (revision 577bf2384ad70fef1d46fe46c399fee1a3401718) +++ Core/Gui/src/Core.Gui/Forms/MainWindow/MainWindow.xaml.cs (.../MainWindow.xaml.cs) (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -69,14 +69,6 @@ private PropertyGridView.PropertyGridView propertyGrid; private IMapView currentMapView; private IChartView currentChartView; - - public ICommand NewProjectCommand { get; } - public ICommand SaveProjectCommand { get; } - public ICommand SaveProjectAsCommand { get; } - public ICommand OpenProjectCommand { get; } - public ICommand CloseApplicationCommand { get; } - public ICommand CloseViewTabCommand { get; } - public ICommand ToggleBackStageCommand { get; } /// /// Initializes a new instance of the class. @@ -330,24 +322,59 @@ UpdateProjectExplorer(); } - #region OnClick events + #region Commands + /// + /// Gets the command to start a new project. + /// + public ICommand NewProjectCommand { get; } + + /// + /// Gets the command to save a project. + /// + public ICommand SaveProjectCommand { get; } + + /// + /// Gets the command to save a project as. + /// + public ICommand SaveProjectAsCommand { get; } + + /// + /// Gets the command to open a project. + /// + public ICommand OpenProjectCommand { get; } + + /// + /// Gets the command to close the application. + /// + public ICommand CloseApplicationCommand { get; } + + /// + /// Gets the command to close a view tab. + /// + public ICommand CloseViewTabCommand { get; } + + /// + /// Gets the command to toggle the backstage. + /// + public ICommand ToggleBackStageCommand { get; } + private void OnNewProject(object obj) { commands.StorageCommands.CreateNewProject(); ValidateItems(); } - + private void OnSaveProject(object obj) { commands.StorageCommands.SaveProject(); } - + private void OnSaveProjectAs(object obj) { commands.StorageCommands.SaveProjectAs(); } - + private void OnOpenProject(object obj) { string projectPath = commands.StorageCommands.GetExistingProjectFilePath(); @@ -361,7 +388,7 @@ { gui.ExitApplication(); } - + private bool CanCloseViewTab(object arg) { return viewController.ViewHost.DocumentViews.Any(); @@ -386,6 +413,10 @@ } } + #endregion + + #region OnClick events + private void ButtonShowProjectExplorer_Click(object sender, RoutedEventArgs e) { ToggleToolWindow(ProjectExplorer, InitProjectExplorerWindow, ButtonShowProjectExplorer); @@ -562,7 +593,7 @@ ValidateItems(); } - + private void OnViewOpened(object sender, ViewChangeEventArgs e) { var mapView = e.View as IMapView; Index: Core/Gui/test/Core.Gui.Test/Commands/MainWindowCommandsTest.cs =================================================================== diff -u --- Core/Gui/test/Core.Gui.Test/Commands/MainWindowCommandsTest.cs (revision 0) +++ Core/Gui/test/Core.Gui.Test/Commands/MainWindowCommandsTest.cs (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -0,0 +1,51 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System.Windows.Input; +using Core.Gui.Commands; +using NUnit.Framework; + +namespace Core.Gui.Test.Commands +{ + [TestFixture] + public class MainWindowCommandsTest + { + [Test] + public void MainWindowCommands_Always_CorrectlyInitialized() + { + // Call + ICommand newProjectCommand = MainWindowCommands.NewProjectCommand; + ICommand saveProjectCommand = MainWindowCommands.SaveProjectCommand; + ICommand saveProjectAsCommand = MainWindowCommands.SaveProjectAsCommand; + ICommand openProjectCommand = MainWindowCommands.OpenProjectCommand; + ICommand closeApplicationCommand = MainWindowCommands.CloseApplicationCommand; + ICommand toggleBackstageCommand = MainWindowCommands.ToggleBackstageCommand; + + // Assert + Assert.IsInstanceOf(newProjectCommand); + Assert.IsInstanceOf(saveProjectCommand); + Assert.IsInstanceOf(saveProjectAsCommand); + Assert.IsInstanceOf(openProjectCommand); + Assert.IsInstanceOf(closeApplicationCommand); + Assert.IsInstanceOf(toggleBackstageCommand); + } + } +} \ No newline at end of file Index: Core/Gui/test/Core.Gui.Test/Commands/RelayCommandTest.cs =================================================================== diff -u --- Core/Gui/test/Core.Gui.Test/Commands/RelayCommandTest.cs (revision 0) +++ Core/Gui/test/Core.Gui.Test/Commands/RelayCommandTest.cs (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -0,0 +1,108 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using System.Collections.Generic; +using Core.Gui.Commands; +using NUnit.Framework; + +namespace Core.Gui.Test.Commands +{ + [TestFixture] + public class RelayCommandTest + { + [Test] + public void WhenCreatingRelayCommandWithoutAction_ThenArgumentNullExceptionIsThrown() + { + // When + void Call() => new RelayCommand(null); + + // Then + var exception = Assert.Throws(Call); + Assert.AreEqual("action", exception.ParamName); + } + + [Test] + public void GivenRelayCommand_WhenCanExecuteIsDetermined_ThenReturnsTrue() + { + // Given + var command = new RelayCommand(p => {}); + + // When + bool canExecute = command.CanExecute(null); + + // Then + Assert.IsTrue(canExecute); + } + + [Test] + public void GivenRelayCommandWithoutCanExecuteFunction_ThenArgumentNullExceptionIsThrown() + { + // When + void Call() => new RelayCommand(p => {}, null); + + // Then + var exception = Assert.Throws(Call); + Assert.AreEqual("canExecute", exception.ParamName); + } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void GivenRelayCommandWithCanExecuteFunction_WhenCanExecuteIsDetermined_ThenFunctionCalled( + bool valueToReturn) + { + // Given + var obj = new object(); + object parameter = null; + var command = new RelayCommand(p => {}, p => + { + parameter = p; + return valueToReturn; + }); + + // When + bool canExecute = command.CanExecute(obj); + + // Then + Assert.AreEqual(valueToReturn, canExecute); + Assert.AreEqual(obj, parameter); + } + + [Test] + public void GivenRelayCommand_WhenExecuted_ThenGivenActionIsExecuted() + { + // Given + var parameter = new object(); + var actionsCalled = new List(); + var command = new RelayCommand(p => actionsCalled.Add(p)); + + // When + command.Execute(parameter); + + // Then + CollectionAssert.AreEqual(new[] + { + parameter + }, actionsCalled); + } + } +} \ No newline at end of file Index: Core/Gui/test/Core.Gui.Test/Commands/RoutedCommandHandlersTest.cs =================================================================== diff -u --- Core/Gui/test/Core.Gui.Test/Commands/RoutedCommandHandlersTest.cs (revision 0) +++ Core/Gui/test/Core.Gui.Test/Commands/RoutedCommandHandlersTest.cs (revision b441bd9ffa8a255a522abceffd49201e96808502) @@ -0,0 +1,166 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System.Linq; +using System.Threading; +using System.Windows; +using System.Windows.Input; +using Core.Gui.Commands; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Gui.Test.Commands +{ + [TestFixture] + [Apartment(ApartmentState.STA)] + public class RoutedCommandHandlersTest + { + [Test] + public void GivenFrameworkElement_WhenCommandsObtainedThroughRoutedCommands_ThenEmptyRoutedCommandHandlersReturned() + { + // Given + var frameworkElement = new FrameworkElement(); + + // When + RoutedCommandHandlers handlers = RoutedCommandHandlers.GetCommands(frameworkElement); + + // Then + Assert.IsEmpty(handlers); + } + + [Test] + public void GivenHandlersFromFrameworkElement_WhenCommandsObtainedTwice_ThenSameInstanceReturned() + { + // Given + var frameworkElement = new FrameworkElement(); + RoutedCommandHandlers handlersA = RoutedCommandHandlers.GetCommands(frameworkElement); + + // When + RoutedCommandHandlers handlersB = RoutedCommandHandlers.GetCommands(frameworkElement); + + // Then + Assert.AreSame(handlersA, handlersB); + } + + [Test] + public void + GivenHandlersFromFrameworkElement_WhenRoutedCommandHandlerAdded_ThenPropertiesRegisteredAsCommandBindingToFrameworkElement() + { + // Given + var frameworkElement = new FrameworkElement(); + RoutedCommandHandlers handlers = RoutedCommandHandlers.GetCommands(frameworkElement); + + // When + var routedCommand = new RoutedCommand(); + var handler = new RoutedCommandHandler + { + RoutedCommand = routedCommand + }; + handlers.Add(handler); + + // Then + Assert.AreEqual(1, handlers.Count); + Assert.AreSame(routedCommand, handlers.First().RoutedCommand); + } + + [Test] + public void GivenAddedRoutedCommandHandlerWithCommand_WhenRoutedCommandExecuted_ThenCommandExecuted() + { + // Given + var parameter = new object(); + + var mocks = new MockRepository(); + var command = mocks.StrictMock(); + command.Expect(c => c.CanExecute(parameter)).Return(true); + command.Expect(c => c.Execute(parameter)); + mocks.ReplayAll(); + + var frameworkElement = new FrameworkElement(); + RoutedCommandHandlers handlers = RoutedCommandHandlers.GetCommands(frameworkElement); + + var routedCommand = new RoutedCommand(); + var handler = new RoutedCommandHandler + { + RoutedCommand = routedCommand, + Command = command + }; + handlers.Add(handler); + + // When + routedCommand.Execute(parameter, frameworkElement); + + // Then + mocks.VerifyAll(); + } + + [Test] + public void GivenAddedRoutedCommandHandlerWithCommand_WhenRoutedCommandCannotExecute_ThenCommandNotExecuted() + { + // Given + var parameter = new object(); + + var mocks = new MockRepository(); + var command = mocks.StrictMock(); + command.Expect(c => c.CanExecute(parameter)).Return(false); + mocks.ReplayAll(); + + var frameworkElement = new FrameworkElement(); + RoutedCommandHandlers handlers = RoutedCommandHandlers.GetCommands(frameworkElement); + + var routedCommand = new RoutedCommand(); + var handler = new RoutedCommandHandler + { + RoutedCommand = routedCommand, + Command = command + }; + handlers.Add(handler); + + // When + routedCommand.Execute(parameter, frameworkElement); + + // Then + mocks.VerifyAll(); + } + + [Test] + public void GivenAddedRoutedCommandHandlerWithoutCommand_WhenRoutedCommandExecuted_ThenNoExceptionsAreThrown() + { + // Given + var frameworkElement = new FrameworkElement(); + RoutedCommandHandlers handlers = RoutedCommandHandlers.GetCommands(frameworkElement); + + var parameter = new object(); + + var routedCommand = new RoutedCommand(); + var handler = new RoutedCommandHandler + { + RoutedCommand = routedCommand + }; + handlers.Add(handler); + + // When + void Call() => routedCommand.Execute(parameter, frameworkElement); + + // Then + Assert.DoesNotThrow(Call); + } + } +} \ No newline at end of file