// Copyright (C) Stichting Deltares 2016. 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; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using Core.Common.Base.Data; using Core.Common.Controls.TreeView; using Core.Common.Gui.ContextMenu; using Core.Common.Gui.Forms; using Core.Common.Gui.Plugin; using Core.Components.Gis.Data; using Core.Plugins.DotSpatial.Forms; using log4net; using Ringtoets.Common.Data; using Ringtoets.Common.Forms.PresentationObjects; using Ringtoets.Common.Placeholder; using Ringtoets.HydraRing.Forms.PresentationObjects; using Ringtoets.HydraRing.Plugin; using Ringtoets.Integration.Data; using Ringtoets.Integration.Data.Contribution; using Ringtoets.Integration.Data.Map; using Ringtoets.Integration.Data.Placeholders; using Ringtoets.Integration.Forms.PresentationObjects; using Ringtoets.Integration.Forms.PropertyClasses; using Ringtoets.Integration.Forms.Views; using RingtoetsDataResources = Ringtoets.Integration.Data.Properties.Resources; using RingtoetsFormsResources = Ringtoets.Integration.Forms.Properties.Resources; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; using UtilsResources = Core.Common.Utils.Properties.Resources; using HydraringResources = Ringtoets.HydraRing.Forms.Properties.Resources; using BaseResources = Core.Common.Base.Properties.Resources; namespace Ringtoets.Integration.Plugin { /// /// The GUI plugin for the Ringtoets application. /// public class RingtoetsGuiPlugin : GuiPlugin { private static readonly ILog log = LogManager.GetLogger(typeof(GuiPlugin)); private static AssessmentSectionMapData assessmentSectionMapData; public override IRibbonCommandHandler RibbonCommandHandler { get { return new RingtoetsRibbon(); } } /// /// Returns all instances provided for data of . /// public override IEnumerable GetPropertyInfos() { yield return new PropertyInfo(); yield return new PropertyInfo(); } /// /// Returns all instances provided for data of . /// public override IEnumerable GetViewInfos() { yield return new ViewInfo { GetViewName = (v, o) => RingtoetsDataResources.FailureMechanismContribution_DisplayName, Image = RingtoetsFormsResources.GenericInputOutputIcon, CloseForData = (v, o) => { var assessmentSection = o as AssessmentSectionBase; return assessmentSection != null && assessmentSection.FailureMechanismContribution == v.Data; } }; yield return new ViewInfo { GetViewName = (v, o) => RingtoetsFormsResources.TrajectMap_DisplayName, GetViewData = assessmentSectionBase => { assessmentSectionMapData = new AssessmentSectionMapData(assessmentSectionBase); return assessmentSectionMapData; }, Image = RingtoetsFormsResources.Map }; } /// /// Gets the child data instances that have definitions of some parent data object. /// /// The parent data object. /// Sequence of child data. public override IEnumerable GetChildDataWithViewDefinitions(object dataObject) { var assessmentSection = dataObject as AssessmentSectionBase; if (assessmentSection != null) { yield return assessmentSection.FailureMechanismContribution; } } /// /// Returns all instances provided for data of . /// public override IEnumerable GetTreeNodeInfos() { yield return new TreeNodeInfo { Text = assessmentSectionBase => assessmentSectionBase.Name, Image = assessmentSectionBase => RingtoetsFormsResources.AssessmentSectionFolderIcon, EnsureVisibleOnCreate = assessmentSectionBase => true, ChildNodeObjects = AssessmentSectionBaseChildNodeObjects, ContextMenuStrip = AssessmentSectionBaseContextMenuStrip, CanRename = (assessmentSectionBase, parentData) => true, OnNodeRenamed = AssessmentSectionBaseOnNodeRenamed, CanRemove = (assessmentSectionBase, parentNodeData) => true, OnNodeRemoved = AssessmentSectionBaseOnNodeRemoved }; yield return new TreeNodeInfo { Text = context => RingtoetsFormsResources.ReferenceLine_DisplayName, Image = context => RingtoetsFormsResources.ReferenceLineIcon, ForeColor = context => context.WrappedData == null ? Color.FromKnownColor(KnownColor.GrayText) : Color.FromKnownColor(KnownColor.ControlText), ContextMenuStrip = (nodeData, parentData, treeViewControl) => Gui.Get(nodeData, treeViewControl).AddImportItem().Build() }; yield return new TreeNodeInfo { Text = failureMechanismPlaceholder => failureMechanismPlaceholder.Name, Image = failureMechanismPlaceholder => RingtoetsFormsResources.FailureMechanismIcon, ForeColor = failureMechanismPlaceholder => Color.FromKnownColor(KnownColor.GrayText), ChildNodeObjects = FailureMechanismPlaceholderChildNodeObjects, ContextMenuStrip = FailureMechanismPlaceholderContextMenuStrip }; yield return new TreeNodeInfo { Text = placeholderWithReadonlyName => placeholderWithReadonlyName.Name, Image = placeholderWithReadonlyName => GetIconForPlaceholder(placeholderWithReadonlyName), ForeColor = placeholderWithReadonlyName => Color.FromKnownColor(KnownColor.GrayText), ContextMenuStrip = PlaceholderWithReadonlyNameContextMenuStrip }; yield return new TreeNodeInfo { Text = categoryTreeFolder => categoryTreeFolder.Name, Image = categoryTreeFolder => GetFolderIcon(categoryTreeFolder.Category), ChildNodeObjects = categoryTreeFolder => categoryTreeFolder.Contents.Cast().ToArray(), ContextMenuStrip = CategoryTreeFolderContextMenu }; yield return new TreeNodeInfo { Text = failureMechanismContribution => RingtoetsDataResources.FailureMechanismContribution_DisplayName, Image = failureMechanismContribution => RingtoetsFormsResources.GenericInputOutputIcon, ContextMenuStrip = (failureMechanismContribution, parentData, treeViewControl) => Gui.Get(failureMechanismContribution, treeViewControl) .AddOpenItem() .AddSeparator() .AddExportItem() .Build() }; yield return new TreeNodeInfo { Text = hydraulicBoundaryDatabase => HydraringResources.HydraulicBoundaryDatabase_DisplayName, Image = hydraulicBoundaryDatabase => RingtoetsFormsResources.GenericInputOutputIcon, CanRename = (context, o) => false, ContextMenuStrip = HydraulicBoundaryDatabaseContextMenuStrip }; } # region AssessmentSectionBase private object[] AssessmentSectionBaseChildNodeObjects(AssessmentSectionBase nodeData) { var childNodes = new List { new ReferenceLineContext(nodeData), nodeData.FailureMechanismContribution, new HydraulicBoundaryDatabaseContext(nodeData.HydraulicBoundaryDatabase, nodeData) }; childNodes.AddRange(nodeData.GetFailureMechanisms()); return childNodes.ToArray(); } private void AssessmentSectionBaseOnNodeRenamed(AssessmentSectionBase nodeData, string newName) { nodeData.Name = newName; nodeData.NotifyObservers(); } private void AssessmentSectionBaseOnNodeRemoved(AssessmentSectionBase nodeData, object parentNodeData) { var parentProject = (Project) parentNodeData; parentProject.Items.Remove(nodeData); parentProject.NotifyObservers(); } private ContextMenuStrip AssessmentSectionBaseContextMenuStrip(AssessmentSectionBase nodeData, object parentData, TreeViewControl treeViewControl) { return Gui.Get(nodeData, treeViewControl) .AddOpenItem() .AddSeparator() .AddRenameItem() .AddDeleteItem() .AddSeparator() .AddImportItem() .AddExportItem() .AddSeparator() .AddExpandAllItem() .AddCollapseAllItem() .AddSeparator() .AddPropertiesItem() .Build(); } # endregion # region FailureMechanismPlaceholder private object[] FailureMechanismPlaceholderChildNodeObjects(FailureMechanismPlaceholder nodeData) { return new object[] { new CategoryTreeFolder(RingtoetsCommonFormsResources.FailureMechanism_Inputs_DisplayName, GetInputs(nodeData), TreeFolderCategory.Input), new CategoryTreeFolder(RingtoetsCommonFormsResources.FailureMechanism_Outputs_DisplayName, GetOutputs(nodeData), TreeFolderCategory.Output) }; } private IList GetInputs(FailureMechanismPlaceholder nodeData) { return new ArrayList { nodeData.SectionDivisions, nodeData.Locations, nodeData.BoundaryConditions }; } private IList GetOutputs(FailureMechanismPlaceholder nodeData) { return new ArrayList { nodeData.AssessmentResult }; } private ContextMenuStrip FailureMechanismPlaceholderContextMenuStrip(FailureMechanismPlaceholder nodeData, object parentData, TreeViewControl treeViewControl) { var calculateItem = new StrictContextMenuItem( RingtoetsCommonFormsResources.Calculate_all, RingtoetsCommonFormsResources.Calculate_all_ToolTip, RingtoetsCommonFormsResources.CalculateAllIcon, null) { Enabled = false }; var clearOutputItem = new StrictContextMenuItem( RingtoetsCommonFormsResources.Clear_all_output, RingtoetsCommonFormsResources.Clear_all_output_ToolTip, RingtoetsCommonFormsResources.ClearIcon, null ) { Enabled = false }; return Gui.Get(nodeData, treeViewControl) .AddCustomItem(calculateItem) .AddCustomItem(clearOutputItem) .AddSeparator() .AddImportItem() .AddExportItem() .AddSeparator() .AddExpandAllItem() .AddCollapseAllItem() .AddSeparator() .AddPropertiesItem() .Build(); } # endregion # region PlaceholderWithReadonlyName private static Bitmap GetIconForPlaceholder(PlaceholderWithReadonlyName nodeData) { if (nodeData is InputPlaceholder || nodeData is OutputPlaceholder) { return RingtoetsFormsResources.GenericInputOutputIcon; } return RingtoetsFormsResources.PlaceholderIcon; } private ContextMenuStrip PlaceholderWithReadonlyNameContextMenuStrip(PlaceholderWithReadonlyName nodeData, object parentData, TreeViewControl treeViewControl) { IContextMenuBuilder menuBuilder = Gui.Get(nodeData, treeViewControl); if (nodeData is InputPlaceholder || nodeData is OutputPlaceholder) { menuBuilder.AddOpenItem(); } if (nodeData is OutputPlaceholder) { var clearItem = new StrictContextMenuItem( RingtoetsCommonFormsResources.FailureMechanism_InputsOutputs_Erase, RingtoetsCommonFormsResources.FailureMechanism_InputsOutputs_Erase_ToolTip, RingtoetsCommonFormsResources.ClearIcon, null) { Enabled = false }; menuBuilder.AddCustomItem(clearItem); } if (nodeData is InputPlaceholder || nodeData is OutputPlaceholder) { menuBuilder.AddSeparator(); } return menuBuilder.AddImportItem() .AddExportItem() .AddSeparator() .AddPropertiesItem() .Build(); } # endregion # region CategoryTreeFolder private Image GetFolderIcon(TreeFolderCategory category) { switch (category) { case TreeFolderCategory.General: return RingtoetsCommonFormsResources.GeneralFolderIcon; case TreeFolderCategory.Input: return RingtoetsCommonFormsResources.InputFolderIcon; case TreeFolderCategory.Output: return RingtoetsCommonFormsResources.OutputFolderIcon; default: throw new NotImplementedException(); } } private ContextMenuStrip CategoryTreeFolderContextMenu(CategoryTreeFolder nodeData, object parentData, TreeViewControl treeViewControl) { return Gui.Get(nodeData, treeViewControl) .AddExpandAllItem() .AddCollapseAllItem() .Build(); } # endregion #region HydraulicBoundaryDatabase private ContextMenuStrip HydraulicBoundaryDatabaseContextMenuStrip(HydraulicBoundaryDatabaseContext nodeData, object parentData, TreeViewControl treeViewControl) { var connectionItem = new StrictContextMenuItem( HydraringResources.HydraulicBoundaryDatabase_Connect, HydraringResources.HydraulicBoundaryDatabase_Connect_ToolTip, RingtoetsCommonFormsResources.DatabaseIcon, (sender, args) => { SelectDatabaseFile(nodeData); }); var DesignWaterLevelItem = new StrictContextMenuItem( HydraringResources.DesignWaterLevel_Calculate, HydraringResources.DesignWaterLevel_Calculate_ToolTip, RingtoetsFormsResources.FailureMechanismIcon, null); if (string.IsNullOrEmpty(nodeData.BoundaryDatabase.FilePath)) { DesignWaterLevelItem.Enabled = false; DesignWaterLevelItem.ToolTipText = HydraringResources.DesignWaterLevel_No_HRD_To_Calculate; } return Gui.Get(nodeData, treeViewControl) .AddOpenItem() .AddSeparator() .AddCustomItem(connectionItem) .AddImportItem() .AddExportItem() .AddSeparator() .AddCustomItem(DesignWaterLevelItem) .AddSeparator() .AddPropertiesItem() .Build(); } private void SelectDatabaseFile(HydraulicBoundaryDatabaseContext nodeData) { var windowTitle = HydraringResources.SelectDatabaseFile_Title; using (var dialog = new OpenFileDialog { Filter = string.Format("{0} (*.sqlite)|*.sqlite", HydraringResources.SelectDatabaseFile_FilterName), Multiselect = false, Title = windowTitle, RestoreDirectory = true, CheckFileExists = false, }) { if (dialog.ShowDialog(Gui.MainWindow) == DialogResult.OK) { ValidateAndImportSelectedFile(nodeData, dialog.FileName); } } } private static void ValidateAndImportSelectedFile(HydraulicBoundaryDatabaseContext nodeData, string selectedFile) { var hydraulicBoundaryLocationsImporter = new HydraulicBoundaryLocationsImporter(); hydraulicBoundaryLocationsImporter.ValidateFile(selectedFile); var currentVersion = nodeData.BoundaryDatabase.Version; var newVersion = hydraulicBoundaryLocationsImporter.Version; // Compare if (!string.IsNullOrEmpty(currentVersion) && currentVersion != newVersion) { // Show dialog ShowCleanDialog(nodeData, hydraulicBoundaryLocationsImporter, selectedFile, newVersion); return; } ImportSelectedFile(nodeData, hydraulicBoundaryLocationsImporter, selectedFile, newVersion); } private static void ShowCleanDialog(HydraulicBoundaryDatabaseContext nodeData, HydraulicBoundaryLocationsImporter hydraulicBoundaryLocationsImporter, string filePath, string version) { var confirmation = MessageBox.Show( HydraringResources.Delete_Calculations_Text, BaseResources.Confirm, MessageBoxButtons.OKCancel); if (confirmation == DialogResult.OK) { ClearCalculations(nodeData.BaseNode); ImportSelectedFile(nodeData, hydraulicBoundaryLocationsImporter, filePath, version); } } private static void ClearCalculations(AssessmentSectionBase nodeData) { var failureMechanisms = nodeData.GetFailureMechanisms(); foreach (ICalculationItem calc in failureMechanisms.SelectMany(fm => fm.CalculationItems)) { calc.ClearOutput(); calc.NotifyObservers(); } log.Info(HydraringResources.Calculations_Deleted); } private static void ImportSelectedFile(HydraulicBoundaryDatabaseContext nodeData, HydraulicBoundaryLocationsImporter hydraulicBoundaryLocationsImporter, string selectedFile, string newVersion) { nodeData.BoundaryDatabase.ClearLocations(); if (hydraulicBoundaryLocationsImporter.Import(nodeData.BoundaryDatabase.Locations, selectedFile)) { SetBoundaryDatabaseData(nodeData, selectedFile, newVersion); UpdateMap(); } } private static void SetBoundaryDatabaseData(HydraulicBoundaryDatabaseContext nodeData, string selectedFile, string version) { nodeData.BoundaryDatabase.FilePath = selectedFile; nodeData.BoundaryDatabase.Version = version; nodeData.NotifyObservers(); log.InfoFormat(HydraringResources.RingtoetsGuiPlugin_SetBoundaryDatabaseFilePath_Database_on_path__0__linked, selectedFile); } private static void UpdateMap() { if (assessmentSectionMapData != null) { assessmentSectionMapData.UpdateHydraulicBoundaryDatabaseMap(); assessmentSectionMapData.NotifyObservers(); } } #endregion } }