Index: Ringtoets/Common/src/Ringtoets.Common.Forms/Ringtoets.Common.Forms.csproj =================================================================== diff -u -r24e3831cb8cb0ee3b0d0c6f6cde536e3a6639391 -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/Common/src/Ringtoets.Common.Forms/Ringtoets.Common.Forms.csproj (.../Ringtoets.Common.Forms.csproj) (revision 24e3831cb8cb0ee3b0d0c6f6cde536e3a6639391) +++ Ringtoets/Common/src/Ringtoets.Common.Forms/Ringtoets.Common.Forms.csproj (.../Ringtoets.Common.Forms.csproj) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -127,11 +127,11 @@ - + UserControl - - CalculatableView.cs + + LocationsView.cs UserControl @@ -185,8 +185,8 @@ ScenarioSelectionControl.cs - - CalculatableView.cs + + LocationsView.cs FailureMechanismView.cs Fisheye: Tag 55ef1e185a9cdaac7edd90877fb57c50370a1140 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.Forms/Views/CalculatableView.Designer.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 55ef1e185a9cdaac7edd90877fb57c50370a1140 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.Forms/Views/CalculatableView.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 55ef1e185a9cdaac7edd90877fb57c50370a1140 refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.Forms/Views/CalculatableView.resx'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Common/src/Ringtoets.Common.Forms/Views/HydraulicBoundaryLocationsView.cs =================================================================== diff -u -r298af52e9de68d5beed50a88ec11be5bce1fc783 -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/Common/src/Ringtoets.Common.Forms/Views/HydraulicBoundaryLocationsView.cs (.../HydraulicBoundaryLocationsView.cs) (revision 298af52e9de68d5beed50a88ec11be5bce1fc783) +++ Ringtoets/Common/src/Ringtoets.Common.Forms/Views/HydraulicBoundaryLocationsView.cs (.../HydraulicBoundaryLocationsView.cs) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -33,7 +33,7 @@ /// order to get a consistent look and feel. /// public abstract partial class HydraulicBoundaryLocationsView - : CalculatableView + : LocationsView { private IEnumerable locations; Index: Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.Designer.cs =================================================================== diff -u --- Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.Designer.cs (revision 0) +++ Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.Designer.cs (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -0,0 +1,134 @@ +// Copyright (C) Stichting Deltares 2017. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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. + +namespace Ringtoets.Common.Forms.Views +{ + partial class LocationsView + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.dataGridViewControl = new Core.Common.Controls.DataGrid.DataGridViewControl(); + this.CalculateForSelectedButton = new System.Windows.Forms.Button(); + this.DeselectAllButton = new System.Windows.Forms.Button(); + this.SelectAllButton = new System.Windows.Forms.Button(); + this.ButtonGroupBox = new System.Windows.Forms.GroupBox(); + this.CalculateForSelectedButtonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components); + this.ButtonGroupBox.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.CalculateForSelectedButtonErrorProvider)).BeginInit(); + this.SuspendLayout(); + // + // dataGridViewControl + // + this.dataGridViewControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridViewControl.Location = new System.Drawing.Point(0, 0); + this.dataGridViewControl.MultiSelect = true; + this.dataGridViewControl.Name = "dataGridViewControl"; + this.dataGridViewControl.Padding = new System.Windows.Forms.Padding(0, 0, 0, 5); + this.dataGridViewControl.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.RowHeaderSelect; + this.dataGridViewControl.Size = new System.Drawing.Size(533, 85); + this.dataGridViewControl.TabIndex = 2; + // + // CalculateForSelectedButton + // + this.CalculateForSelectedButton.Enabled = false; + this.CalculateForSelectedButton.Location = new System.Drawing.Point(227, 29); + this.CalculateForSelectedButton.Name = "CalculateForSelectedButton"; + this.CalculateForSelectedButton.Size = new System.Drawing.Size(207, 23); + this.CalculateForSelectedButton.TabIndex = 2; + this.CalculateForSelectedButton.UseVisualStyleBackColor = true; + this.CalculateForSelectedButton.Click += new System.EventHandler(this.CalculateForSelectedButton_Click); + // + // DeselectAllButton + // + this.DeselectAllButton.Location = new System.Drawing.Point(110, 29); + this.DeselectAllButton.Name = "DeselectAllButton"; + this.DeselectAllButton.Size = new System.Drawing.Size(111, 23); + this.DeselectAllButton.TabIndex = 1; + this.DeselectAllButton.UseVisualStyleBackColor = true; + this.DeselectAllButton.Click += new System.EventHandler(this.DeselectAllButton_Click); + // + // SelectAllButton + // + this.SelectAllButton.Location = new System.Drawing.Point(6, 29); + this.SelectAllButton.Name = "SelectAllButton"; + this.SelectAllButton.Size = new System.Drawing.Size(98, 23); + this.SelectAllButton.TabIndex = 0; + this.SelectAllButton.UseVisualStyleBackColor = true; + this.SelectAllButton.Click += new System.EventHandler(this.SelectAllButton_Click); + // + // ButtonGroupBox + // + this.ButtonGroupBox.Controls.Add(this.CalculateForSelectedButton); + this.ButtonGroupBox.Controls.Add(this.DeselectAllButton); + this.ButtonGroupBox.Controls.Add(this.SelectAllButton); + this.ButtonGroupBox.Dock = System.Windows.Forms.DockStyle.Bottom; + this.ButtonGroupBox.Location = new System.Drawing.Point(0, 85); + this.ButtonGroupBox.MinimumSize = new System.Drawing.Size(445, 61); + this.ButtonGroupBox.Name = "ButtonGroupBox"; + this.ButtonGroupBox.Size = new System.Drawing.Size(533, 61); + this.ButtonGroupBox.TabIndex = 3; + this.ButtonGroupBox.TabStop = false; + // + // CalculateForSelectedButtonErrorProvider + // + this.CalculateForSelectedButtonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink; + this.CalculateForSelectedButtonErrorProvider.ContainerControl = this; + this.CalculateForSelectedButtonErrorProvider.Icon = Properties.Resources.warning; + this.CalculateForSelectedButtonErrorProvider.SetIconPadding(CalculateForSelectedButton, 2); + // + // LocationsView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.AutoScrollMinSize = new System.Drawing.Size(526, 85); + this.Controls.Add(this.dataGridViewControl); + this.Controls.Add(this.ButtonGroupBox); + this.Name = "LocationsView"; + this.Size = new System.Drawing.Size(533, 146); + this.ButtonGroupBox.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.CalculateForSelectedButtonErrorProvider)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + protected Core.Common.Controls.DataGrid.DataGridViewControl dataGridViewControl; + private System.Windows.Forms.Button CalculateForSelectedButton; + private System.Windows.Forms.Button DeselectAllButton; + private System.Windows.Forms.Button SelectAllButton; + protected System.Windows.Forms.GroupBox ButtonGroupBox; + private System.Windows.Forms.ErrorProvider CalculateForSelectedButtonErrorProvider; + } +} \ No newline at end of file Index: Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.cs =================================================================== diff -u --- Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.cs (revision 0) +++ Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.cs (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -0,0 +1,229 @@ +// Copyright (C) Stichting Deltares 2017. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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 System.Linq; +using System.Windows.Forms; +using Core.Common.Controls.Views; +using Core.Common.Utils.Extensions; +using Ringtoets.Common.Forms.Properties; + +namespace Ringtoets.Common.Forms.Views +{ + /// + /// Base view for selecting locations and starting calculation for said objects. + /// + /// The type of the location object. + public abstract partial class LocationsView : UserControl, ISelectionProvider where T : class + { + private const int calculateColumnIndex = 0; + private bool updatingDataSource; + public event EventHandler SelectionChanged; + + /// + /// Creates a new instance of . + /// + protected LocationsView() + { + InitializeComponent(); + LocalizeControls(); + InitializeEventHandlers(); + } + + public abstract object Data { get; set; } + + public object Selection + { + get + { + return CreateSelectedItemFromCurrentRow(); + } + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + InitializeDataGridView(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + components?.Dispose(); + } + + base.Dispose(disposing); + } + + /// + /// Updates the data source of the data table based on the . + /// + protected void UpdateDataGridViewDataSource() + { + updatingDataSource = true; + SetDataSource(); + updatingDataSource = false; + UpdateCalculateForSelectedButton(); + } + + /// + /// Initializes the . + /// + protected virtual void InitializeDataGridView() + { + dataGridViewControl.AddCheckBoxColumn(nameof(CalculatableRow.ShouldCalculate), + Resources.CalculatableView_Calculate); + } + + /// + /// Creates a new object that is used as the object for from + /// the currently selected row in the data table. + /// + /// The newly created object. + protected abstract object CreateSelectedItemFromCurrentRow(); + + /// + /// Sets the datasource on the . + /// + protected abstract void SetDataSource(); + + /// + /// Handles the calculation routine for the currently selected rows. + /// + protected abstract void CalculateForSelectedRows(); + + /// + /// Gets all the row items from the . + /// + protected IEnumerable> GetCalculatableRows() + { + return dataGridViewControl.Rows + .Cast() + .Select(row => (CalculatableRow) row.DataBoundItem); + } + + /// + /// Gets all the selected calculatable objects. + /// + protected IEnumerable GetSelectedCalculatableObjects() + { + return GetCalculatableRows().Where(r => r.ShouldCalculate) + .Select(r => r.CalculatableObject); + } + + /// + /// Validates the calculatable objects. + /// + /// A validation message in case no calculations can be performed, null otherwise. + protected virtual string ValidateCalculatableObjects() + { + if (!GetCalculatableRows().Any(r => r.ShouldCalculate)) + { + return Resources.CalculatableViews_No_calculations_selected; + } + + return null; + } + + /// + /// Updates the state of the calculation button and the corresponding error provider. + /// + protected void UpdateCalculateForSelectedButton() + { + string validationText = ValidateCalculatableObjects(); + if (!string.IsNullOrEmpty(validationText)) + { + CalculateForSelectedButton.Enabled = false; + CalculateForSelectedButtonErrorProvider.SetError(CalculateForSelectedButton, validationText); + } + else + { + CalculateForSelectedButton.Enabled = true; + CalculateForSelectedButtonErrorProvider.SetError(CalculateForSelectedButton, ""); + } + } + + private void LocalizeControls() + { + CalculateForSelectedButton.Text = Resources.CalculatableView_CalculateForSelectedButton_Text; + DeselectAllButton.Text = Resources.CalculatableView_DeselectAllButton_Text; + SelectAllButton.Text = Resources.CalculatableView_SelectAllButton_Text; + ButtonGroupBox.Text = Resources.CalculatableView_ButtonGroupBox_Text; + } + + private void InitializeEventHandlers() + { + dataGridViewControl.AddCurrentCellChangedHandler(DataGridViewOnCurrentCellChangedHandler); + dataGridViewControl.AddCellValueChangedHandler(DataGridViewCellValueChanged); + } + + private void OnSelectionChanged() + { + SelectionChanged?.Invoke(this, new EventArgs()); + } + + #region Event handling + + private void DataGridViewCellValueChanged(object sender, DataGridViewCellEventArgs e) + { + if (!updatingDataSource && e.ColumnIndex == calculateColumnIndex) + { + UpdateCalculateForSelectedButton(); + } + } + + private void DataGridViewOnCurrentCellChangedHandler(object sender, EventArgs e) + { + if (updatingDataSource) + { + return; + } + + OnSelectionChanged(); + } + + private void SelectAllButton_Click(object sender, EventArgs e) + { + SetShouldCalculateForAllRowsAndRefresh(true); + } + + private void DeselectAllButton_Click(object sender, EventArgs e) + { + SetShouldCalculateForAllRowsAndRefresh(false); + } + + private void SetShouldCalculateForAllRowsAndRefresh(bool newShouldCalculateValue) + { + GetCalculatableRows().ForEachElementDo(row => row.ShouldCalculate = newShouldCalculateValue); + dataGridViewControl.RefreshDataGridView(); + UpdateCalculateForSelectedButton(); + } + + private void CalculateForSelectedButton_Click(object sender, EventArgs e) + { + CalculateForSelectedRows(); + } + + #endregion + } +} \ No newline at end of file Index: Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.resx =================================================================== diff -u --- Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.resx (revision 0) +++ Ringtoets/Common/src/Ringtoets.Common.Forms/Views/LocationsView.resx (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Ringtoets.Common.Forms.Test.csproj =================================================================== diff -u -r24e3831cb8cb0ee3b0d0c6f6cde536e3a6639391 -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Ringtoets.Common.Forms.Test.csproj (.../Ringtoets.Common.Forms.Test.csproj) (revision 24e3831cb8cb0ee3b0d0c6f6cde536e3a6639391) +++ Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Ringtoets.Common.Forms.Test.csproj (.../Ringtoets.Common.Forms.Test.csproj) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -116,7 +116,7 @@ - + Fisheye: Tag 55ef1e185a9cdaac7edd90877fb57c50370a1140 refers to a dead (removed) revision in file `Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/CalculatableViewTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/HydraulicBoundaryLocationsViewTest.cs =================================================================== diff -u -ra3273b4a5d21f952ab7dabfd2120f8c8632e0519 -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/HydraulicBoundaryLocationsViewTest.cs (.../HydraulicBoundaryLocationsViewTest.cs) (revision a3273b4a5d21f952ab7dabfd2120f8c8632e0519) +++ Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/HydraulicBoundaryLocationsViewTest.cs (.../HydraulicBoundaryLocationsViewTest.cs) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -62,7 +62,7 @@ using (var view = new TestHydraulicBoundaryLocationsView()) { // Assert - Assert.IsInstanceOf>(view); + Assert.IsInstanceOf>(view); Assert.IsNull(view.Data); } } Index: Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/LocationsViewTest.cs =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/LocationsViewTest.cs (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.Forms.Test/Views/LocationsViewTest.cs (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -0,0 +1,311 @@ +// Copyright (C) Stichting Deltares 2017. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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.Generic; +using System.Linq; +using System.Windows.Forms; +using Core.Common.Controls.Views; +using Core.Common.Utils.Reflection; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Ringtoets.Common.Forms.Views; + +namespace Ringtoets.Common.Forms.Test.Views +{ + [TestFixture] + public class LocationsViewTest + { + private const int calculateColumnIndex = 0; + + private Form testForm; + + [SetUp] + public void Setup() + { + testForm = new Form(); + } + + [TearDown] + public void TearDown() + { + testForm.Dispose(); + } + + [Test] + public void DefaultConstructor_DefaultValues() + { + // Call + using (var view = new TestLocationsView()) + { + // Assert + Assert.IsInstanceOf(view); + Assert.IsInstanceOf(view); + Assert.IsNull(view.Data); + } + } + + [Test] + public void Constructor_CalculateAllButtonCorrectlyInitialized() + { + // Setup & Call + TestLocationsView view = ShowTestCalculatableView(); + + // Assert + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsFalse(button.Enabled); + } + + [Test] + public void OnLoad_DataGridViewCorrectlyInitialized() + { + // Setup & Call + TestLocationsView view = ShowTestCalculatableView(); + + // Assert + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + Assert.AreEqual(1, dataGridView.ColumnCount); + + var calculateColumn = (DataGridViewCheckBoxColumn) dataGridView.Columns[calculateColumnIndex]; + const string expectedCalculateHeaderText = "Berekenen"; + Assert.AreEqual(expectedCalculateHeaderText, calculateColumn.HeaderText); + + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsFalse(button.Enabled); + } + + [Test] + public void GivenFullyConfiguredView_WhenSelectingCellInRow_ThenSelectionChangedFired() + { + // Given + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var createdSelection = new object(); + view.CreateForSelection = createdSelection; + + var selectionChangedCount = 0; + view.SelectionChanged += (sender, args) => selectionChangedCount++; + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + + // When + dataGridView.CurrentCell = dataGridView.Rows[1].Cells[calculateColumnIndex]; + EventHelper.RaiseEvent(dataGridView, "CellClick", new DataGridViewCellEventArgs(0, 0)); + + // Then + Assert.AreEqual(1, selectionChangedCount); + } + + [Test] + public void Selection_Always_ReturnsCreatedSelectionObject() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var createdSelection = new object(); + view.CreateForSelection = createdSelection; + + // Call + object selection = view.Selection; + + // Assert + Assert.AreSame(createdSelection, selection); + } + + [Test] + public void SelectAllButton_SelectAllButtonClicked_AllCalculatableItemsSelected() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + DataGridViewRowCollection rows = dataGridView.Rows; + var button = new ButtonTester("SelectAllButton", testForm); + + // Precondition + Assert.IsFalse((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsFalse((bool) rows[1].Cells[calculateColumnIndex].Value); + + // Call + button.Click(); + + // Assert + Assert.IsTrue((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsTrue((bool) rows[1].Cells[calculateColumnIndex].Value); + } + + [Test] + public void DeselectAllButton_AllCalculatableItemsSelectedDeselectAllButtonClicked_AllCalculatableItemsNotSelected() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + var button = new ButtonTester("DeselectAllButton", testForm); + + DataGridViewRowCollection rows = dataGridView.Rows; + foreach (DataGridViewRow row in rows) + { + row.Cells[calculateColumnIndex].Value = true; + } + + // Precondition + Assert.IsTrue((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsTrue((bool) rows[1].Cells[calculateColumnIndex].Value); + + // Call + button.Click(); + + // Assert + Assert.IsFalse((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsFalse((bool) rows[1].Cells[calculateColumnIndex].Value); + } + + [Test] + public void GivenFullyConfiguredView_WhenNoRowsSelected_ThenCalculateForSelectedButtonDisabledAndErrorMessageProvided() + { + // Given & When + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + // Then + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsFalse(button.Enabled); + var errorProvider = TypeUtils.GetField(view, "CalculateForSelectedButtonErrorProvider"); + Assert.AreEqual("Er zijn geen berekeningen geselecteerd.", errorProvider.GetError(button)); + } + + [Test] + public void GivenFullyConfiguredView_WhenRowsSelected_ThenCalculateForSelectedButtonEnabledAndNoErrorMessageProvided() + { + // Given + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + + // When + dataGridView.Rows[0].Cells[calculateColumnIndex].Value = true; + + // Then + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsTrue(button.Enabled); + var errorProvider = TypeUtils.GetField(view, "CalculateForSelectedButtonErrorProvider"); + Assert.AreEqual("", errorProvider.GetError(button)); + } + + [Test] + public void CalculateForSelectedButton_OneSelected_CallsCalculateHandleCalculateSelectedObjects() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + + DataGridViewRowCollection rows = dataGridView.Rows; + rows[0].Cells[calculateColumnIndex].Value = true; + + var buttonTester = new ButtonTester("CalculateForSelectedButton", testForm); + + // Call + buttonTester.Click(); + + // Assert + Assert.AreEqual(1, view.ObjectsToCalculate.Count()); + TestCalculatableObject expectedObject = ((IEnumerable) view.Data).First(); + Assert.AreEqual(expectedObject, view.ObjectsToCalculate.First()); + } + + private TestLocationsView ShowTestCalculatableView() + { + var view = new TestLocationsView(); + + testForm.Controls.Add(view); + testForm.Show(); + return view; + } + + private TestLocationsView ShowFullyConfiguredTestCalculatableView() + { + TestLocationsView view = ShowTestCalculatableView(); + view.Data = new[] + { + new TestCalculatableObject(), + new TestCalculatableObject() + }; + return view; + } + + private class TestCalculatableRow : CalculatableRow + { + public TestCalculatableRow(TestCalculatableObject calculatableObject) : base(calculatableObject) + { + ShouldCalculate = calculatableObject.IsChecked; + } + } + + private class TestCalculatableObject + { + public bool IsChecked { get; } + } + + private class TestLocationsView : LocationsView + { + private IEnumerable data; + + public TestLocationsView() + { + ObjectsToCalculate = new List(); + } + + public override object Data + { + get + { + return data; + } + set + { + data = value as IEnumerable; + UpdateDataGridViewDataSource(); + } + } + + public object CreateForSelection { private get; set; } + + public IEnumerable ObjectsToCalculate { get; private set; } + + protected override object CreateSelectedItemFromCurrentRow() + { + return CreateForSelection; + } + + protected override void SetDataSource() + { + dataGridViewControl.SetDataSource(data.Select(d => new TestCalculatableRow(d)).ToArray()); + } + + protected override void CalculateForSelectedRows() + { + ObjectsToCalculate = GetCalculatableRows() + .Where(r => r.ShouldCalculate) + .Cast() + .Select(row => row.CalculatableObject); + } + } + } +} \ No newline at end of file Index: Ringtoets/DuneErosion/src/Ringtoets.DuneErosion.Forms/Ringtoets.DuneErosion.Forms.csproj =================================================================== diff -u -r3f08de6c9ea2fce2f5fc15302fda17c119b3798c -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/DuneErosion/src/Ringtoets.DuneErosion.Forms/Ringtoets.DuneErosion.Forms.csproj (.../Ringtoets.DuneErosion.Forms.csproj) (revision 3f08de6c9ea2fce2f5fc15302fda17c119b3798c) +++ Ringtoets/DuneErosion/src/Ringtoets.DuneErosion.Forms/Ringtoets.DuneErosion.Forms.csproj (.../Ringtoets.DuneErosion.Forms.csproj) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -77,6 +77,12 @@ DuneLocationsView.cs + + UserControl + + + DuneLocationsViewBase.cs + @@ -155,6 +161,9 @@ DuneErosionFailureMechanismView.cs + + DuneLocationsViewBase.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file Index: Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Ringtoets.DuneErosion.Forms.Test.csproj =================================================================== diff -u -re93f3cb97066cae85be4a977098261d47ba6eb57 -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Ringtoets.DuneErosion.Forms.Test.csproj (.../Ringtoets.DuneErosion.Forms.Test.csproj) (revision e93f3cb97066cae85be4a977098261d47ba6eb57) +++ Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Ringtoets.DuneErosion.Forms.Test.csproj (.../Ringtoets.DuneErosion.Forms.Test.csproj) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -72,6 +72,7 @@ + Index: Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Views/DuneLocationsViewBaseTest.cs =================================================================== diff -u --- Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Views/DuneLocationsViewBaseTest.cs (revision 0) +++ Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Views/DuneLocationsViewBaseTest.cs (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -0,0 +1,313 @@ +// Copyright (C) Stichting Deltares 2017. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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.Generic; +using System.Linq; +using System.Windows.Forms; +using Core.Common.Base.Geometry; +using Core.Common.Controls.Views; +using Core.Common.Utils.Reflection; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Ringtoets.DuneErosion.Data; +using Ringtoets.DuneErosion.Forms.Views; + +namespace Ringtoets.DuneErosion.Forms.Test.Views +{ + [TestFixture] + public class DuneLocationsViewBaseTest + { + private const int calculateColumnIndex = 0; + + private Form testForm; + + [SetUp] + public void Setup() + { + testForm = new Form(); + } + + [TearDown] + public void TearDown() + { + testForm.Dispose(); + } + + [Test] + public void DefaultConstructor_DefaultValues() + { + // Call + using (var view = new TestLocationsView()) + { + // Assert + Assert.IsInstanceOf(view); + Assert.IsInstanceOf(view); + Assert.IsNull(view.Data); + } + } + + [Test] + public void Constructor_CalculateAllButtonCorrectlyInitialized() + { + // Setup & Call + TestLocationsView view = ShowTestCalculatableView(); + + // Assert + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsFalse(button.Enabled); + } + + [Test] + public void OnLoad_DataGridViewCorrectlyInitialized() + { + // Setup & Call + TestLocationsView view = ShowTestCalculatableView(); + + // Assert + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + Assert.AreEqual(1, dataGridView.ColumnCount); + + var calculateColumn = (DataGridViewCheckBoxColumn) dataGridView.Columns[calculateColumnIndex]; + const string expectedCalculateHeaderText = "Berekenen"; + Assert.AreEqual(expectedCalculateHeaderText, calculateColumn.HeaderText); + + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsFalse(button.Enabled); + } + + [Test] + public void GivenFullyConfiguredView_WhenSelectingCellInRow_ThenSelectionChangedFired() + { + // Given + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var createdSelection = new object(); + view.CreateForSelection = createdSelection; + + var selectionChangedCount = 0; + view.SelectionChanged += (sender, args) => selectionChangedCount++; + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + + // When + dataGridView.CurrentCell = dataGridView.Rows[1].Cells[calculateColumnIndex]; + EventHelper.RaiseEvent(dataGridView, "CellClick", new DataGridViewCellEventArgs(0, 0)); + + // Then + Assert.AreEqual(1, selectionChangedCount); + } + + [Test] + public void Selection_Always_ReturnsCreatedSelectionObject() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var createdSelection = new object(); + view.CreateForSelection = createdSelection; + + // Call + object selection = view.Selection; + + // Assert + Assert.AreSame(createdSelection, selection); + } + + [Test] + public void SelectAllButton_SelectAllButtonClicked_AllCalculatableItemsSelected() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + DataGridViewRowCollection rows = dataGridView.Rows; + var button = new ButtonTester("SelectAllButton", testForm); + + // Precondition + Assert.IsFalse((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsFalse((bool) rows[1].Cells[calculateColumnIndex].Value); + + // Call + button.Click(); + + // Assert + Assert.IsTrue((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsTrue((bool) rows[1].Cells[calculateColumnIndex].Value); + } + + [Test] + public void DeselectAllButton_AllCalculatableItemsSelectedDeselectAllButtonClicked_AllCalculatableItemsNotSelected() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + var button = new ButtonTester("DeselectAllButton", testForm); + + DataGridViewRowCollection rows = dataGridView.Rows; + foreach (DataGridViewRow row in rows) + { + row.Cells[calculateColumnIndex].Value = true; + } + + // Precondition + Assert.IsTrue((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsTrue((bool) rows[1].Cells[calculateColumnIndex].Value); + + // Call + button.Click(); + + // Assert + Assert.IsFalse((bool) rows[0].Cells[calculateColumnIndex].Value); + Assert.IsFalse((bool) rows[1].Cells[calculateColumnIndex].Value); + } + + [Test] + public void GivenFullyConfiguredView_WhenNoRowsSelected_ThenCalculateForSelectedButtonDisabledAndErrorMessageProvided() + { + // Given & When + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + // Then + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsFalse(button.Enabled); + var errorProvider = TypeUtils.GetField(view, "CalculateForSelectedButtonErrorProvider"); + Assert.AreEqual("Er zijn geen berekeningen geselecteerd.", errorProvider.GetError(button)); + } + + [Test] + public void GivenFullyConfiguredView_WhenRowsSelected_ThenCalculateForSelectedButtonEnabledAndNoErrorMessageProvided() + { + // Given + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + + // When + dataGridView.Rows[0].Cells[calculateColumnIndex].Value = true; + + // Then + var button = (Button) view.Controls.Find("CalculateForSelectedButton", true)[0]; + Assert.IsTrue(button.Enabled); + var errorProvider = TypeUtils.GetField(view, "CalculateForSelectedButtonErrorProvider"); + Assert.AreEqual("", errorProvider.GetError(button)); + } + + [Test] + public void CalculateForSelectedButton_OneSelected_CallsCalculateHandleCalculateSelectedObjects() + { + // Setup + TestLocationsView view = ShowFullyConfiguredTestCalculatableView(); + + var dataGridView = (DataGridView) view.Controls.Find("dataGridView", true)[0]; + + DataGridViewRowCollection rows = dataGridView.Rows; + rows[0].Cells[calculateColumnIndex].Value = true; + + var buttonTester = new ButtonTester("CalculateForSelectedButton", testForm); + + // Call + buttonTester.Click(); + + // Assert + Assert.AreEqual(1, view.ObjectsToCalculate.Count()); + TestCalculatableObject expectedObject = ((IEnumerable) view.Data).First(); + Assert.AreEqual(expectedObject, view.ObjectsToCalculate.First()); + } + + private TestLocationsView ShowTestCalculatableView() + { + var view = new TestLocationsView(); + + testForm.Controls.Add(view); + testForm.Show(); + return view; + } + + private TestLocationsView ShowFullyConfiguredTestCalculatableView() + { + TestLocationsView view = ShowTestCalculatableView(); + view.Data = new[] + { + new TestCalculatableObject(), + new TestCalculatableObject() + }; + return view; + } + + private class TestCalculatableRow : DuneLocationRow + { + public TestCalculatableRow(TestCalculatableObject calculatableObject) : base(calculatableObject) + { + ShouldCalculate = calculatableObject.IsChecked; + } + } + + private class TestCalculatableObject : DuneLocation + { + public TestCalculatableObject() : base(1, "1", new Point2D(0, 0), new ConstructionProperties()) {} + public bool IsChecked { get; } + } + + private class TestLocationsView : DuneLocationsViewBase + { + private IEnumerable data; + + public TestLocationsView() + { + ObjectsToCalculate = new List(); + } + + public override object Data + { + get + { + return data; + } + set + { + data = value as IEnumerable; + UpdateDataGridViewDataSource(); + } + } + + public object CreateForSelection { private get; set; } + + public IEnumerable ObjectsToCalculate { get; private set; } + + protected override object CreateSelectedItemFromCurrentRow() + { + return CreateForSelection; + } + + protected override void SetDataSource() + { + dataGridViewControl.SetDataSource(data.Select(d => new TestCalculatableRow(d)).ToArray()); + } + + protected override void CalculateForSelectedRows() + { + ObjectsToCalculate = GetCalculatableRows() + .Where(r => r.ShouldCalculate) + .Select(row => row.CalculatableObject); + } + } + } +} \ No newline at end of file Index: Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Views/DuneLocationsViewTest.cs =================================================================== diff -u -re93f3cb97066cae85be4a977098261d47ba6eb57 -r55ef1e185a9cdaac7edd90877fb57c50370a1140 --- Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Views/DuneLocationsViewTest.cs (.../DuneLocationsViewTest.cs) (revision e93f3cb97066cae85be4a977098261d47ba6eb57) +++ Ringtoets/DuneErosion/test/Ringtoets.DuneErosion.Forms.Test/Views/DuneLocationsViewTest.cs (.../DuneLocationsViewTest.cs) (revision 55ef1e185a9cdaac7edd90877fb57c50370a1140) @@ -36,7 +36,6 @@ using Ringtoets.Common.Data.Contribution; using Ringtoets.Common.Data.FailureMechanism; using Ringtoets.Common.Data.Hydraulics; -using Ringtoets.Common.Forms.Views; using Ringtoets.Common.Service.TestUtil; using Ringtoets.DuneErosion.Data; using Ringtoets.DuneErosion.Forms.GuiServices; @@ -81,7 +80,7 @@ using (var view = new DuneLocationsView()) { // Assert - Assert.IsInstanceOf>(view); + Assert.IsInstanceOf(view); Assert.IsNull(view.Data); } }