Files
SourceCode/PROMS/VEPROMS.CSLA.Library/Extension/FolderExt.cs
T
2026-09-01 08:21:41 -04:00

330 lines
11 KiB
C#

// ========================================================================
// Copyright 2006 - Volian Enterprises, Inc. All rights reserved.
// Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
// ------------------------------------------------------------------------
// $Workfile: $ $Revision: $
// $Author: $ $Date: $
//
// $History: $
// ========================================================================
using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using System.Drawing;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Linq;
namespace VEPROMS.CSLA.Library
{
public partial class Folder : IVEDrillDown
{
#region Folder Config
[NonSerialized]
private FolderConfig _FolderConfig;
public FolderConfig FolderConfig
{
get
{
if (_FolderConfig == null)
{
_FolderConfig = new FolderConfig(this);
_FolderConfig.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_FolderConfig_PropertyChanged);
}
return _FolderConfig;
}
}
public void FolderConfigRefresh() => _FolderConfig = null;
private void _FolderConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) => Config = _FolderConfig.ToString();
#endregion
public override string ToString() => _Title;
#region IVEReadOnlyItem
public ConfigDynamicTypeDescriptor MyConfig => FolderConfig;
#endregion
#region MakeFolders for ManualOrder
public static Folder MakeFolder(Folder myParent, Connection myConnection, string name, string title, string shortName, Format myFormat, string config, DateTime dts, string usrID) => MakeFolder(myParent, myConnection, name, title, shortName, myFormat, null, config, dts, usrID);
public static Folder MakeFolder(Folder myParent, Connection myConnection, string name, string title, string shortName, Format myFormat, string config) => MakeFolder(myParent, myConnection, name, title, shortName, myFormat, null, config);
#endregion
public FolderInfo MyFolderInfo => FolderInfo.Get(FolderID);
}
public partial class FolderInfo:IVEDrillDownReadOnly
{
#region Search Paths
public string _SearchDVPath;
public string SearchDVPath
{
get
{
if (_SearchDVPath == null)
{
if (ActiveParent == null)
_SearchDVPath = Name;
else
_SearchDVPath = ActiveParent.SearchDVPath + "\u0007" + Name;
}
return _SearchDVPath;
}
}
public string SearchPath => "";
// B2021-076: Proms search results are not presented in order when printed to PDF
public string SearchDefaultSort => string.Empty;
#endregion
#region Folder Config (Read-Only)
[NonSerialized]
private FolderConfig _FolderConfig;
public FolderConfig FolderConfig => _FolderConfig ?? (_FolderConfig = new FolderConfig(this));
private void FolderConfigRefresh() => _FolderConfig = null;
#endregion
#region SortingChildren
private static bool IsInManualOrderNullFix = false;
[NonSerialized]
public Csla.SortedBindingList<FolderInfo> _SortedChildFolders;
public Csla.SortedBindingList<FolderInfo> SortedChildFolders
{
get
{
if (ChildFolders != null)
{
//B2025-018 Issues with folder order in tree view
// if any ChildFolders with a missing Manual Order
// set them to the end of the list
// use IsInManualOrderNullFix - so, if setting ChildFolders Currently,
// do not try to set them (thus creating an infinite loop)
if (!IsInManualOrderNullFix && ChildFolders.Any(x => x.ManualOrder == null))
{
IsInManualOrderNullFix = true;
foreach (FolderInfo fi in ChildFolders.Where(x => x.ManualOrder == null))
{
using (FolderInfo parfolderinfo = FolderInfo.Get(fi.ParentID))
{
using (Folder fldr = fi.Get())
{
fldr.ManualOrder = parfolderinfo.NewManualOrder(9999);
fldr.Save();
}
}
}
RefreshChildFolders();
IsInManualOrderNullFix = false;
}
if (_SortedChildFolders == null)
{
_SortedChildFolders = new SortedBindingList<FolderInfo>(ChildFolders);
}
else if (_SortedChildFolders.Count != ChildFolders.Count)
{
_SortedChildFolders = new SortedBindingList<FolderInfo>(ChildFolders);
}
_SortedChildFolders.ApplySort("ManualOrder", ListSortDirection.Ascending);
}
return _SortedChildFolders;
}
}
//B2025-018 Issues with folder order in tree view
//Note: this should be called from the parent item
//As you want to put this into the sorted order of the parent item
public double? NewManualOrder(int index)
{
double? retval = 1;
if (SortedChildFolders == null || SortedChildFolders.Count == 0)
retval = 1; // First value
else if (index == 0)
{
if (retval >= SortedChildFolders[index].ManualOrder) // If one is too big, then divide first value in half
retval = SortedChildFolders[index].ManualOrder / 2.0;
}
else if (SortedChildFolders.Count > index)
{
//B2025-018 Issues with folder order in tree view
//filter to just items with the same parent
//want new order to be halfway between the previous item
//and the next ManualOrder
var tmp = SortedChildFolders.Where(x => x.ParentID == FolderID);
var lbound = SortedChildFolders[index - 1].ManualOrder;
var ubound = tmp.OrderBy(y => y.ManualOrder).FirstOrDefault(x => x.ManualOrder > lbound)?.ManualOrder;
if (ubound != null)
{
retval = ((ubound - lbound) / 2.0) + lbound;
}
else
{
//in this case, item before is highest for that parent
//so just make this 1 more
retval = lbound + 1;
}
}
else
{
if (index >= SortedChildFolders.Count) index = SortedChildFolders.Count;
retval += SortedChildFolders[index - 1].ManualOrder;
}
return retval;
}
/// <summary>
/// UniqueChildName will check the existing children to assure that the name is not a duplicate name.
/// </summary>
/// <param name="folderName"></param>
/// <returns></returns>
public string UniqueChildName(string folderName)
{
string retval = folderName;
int iSuffix = -1;
RefreshChildFolders();
foreach (FolderInfo fi in ChildFolders)
{
if (fi.Name.StartsWith(folderName))
{
if (fi.Name == folderName)
iSuffix = 0;
else if (Regex.IsMatch(fi.Name, folderName + "[_][0-9]+"))
{
int ii = int.Parse(fi.Name.Substring(1 + folderName.Length));
if (ii > iSuffix) iSuffix = ii;
}
}
}
if (iSuffix >= 0)
retval = string.Format("{0}_{1}", folderName, iSuffix + 1);
// Console.WriteLine("FolderName = '{0}'", retval);
return retval;
}
#endregion
#region IVEReadOnlyItem
public System.Collections.IList GetChildren()
{
if(FolderDocVersionCount != 0)return FolderDocVersions;
if (ChildFolderCount != 0) return SortedChildFolders;
return null;
}
public bool HasChildren => FolderDocVersionCount > 0 || ChildFolderCount > 0;
public IVEDrillDownReadOnly ActiveParent => MyParent;
public FormatInfo ActiveFormat => LocalFormat ?? (ActiveParent?.ActiveFormat);
public FormatInfo LocalFormat => MyFormat;
public ConfigDynamicTypeDescriptor MyConfig => FolderConfig;
/// <summary>
/// These settings are set on the user interface side.
/// This is used to control whether the Name and/or Title is displayed
/// next to the tree nodes in the user interface
/// </summary>
private bool _DisplayTreeNodeNames = true;
public bool DisplayTreeNodeNames
{
get { return _DisplayTreeNodeNames; }
set { _DisplayTreeNodeNames = value; }
}
private bool _DisplayTreeNodeTitles = false;
public bool DisplayTreeNodeTitles
{
get { return _DisplayTreeNodeTitles; }
set { _DisplayTreeNodeTitles = value; }
}
public override string ToString()
{
// assume that at least one of the two options was selected
string rtnstr = "";
if ( _DisplayTreeNodeNames) rtnstr = Name;
if (_DisplayTreeNodeTitles)
{
if (rtnstr.Length > 0) rtnstr += " - ";
rtnstr += Title;
}
return rtnstr;
}
#endregion
public Color BackColor
{ get { return FolderConfig.Default_BkColor; } }
public bool HasWorkingDraft
{
get
{
if (FolderDocVersionCount > 0)
{
foreach (DocVersionInfo dvi in FolderDocVersions)
if (dvi.VersionType == 0)
return true;
}
return false;
}
}
#region Extension
partial class FolderInfoExtension : extensionBase
{
public override void Refresh(FolderInfo tmp) => tmp.FolderConfigRefresh();
}
public static FolderInfo GetTop()
{
try
{
FolderInfo tmp = DataPortal.Fetch<FolderInfo>(new TopCriteria());
if (tmp.ErrorMessage == "No Record Found")
{
tmp.Dispose(); // Clean-up FolderInfo
tmp = null;
}
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on FolderInfo.GetTop", ex);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Keeping until replace CSLA")]
private void DataPortal_Fetch(TopCriteria criteria)
{
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] FolderInfo.DataPortal_Fetch", GetHashCode());
try
{
using (SqlConnection cn = Database.VEPROMS_SqlConnection)
{
ApplicationContext.LocalContext["cn"] = cn;
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "getTopFolder";
cm.CommandTimeout = Database.DefaultTimeout;
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
if (!dr.Read())
{
_ErrorMessage = "No Record Found";
return;
}
ReadData(dr);
}
}
// removing of item only needed for local data portal
if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client)
ApplicationContext.LocalContext.Remove("cn");
}
}
catch (Exception ex)
{
if (_MyLog.IsErrorEnabled) _MyLog.Error("FolderInfo.DataPortal_Fetch", ex);
_ErrorMessage = ex.Message;
throw new DbCslaException("FolderInfo.DataPortal_Fetch", ex);
}
}
#endregion
[Serializable()]
protected class TopCriteria
{
public TopCriteria() { ;}
}
public bool IsFolder => true;
public bool IsDocVersion => false;
public bool IsProcedure => false;
public bool IsSection => false;
public bool IsStep => false;
}
}