// 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
}
}