// Copyright (C) Stichting Deltares 2025. All rights reserved.
//
// This file is part of the application DAM - UI.
//
// DAM - UI 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.Linq;
using Deltares.Dam.Data;
using Deltares.Geotechnics;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard.Attributes;
using Deltares.Standard.Forms;
using Deltares.Standard.Forms.DExpress;
using Deltares.Standard.Forms.Maps;
using Deltares.Standard.Reflection;
using DevExpress.Utils.Menu;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Menu;
namespace Deltares.Dam.Forms
{
public class DamContext : GeotechnicsContext
{
public DamContext()
{
SetUpLocationsFilters();
SetUpSoilsFilters();
}
///
/// Method indicating a visibility override value for a given instance object.
///
/// Object being evaluated.
/// Name of the member which is part of .
///
/// True if visible; False if hidden; Null if no override.
///
public override bool? IsVisible(object source, string member)
{
var locationScenariosControl = source as LocationScenariosControl;
if (null != locationScenariosControl)
{
if (member == StaticReflection.GetMemberName(x => x.SelectedContextFilter))
{
return locationScenariosControl.HasItems;
}
}
if (source is SoilList)
{
return true;
}
if (source is Location && member == StaticReflection.GetMemberName(x => x.SurfaceLine2))
{
return false;
}
if (source is Location && member == StaticReflection.GetMemberName(x => x.LocalXZSurfaceLine2))
{
return true;
}
var soil = source as DamSoil;
if (soil != null)
{
bool? visibleAccordingSoilUserFilter = VisibleAccordingSoilUserFilter(member);
if (visibleAccordingSoilUserFilter != null)
{
return visibleAccordingSoilUserFilter;
}
}
// Make sure unwanted operations are hidden for the surface line grid for now.
var grid = source as GridViewControl;
if (grid != null)
{
if ((member == "AddRowCommand" || member == "DeleteRowCommand" || member == "PasteCommand" || member == "EditCommand") && (grid.Name == "SurfaceLinePointsGridControl"))
{
return false;
}
}
if (source is DikeTreeView dikeTreeView)
{
TreeList treeList = dikeTreeView.TreeList;
treeList.PopupMenuShowing += DikeTreeListPopupMenuShowing;
}
if (source is VisualValidationResult)
{
// Make sure that for DAM, all repairers are not used.
var vr = (VisualValidationResult) source;
vr.Repairer = null;
}
if (source is CsvExportData && member.Equals("ResultSlices"))
{
return false;
}
bool? isVisible = base.IsVisible(source, member);
if (isVisible != null && isVisible.Value)
{
return true;
}
return isVisible;
}
///
/// Method indicating if the enabled override value for a given instance object.
///
/// Object being evaluated.
/// Name of the member which is part of .
///
/// True if enabled; False if disabled; Null if no override.
///
public override bool? IsEnabled(object source, string member)
{
// Legend in DotSpatial 1.8 uses ContextMenu which is not supported in .NET6
if (source is MapEditor)
{
if (member == "ShowLegend")
{
return false;
}
}
// Make sure CharacteristicPoints can not be edited for now.
if (source is CharacteristicPoint)
{
if (member == StaticReflection.GetMemberName(x => x.X) ||
member == StaticReflection.GetMemberName(x => x.Y) ||
member == StaticReflection.GetMemberName(x => x.Z))
{
return false;
}
return true;
}
if (source is SoilList)
{
return true;
}
if (source is DamSoil soil)
{
if (member == StaticReflection.GetMemberName(s => s.Name) ||
member == StaticReflection.GetMemberName(s => s.StressTable) ||
member == StaticReflection.GetMemberName(s => s.SuTable))
{
return false;
}
if (member == StaticReflection.GetMemberName(s => s.POP) ||
member == StaticReflection.GetMemberName(s => s.RatioCuPc) ||
member == StaticReflection.GetMemberName(s => s.StrengthIncreaseExponent))
{
return soil.ShearStrengthModel == ShearStrengthModel.CuCalculated;
}
if (member == StaticReflection.GetMemberName(s => s.Cohesion) ||
member == StaticReflection.GetMemberName(s => s.FrictionAngle))
{
return soil.ShearStrengthModel == ShearStrengthModel.CPhi;
}
return true;
}
if (source is GridViewControl grid)
{
// Make sure you can not add or delete soil material
if (grid.Name == "MaterialsGridViewControl" && member is "DeleteRowCommand" or "AddRowCommand")
{
return false;
}
}
return base.IsEnabled(source, member);
}
///
/// Returns a collection of allowed values for a property as part of the IDomain interface.
/// This is used for populating drop down values in a drop down list.
/// Note that this isn’t necessary when the property is defined as an enumeration.
/// All enumeration values are used by default.
///
/// The name of the property for which to return the possible values.
///
/// A containing the possible values for the given property.
///
public override ICollection GetDomain(string property)
{
if (property == "CharacteristicPointType")
{
return new List
{
CharacteristicPointType.SurfaceLevelOutside,
CharacteristicPointType.DikeToeAtRiver,
CharacteristicPointType.ShoulderTopOutside,
CharacteristicPointType.ShoulderBaseOutside,
CharacteristicPointType.DikeTopAtRiver,
CharacteristicPointType.TrafficLoadOutside,
CharacteristicPointType.TrafficLoadInside,
CharacteristicPointType.DikeTopAtPolder,
CharacteristicPointType.ShoulderBaseInside,
CharacteristicPointType.ShoulderTopInside,
CharacteristicPointType.DikeToeAtPolder,
CharacteristicPointType.DitchDikeSide,
CharacteristicPointType.BottomDitchDikeSide,
CharacteristicPointType.BottomDitchPolderSide,
CharacteristicPointType.DitchPolderSide,
CharacteristicPointType.SurfaceLevelInside,
CharacteristicPointType.None
};
}
if (property == "SoilUserFilter")
{
return GetSoilUserFilters();
}
return base.GetDomain(property);
}
public override ICollection GetDomain(object source, string member)
{
if (source is DamSoil && member == StaticReflection.GetMemberName(s => s.ShearStrengthModel))
{
return new List
{
ShearStrengthModel.CPhi,
ShearStrengthModel.CuCalculated,
ShearStrengthModel.StressTable,
ShearStrengthModel.SuTable
};
}
return null;
}
public override string GetFormat(Type type, object source, string member)
{
if ((type == typeof(DamSoil) || source is DamSoil) && (member == StaticReflection.GetMemberName(x => x.PermeabKx)))
{
return "E3";
}
return base.GetFormat(type, source, member);
}
private bool? VisibleAccordingSoilUserFilter(string member)
{
if (alwaysVisibleProperties.Contains(member))
{
return true;
}
HashSet filteredProperties = GetFilteredProperties(SoilUserFilter);
if (filteredProperties == null)
{
return null;
}
return filteredProperties.Contains(member);
}
private static void DikeTreeListPopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
{
if (e.Menu is TreeListColumnMenu columnMenu)
{
DXMenuItem showAutoFilterRowItem = columnMenu.Items
.FirstOrDefault(item => item.Caption == "Show Auto Filter Row");
if (showAutoFilterRowItem != null)
{
showAutoFilterRowItem.Visible = false;
}
DXMenuItem filterEditorItem = columnMenu.Items
.FirstOrDefault(item => item.Caption == "Filter Editor...");
if (filterEditorItem != null)
{
filterEditorItem.Visible = false;
}
}
}
#region SoilFilters
private readonly HashSet alwaysVisibleProperties = new HashSet
{
StaticReflection.GetMemberName(s => s.Name),
StaticReflection.GetMemberName(s => s.Color),
StaticReflection.GetMemberName(s => s.SoilType)
};
private readonly HashSet macrostabilitySoilProperties = new HashSet
{
StaticReflection.GetMemberName(s => s.AbovePhreaticLevel),
StaticReflection.GetMemberName(s => s.BelowPhreaticLevel),
StaticReflection.GetMemberName(s => s.ShearStrengthModel),
StaticReflection.GetMemberName(s => s.Cohesion),
StaticReflection.GetMemberName(s => s.FrictionAngle),
StaticReflection.GetMemberName(s => s.POP),
StaticReflection.GetMemberName(s => s.RatioCuPc),
StaticReflection.GetMemberName(s => s.StrengthIncreaseExponent),
StaticReflection.GetMemberName(s => s.StressTable),
StaticReflection.GetMemberName(s => s.TrafficLoadDegreeOfConsolidation)
};
private readonly HashSet pipingSoilProperties = new HashSet
{
StaticReflection.GetMemberName(s => s.AbovePhreaticLevel),
StaticReflection.GetMemberName(s => s.BelowPhreaticLevel),
StaticReflection.GetMemberName(s => s.DiameterD70),
StaticReflection.GetMemberName(s => s.PermeabKx)
};
private HashSet combinedSoilProperties;
private void SetUpSoilsFilters()
{
SoilUserFilter = UserColumnFilters.MacrostabilityWti;
combinedSoilProperties = new HashSet();
combinedSoilProperties.UnionWith(macrostabilitySoilProperties);
combinedSoilProperties.UnionWith(pipingSoilProperties);
}
protected override HashSet GetFilteredProperties(object userColumnFilters)
{
return combinedSoilProperties;
}
#endregion SoilFilters
#region LocationFilters
private readonly Dictionary>> filters = new Dictionary>>();
private const string LocationScenarioInsideStability = "InsideStabilityScenarioCategory";
private const string LocationScenarioPiping = "PipingScenarioCategory";
private const string LocationScenarioPlLineSchematization = "PlLineSchematizationScenarioCategory";
private void SetUpLocationsFilters()
{
var locationScenarioFilter = new Dictionary>();
filters[typeof(Scenario)] = locationScenarioFilter;
locationScenarioFilter.Add(LocationScenarioInsideStability, new List
{
StaticReflection.GetMemberName(x => x.LocationScenarioID),
StaticReflection.GetMemberName(x => x.RiverLevel),
StaticReflection.GetMemberName(x => x.DikeTableHeight),
StaticReflection.GetMemberName(x => x.RequiredSafetyFactorStabilityInnerSlope),
StaticReflection.GetMemberName(x => x.HeadPl3),
StaticReflection.GetMemberName(x => x.HeadPl4),
StaticReflection.GetMemberName(x => x.PolderLevel),
StaticReflection.GetMemberName(x => x.HeadPl2)
});
locationScenarioFilter.Add(LocationScenarioPiping, new List
{
StaticReflection.GetMemberName(x => x.LocationScenarioID),
StaticReflection.GetMemberName(x => x.RiverLevel),
StaticReflection.GetMemberName(x => x.DikeTableHeight),
StaticReflection.GetMemberName(x => x.RequiredSafetyFactorPiping),
StaticReflection.GetMemberName(x => x.HeadPl3),
StaticReflection.GetMemberName(x => x.HeadPl4),
StaticReflection.GetMemberName(x => x.PolderLevel),
StaticReflection.GetMemberName(x => x.HeadPl2)
});
locationScenarioFilter.Add(LocationScenarioPlLineSchematization, new List
{
StaticReflection.GetMemberName(x => x.LocationScenarioID),
StaticReflection.GetMemberName(x => x.RiverLevel),
StaticReflection.GetMemberName(x => x.PlLineOffsetBelowDikeTopAtRiver),
StaticReflection.GetMemberName(x => x.PlLineOffsetBelowDikeTopAtPolder),
StaticReflection.GetMemberName(x => x.PlLineOffsetBelowShoulderBaseInside),
StaticReflection.GetMemberName(x => x.PlLineOffsetBelowDikeToeAtPolder),
StaticReflection.GetMemberName(x => x.PlLineOffsetBelowDikeCrestMiddle),
StaticReflection.GetMemberName(x => x.PlLineOffsetFactorBelowShoulderCrest),
StaticReflection.GetMemberName(x => x.UsePlLineOffsetBelowDikeCrestMiddle),
StaticReflection.GetMemberName(x => x.UsePlLineOffsetFactorBelowShoulderCrest),
StaticReflection.GetMemberName(x => x.PolderLevel)
});
}
///
/// Returns the possible named filters for a given type.
///
/// A type for which named filters will be returned.
/// A of the named filters or null if no named filters exists.
public IEnumerable GetColumnNamedFilters(Type type)
{
if (filters.ContainsKey(type))
{
return filters[type].Keys.ToArray();
}
return null;
}
///
/// Returns a list of visible properties for a type and a named filter returned by .
///
/// A type for which named filters are defined.
/// One of the named filters for this type.
/// A list of visible properties.
public IList GetFilteredColumns(Type type, string value)
{
if (filters.ContainsKey(type) && filters[type].ContainsKey(value))
{
return filters[type][value];
}
return null;
}
#endregion LocationFilters
}
}