4304 lines
176 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Runtime.InteropServices; // For DragHelper
using System.Reflection;
using Csla;
using Csla.Validation;
using VEPROMS.CSLA.Library;
using System.IO;
using Volian.Base.Library;
using DevComponents.DotNetBar;
using JR.Utils.GUI.Forms; //C2018-026 show notes entered during approval or workflow stage
namespace Volian.Controls.Library
{
#region DelegatesAndEventArgs
public delegate void vlnTreeViewEvent(object sender, vlnTreeEventArgs args);
public delegate void vlnTreeViewTimeEvent(object sender, vlnTreeTimeEventArgs args);
public delegate void vlnTreeViewStatusEvent(object sender, vlnTreeStatusEventArgs args);
public delegate ItemInfo vlnTreeViewClipboardStatusEvent(object sender, vlnTreeEventArgs args);
public delegate void vlnTreeViewItemInfoEvent(object sender, vlnTreeItemInfoEventArgs args);
public delegate bool vlnTreeViewBoolEvent(object sender, vlnTreeEventArgs args);
public delegate bool vlnTreeViewItemInfoDeleteEvent(object sender, vlnTreeItemInfoEventArgs args);
public delegate bool vlnTreeViewItemInfoInsertEvent(object sender, vlnTreeItemInfoInsertEventArgs args);
public delegate bool vlnTreeViewItemInfoPasteEvent(object sender, vlnTreeItemInfoPasteEventArgs args);
public delegate TreeNode vlnTreeViewTreeNodeEvent(object sender, vlnTreeEventArgs args);
public delegate DialogResult vlnTreeViewPropertyEvent(object sender, vlnTreePropertyEventArgs args);
public delegate DialogResult vlnTreeViewPSIEvent(object sender, vlnTreeEventArgs args);
public delegate DialogResult vlnTreeViewSIEvent(object sender, vlnTreeEventArgs args);
public delegate void vlnTreeViewSectionInfoEvent(object sender, vlnTreeSectionInfoEventArgs args);
public delegate void WordSectionDeletedEvent(object sender, WordSectionEventArgs args);
public delegate void vlnTreeViewPdfEvent(object sender, vlnTreeViewPdfArgs args);
public delegate string vlnTreeViewGetChangeIdEvent(object sender, vlnTreeItemInfoEventArgs args);
public delegate ItemInfo vlnTreeViewSearchIncTransEvent(object sender, vlnTreeItemInfoEventArgs args);
public partial class vlnTreeSectionInfoEventArgs
{
private bool _IsDeleting = false;
public bool IsDeleting
{
get { return _IsDeleting; }
set { _IsDeleting = value; }
}
private SectionInfo _MySectionInfo;
public SectionInfo MySectionInfo
{
get { return _MySectionInfo; }
set { _MySectionInfo = value; }
}
public vlnTreeSectionInfoEventArgs(SectionInfo mySectionInfo)
{
_MySectionInfo = mySectionInfo;
}
public vlnTreeSectionInfoEventArgs(SectionInfo mySectionInfo,bool isDeleting)
{
_MySectionInfo = mySectionInfo;
_IsDeleting = isDeleting;
}
}
public partial class vlnTreeViewPdfArgs
{
private string _MyFilename;
public string MyFilename
{
get { return _MyFilename; }
set { _MyFilename = value; }
}
private byte[] _MyBuffer;
public byte[] MyBuffer
{
get { return _MyBuffer; }
set { _MyBuffer = value; }
}
private string _MyWatermark;
public string MyWatermark
{
get { return _MyWatermark; }
set { _MyWatermark = value; }
}
public vlnTreeViewPdfArgs(string filename, byte[] buffer, string watermark)
{
_MyFilename = filename;
_MyBuffer = buffer;
_MyWatermark = watermark;
}
}
public partial class vlnTreeTimeEventArgs
{
private TimeSpan _myTimeSpan;
public TimeSpan MyTimeSpan
{
get { return _myTimeSpan; }
set { _myTimeSpan = value; }
}
private string _MyMessage;
public string MyMessage
{
get { return _MyMessage; }
set { _MyMessage = value; }
}
public vlnTreeTimeEventArgs(DateTime dtStart, string message)
{
MyTimeSpan = TimeSpan.FromTicks(DateTime.Now.Ticks - dtStart.Ticks);
MyMessage = message;
}
}
public partial class vlnTreeStatusEventArgs
{
private bool _MyStatus;
public bool MyStatus
{
get { return _MyStatus; }
set { _MyStatus = value; }
}
private string _MyMessage;
public string MyMessage
{
get { return _MyMessage; }
set { _MyMessage = value; }
}
public vlnTreeStatusEventArgs(bool status, string message)
{
MyStatus = status;
MyMessage = message;
}
}
public partial class vlnTreeEventArgs
{
#region Business Methods
private TreeNode _Node;
public TreeNode Node
{
get { return _Node; }
set { _Node = value; }
}
private TreeNode _Destination=null;
public TreeNode Destination
{
get { return _Destination; }
set { _Destination = value; }
}
private int _Index;
public int Index
{
get { return _Index; }
set { _Index = value; }
}
//jcb multiunit
private string _Unit;
public string Unit
{
get { return _Unit; }
set { _Unit = value; }
}
private int _UnitIndex = -1;
public int UnitIndex
{
get { return _UnitIndex; }
set { _UnitIndex = value; }
}
//end jcb multiunit
#endregion
#region Factory Methods
private vlnTreeEventArgs() { ;}
public vlnTreeEventArgs(TreeNode node)
{
_Node = node;
}
public vlnTreeEventArgs(TreeNode node, TreeNode destination, int index)
{
_Node = node;
_Destination = destination;
_Index = index;
}
//jcb multiunit
public vlnTreeEventArgs(TreeNode node, TreeNode destination, int index, string unit, int unitIndex)
{
_Node = node;
_Destination = destination;
_Index = index;
_Unit = unit;
_UnitIndex = unitIndex;
}
//end jcb multiunit
#endregion
public override string ToString()
{
return string.Format("Node={0},Destination={1},Index={2},Unit={3},UnitIndex={4}",NodePath(this.Node),this.Destination, this.Index,this.Unit, this.UnitIndex);
}
private string NodePath(TreeNode node)
{
string retval = "";
if (node.Parent != null)
retval = NodePath(node.Parent) + ":";
retval += node.Text;
return retval;
}
}
public partial class vlnTreeItemInfoEventArgs
{
#region Business Methods
private ItemInfo _MyItemInfo;
public ItemInfo MyItemInfo
{
get { return _MyItemInfo; }
set { _MyItemInfo = value; }
}
#endregion
#region Factory Methods
private vlnTreeItemInfoEventArgs() { ;}
public vlnTreeItemInfoEventArgs(ItemInfo myItemInfo)
{
_MyItemInfo = myItemInfo;
}
#endregion
}
public enum E_InsertType {Before, After, Child};
public partial class vlnTreeItemInfoInsertEventArgs
{
#region Business Methods
private ItemInfo _MyItemInfo;
public ItemInfo MyItemInfo
{
get { return _MyItemInfo; }
set { _MyItemInfo = value; }
}
private E_InsertType _InsertType;
public E_InsertType InsertType
{
get { return _InsertType; }
set { _InsertType = value; }
}
private int _Type;
public int Type
{
get { return _Type; }
set { _Type = value; }
}
private E_FromType _FromType;
public E_FromType FromType
{
get { return _FromType; }
set { _FromType = value; }
}
private string _StepText;
public string StepText
{
get { return _StepText; }
set { _StepText = value; }
}
#endregion
#region Factory Methods
private vlnTreeItemInfoInsertEventArgs() { ;}
public vlnTreeItemInfoInsertEventArgs(ItemInfo myItemInfo, E_InsertType insertType, string stepText)
{
_MyItemInfo = myItemInfo;
_InsertType = insertType;
_StepText = stepText;
}
public vlnTreeItemInfoInsertEventArgs(ItemInfo myItemInfo, E_InsertType insertType, string stepText, int type, E_FromType fromType)
{
_MyItemInfo = myItemInfo;
_InsertType = insertType;
_StepText = stepText;
_Type = type;
_FromType = fromType;
}
#endregion
}
#region PasteEventArgs
public partial class vlnTreeItemInfoPasteEventArgs
{
#region Business Methods
private ItemInfo _MyItemInfo;
public ItemInfo MyItemInfo
{
get { return _MyItemInfo; }
set { _MyItemInfo = value; }
}
private int _CopyStartID;
public int CopyStartID
{
get { return _CopyStartID; }
set { _CopyStartID = value; }
}
private ItemInfo.EAddpingPart _PasteType;
public ItemInfo.EAddpingPart PasteType
{
get { return _PasteType; }
set { _PasteType = value; }
}
private int? _Type;
public int? Type
{
get { return _Type; }
set { _Type = value; }
}
#endregion
#region Factory Methods
private vlnTreeItemInfoPasteEventArgs() { ;}
public vlnTreeItemInfoPasteEventArgs(ItemInfo myItemInfo, int copyStartId, ItemInfo.EAddpingPart pasteType, int? type)
{
_MyItemInfo = myItemInfo;
_CopyStartID = copyStartId;
_PasteType = pasteType;
_Type = type;
}
#endregion
}
#endregion
public partial class vlnTreePropertyEventArgs : EventArgs
{
private string _Title;
public string Title
{
get { return _Title; }
set { _Title = value; }
}
private object _ConfigObject;
public object ConfigObject
{
get { return _ConfigObject; }
set { _ConfigObject = value; }
}
private FolderConfig _FolderConfig;
public FolderConfig FolderConfig
{
get { return _FolderConfig; }
set { _ConfigObject = _FolderConfig = value; }
}
private DocVersionConfig _DocVersionConfig;
public DocVersionConfig DocVersionConfig
{
get { return _DocVersionConfig; }
set { _ConfigObject = _DocVersionConfig = value; }
}
private ProcedureConfig _ProcedureConfig;
public ProcedureConfig ProcedureConfig
{
get { return _ProcedureConfig; }
set { _ConfigObject = _ProcedureConfig = value; }
}
private SectionConfig _SectionConfig;
public SectionConfig SectionConfig
{
get { return _SectionConfig; }
set { _ConfigObject = _SectionConfig = value; }
}
private vlnTreePropertyEventArgs() { ;}
public vlnTreePropertyEventArgs(string title, FolderConfig folderConfig)
{
_Title = title;
FolderConfig = folderConfig;
}
public vlnTreePropertyEventArgs(string title, DocVersionConfig docVersionConfig)
{
_Title = title;
DocVersionConfig = docVersionConfig;
}
public vlnTreePropertyEventArgs(string title, ProcedureConfig procedureConfig)
{
_Title = title;
ProcedureConfig = procedureConfig;
}
public vlnTreePropertyEventArgs(string title, SectionConfig sectionConfig)
{
_Title = title;
DocStyleListConverter.MySection = sectionConfig.MySection;
SectionConfig = sectionConfig;
}
}
#endregion
public partial class vlnTreeView : TreeView
{
private ProcedureInfo _currentPri = null; // used to get child name to append to approved export filename -AddApprovedRevisionsMultiUnit() & ImportProcedure_Click()
private SessionInfo _MySessionInfo;
public SessionInfo MySessionInfo
{
get { return _MySessionInfo; }
set { _MySessionInfo = value; }
}
private UserInfo _MyUserInfo;
public UserInfo MyUserInfo
{
get { return _MyUserInfo; }
set { _MyUserInfo = value; }
}
private string _DelProcReason; // C2020-038: request reason for delete procedure so this can be saved in database
public string DelProcReason
{
get { return _DelProcReason; }
set { _DelProcReason = value; }
}
#region Local Vars
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
FolderInfo _LastFolderInfo = null;
ProcedureInfo _LastProcedureInfo = null;
DocVersionInfo _LastDocVersionInfo = null;
SectionInfo _LastSectionInfo = null;
VETreeNode _LastTreeNode = null;
StepInfo _LastStepInfo = null;
ItemInfo _LastItemInfo = null;
#endregion
#region Events
public event vlnTreeViewGetChangeIdEvent GetChangeId;
private string OnGetChangeId(object sender, vlnTreeItemInfoEventArgs args)
{
if (GetChangeId != null) return GetChangeId(sender, args);
return null;
}
public event vlnTreeViewPdfEvent ViewPDF;
private void OnViewPDF(object sender, vlnTreeViewPdfArgs args)
{
if (ViewPDF != null) ViewPDF(sender, args);
}
public event vlnTreeViewItemInfoDeleteEvent DeleteItemInfo;
private bool OnDeleteItemInfo(object sender, vlnTreeItemInfoEventArgs args)
{
if (DeleteItemInfo != null) return DeleteItemInfo(sender, args);
return false;
}
public event vlnTreeViewItemInfoInsertEvent InsertItemInfo;
private bool OnInsertItemInfo(object sender, vlnTreeItemInfoInsertEventArgs args)
{
if (InsertItemInfo != null) return InsertItemInfo(sender, args);
return false;
}
public event vlnTreeViewItemInfoPasteEvent PasteItemInfo;
private bool OnPasteItemInfo(object sender, vlnTreeItemInfoPasteEventArgs args)
{
if (PasteItemInfo != null) return PasteItemInfo(sender, args);
return false;
}
public event vlnTreeViewEvent NodeMove;
private void OnNodeMove(object sender, vlnTreeEventArgs args)
{
if (NodeMove != null) NodeMove(sender, args);
}
public event vlnTreeViewClipboardStatusEvent ClipboardStatus;
private ItemInfo OnClipboardStatus(object sender, vlnTreeEventArgs args)
{
ItemInfo rv = null;
if (ClipboardStatus != null) rv = ClipboardStatus(sender, args);
return rv;
}
public event vlnTreeViewEvent NodeCopy;
private void OnNodeCopy(object sender, vlnTreeEventArgs args)
{
if (NodeCopy != null) NodeCopy(sender, args);
}
public event vlnTreeViewPropertyEvent NodeOpenProperty;
private DialogResult OnNodeOpenProperty(object sender, vlnTreePropertyEventArgs args)
{
if (NodeOpenProperty != null) return NodeOpenProperty(sender, args);
return DialogResult.Cancel;
}
public event vlnTreeViewPSIEvent NodePSI;
private DialogResult OnNodePSI(object sender, vlnTreeEventArgs args)
{
if (NodePSI != null) return NodePSI(sender, args);
return DialogResult.Cancel;
}
// C2020-033: Support the menu item to bring up Search/Incoming Transitions panel
public event vlnTreeViewSearchIncTransEvent SearchIncTrans;
private ItemInfo OnSearchIncTransIn(object sender, vlnTreeItemInfoEventArgs args)
{
if (SearchIncTrans != null) return SearchIncTrans(sender, args);
return args.MyItemInfo;
}
public event vlnTreeViewSIEvent NodeSI;
private DialogResult OnNodeSI(object sender, vlnTreeEventArgs args)
{
if (NodeSI != null) return NodeSI(sender, args);
return DialogResult.Cancel;
}
public event vlnTreeViewEvent NodeSelect;
private void OnNodeSelect(object sender, vlnTreeEventArgs args)
{
if (NodeSelect != null) NodeSelect(sender, args);
}
public event vlnTreeViewEvent CreateContinuousActionSummary;
private void OnCreateContinuousActionSummary(object sender, vlnTreeEventArgs args)
{
if (CreateContinuousActionSummary != null) CreateContinuousActionSummary(sender, args);
}
public event vlnTreeViewEvent CreateTimeCriticalActionSummary;
private void OnCreateTimeCriticalActionSummary(object sender, vlnTreeEventArgs args)
{
if (CreateTimeCriticalActionSummary != null) CreateTimeCriticalActionSummary(sender, args);
}
public event vlnTreeViewEvent PrintProcedure;
private void OnPrintProcedure(object sender, vlnTreeEventArgs args)
{
if (PrintProcedure != null) PrintProcedure(sender, args);
}
public event vlnTreeViewEvent QPrintProcedure;
private void OnQPrintProcedure(object sender, vlnTreeEventArgs args)
{
if (QPrintProcedure != null) QPrintProcedure(sender, args);
}
public event vlnTreeViewEvent PrintSection;
private void OnPrintSection(object sender, vlnTreeEventArgs args)
{
if (PrintSection != null) PrintSection(sender, args);
}
public event vlnTreeViewEvent PrintAllProcedures;
private void OnPrintAllProcedures(object sender, vlnTreeEventArgs args)
{
if (PrintAllProcedures != null) PrintAllProcedures(sender, args);
}
public event vlnTreeViewEvent SelectDateToStartChangeBars;
private void OnSelectDateToStartChangeBars(object sender, vlnTreeEventArgs args)
{
if (SelectDateToStartChangeBars != null) SelectDateToStartChangeBars(sender, args);
}
public event vlnTreeViewEvent ApproveProcedure;
private void OnApproveProcedure(object sender, vlnTreeEventArgs args)
{
if (ApproveProcedure != null) ApproveProcedure(sender, args);
}
public event vlnTreeViewEvent ApproveAllProcedures;
private void OnApproveAllProcedures(object sender, vlnTreeEventArgs args)
{
if (ApproveAllProcedures != null) ApproveAllProcedures(sender, args);
}
public event vlnTreeViewEvent ApproveSomeProcedures;
private void OnApproveSomeProcedures(object sender, vlnTreeEventArgs args)
{
if (ApproveSomeProcedures != null) ApproveSomeProcedures(sender, args);
}
public event vlnTreeViewEvent ReportAllProceduresInconsistencies;
private void OnReportAllProceduresInconsistencies(object sender, vlnTreeEventArgs args)
{
if (ReportAllProceduresInconsistencies != null) ReportAllProceduresInconsistencies(sender, args);
}
public event vlnTreeViewEvent RefreshCheckedOutProcedures;
private void OnRefreshCheckedOutProcedures(object sender, vlnTreeEventArgs args)
{
if (RefreshCheckedOutProcedures != null) RefreshCheckedOutProcedures(sender, args);
}
public event vlnTreeViewEvent ProcedureCheckedOutTo;
private void OnProcedureCheckedOutTo(object sender, vlnTreeEventArgs args)
{
if (ProcedureCheckedOutTo != null) ProcedureCheckedOutTo(sender, args);
}
public event vlnTreeViewEvent ExportImportProcedureSets;
private void OnExportImportProcedureSets(object sender, vlnTreeEventArgs args)
{
if (ExportImportProcedureSets != null) ExportImportProcedureSets(sender, args);
}
public event vlnTreeViewEvent PrintTransitionReport;
private void OnPrintTransitionReport(object sender, vlnTreeEventArgs args)
{
if (PrintTransitionReport != null) PrintTransitionReport(sender, args);
}
public event vlnTreeViewEvent NodeNew;
private void OnNodeNew(object sender, vlnTreeEventArgs args)
{
if (NodeNew != null) NodeNew(sender, args);
}
/// <summary>
/// Raised after a new step is added.
/// </summary>
public event vlnTreeViewEvent NodeInsert;
private void OnNodeInsert(object sender, vlnTreeEventArgs args)
{
if (NodeInsert != null) NodeInsert(sender, args);
}
public event vlnTreeViewEvent NodeSelectionChange;
private void OnNodeSelectionChange(object sender, vlnTreeEventArgs args)
{
if (NodeSelectionChange != null) NodeSelectionChange(sender, args);
}
public event vlnTreeViewSectionInfoEvent SectionShouldClose;
private void OnSectionShouldClose(object sender, vlnTreeSectionInfoEventArgs args)
{
if (SectionShouldClose != null) SectionShouldClose(sender, args);
}
public event vlnTreeViewSectionInfoEvent PauseRefresh;
private void OnPauseRefresh(object sender, vlnTreeSectionInfoEventArgs args)
{
if (PauseRefresh != null) PauseRefresh(sender, args);
}
public event vlnTreeViewSectionInfoEvent UnPauseRefresh;
private void OnUnPauseRefresh(object sender, vlnTreeSectionInfoEventArgs args)
{
if (UnPauseRefresh != null) UnPauseRefresh(sender, args);
}
public event WordSectionDeletedEvent WordSectionDeleted;
internal void OnWordSectionDeleted(object sender, WordSectionEventArgs args)
{
WordSectionDeleted(sender, args);
}
public event vlnTreeViewItemInfoEvent OpenItem;
private void OnOpenItem(object sender, vlnTreeItemInfoEventArgs args)
{
if (OpenItem != null) OpenItem(sender, args);
}
// This event was added to update the Step Properties/RO & Tools/Search RO & Reports
// when an update of ro.fst is done & the ro trees on those panels needs refreshed.
// (bug fix B2015-226)
public event StepPanelTabDisplayEvent TabDisplay;
private void OnTabDisplay(object sender, StepPanelTabDisplayEventArgs args)
{
if (TabDisplay != null) TabDisplay(sender, args);
}
#endregion
#region Constructors
public vlnTreeView()
{
InitializeComponent();
this.AllowDrop = true;
DragHelper.InitCommonControls();
this.ItemDrag += new ItemDragEventHandler(tv_ItemDrag);
this.DragDrop += new DragEventHandler(tv_DragDrop);
this.DragEnter += new DragEventHandler(tv_DragEnter);
this.DragLeave += new EventHandler(tv_DragLeave);
this.DragOver += new DragEventHandler(tv_DragOver);
this.MouseDown += new MouseEventHandler(tv_MouseDown);
this.KeyPress += new KeyPressEventHandler(tv_KeyPress);
base.AfterSelect += new TreeViewEventHandler(tv_AfterSelect);
}
#endregion
#region MenuSupport
private void tv_AfterSelect(object sender, TreeViewEventArgs e)
{
if (!_AdjustingTree)
OnNodeSelectionChange(sender, new vlnTreeEventArgs(e.Node));
}
// use to determine which menu items have been selected for those tree nodes
// that allow more than one type of operation associated with their selection.
public enum MenuSelections : int
{
Folder = 1, FolderBefore = 2, FolderAfter = 3, DocVersion = 4, Procedure = 5, ProcedureBefore = 6, ProcedureAfter = 7, Section = 8, SectionBefore = 9, SectionAfter = 10, Step = 11, StepBefore = 12, StepAfter = 13, StepReplace = 14
}
void tv_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
OwnerInfoList oil = null;
OwnerInfo oi = null;
FolderInfo fi = null;
// B2016-058 so we can customize the "collapse" menu item text
bool isProcNode = false;
bool isSectNode = false;
bool isFolderNode = false;
bool isWrkDftNode = false;
VETreeNode tn = this.GetNodeAt(new Point(e.X, e.Y)) as VETreeNode;
if (tn != null)
{
this.SelectedNode = tn as TreeNode;
Application.DoEvents();
// Display Menu
ToolStripMenuItem mi = new ToolStripMenuItem();
ContextMenu cm = new ContextMenu();
//_MyLog.WarnFormat("Context Menu 1 - {0}",GC.GetTotalMemory(true));
UserInfo ui = UserInfo.GetByUserID(VlnSettings.UserID);
//_MyLog.WarnFormat("Context Menu 1a - {0}", GC.GetTotalMemory(true));
if (ui == null)
{
FlexibleMessageBox.Show("Security has not been defined for PROMS. All functionality has been defaulted to the lowest level for all users until security is defined.", "no security defined", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
this.Cursor = Cursors.WaitCursor;
#region Menu_New
if (tn.VEObject as FolderInfo != null)
{
isFolderNode = true;
// For Folders, if no children, can add either docversion or folder. If children are
// folders then can only add another folder, and if children are docversions can only
// add docversion.
fi = tn.VEObject as FolderInfo;
bool DoSpecificInfo = fi.ActiveFormat.PlantFormat.FormatData.SpecificInfo;
if (ui.IsAdministrator() || ui.IsSetAdministrator(fi))// && fi.MyParent == null) //VEPROMS level
{
if (fi.HasWorkingDraft)
cm.MenuItems.Add("Export Procedure Set", new EventHandler(mi_Click));
else
cm.MenuItems.Add("Import Procedure Set", new EventHandler(mi_Click));
if (DoSpecificInfo)
cm.MenuItems.Add("Folder Specific Information", new EventHandler(mi_Click)); // C2020-008: change to 'Folder'
}
//_MyLog.WarnFormat("Context Menu 1b - {0}", GC.GetTotalMemory(true));
if (ui.IsAdministrator() || ui.IsSetAdministrator(fi))
{
if (fi.MyParent != null) // don't allow insert before/after if at top node
{
if (!ui.IsAdministrator() && DoSpecificInfo) cm.MenuItems.Add("Procedure Set Specific Information", new EventHandler(mi_Click));
// B2020-111 only allow Set Administrator to add new folders inside folders they admininstrate
if (ui.IsAdministrator()||ui.IsSetAdministrator(fi.MyParent))
{
cm.MenuItems.Add("Insert Folder Before", new EventHandler(mi_Click));
cm.MenuItems.Add("Insert Folder After", new EventHandler(mi_Click));
}
}
// B2020-111 only allow Set Administrator to add new folders inside folders they admininstrate
if ((ui.IsAdministrator() || ui.IsSetAdministrator(fi.MyParent)) && fi.FolderDocVersionCount == 0)
cm.MenuItems.Add("New Folder", new EventHandler(mi_Click));
if (fi.ChildFolderCount == 0 && !fi.HasWorkingDraft)
cm.MenuItems.Add("Create Working Draft", new EventHandler(mi_Click));
}
if (fi.HasWorkingDraft)
cm.MenuItems.Add("Print Transition Report", new EventHandler(mi_Click));
}
else if (tn.VEObject as DocVersionInfo != null) // DocVersions can only contain procs
{
isWrkDftNode = true;
//_MyLog.WarnFormat("Context Menu 1c - {0}", GC.GetTotalMemory(true));
DocVersionInfo dvi = tn.VEObject as DocVersionInfo;
if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi))
{
cm.MenuItems.Add("Import Procedure", mi_Click);
}
if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi) || ui.IsWriter(dvi))
{
OwnerInfoList.Reset();
oil = OwnerInfoList.GetByVersionID(dvi.VersionID);
if (dvi.ActiveFormat.PlantFormat.FormatData.SpecificInfo)
cm.MenuItems.Add("Procedure Set Specific Information", new EventHandler(mi_Click));
cm.MenuItems.Add("Refresh Checked Out Procedures", new EventHandler(mi_Click));
cm.MenuItems.Add("New Procedure", new EventHandler(mi_Click));
if (dvi.MultiUnitCount > 1)
{
MenuItem mip = new MenuItem("Print All Procedures for");
MenuItem mia = new MenuItem("Approve All Procedures for");
MenuItem mis = new MenuItem("Approve Some Procedures for");
int k = 0;
foreach (string s in dvi.UnitNames)
{
k++;
MenuItem mp = mip.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mp.Tag = k;
MenuItem ma = mia.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
ma.Tag = k;
MenuItem ms = mis.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
ms.Tag = k;
}
//MenuItem mmp = mip.MenuItems.Add("All Units", new EventHandler(miMultiUnit_Click));
//mmp.Tag = 0;
//MenuItem mma = mia.MenuItems.Add("All Units", new EventHandler(miMultiUnit_Click));
//mma.Tag = 0;
//MenuItem mms = mis.MenuItems.Add("All Units", new EventHandler(miMultiUnit_Click));
//mms.Tag = 0;
cm.MenuItems.Add(mip);
cm.MenuItems.Add(mia);
cm.MenuItems.Add(mis);
}
else
{
//_MyLog.WarnFormat("Context Menu 1d - {0}", GC.GetTotalMemory(true));
cm.MenuItems.Add("Print All Procedures", new EventHandler(mi_Click));
cm.MenuItems.Add("Approve All Procedures", new EventHandler(mi_Click));
cm.MenuItems.Add("Approve Some Procedures", new EventHandler(mi_Click));
}
cm.MenuItems.Add("Report All Procedures Inconsistencies", new EventHandler(mi_Click));
}
else
{
//_MyLog.WarnFormat("Context Menu 1e - {0}", GC.GetTotalMemory(true));
OwnerInfoList.Reset();
oil = OwnerInfoList.GetByVersionID(dvi.VersionID);
cm.MenuItems.Add("Refresh Checked Out Procedures", new EventHandler(mi_Click));
if (dvi.MultiUnitCount > 1)
{
MenuItem mip = new MenuItem("Print All Procedures for");
int k = 0;
foreach (string s in dvi.UnitNames)
{
k++;
MenuItem mp = mip.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mp.Tag = k;
}
//MenuItem mmp = mip.MenuItems.Add("All Units", new EventHandler(miMultiUnit_Click));
//mmp.Tag = 0;
//MenuItem mma = mia.MenuItems.Add("All Units", new EventHandler(miMultiUnit_Click));
//mma.Tag = 0;
//MenuItem mms = mis.MenuItems.Add("All Units", new EventHandler(miMultiUnit_Click));
//mms.Tag = 0;
cm.MenuItems.Add(mip);
}
else
{
//_MyLog.WarnFormat("Context Menu 1f - {0}", GC.GetTotalMemory(true));
cm.MenuItems.Add("Print All Procedures", new EventHandler(mi_Click));
}
}
//if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi))
//{
// cm.MenuItems.Add("Check Out Procedure Set", new EventHandler(mi_Click));
// cm.MenuItems.Add("Check In Procedure Set", new EventHandler(mi_Click));
//}
if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi) || ui.IsROEditor(dvi))
{
//_MyLog.WarnFormat("Context Menu 1g - {0}", GC.GetTotalMemory(true));
cm.MenuItems.Add("Run RO Editor", new EventHandler(mi_Click));
}
if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi))
{
//_MyLog.WarnFormat("Context Menu 1h - {0}", GC.GetTotalMemory(true));
MenuItem urv = cm.MenuItems.Add("Update RO Values", new EventHandler(mi_Click));
// only allow update if association, and the RO update was not done and/or not completed
urv.Enabled = !dvi.ROfstLastCompleted || dvi.NewerRoFst;
}
}
else if (tn.VEObject as ProcedureInfo != null) // Procs can only contain sections
{
isProcNode = true;
ProcedureInfo pri = tn.VEObject as ProcedureInfo;
oi = OwnerInfo.GetByItemID(pri.ItemID, CheckOutType.Procedure);
if (ui.IsAdministrator() || ui.IsSetAdministrator(pri.MyDocVersion))
{
cm.MenuItems.Add("Export Procedure", mi_Click);
}
if (ui.IsAdministrator() || ui.IsSetAdministrator(pri.MyDocVersion) || ui.IsWriter(pri.MyDocVersion))
{
if (oi != null && oi.SessionID != MySessionInfo.SessionID)
cm.MenuItems.Add(string.Format("Procedure Checked Out to {0}", oi.SessionUserID), new EventHandler(mi_Click));
if (pri.ActiveFormat.PlantFormat.FormatData.ProcData.PSI.Caption != null) cm.MenuItems.Add("Procedure Specific Information", new EventHandler(mi_Click));
cm.MenuItems.Add("Insert Procedure Before", new EventHandler(mi_Click));
cm.MenuItems.Add("Insert Procedure After", new EventHandler(mi_Click));
// if this format has change ids that were added from edit, allow removal of
// change ids for this procedure:
//FolderInfo fi = FolderInfo.Get(1);
//FormatInfo frmI = FormatInfo.Get(fi.FormatID ?? 1);
//if (frmI.PlantFormat.FormatData.ProcData.ChangeBarData.ChgBarMessageFromEdit)
// cm.MenuItems.Add("Remove Change Ids", new EventHandler(mi_Click));
cm.MenuItems.Add("New Section", new EventHandler(mi_Click));
if (pri.MyDocVersion.MultiUnitCount > 1)
{
MenuItem micas = new MenuItem("Create Continuous Action Summary");
MenuItem mitcas = new MenuItem("Create Time Critical Action Summary"); //F2022-024 added menu option
MenuItem mip = new MenuItem("Print");
MenuItem miqp = new MenuItem("Quick Print");
//MenuItem mips = new MenuItem("Print Section");
MenuItem mia = new MenuItem("Approve");
int k = 0;
foreach (string s in pri.MyDocVersion.UnitNames)
{
// C2021-027: Procedure level PC/PC - see if menu items for unit should be enabled
bool procAppl = pri.ApplIncludeFromStr(s);
k++;
MenuItem mp = mip.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mp.Enabled = procAppl;
mp.Tag = k;
MenuItem mqp = miqp.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mqp.Enabled = procAppl;
mqp.Tag = k;
//MenuItem mps = mips.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
//mps.Enabled = procAppl;
//mps.Tag = k;
MenuItem ma = mia.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
ma.Enabled = procAppl;
ma.Tag = k;
MenuItem mc = micas.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mc.Enabled = procAppl;
mc.Tag = k;
MenuItem mtc = mitcas.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mtc.Enabled = procAppl;
mtc.Tag = k;
}
cm.MenuItems.Add(micas);
cm.MenuItems.Add(mitcas);
cm.MenuItems.Add(mip);
cm.MenuItems.Add(miqp);
//cm.MenuItems.Add(mips);
AddShowChangeBarsAfterMenuItem(cm.MenuItems, pri);
cm.MenuItems.Add(mia);
AddApprovedRevisionsMultiUnit(cm.MenuItems, pri);
}
else
{
cm.MenuItems.Add("Create Continuous Action Summary", new EventHandler(mi_Click));
cm.MenuItems.Add("Create Time Critical Action Summary", new EventHandler(mi_Click));
cm.MenuItems.Add("Print", new EventHandler(mi_Click));
cm.MenuItems.Add("Quick Print", new EventHandler(mi_Click));
//cm.MenuItems.Add("Print Section", new EventHandler(mi_Click));
//MenuItem miqp = new MenuItem("Print");
AddShowChangeBarsAfterMenuItem(cm.MenuItems, pri);
cm.MenuItems.Add("Approve", new EventHandler(mi_Click));
//_MyLog.WarnFormat("Context Menu 1 before - {0}", GC.GetTotalMemory(true));
AddApprovedRevisions(cm.MenuItems, pri);
//_MyLog.WarnFormat("Context Menu 1 after - {0}", GC.GetTotalMemory(true));
}
}
else
{
if (oi != null && oi.SessionID != MySessionInfo.SessionID)
cm.MenuItems.Add(string.Format("Procedure Checked Out to {0}", oi.SessionUserID), new EventHandler(mi_Click));
if (pri.MyDocVersion.MultiUnitCount > 1)
{
MenuItem mip = new MenuItem("Print");
MenuItem miqp = new MenuItem("Quick Print");
int k = 0;
foreach (string s in pri.MyDocVersion.UnitNames)
{
k++;
MenuItem mp = mip.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mp.Tag = k;
MenuItem mqp = miqp.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mqp.Tag = k;
}
cm.MenuItems.Add(mip);
cm.MenuItems.Add(miqp);
AddApprovedRevisionsMultiUnit(cm.MenuItems, pri);
}
else
{
cm.MenuItems.Add("Print", new EventHandler(mi_Click));
cm.MenuItems.Add("Quick Print", new EventHandler(mi_Click));
AddApprovedRevisions(cm.MenuItems, pri);
}
}
cm.MenuItems.Add("Print Transition Report", new EventHandler(mi_Click));
}
else if (tn.VEObject as SectionInfo != null)
{
isSectNode = true;
// A step Section can contain other steps or can contain subsections (either step section
// or word doc section). Also note that there can be a mix.
// A word doc section can contain another subsection (either step section or word doc section),
// but cannot contain steps.
SectionInfo si = tn.VEObject as SectionInfo;
// if this is an enhanced section, don't do 'New Step'
if (ui.IsAdministrator() || ui.IsSetAdministrator(si.MyProcedure.MyDocVersion) || ui.IsWriter(si.MyProcedure.MyDocVersion))
{
if (si.HasWordContent)
{
oi = OwnerInfo.GetByItemID(si.MyContent.MyEntry.DocID, CheckOutType.Document);
}
si.MyConfig = null;
// Do not need step versus Word doc options, user enters this in property page during
// insert process.
if (oi != null && oi.SessionID != MySessionInfo.SessionID)
cm.MenuItems.Add(string.Format("Document Checked Out to {0}", oi.SessionUserID), new EventHandler(mi_Click));
cm.MenuItems.Add("Insert Section Before", new EventHandler(mi_Click));
cm.MenuItems.Add("Insert Section After", new EventHandler(mi_Click));
if (!si.IsAutoTOCSection && si.IsStepSection) // B2016-282: Don't allow insert of subsections off Word Section.
{
bool meta = si.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections;
if (meta) cm.MenuItems.Add("New Subsection", new EventHandler(mi_Click));
// if this section has subsections, then be sure that the 'editable' data config
// is set to allow new step creation.
if (si.IsStepSection)
{
SectionConfig sc = si.MyConfig as SectionConfig;
if (!si.IsEnhancedSection && (si.Sections == null || si.Sections.Count == 0 || (meta && sc != null && si.Sections != null && si.Sections.Count > 0 && sc.SubSection_Edit == "Y")))
cm.MenuItems.Add("New Step", new EventHandler(mi_Click));
//ProcedureInfo pri = tn as SectionInfo;
SectionInfo si2 = (tn as VETreeNode).VEObject as SectionInfo;
if (si2.MyDocVersion.MultiUnitCount > 1)
{
MenuItem mps = new MenuItem("Print Section");
int k = 0;
foreach (string s in si2.MyDocVersion.UnitNames)
{
k++;
MenuItem mp = mps.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
mp.Tag = k;
}
cm.MenuItems.Add(mps);
}
else
{
cm.MenuItems.Add("Print Section", new EventHandler(mi_Click));
}
}
}
}
}
else if (tn.VEObject as StepInfo != null)
{
// check the format for allowable inserts, and also,
ItemInfo i = tn.VEObject as ItemInfo;
if (ui.IsAdministrator() || ui.IsSetAdministrator(i.MyProcedure.MyDocVersion) || ui.IsWriter(i.MyProcedure.MyDocVersion))
{
//oi = OwnerInfo.GetByItemID(i.MyProcedure.ItemID);
if (AddToInsertMenu(i, 0)) cm.MenuItems.Add("Insert Step Before", new EventHandler(mi_Click));
if (AddToInsertMenu(i, 1)) cm.MenuItems.Add("Insert Step After", new EventHandler(mi_Click));
}
}
#endregion
//_MyLog.WarnFormat("Context Menu 2 - {0}", GC.GetTotalMemory(true));
//#region Print_Section
//if (!tn.IsExpanded && tn.VEObject as SectionInfo != null)
//{
// SectionInfo si = tn.VEObject as SectionInfo;
// if (si.IsStepSection) cm.MenuItems.Add("Print Section", new EventHandler(mi_Click));
//}
//#endregion
#region Menu_Open
if (!tn.IsExpanded && tn.VEObject as SectionInfo != null)
{
SectionInfo si = tn.VEObject as SectionInfo;
if (si.IsStepSection) cm.MenuItems.Add("Open", new EventHandler(mi_Click));
}
else if (!tn.IsExpanded && tn.VEObject as StepInfo != null)
{
StepInfo stpi = tn.VEObject as StepInfo;
if (stpi.HasChildren) cm.MenuItems.Add("Open", new EventHandler(mi_Click));
}
else if (!tn.IsExpanded)
cm.MenuItems.Add("Open", new EventHandler(mi_Click));
else
{ // B2016-058 customize the "Collapse" menu text based on tree node type
string mtext = "Collapse"; // only the step or substep (RNOs, Cautions, Notes as well) will be collapsed
if (isFolderNode || isWrkDftNode)
mtext += " All Procedures"; // all expanded procedure nodes in all procedure sets are collapsed (folder and working draft nodes remain expanded)
else if (isProcNode)
mtext += " Procedure"; // only the current procedure node is collapsed
else if (isSectNode)
mtext += " Section"; // only the current section node is collapsed
cm.MenuItems.Add(mtext, new EventHandler(mi_Click));
}
#endregion
//_MyLog.WarnFormat("Context Menu 3 - {0}", GC.GetTotalMemory(true));
#region Menu_CutCopy
// For initial release, copy is not available for folders or docversions
if (tn.VEObject as ItemInfo != null)
{
ItemInfo i = tn.VEObject as ItemInfo;
// in the following, 'Copy' is not allowed for any procedure/section/step that is enhanced. Note that this may be
// changed later, but for the initial enhanced development it was decided to not allow copy of enhanced since paste would
// require clearing of all enhanced config data or mapping it to existing data (quite complicated)
if ((ui.IsAdministrator() || ui.IsSetAdministrator(i.MyProcedure.MyDocVersion) || ui.IsWriter(i.MyProcedure.MyDocVersion)) && (!i.IsEnhancedStep && !i.IsEnhancedProcedure && !i.IsEnhancedSection && !i.IsRtfRaw && !i.IsFigure))
cm.MenuItems.Add("Copy", new EventHandler(mi_Click));
if (i.HasWordContent)
{
cm.MenuItems.Add("Print Section", new EventHandler(mi_Click));
}
}
#endregion
//_MyLog.WarnFormat("Context Menu 4 - {0}", GC.GetTotalMemory(true));
#region Menu_Paste
bool ok = false;
if (tn.VEObject is FolderInfo && (ui.IsAdministrator() || ui.IsSetAdministrator(tn.VEObject as FolderInfo)))
ok = true;
else if (tn.VEObject is DocVersionInfo && (ui.IsAdministrator() || ui.IsSetAdministrator(tn.VEObject as DocVersionInfo)))
ok = true;
else if (tn.VEObject is ItemInfo && (ui.IsAdministrator() || ui.IsSetAdministrator((tn.VEObject as ItemInfo).MyProcedure.MyDocVersion) || ui.IsWriter((tn.VEObject as ItemInfo).MyProcedure.MyDocVersion)))
ok = true;
if(ok)
Menu_Paste(tn, cm);
#endregion
//_MyLog.WarnFormat("Context Menu 5 - {0}", GC.GetTotalMemory(true));
#region Menu_Delete
if (ok)
{
// Add delete to the menu unless at the very 'top' node, on a grouping (partinfo)
// node (RNOs, Steps, Cautions, Notes) or Folder/DocVersion that contains any items.
PartInfo pi = tn.VEObject as PartInfo;
if (pi == null && tn.Parent != null) // it's not a part and it's not the top....
{
fi = tn.VEObject as FolderInfo;
if (fi == null || tn.Nodes.Count == 0) // it's not a folder or it has no children
{
DocVersionInfo di = tn.VEObject as DocVersionInfo;
if (di == null || tn.Nodes.Count == 0) // it's not a docversion or it has no children
{
// if it's an enhanced step that was linked from a source, don't allow delete
bool canDoDel = true;
ItemInfo iienh = tn.VEObject as ItemInfo;
if (iienh != null && iienh.IsProcedure && iienh.IsEnhancedProcedure) canDoDel = false;
if (iienh != null && iienh.IsSection && iienh.IsEnhancedSection && !iienh.IsEnhancedSectionTitleOnly) canDoDel = false;
if (iienh != null && iienh.IsEnhancedStep) canDoDel = false;
if (canDoDel) cm.MenuItems.Add("Delete", new EventHandler(mi_Click));
}
}
}
}
#endregion
//_MyLog.WarnFormat("Context Menu 6 - {0}", GC.GetTotalMemory(true));
#region Menu_ExternalTransitions
// C2020-033: Support the menu item to bring up Search/Incoming Transitions panel
ItemInfo iix = tn.VEObject as ItemInfo;
if (iix != null)
{
cm.MenuItems.Add("Incoming Transitions", new EventHandler(mi_Click));
}
#endregion
#region Menu_UnLinkEnhanced
// B2022-049: provide for way to unlink a procedure from the tree view. Also unlinks procedure if no
// connected (linked) procedure.
if (tn.VEObject is ProcedureInfo)
{
ItemInfo prc = (ItemInfo)tn.VEObject;
if (ui.IsAdministrator() || ui.IsSetAdministrator(prc.MyDocVersion) || ui.IsWriter(prc.MyDocVersion))
{
DVEnhancedDocuments dveds = prc.MyDocVersion.DocVersionConfig.MyEnhancedDocuments;
EnhancedDocuments eds = prc.GetMyEnhancedDocuments();
// if just one link, add single menu item to unlink. If more than one, need a list with all.
if (eds != null && eds.Count == 1)
{
// Get menu string, must start with 'Unlink Source '
string doclink = null;
doclink = dveds.GetByType(eds[0].Type).Name; // need background/dev if on source
if (eds[0].Type == 0)
{
ItemInfo prl = ItemInfo.Get(eds[0].ItemID);
DVEnhancedDocuments dvedsl = prl.MyDocVersion.DocVersionConfig.MyEnhancedDocuments;
foreach (DVEnhancedDocument dvel in dvedsl) if (dvel.VersionID == prc.MyDocVersion.VersionID) doclink = dvel.Name;
}
doclink = string.Format("Unlink Source and {0} Procedure", doclink);
MenuItem mix = cm.MenuItems.Add(doclink, new EventHandler(miEnhanced_Click));
mix.Tag = -1; // NOTE this is what flags what gets processed on menu click, i.e. -1
}
// if this is a source procedure that has enhanced, for example Background and/or deviation, ask which should be unlinked including all
else if (eds != null && eds.Count > 1)
{
MenuItem miu = new MenuItem("Unlink Enhanced Procedure(s) from Source");
miu.Tag = -2; // this menu item doesn't get used.
int k = 0;
foreach (EnhancedDocument ed in eds)
{
// add submenu item for it
k++;
MenuItem mp = miu.MenuItems.Add(dveds.GetByType(ed.Type).Name, new EventHandler(miEnhanced_Click));
mp.Tag = k;
}
// add all submenu item
MenuItem mp1 = miu.MenuItems.Add("All", new EventHandler(miEnhanced_Click));
mp1.Tag = 0; // Tag of 0 flags All
cm.MenuItems.Add(miu);
}
}
}
#endregion
#region Menu_Properties
// Add Properties to the menu unless at the very 'top' node or on a grouping (partinfo)
// node (RNOs, Steps, Cautions, Notes) or at the step level.
// B2020-105 Allow Set Administrators to rename folder's (sets of procedures) to which they have been given access.
if ( tn.VEObject is FolderInfo) ok = (ui.IsAdministrator() || ui.IsSetAdministrator(tn.VEObject as FolderInfo));
else ok = (tn.VEObject is DocVersionInfo) ? (ui.IsAdministrator() || ui.IsSetAdministrator(tn.VEObject as DocVersionInfo))
: (ui.IsAdministrator() || (tn.VEObject is ItemInfo) && (ui.IsSetAdministrator((tn.VEObject as ItemInfo).MyProcedure.MyDocVersion)
|| ui.IsWriter((tn.VEObject as ItemInfo).MyProcedure.MyDocVersion)));
PartInfo pia = tn.VEObject as PartInfo;
ItemInfo ii = tn.VEObject as ItemInfo;
if (ok)
if (pia == null && tn.VEObject as StepInfo == null) cm.MenuItems.Add("Properties...", new EventHandler(mi_Click));
#endregion
//_MyLog.WarnFormat("Context Menu 7 - {0}", GC.GetTotalMemory(true));
if (fi != null && fi.HasWorkingDraft)
{
/*
--Folder level
see if we need to disable "Export Procedure Set" or "Folder Specific Information"
*/
if (tn.MovedToSeparateWindow)
{
foreach (MenuItem itm in cm.MenuItems)
{
if (!itm.Text.StartsWith("Insert")) // C2015-022 only enable insert folder before/after if in the main window and the procedures of this folder are in a child window
itm.Enabled = false;
}
}
else if (tn.InChildWindow)
{
foreach (MenuItem itm in cm.MenuItems)
{
if (itm.Text.StartsWith("Insert")) // C2015-022 disable insert folder before/after if doing a properties on a folder in a child window
itm.Enabled = false;
}
}
else
{
if (!tn.ChildrenLoaded) tn.LoadChildren();
VETreeNode wrkdrft = (VETreeNode)tn.LastNode;
DocVersionInfo docver = wrkdrft.VEObject as DocVersionInfo;
OwnerInfoList.Reset();
oil = OwnerInfoList.GetByVersionID(docver.VersionID);
bool greyOut = false;
foreach (OwnerInfo own in oil)
{
if (own.SessionID != MySessionInfo.SessionID)
{
greyOut = true;
break;
}
}
if (greyOut)
{
foreach (MenuItem itm in cm.MenuItems)
{
if (itm.Text == "Export Procedure Set" || itm.Text == "Folder Specific Information") // C2020-008: change to 'Folder'
itm.Enabled = false;
}
}
}
}
if (oil != null && oil.Count > 0 && tn.VEObject as DocVersionInfo != null)
{
/*
--docversion level
Approve All Procedures
Report All Procedures Inconsistencies
*/
bool greyOut = false;
foreach (OwnerInfo own in oil)
{
if (own.SessionID != MySessionInfo.SessionID)
{
greyOut = true;
break;
}
}
if (greyOut)
{
foreach (MenuItem itm in cm.MenuItems)
{
if (itm.Text == "Approve All Procedures" || itm.Text == "Report All Procedures Inconsistencies" ||
itm.Text == "Procedure Set Specific Information" || itm.Text == "Approve All Procedures for" ||
itm.Text == "Approve Some Procedures" || itm.Text == "Approve Some Procedures for")
itm.Enabled = false;
}
}
}
if (oi != null && oi.SessionID != MySessionInfo.SessionID)
{
/*
--procedure level
Procedure Specific Information
New Section
Approve
Open
Copy
Delete
Properties...
--section level
all of them
--step level
all of them
*/
//_MyLog.WarnFormat("Context Menu 8 - {0}", GC.GetTotalMemory(true));
if (tn.VEObject as ProcedureInfo != null)
{
// F2022-024 added Time Critical Action Summary option
foreach (MenuItem itm in cm.MenuItems)
{
if(itm.Text == "Procedure Specific Information" || itm.Text == "New Section" || itm.Text == "Approve" || itm.Text == "Open" ||
itm.Text == "Copy" || itm.Text == "Delete" || itm.Text == "Properties..." || itm.Text == "Replace Existing Procedure" ||
itm.Text.StartsWith("Showing Change Bars Starting") || itm.Text == "Create Continuous Action Summary" ||
itm.Text == "Create Time Critical Action Summary" || itm.Text == "Export Procedure")
itm.Enabled = false;
}
}
if (tn.VEObject as SectionInfo != null || tn.VEObject as StepInfo != null)
{
foreach (MenuItem itm in cm.MenuItems)
{
if(!itm.Text.StartsWith("Document Checked Out"))
itm.Enabled = false;
}
}
}
this.Cursor = Cursors.Default;
//_MyLog.WarnFormat("Context Menu 9 - {0}", GC.GetTotalMemory(true));
cm.Show(this, new Point(e.X, e.Y));
}
}
}
private void AddApprovedRevisionsMultiUnit(Menu.MenuItemCollection menuItemCollection, ProcedureInfo pri)
{
_currentPri = pri;
RevisionInfoList ril = RevisionInfoList.GetByItemID(pri.ItemID);
if (ril.Count == 0) return; // no versions to list
MenuItem mi = menuItemCollection.Add("Versions");
int k = 0;
int lastApprovedRevisionID = 0;
foreach (string s in pri.MyDocVersion.UnitNames)
{
k++;
MenuItem mv = mi.MenuItems.Add(s);
mv.Tag = k;
ril = RevisionInfoList.GetByItemIDandUnitID(pri.ItemID, k);
foreach (RevisionInfo ri in ril)
{
MenuItem mir = mv.MenuItems.Add(ri.ToString());
mir.Tag = ri;
if (ri.LatestVersion.MyStage.IsApproved > 0 && (ri.RevisionID > lastApprovedRevisionID))
lastApprovedRevisionID = ri.RevisionID;
if (ri.Notes.Length > 0) //C2018-026 add the ability to show notes entered during approval or workflow stage in the sub-menu
{
MenuItem mirp = mir.MenuItems.Add("View Revision Stage Notes");
mirp.Tag = ri;
mirp.Click += new EventHandler(ViewRevisonStageNotes_Click);
}
if (ri.LatestVersion.PDF != null)
{
MenuItem mirp = mir.MenuItems.Add("View Procedure");
mirp.Tag = ri;
mirp.Click += new EventHandler(MultiUnitApprovedRevision_Click);
}
if (ri.LatestVersion.SummaryPDF != null)
{
MenuItem mirs = mir.MenuItems.Add("View Summary of Changes");
mirs.Tag = ri;
mirs.Click += new EventHandler(MultiUnitSummaryOfChanges_Click);
}
if (ri.LatestVersion.ApprovedXML != null && ri.LatestVersion.ApprovedXML != "")
{
MenuItem miri = mir.MenuItems.Add("Create Procedure to Import");
miri.Tag = ri;
miri.Click += new EventHandler(ImportProcedure_Click);
}
//end added jcb 20111031
mv.Tag = lastApprovedRevisionID;
}
}
}
public void AddNewNode(IVEDrillDownReadOnly o)
{
VETreeNode tn = new VETreeNode(o);
SelectedNode.Nodes.Add(tn);
}
private void AddApprovedRevisions(Menu.MenuItemCollection menuItemCollection, ProcedureInfo pri)
{
try
{
//_MyLog.WarnFormat("Context Menu 1 before GET - {0}", GC.GetTotalMemory(true));
_currentPri = pri;
using (RevisionInfoList ril = RevisionInfoList.GetByItemID(pri.ItemID))
{
//_MyLog.WarnFormat("Context Menu 1 After GET - {0}", GC.GetTotalMemory(true));
if (ril.Count == 0) return; // no versions to list
MenuItem mi = menuItemCollection.Add("Versions");
int lastApprovedRevisionID = 0;
foreach (RevisionInfo ri in ril)
{
MenuItem mir = mi.MenuItems.Add(ri.ToString());
mir.Tag = ri;
bool addImportMI = false;
if (ri.LatestVersion.MyStage.IsApproved > 0 && (ri.RevisionID > lastApprovedRevisionID))
{
lastApprovedRevisionID = ri.RevisionID;
addImportMI = true;
}
//mir.Click += new EventHandler(ApprovedRevision_Click);
//added jcb 20111031
//_MyLog.WarnFormat("Context Menu 1 b4ViewProc- {0}", GC.GetTotalMemory(true));
if (ri.Notes.Length > 0) //C2018-026 add the ability to show notes entered during approval or workflow stage in the sub-menu
{
MenuItem mirp = mir.MenuItems.Add("View Revision Stage Notes");
mirp.Tag = ri;
mirp.Click += new EventHandler(ViewRevisonStageNotes_Click);
}
if (ri.LatestVersion.PDF != null)
{
MenuItem mirp = mir.MenuItems.Add("View Procedure");
mirp.Tag = ri;
mirp.Click += new EventHandler(ApprovedRevision_Click);
}
//_MyLog.WarnFormat("Context Menu 1 b4viewSum- {0}", GC.GetTotalMemory(true));
if (ri.LatestVersion.SummaryPDF != null)
{
MenuItem mirs = mir.MenuItems.Add("View Summary of Changes");
mirs.Tag = ri;
mirs.Click += new EventHandler(SummaryOfChanges_Click);
}
//_MyLog.WarnFormat("Context Menu 1 b4 import - {0}", GC.GetTotalMemory(true));
if (addImportMI && ri.LatestVersion.ApprovedXML != null && ri.LatestVersion.ApprovedXML != "")
{
MenuItem miri = mir.MenuItems.Add("Create Procedure to Import");
miri.Tag = ri;
miri.Click += new EventHandler(ImportProcedure_Click);
}
//_MyLog.WarnFormat("Context Menu 1 after import- {0}", GC.GetTotalMemory(true));
//end added jcb 20111031
mi.Tag = lastApprovedRevisionID;
}
}
}
catch
{
return;
}
}
private void AddShowChangeBarsAfterMenuItem(Menu.MenuItemCollection menuItemCollection, ProcedureInfo pri)
{
using (RevisionInfoList ril = RevisionInfoList.GetByItemID(pri.ItemID))
{
if (ril.Count == 0 || MyUserInfo.IsAdministrator() || MyUserInfo.IsSetAdministrator(pri.MyDocVersion))
{
ProcedureConfig pc = pri.MyConfig as ProcedureConfig;
string currentChgBarDateTime = "";
if (pc != null)
currentChgBarDateTime = pc.Print_ChangeBarDate; // Current change bar date time before
if (currentChgBarDateTime == "")
currentChgBarDateTime = "(date not set)";
else
currentChgBarDateTime = currentChgBarDateTime.Split(' ')[0]; // only show the date not the time
menuItemCollection.Add(string.Format("Showing Change Bars Starting {0}", currentChgBarDateTime), new EventHandler(mi_Click));
}
}
}
void ImportProcedure_Click(object sender, EventArgs e)
{
RevisionInfo ri = (sender as MenuItem).Tag as RevisionInfo;
RevisionConfig rc = ri.MyConfig as RevisionConfig;
// bug fix: B2016-183 - add the child's name (ex Unit 1) to the export file name for Parent/Child procedures.
int applIdx = rc.Applicability_Index;
string str = (applIdx > 0)?_currentPri.MyDocVersion.UnitNames[applIdx-1] +"_":""; // if parent/child get the defined child name to inlcude the export filename
System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
xd.LoadXml(ri.LatestVersion.ApprovedXML);
string PEIPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\VEPROMS\PEI_" + Database.VEPROMS_SqlConnection.Database;
DirectoryInfo di = new DirectoryInfo(PEIPath);
if (!di.Exists) di.Create();
// B2022-048: Crash when creating Procedure to Import from versions. Couldn't handle '/' in proc number.
string fNametmp = xd.SelectSingleNode("procedure/content/@number").InnerText.Replace(" ", "_").Replace(@"\u8209?", "-").Replace(@"\u9586?", "_").Replace("/", "-") + ".pxml";
// B2022-112: If applicability, need to resolve the '<' and '>' characters. Just use the UnitNames, i.e. str, from above.
if (applIdx > 0) fNametmp = Regex.Replace(fNametmp, @"\<U-ID\>", str, RegexOptions.IgnoreCase);
string fileName = PEIPath + "\\" + str + "Approved_Rev_" + ri.RevisionNumber.Replace(" ", "_").Replace("\\", "-").Replace("/", "-") + "_" + fNametmp;
xd.Save(fileName);
FlexibleMessageBox.Show("Approved procedure saved to import file " + fileName, "Creating Export of Approved Procedure", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
void ApprovedRevision_Click(object sender, EventArgs e)
{
bool superceded = false;
MenuItem mi = sender as MenuItem;
if (mi == null) return;
RevisionInfo ri = mi.Tag as RevisionInfo;
{
MenuItem mip = mi.Parent as MenuItem;
//B2021-086 Added the check for the last revision stage is an Approved stage
if ((ri.RevisionID < int.Parse(mip.Parent.Tag.ToString())) && ri.LatestVersion.MyStage.IsApproved!=0)
superceded = true;
}
vlnTreeViewPdfArgs args = new vlnTreeViewPdfArgs(Volian.Base.Library.TmpFile.CreateFileName(ProcedureInfo.Get(ri.ItemID).PDFNumber), ri.LatestVersion.PDF, superceded ? "Superceded" : "");
OnViewPDF(sender, args);
// System.Diagnostics.Process pp = System.Diagnostics.Process.Start(GetDocPdf(ri, superceded));
}
void MultiUnitApprovedRevision_Click(object sender, EventArgs e)
{
bool superceded = false;
MenuItem mi = sender as MenuItem;
if (mi == null) return;
RevisionInfo ri = mi.Tag as RevisionInfo;
{
MenuItem mip = mi.Parent as MenuItem;
//B2021-086 Added the check for the last revision stage is an Approved stage
if ((ri.RevisionID < int.Parse(mip.Parent.Tag.ToString())) && ri.LatestVersion.MyStage.IsApproved != 0)
superceded = true;
}
ItemInfo ii = ItemInfo.Get(ri.ItemID);
ii.MyDocVersion.DocVersionConfig.SelectedSlave = ri.MyConfig.Applicability_Index;
vlnTreeViewPdfArgs args = new vlnTreeViewPdfArgs(Volian.Base.Library.TmpFile.CreateFileName(ProcedureInfo.Get(ri.ItemID).PDFNumber), ri.LatestVersion.PDF, superceded ? "Superceded" : "");
OnViewPDF(sender, args);
// System.Diagnostics.Process pp = System.Diagnostics.Process.Start(GetDocPdf(ri, superceded));
}
void SummaryOfChanges_Click(object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi == null) return;
RevisionInfo ri = mi.Tag as RevisionInfo;
vlnTreeViewPdfArgs args = new vlnTreeViewPdfArgs(Volian.Base.Library.TmpFile.CreateFileName(ProcedureInfo.Get(ri.ItemID).PDFNumber + " Summary of Changes"), ri.LatestVersion.SummaryPDF, "");
OnViewPDF(sender, args);
// System.Diagnostics.Process pps = System.Diagnostics.Process.Start(GetDocSummaryPdf(ri));
}
void MultiUnitSummaryOfChanges_Click(object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi == null) return;
RevisionInfo ri = mi.Tag as RevisionInfo;
ItemInfo ii = ItemInfo.Get(ri.ItemID);
ii.MyDocVersion.DocVersionConfig.SelectedSlave = ri.MyConfig.Applicability_Index;
vlnTreeViewPdfArgs args = new vlnTreeViewPdfArgs(Volian.Base.Library.TmpFile.CreateFileName(ProcedureInfo.Get(ri.ItemID).PDFNumber + " Summary of Changes"), ri.LatestVersion.SummaryPDF, "");
OnViewPDF(sender, args);
// System.Diagnostics.Process pps = System.Diagnostics.Process.Start(GetDocSummaryPdf(ri));
}
//C2018-026 show notes entered during approval or workflow stage
private void ViewRevisonStageNotes_Click(object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi == null) return;
RevisionInfo ri = mi.Tag as RevisionInfo;
FlexibleMessageBox.Show(ri.Notes, "Revison Stage Notes", MessageBoxButtons.OK);
}
//private string GetDocPdf(RevisionInfo ri, bool superceded)
//{
// string fileName = Volian.Base.Library.TmpFile.CreateFileName(ItemInfo.Get(ri.ItemID).DisplayNumber);
// FileInfo fi = new FileInfo(VlnSettings.TemporaryFolder + @"\" + fileName);
// FileStream fs = fi.Create();
// byte[] myPdf = ri.LatestVersion.PDF;
// if (myPdf != null) fs.Write(myPdf, 0, myPdf.Length);
// fs.Close();
// if (superceded)
// AddSupercededWatermark(VlnSettings.TemporaryFolder + @"\" + fileName);
// return VlnSettings.TemporaryFolder + @"\" + fileName;
//}
//private void AddSupercededWatermark(string p)
//{
// MessageBox.Show("superceded");
//}
//private string GetDocSummaryPdf(RevisionInfo ri)
//{
// string fileName = Volian.Base.Library.TmpFile.CreateFileName(ItemInfo.Get(ri.ItemID).DisplayNumber + " Summary of Changes");
// FileInfo fi = new FileInfo(VlnSettings.TemporaryFolder + @"\" + fileName);
// FileStream fs = fi.Create();
// byte[] myPdf = ri.LatestVersion.SummaryPDF;
// if (myPdf != null) fs.Write(myPdf, 0, myPdf.Length);
// fs.Close();
// return VlnSettings.TemporaryFolder + @"\" + fileName;
//}
private bool AddToInsertMenu(ItemInfo ii, int ba) // 0 = before, 1 = after
{
// set up insert buttons based on format
bool retB = true;
E_AccStep? actable = 0;
StepData sd = ii.FormatStepData;
if (sd != null) actable = sd.StepEditData.AcTable;
if (actable == null) actable = 0;
return (ba == 0) ? !ii.IsRNOPart && (actable & E_AccStep.AddingPrev) > 0 :
!ii.IsRNOPart && (actable & E_AccStep.AddingNext) > 0;
}
private void Menu_Paste(VETreeNode tn, ContextMenu cm)
{
#region Menu_Paste method
// Find what's in paste buffer & determine whether the paste can occur for the selected node.
ItemInfo iiClipboard = OnClipboardStatus(this, new vlnTreeEventArgs(tn));
if (iiClipboard != null)
{
// can it be pasted at current node.
// for now (Jan 2016 - initial implementation of enhanced document support) do NOT paste
// any items that have enhanced data associated with it unless pasting within an enhanced source item.
// The reason is that code would need to handle clearing/setting the pasted enhanced config which
// becomes very complicated.
// For all enhanced comments in code use the following:
// 'source' is Procedures, for example EOP procedures (that has config's myenhanceddocuments pointing to enhanced, i.e. not source)
// 'enhanced' is enhanced procedures, for example Background/deviation (that has config's myenhanceddocuments pointing back to source)
// 'non' or 'not enhanced', anything other than 'source' or 'enhanced' (has no myenhanceddocuments on config)
// 'from' is object copied
// 'to' is object where paste was selected from
#region Menu_Paste_ToDocVersion
if (tn.VEObject as DocVersionInfo != null) // paste item must be a proc
{
if (iiClipboard.IsProcedure)
{
// In order to paste a procedure into a docVersion: NOTE that an 'enhanced' procedure cannot be in paste buffer!
// 1) 'to' & 'from' both 'non', i.e. Neither can have enhanced config data (be source or enhanced)
// 2) 'to' docVersion is 'source' and 'from' procedure is 'non' (has no MyEnhancedDocuments)
// 3) 'to' docversion is 'source' and 'from' procedure is within this docversion
// 4) 'to' docVersion is 'enhanced' and 'from' procedure is not
bool canPaste = false;
DocVersionInfo dvi = tn.VEObject as DocVersionInfo;
DocVersionConfig dvc = dvi.DocVersionConfig;
bool docVersionIsEnhanced = dvc.MyEnhancedDocuments != null && dvc.MyEnhancedDocuments.Count > 0 && dvc.MyEnhancedDocuments[0].Type == 0;
bool docVersionIsSource = dvc.MyEnhancedDocuments != null && dvc.MyEnhancedDocuments.Count > 0 && dvc.MyEnhancedDocuments[0].Type != 0;
ProcedureInfo pi = iiClipboard as ProcedureInfo;
ProcedureConfig pcfg = pi.MyConfig as ProcedureConfig;
bool procIsSource = pcfg.MyEnhancedDocuments != null && pcfg.MyEnhancedDocuments.Count > 0 && pcfg.MyEnhancedDocuments[0].Type != 0;
if (!docVersionIsEnhanced && !docVersionIsSource && !procIsSource) canPaste = true;
else if (docVersionIsSource && !procIsSource) canPaste = true;
else if (docVersionIsSource) canPaste = (!procIsSource || (iiClipboard.MyDocVersion.ItemID == dvi.ItemID));
else if (docVersionIsEnhanced) canPaste = !procIsSource;
if (iiClipboard.IsRtfRaw) canPaste = false; // never paste an equation.
if (canPaste) cm.MenuItems.Add("Paste Procedure", new EventHandler(mi_Click));
}
#endregion
}
else
{
ItemInfo iiPasteHere = tn.VEObject as ItemInfo;
if (iiPasteHere == null) return;
bool okToReplace = iiClipboard.ItemID != iiPasteHere.ItemID;
if (iiPasteHere != null)
{
SectionInfo si = (tn.VEObject as SectionInfo != null) ? tn.VEObject as SectionInfo : null;
#region Menu_Paste_ToFromProcedure
if (iiPasteHere.IsProcedure && iiClipboard.IsProcedure) // procedure can be pasted before/replace/after
{
// Enhanced considerations, in order to paste a procedure around another procedure: NOTE that an 'enhanced' procedure cannot be in paste buffer!
// 1) 'to' & 'from' both 'non', i.e. Neither can have enhanced config data (be source or enhanced)
// can do Before/After/Replace
// 2) 'to' is 'non', 'from' is 'source'
// cannot do any
// 3) 'to' procedure is 'source' and 'from' procedure is 'non' (has no MyEnhancedDocuments)
// can do Before/After - no links exist in pasted procedure.
// cannot do Replace
// 4) 'to' procedure is 'source' and 'from' procedure is same docversion 'source'
// can do Before/After/Replace
// 5) 'to' procedure is 'source' and 'from' procedure is different docversion 'source'
// cannot do any
// 6) 'to' procedure is 'enhanced' and 'from' procedure is 'source'
// cannot do any
ProcedureConfig pcToCfg = iiPasteHere.MyConfig as ProcedureConfig;
ProcedureConfig pcFromCfg = iiClipboard.MyConfig as ProcedureConfig;
bool prToIsEnhanced = iiPasteHere.IsEnhancedProcedure;
bool prToIsSource = pcToCfg.MyEnhancedDocuments != null && pcToCfg.MyEnhancedDocuments.Count > 0 && pcToCfg.MyEnhancedDocuments[0].Type != 0;
bool prFromIsEnhanced = iiClipboard.IsEnhancedProcedure;
bool prFromIsSource = pcFromCfg.MyEnhancedDocuments != null && pcFromCfg.MyEnhancedDocuments.Count > 0 && pcFromCfg.MyEnhancedDocuments[0].Type != 0;
bool prCanPaste = false;
if (!prToIsEnhanced && !prToIsSource && !prFromIsEnhanced && !prFromIsSource) prCanPaste = true; // 1)
// else if ((!prToIsEnhanced && !prToIsSource) && prFromIsSource) prCanPaste = false; // 2) commented out because already set to false
else if (prToIsSource && !prFromIsEnhanced && !prFromIsSource) // 3)
{
prCanPaste = true;
okToReplace = false;
}
else if (prToIsSource && iiPasteHere.MyDocVersion.VersionID == iiClipboard.MyDocVersion.VersionID) prCanPaste = true; // 4)
//else if (prToIsSource && iiPasteHere.MyDocVersion.VersionID != iiClipboard.MyDocVersion.VersionID) prCanPaste = false; // 5) commented out because already set to false
//else if (prToIsEnhanced && prFromIsSource) prCanPaste = false; // 6)commented out because already set to false
if (iiClipboard.IsRtfRaw) prCanPaste = okToReplace = prCanPaste = false; // never paste an equation.
if (prCanPaste) cm.MenuItems.Add("Paste Procedure Before", new EventHandler(mi_Click));
if (okToReplace && prCanPaste) cm.MenuItems.Add("Replace Existing Procedure", new EventHandler(mi_Click));
if (prCanPaste) cm.MenuItems.Add("Paste Procedure After", new EventHandler(mi_Click));
// B2017-243 added the following two Cannot Paste menu items when dealing with enhanced documents
// when then user selects these menu items a message box will appear giving more information as to why it cannot be pasted
if (!prCanPaste)
{
if (prToIsEnhanced)
cm.MenuItems.Add("CANNOT PASTE HERE, Click for more information...", new EventHandler(mi_Click));
else
cm.MenuItems.Add("CANNOT PASTE HERE. Click for more information...", new EventHandler(mi_Click));
}
}
#endregion
#region Menu_Paste_ToProcedureFromSection
else if (iiPasteHere.IsProcedure && iiClipboard.IsSection) // procedure must have sections only
{
// In order to paste a section into a procedure: NOTE that an 'enhanced' section cannot be in paste buffer!
// 1) 'to' & 'from' both 'non', i.e. Neither can have enhanced config data (be source or enhanced)
// can do
// 2) 'to' procedure is 'source' and 'from' section is 'non' (has no MyEnhancedDocuments)
// can do
// 3) 'to' procedure is 'source' and 'from' section is same source
ProcedureConfig pccToCfg = iiPasteHere.MyConfig as ProcedureConfig;
SectionConfig scFromCfg = iiClipboard.MyConfig as SectionConfig;
bool prToIsEnhanced = iiPasteHere.IsEnhancedProcedure;
bool prToIsSource = pccToCfg.MyEnhancedDocuments != null && pccToCfg.MyEnhancedDocuments.Count > 0 && pccToCfg.MyEnhancedDocuments[0].Type != 0;
bool scFromIsEnhanced = iiClipboard.IsEnhancedSection;
bool scFromIsSource = scFromCfg.MyEnhancedDocuments != null && scFromCfg.MyEnhancedDocuments.Count > 0 && scFromCfg.MyEnhancedDocuments[0].Type != 0;
bool scCanPaste = false;
if (!prToIsEnhanced && !prToIsSource && !scFromIsEnhanced && !scFromIsSource) scCanPaste = true; // 1)
else if (prToIsSource && !scFromIsEnhanced && !scFromIsSource) scCanPaste = true;
else if (prToIsSource && iiPasteHere.MyDocVersion.VersionID == iiClipboard.MyDocVersion.VersionID) scCanPaste = true; // 3)
if (iiClipboard.IsRtfRaw) scCanPaste = false; // never paste an equation.
if (scCanPaste) cm.MenuItems.Add("Paste Section", new EventHandler(mi_Click));
}
#endregion
#region Menu_Paste_ToSectionFromSection
else if (iiPasteHere.IsSection && iiClipboard.IsSection)
{
// Enhanced considerations, in order to paste a section around another section: NOTE that an 'enhanced' section cannot be in paste buffer!
// 1) 'to' & 'from' both 'non', i.e. Neither can have enhanced config data (be source or enhanced)
// can do Before/After/Replace
// 2) 'to' section is 'source' and 'from' section is 'non' (has no MyEnhancedDocuments)
// can do Before/After - no links exist in pasted section.
// cannot do Replace
// 3) 'to' section is 'source' and 'from' section is same docversion 'source'
// can do Before/After/Replace
SectionConfig secToCfg = iiPasteHere.MyConfig as SectionConfig;
SectionConfig secFromCfg = iiClipboard.MyConfig as SectionConfig;
bool secToIsEnhanced = iiPasteHere.IsEnhancedSection;
bool secToIsSource = secToCfg.MyEnhancedDocuments != null && secToCfg.MyEnhancedDocuments.Count > 0 && secToCfg.MyEnhancedDocuments[0].Type != 0;
bool secFromIsEnhanced = iiClipboard.IsEnhancedSection;
bool secFromIsSource = secFromCfg.MyEnhancedDocuments != null && secFromCfg.MyEnhancedDocuments.Count > 0 && secFromCfg.MyEnhancedDocuments[0].Type != 0;
bool secCanPaste = false;
if (!secToIsEnhanced && !secToIsSource && !secFromIsEnhanced && !secFromIsSource) secCanPaste = true; // 1)
else if (secToIsSource && !secFromIsEnhanced && !secFromIsSource) // 2)
{
secCanPaste = true;
okToReplace = false;
}
else if (secToIsSource && iiPasteHere.MyDocVersion.VersionID == iiClipboard.MyDocVersion.VersionID) secCanPaste = true; // 3)
if (iiClipboard.IsRtfRaw) secCanPaste = okToReplace = false; // never paste an equation.
if (secCanPaste) cm.MenuItems.Add("Paste Section Before", new EventHandler(mi_Click));
if (okToReplace && secCanPaste) cm.MenuItems.Add("Replace Existing Section", new EventHandler(mi_Click));
if (secCanPaste) cm.MenuItems.Add("Paste Section After", new EventHandler(mi_Click));
if (si.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections && iiPasteHere.IsStepSection && iiClipboard.IsStepSection)
{
// only paste a subsection if the paste here is an empty section or has
// subsections.
if (!iiClipboard.IsRtfRaw && (iiPasteHere.Sections == null || iiPasteHere.Sections.Count > 0))
cm.MenuItems.Add("Paste Subsection", new EventHandler(mi_Click));
}
}
#endregion
#region Menu_Paste_ToSectionFromStep
else if (iiPasteHere.IsStepSection && iiClipboard.IsStep)
{
// In order to paste a step into a section: NOTE that an 'enhanced' step cannot be in paste buffer!
// 1) 'to' & 'from' both 'non', i.e. Neither can have enhanced config data (be source or enhanced)
// can do
// 2) 'to' section is 'source' and 'from' step is 'non' (has no MyEnhancedDocuments)
// can do
// 3) 'to' section is 'source' and 'from' section is same source
SectionConfig secToCfg = iiPasteHere.MyConfig as SectionConfig;
StepConfig stpFromCfg = iiClipboard.MyConfig as StepConfig;
bool secToIsEnhanced = iiPasteHere.IsEnhancedSection;
bool secToIsSource = secToCfg.MyEnhancedDocuments != null && secToCfg.MyEnhancedDocuments.Count > 0 && secToCfg.MyEnhancedDocuments[0].Type != 0;
bool stpFromIsEnhanced = iiClipboard.IsEnhancedStep;
bool stpFromIsSource = stpFromCfg.MyEnhancedDocuments != null && stpFromCfg.MyEnhancedDocuments.Count > 0 && stpFromCfg.MyEnhancedDocuments[0].Type != 0;
bool stpCanPaste = false;
if (!secToIsEnhanced && !secToIsSource && !stpFromIsEnhanced && !stpFromIsSource) stpCanPaste = true; // 1)
else if (secToIsSource && !stpFromIsEnhanced && !stpFromIsSource) stpCanPaste = true; // 2)
else if (secToIsSource && iiPasteHere.MyDocVersion.VersionID == iiClipboard.MyDocVersion.VersionID) stpCanPaste = true; // 3)
if (iiClipboard.IsRtfRaw) stpCanPaste = false; // never paste an equation.
if (stpCanPaste) cm.MenuItems.Add("Paste Step", new EventHandler(mi_Click));
}
#endregion
#region Menu_Paste_ToStepFromStep
else if (iiPasteHere.IsStep && iiClipboard.IsStep)
{
// Enhanced considerations, in order to paste a step around another step: NOTE that an 'enhanced' section cannot be in paste buffer!
// 1) 'to' & 'from' both 'non', i.e. Neither can have enhanced config data (be source or enhanced)
// can do Before/After/Replace
// 2) 'to' step is 'source' and 'from' step is 'non' (has no MyEnhancedDocuments)
// can do Before/After - no links exist in pasted step, treat like an insert..
// cannot do Replace
// 3) 'to' step is 'source' and 'from' step is same docversion 'source'
// can do Before/After/Replace (Note that replace is not allowed per B2017-183)
StepConfig stpToCfg = iiPasteHere.MyConfig as StepConfig;
StepConfig stpFromCfg = iiClipboard.MyConfig as StepConfig;
bool stpToIsEnhanced = iiPasteHere.IsEnhancedStep;
bool stpToIsSource = stpToCfg.MyEnhancedDocuments != null && stpToCfg.MyEnhancedDocuments.Count > 0 && stpToCfg.MyEnhancedDocuments[0].Type != 0;
bool stpFromIsEnhanced = iiClipboard.IsEnhancedStep;
bool stpFromIsSource = stpFromCfg.MyEnhancedDocuments != null && stpFromCfg.MyEnhancedDocuments.Count > 0 && stpFromCfg.MyEnhancedDocuments[0].Type != 0;
bool stpCanPaste = false;
if (!stpToIsEnhanced && !stpToIsSource && !stpFromIsEnhanced && !stpFromIsSource) stpCanPaste = true; // 1)
else if (stpToIsSource && !stpFromIsEnhanced && !stpFromIsSource) // 2)
{
stpCanPaste = true;
okToReplace = false;
}
else if (stpToIsSource && iiPasteHere.MyDocVersion.VersionID == iiClipboard.MyDocVersion.VersionID) // 3
{
stpCanPaste = true;
if (stpFromIsSource) okToReplace = false; // B2017-183: don't allow a replace to source steps
}
if (iiClipboard.IsRtfRaw) stpCanPaste = false; // never paste an equation.
if (stpCanPaste && AddToInsertMenu(iiPasteHere, 0)) cm.MenuItems.Add("Paste Step Before", new EventHandler(mi_Click));
if (stpCanPaste && okToReplace) cm.MenuItems.Add("Replace Existing Step", new EventHandler(mi_Click));
if (stpCanPaste && AddToInsertMenu(iiPasteHere, 1)) cm.MenuItems.Add("Paste Step After", new EventHandler(mi_Click));
}
#endregion
}
}
}
#endregion menupaste
}
//jcb multiunit
void miMultiUnit_Click(object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
MenuItem mip = mi.Parent as MenuItem;
switch (mip.Text)
{
case "Print":
OnPrintProcedure(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, mi.Text, (int)mi.Tag));
break;
case "Quick Print":
OnQPrintProcedure(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, mi.Text, (int)mi.Tag));
break;
case "Print All Procedures for":
OnPrintAllProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0,mi.Text,(int)mi.Tag));
break;
case "Approve":
OnApproveProcedure(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, mi.Text, (int)mi.Tag));
break;
case "Approve All Procedures for":
OnApproveAllProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, mi.Text, (int)mi.Tag));
break;
case "Approve Some Procedures for":
OnApproveSomeProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, mi.Text, (int)mi.Tag));
break;
case "Create Continuous Action Summary":
OnCreateContinuousActionSummary(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null,0,mi.Text,(int)mi.Tag));
break;
case "Create Time Critical Action Summary":
OnCreateTimeCriticalActionSummary(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null,0,mi.Text,(int)mi.Tag));
break;
default:
if (mip.Text.StartsWith("Showing Change Bars Starting"))
OnSelectDateToStartChangeBars(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
else
FlexibleMessageBox.Show(string.Format("Unrecognized Menu Item '{0}'", mip.Text));
break;
}
}
//end jcb multiunit
private bool CheckForValidEnhLink(ItemInfo prc) // Check if this procedure has valid link
{
EnhancedDocuments eds = prc.GetMyEnhancedDocuments();
foreach (EnhancedDocument ed in eds) // only unlink those that are selected
{
ItemInfo lprc = ItemInfo.Get(ed.ItemID);
EnhancedDocuments edsl = lprc.GetMyEnhancedDocuments();
foreach (EnhancedDocument edl in edsl) if (edl.ItemID == prc.ItemID) return true;
}
return false;
}
// B2022-049: Copy/paste of enhanced procedure and bad links between source and enhanced
// Handle menu selection for unlinking the source/enhanced OR if not valid links, just the procedure selected
void miEnhanced_Click(object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
VETreeNode tnprc = SelectedNode as VETreeNode;
ItemInfo selprc = tnprc.VEObject as ItemInfo;
EnhancedDocuments seleds = selprc.GetMyEnhancedDocuments();
// if tag on menu = -1, it is a single document, no need to loop. This can be from either the source or enhanced.
if ((int)mi.Tag == -1)
{
bool hasValidConnectingProc = CheckForValidEnhLink(selprc);
if (FlexibleMessageBox.Show(this, "Do you want to unlink the Enhanced procedure from its Source?", "Confirm Procedure Unlink", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
if (selprc.IsEnhancedProcedure)
{
selprc.DoUnlinkEnhanced(selprc, 0, !hasValidConnectingProc); // if no valid linked: enhtype = 0 since this an enhanced doc is getting unlinked
}
else // from source
{
// if valid connection, make call from the linked enhanced, otherwise just unlink the source only
if (hasValidConnectingProc)
{
ItemInfo lprc = ItemInfo.Get(seleds[0].ItemID);
lprc.DoUnlinkEnhanced(lprc, 0, !hasValidConnectingProc);
}
else
selprc.DoUnlinkEnhanced(selprc, seleds[0].Type, !hasValidConnectingProc);
}
}
}
else
{
// The following code is run if selection made from source. There may be moore than one enhanced, for example background
// and deviation
if (FlexibleMessageBox.Show(this, "Do you want to unlink the selected Enhanced procedure(s) from the Source procedure?", "Confirm Procedure Unlink", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int k = 1;
foreach (EnhancedDocument ed in seleds) // only unlink those that are selected
{
if (k == (int)mi.Tag || (int)mi.Tag == 0)
{
ItemInfo lprc = ItemInfo.Get(ed.ItemID);
bool hasValidConnectingProc = CheckForValidEnhLink(lprc);
// if there is a valid connection, unlink both. Otherwise, just unlink this selected procedure.
if (hasValidConnectingProc)
lprc.DoUnlinkEnhanced(lprc, ed.Type, !hasValidConnectingProc);
else
selprc.DoUnlinkEnhanced(selprc, ed.Type, !hasValidConnectingProc);
}
k++;
}
}
}
}
void mi_Click(object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi == null)
return;
// B2019-076: make folder/working draft level proc set specific info consistent (various places in this file were changed from Folder Specific & Working Draft Specific)
if (mi.Text == "Procedure Set Specific Information" || mi.Text == "Folder Specific Information") // C2020-008: change to 'Folder'
{
VETreeNode tn = SelectedNode as VETreeNode;
OnNodeSI(this, new vlnTreeEventArgs(tn, null, 0));
return;
}
if (mi.Text.StartsWith("Collapse"))
{
CollapseProcedures();
return;
}
if (mi.Text == "Print Transition Report")
{
OnPrintTransitionReport(this, new vlnTreeEventArgs(SelectedNode as VETreeNode));
return;
}
if (mi.Text == "Export Procedure Set" || mi.Text == "Export Procedure")
{
OnExportImportProcedureSets(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
return;
}
if (mi.Text == "Import Procedure Set" || mi.Text == "Import Procedure")
{
OnExportImportProcedureSets(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 1));
return;
}
if (mi.Text.StartsWith("Procedure Checked Out to") || mi.Text.StartsWith("Document Checked Out to"))
{
OnProcedureCheckedOutTo(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
return;
}
switch (mi.Text)
{
case "Print Section":
VETreeNode tn2 = SelectedNode as VETreeNode;
OnPrintSection(this, new vlnTreeEventArgs(tn2 as VETreeNode, null, 0));
break;
case "Open":
OpenNode();
break;
case "Insert Folder Before":
tv_NodeNew(MenuSelections.FolderBefore);
break;
case "Insert Folder After":
tv_NodeNew(MenuSelections.FolderAfter);
break;
case "New Folder":
SelectedNode.Expand();
tv_NodeNew(MenuSelections.Folder);
break;
case "Create Working Draft":
SelectedNode.Expand();
tv_NodeNew(MenuSelections.DocVersion);
break;
case "New Procedure":
SelectedNode.Expand();
tv_NodeNew(MenuSelections.Procedure);
break;
case "Insert Procedure Before":
tv_NodeNew(MenuSelections.ProcedureBefore);
break;
case "Insert Procedure After":
tv_NodeNew(MenuSelections.ProcedureAfter);
break;
case "Remove Change Ids":
tv_RemoveChgIds();
break;
case "New Section":
case "New Subsection":
SelectedNode.Expand();
tv_NodeNew(MenuSelections.Section);
break;
case "Insert Section Before":
tv_NodeNew(MenuSelections.SectionBefore);
break;
case "Insert Section After":
tv_NodeNew(MenuSelections.SectionAfter);
break;
case "Insert Step Before":
tv_NodeNew(MenuSelections.StepBefore);
break;
case "Insert Step After":
tv_NodeNew(MenuSelections.StepAfter);
break;
case "New Step":
SelectedNode.Expand();
tv_NodeNew(MenuSelections.Step);
break;
case "Copy"://Copy the selected node
tv_NodeCopy();
break;
// lots of paste options:
case "Paste Procedure":
case "Paste Procedure Before":
case "Replace Existing Procedure":
case "Paste Procedure After":
case "Paste Section":
case "Paste Section Before":
case "Replace Existing Section":
case "Paste Section After":
case "Paste Step":
case "Paste Step Before":
case "Replace Existing Step":
case "Paste Step After":
case "Paste Subsection":
tv_NodePaste(mi.Text);
break;
case "Delete":
if (tv_NodeDelete())
{
TreeNode myParent = SelectedNode.Parent;
SelectedNode.Remove();
SelectedNode = myParent;
OnNodeSelect(this, new vlnTreeEventArgs(SelectedNode));
}
break;
case "Incoming Transitions": // C2020-033: Support the menu item to bring up Search/Incoming Transitions panel
VETreeNode tnx = SelectedNode as VETreeNode;
ItemInfo iii = tnx.VEObject as ItemInfo;
if (iii != null)
{
this.Cursor = Cursors.WaitCursor; // B2023-103 add spinner when searching for incoming transitions
OnSearchIncTransIn(this, new vlnTreeItemInfoEventArgs(iii));
this.Cursor = Cursors.Default;
}
break;
case "Properties..."://Show the properties for the selected node
SetLastValues((VETreeNode)SelectedNode);
SetupNodeProperties();
break;
case "Procedure Specific Information":
VETreeNode tn = SelectedNode as VETreeNode;
ProcedureInfo pi = tn.VEObject as ProcedureInfo;
if (pi != null)
{
using (Procedure proc = pi.Get())
{
OnNodePSI(this, new vlnTreeEventArgs(tn, null, 0));
}
}
break;
case "Print":
OnPrintProcedure(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Quick Print":
OnQPrintProcedure(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Print All Procedures":
OnPrintAllProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Approve":
OnApproveProcedure(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Approve All Procedures":
OnApproveAllProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Approve Some Procedures":
OnApproveSomeProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Report All Procedures Inconsistencies":
OnReportAllProceduresInconsistencies(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Refresh Checked Out Procedures":
OnRefreshCheckedOutProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
break;
case "Run RO Editor":
RunROEditor(SelectedNode as VETreeNode);
break;
case "Update RO Values":
UpdateROValues(SelectedNode as VETreeNode);
break;
case "Create Continuous Action Summary":
OnCreateContinuousActionSummary(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null,0));
break;
// F2022-024 Time Critical Action Summary
case "Create Time Critical Action Summary":
OnCreateTimeCriticalActionSummary(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null,0));
break;
// B2017-243 added the following two Cannot Paste items when dealing with enhanced documents
// when then user selects these menu items a message box will appear giving more information as to why it cannot be pasted
case "CANNOT PASTE HERE. Click for more information...":
FlexibleMessageBox.Show("You have copied a document that is linked to an Enhanced Document.\n\n" +
"It can only be pasted before or after another document, within the set, that is linked to an Enhanced Document.", "Cannot Paste Here");
break;
case "CANNOT PASTE HERE, Click for more information...":
FlexibleMessageBox.Show("You have copied a document that is NOT linked to an Enhanced Document.\n\n" +
"It CANNOT be pasted before or after an Enhanced Document.", "Cannot Paste Here");
break;
//case "Check Out Procedure Set":
// CheckOutDocVersion(SelectedNode as VETreeNode);
// break;
//case "Check In Procedure Set":
// CheckInDocVersion(SelectedNode as VETreeNode);
// break;
default:
if (mi.Text.StartsWith("Showing Change Bars Starting"))
OnSelectDateToStartChangeBars(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
else
FlexibleMessageBox.Show(string.Format("Unrecognized Menu Item '{0}'", mi.Text));
break;
}
}
private bool _doingCollapseNode = false; // B2016-058 when collapse is done, it always calls the drag node event which doesn't appear to be needed
private void CollapseProcedures()
{
CollapseProcedures(SelectedNode as VETreeNode);
}
private void CollapseProcedures(VETreeNode tn)
{
if (tn == null) return;
if (!tn.IsExpanded) return;
if (tn.VEObject.GetType() == typeof(ProcedureInfo))
{
tn.Collapse();
_doingCollapseNode = true; // B2016-058 this will prevent a Drag Node error when collapsing an RNOs, Cautions, or Notes tree node
return;
}
foreach (VETreeNode tnc in tn.Nodes)
CollapseProcedures(tnc);
if (tn.VEObject as DocVersionInfo == null && tn.VEObject as FolderInfo == null)
tn.Collapse();
_doingCollapseNode = true; // B2016-058 this will prevent a Drag Node error when collapsing an RNOs, Cautions, or Notes tree node
}
private void tv_RemoveChgIds()
{
//Console.WriteLine("HERE"); // add code/query to clear change ids in config.
}
private Dictionary<int, int> MyCheckedOutDocVersions;
private void CheckInDocVersion(VETreeNode tn)
{
DocVersionInfo MyDVI = tn.VEObject as DocVersionInfo;
MySessionInfo.CheckInItem(MyCheckedOutDocVersions[MyDVI.VersionID]);
MyCheckedOutDocVersions.Remove(MyDVI.VersionID);
}
private void UpdateROValues(VETreeNode tn)
{
InitialProgressBarMessage = "Updating ROs";
DocVersionInfo MyDVI = tn.VEObject as DocVersionInfo;
// use rodb directory path of the first rofst for the this document version. Later, will need
// to modify code to get which one (when there is more than one)
if (MyDVI.DocVersionAssociations.Count < 1)
{
FlexibleMessageBox.Show("Error Updating ro.fst. No associated ro.fst", "No ROs associated"); //B2017-125 added title to messagebox
FinalProgressBarMessage = "No ROs associated";
return;
}
ROFstInfo roFstInfo = MyDVI.DocVersionAssociations[0].MyROFst;
string rofstPath = roFstInfo.MyRODb.FolderPath + @"\ro.fst";
if (!File.Exists(rofstPath))
{
FlexibleMessageBox.Show("No existing ro.fst in path " + roFstInfo.MyRODb.FolderPath + ". Check for invalid path", "No existing RO.FST"); //B2017-125 added title to messagebox
FinalProgressBarMessage = "No existing RO.FST";
return;
}
FileInfo fiRofst = new FileInfo(rofstPath);
if (roFstInfo.DTS == fiRofst.LastWriteTimeUtc)
{
FlexibleMessageBox.Show("ro.fst files are same for path " + roFstInfo.MyRODb.FolderPath + ", import of that ro.fst will not be done", "RO.FST up to date"); //B2017-125 added title to messagebox
FinalProgressBarMessage = "RO.FST up to date";
return;
}
if (roFstInfo.DTS > fiRofst.LastWriteTimeUtc)
{
FlexibleMessageBox.Show("Cannot copy older ro.fst from " + roFstInfo.MyRODb.FolderPath + ", import of that ro.fst will not be done", "Older RO.FST"); //B2017-125 added title to messagebox
FinalProgressBarMessage = "Older RO.FST";
return;
}
string message = string.Empty;
if (!MySessionInfo.CanCheckOutItem(MyDVI.VersionID, CheckOutType.DocVersion, ref message))
{
FlexibleMessageBox.Show(this, message, "Working Draft Has Items Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
FinalProgressBarMessage = "Cannot check-out Working Draft";
return;
}
Cursor = Cursors.WaitCursor; // C2023-002: move wait cursor after check out error
int ownerid = MySessionInfo.CheckOutItem(MyDVI.VersionID, CheckOutType.DocVersion);
using (DocVersion dv = DocVersion.Get(MyDVI.VersionID))
{
swROUpdate = new System.IO.StreamWriter(ROFstInfo.ROUpdateResultsPath(MyDVI)); // RO changes placed in file in the Documents\VEPROMS folder
// B2022-026 RO Memory Reduction code - first load the new ro.fst so that we can assign the ROTableUpdate event to the correct roFstInfo
if (dv.ROfstLoadingFigures || dv.NewerRoFst) // B2017-125 see if loading figures was completed
{
// only load the RO.fst
ROFstInfo.UpdateRoFst(roFstInfo.MyRODb, dv, roFstInfo, DoProgressBarRefresh);
roFstInfo = MyDVI.DocVersionAssociations[0].MyROFst;
}
roFstInfo.ROTableUpdate += new ROFstInfoROTableUpdateEvent(roFstInfo_ROTableUpdate);
ContentInfo.StaticContentInfoChange += ContentInfo_StaticContentInfoChange; // write changes to a text file
ROFst newrofst = ROFstInfo.RefreshROFst(dv, roFstInfo, DoProgressBarRefresh, null);
swROUpdate.Close();
ContentInfo.StaticContentInfoChange -= ContentInfo_StaticContentInfoChange;
roFstInfo.ROTableUpdate -= new ROFstInfoROTableUpdateEvent(roFstInfo_ROTableUpdate);
OnTabDisplay(this, new StepPanelTabDisplayEventArgs("DisplayROUpdateROFST"));
}
MySessionInfo.CheckInItem(ownerid);
Cursor = Cursors.Default;
FinalProgressBarMessage = "ROs values updated";
}
private System.IO.StreamWriter swROUpdate;
// write the RO reference changes to a text file, include the old/new text, location, and the itemid of the step element
void ContentInfo_StaticContentInfoChange(object sender, StaticContentInfoEventArgs args)
{
if (args.Type == "RO")
swROUpdate.Write(string.Format("Fixed Referenced Object for {1}({4}){0}Old Text: {2}{0}New Text: {3}{0}{0}", Environment.NewLine, (sender as ItemInfo).ShortPath, args.OldValue, args.NewValue, (sender as ItemInfo).ItemID));
}
private ProgressBarItem _ProgressBar=null;
public ProgressBarItem ProgressBar
{
get { return _ProgressBar; }
set { _ProgressBar = value; }
}
private void DoProgressBarRefresh(int value, int max, string text)
{
if (ProgressBar == null) return;
ProgressBar.Maximum = max;
ProgressBar.Value = value;
ProgressBar.Text = text;
Application.DoEvents();
}
private string InitialProgressBarMessage
{
set
{
if (ProgressBar == null) return;
ProgressBar.Value = 0;
ProgressBar.Maximum = 100;
ProgressBar.Text = value;
Application.DoEvents();
}
}
private string FinalProgressBarMessage
{
set
{
if (ProgressBar == null) return;
ProgressBar.Value = 100;
ProgressBar.Maximum = 100;
ProgressBar.Text = value;
Application.DoEvents();
}
}
public List<string> roFstInfo_ROTableUpdate(object sender, ROFstInfoROTableUpdateEventArgs args)
{
return VlnFlexGrid.ROTableUpdate(sender, args);
//string xml = null;
//string srchtxt = null;
//using (VlnFlexGrid myGrid = new VlnFlexGrid())
//{
// using (StringReader sr = new StringReader(args.OldGridXml))
// {
// myGrid.ReadXml(sr);
// myGrid.KeyActionTab = C1.Win.C1FlexGrid.KeyActionEnum.MoveAcross;
// sr.Close();
// }
// string roid = myGrid.ROID;
// int rodbid = myGrid.RODbId;
// Font GridFont = myGrid.Font;
// myGrid.Clear();
// myGrid.ParseTableFromText(args.ROText, GridLinePattern.Single);
// myGrid.AutoSizeCols();
// myGrid.AutoSizeRows();
// myGrid.MakeRTFcells();
// myGrid.RODbId = rodbid;
// myGrid.ROID = roid;
// myGrid.IsRoTable = true;
// using (StringWriter sw = new StringWriter())
// {
// myGrid.WriteXml(sw);
// xml = sw.GetStringBuilder().ToString();
// sw.Close();
// }
// srchtxt = myGrid.GetSearchableText();
//}
//List<string> retlist = new List<string>();
//retlist.Add(srchtxt);
//retlist.Add(xml);
//return retlist;
}
private void RunROEditor(VETreeNode tn)
{
DocVersionInfo MyDVI = tn.VEObject as DocVersionInfo;
if (VlnSettings.ReleaseMode.Equals("DEMO"))
{
FlexibleMessageBox.Show("Referenced Object Editor not available in the Demo version.", "PROMS Demo Version");
return;
}
//string roapp = Environment.GetEnvironmentVariable("roapp");
string roapp = Volian.Base.Library.ExeInfo.GetROEditorPath(); // get the path to the RO Editor Executable
if (roapp == null || roapp == string.Empty)
{
FlexibleMessageBox.Show("The 'roapp' environment variable needs to be set to the path of the RO Editor\n\n Ex: C:\\VE-PROMS.NET\\Bin\\roeditor.exe", "Environment Variable Error");
return;
}
if (!File.Exists(roapp))
{
string errtxt = string.Format("Could not find path to Referenced Objects Editor:\n\n roapp = {0}\n\n Verify the path assigned to the 'roapp' environment variable", roapp);
FlexibleMessageBox.Show(errtxt, "Environment Variable Error");
//MessageBox.Show("Could not find path to Ro Editor, check 'roapp' environment variable","Environment Variable Error");
return;
}
//if (roapp == null)
//{
// MessageBox.Show("Could not find path to Ro Editor, check 'roapp' environment variable");
// return;
//}
if (MyDVI == null || MyDVI.DocVersionAssociationCount < 1)
{
FlexibleMessageBox.Show("Could not find associated path for ro data.", "No RO Data", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
string roloc = "\"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath + "\"";
if (!Directory.Exists(MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath))
{
FlexibleMessageBox.Show(string.Format("RO Database directory does not exist: {0}", MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath));
return;
}
// C2017-003: ro data in sql server, check for sql connection string
if (MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString != "cstring")
roloc = roloc + " \"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString + "\"";
// C2021-026 pass in Parent/Child information (list of the children)
// B2022-019 look at all DocVersions to find ParentChild information
// to ensure we pass in Parent/Child even when not coming from a Parent/Child procedure set
// B2022-073 Break out of the foreach when we find a set with parent/child information
DocVersionInfoList dvil = DocVersionInfoList.Get();
foreach (DocVersionInfo dvi in dvil)
{
DocVersionConfig dvc = dvi.DocVersionConfig as DocVersionConfig;
if (dvc != null && dvc.Unit_Name != "" && dvc.Unit_Count > 1) // B2021-089 only pass in applicability info if defined for more than one unit
{
roloc += " \"PC=" + dvc.Unit_Name + "\"";
break;
}
}
System.Diagnostics.Process.Start(roapp, roloc);
}
[Serializable]
public struct PromsClipboard
{
public int cType;
public int itemId;
}
public enum PromsClipboardType : int
{
Copy = 1, Cut = 2
}
private void tv_NodePaste(string p)
{
ItemInfo iiClipboard = OnClipboardStatus(this, null);
if (iiClipboard == null) return;
string message = string.Empty;
if (iiClipboard.MyContent.MyEntry == null)
{
if (!MySessionInfo.CanCheckOutItem(iiClipboard.MyProcedure.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Copied Procedure Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
}
else
{
if (!MySessionInfo.CanCheckOutItem(iiClipboard.MyContent.MyEntry.DocID, CheckOutType.Document, ref message))
{
FlexibleMessageBox.Show(this, message, "Copied Document Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
}
VETreeNode tn = SelectedNode as VETreeNode;
DocVersionInfo dvi = tn.VEObject as DocVersionInfo;
// Check for paste into a docversion - queries/code is different than paste related to an item (into a proc or section)
if (dvi != null)
{
// If the docversion has procedures (children), change to a 'paste-after the last procedure'.
if (tn.Nodes.Count > 0)
{
// if the node count is 1, children may not have been loaded yet - load if necessary:
if (tn.Nodes.Count == 1 && tn.Nodes[0].Text.ToUpper().Contains("DUMMY VETREENODE"))
tn.LoadChildren();
// assume that item to paste is a procedure, otherwise the menuing would not have
// included the paste options
tn = (VETreeNode) tn.Nodes[tn.Nodes.Count - 1];
p = "After";
}
else // this is an empty docversion:
{
// First check if the doc version has RO's
// Paste as a child to the doc version:
this.Cursor = Cursors.WaitCursor;
PasteAsDocVersionChild(tn, iiClipboard.ItemID);
this.Cursor = Cursors.Default;
return;
}
}
ItemInfo iiPaste = tn.VEObject as ItemInfo;
if (iiPaste == null) return;
this.Cursor = Cursors.WaitCursor;
if (p.IndexOf("Before") > -1)
PasteBeforeOrAfter(MenuSelections.StepBefore, tn, iiClipboard.ItemID);
else if (p.IndexOf("After") > -1)
PasteBeforeOrAfter(MenuSelections.StepAfter, tn, iiClipboard.ItemID);
else if (p.IndexOf("Replace") > -1)
PasteReplace(tn, iiClipboard.ItemID);
else // paste as child
PasteAsChild(tn, iiClipboard.ItemID);
this.Cursor = Cursors.Default;
}
private void PasteAsDocVersionChild(VETreeNode tn, int copyStartID)
{
// Only need to handle paste in tree since this will create a new procedure.
DocVersionInfo dvi = tn.VEObject as DocVersionInfo;
if (dvi.DocVersionAssociationCount == 0)
{
// Set docversionassociation to the copied docversion association
// so that the rofst for ro's can be found. (if there is no association set)
ROFstInfo rfi = GetAssociationRofstId(copyStartID);
Association myAs = Association.MakeAssociation(dvi.Get(), rfi.GetJustROFst(), "");
dvi.RefreshDocVersionAssociations();
}
ItemInfo newProc = dvi.PasteChild(copyStartID);
VETreeNode tn1 = new VETreeNode(newProc);
SelectedNode.Nodes.Add(tn1); // add tree node to end of list.
SelectedNode = tn1;
}
private ROFstInfo GetAssociationRofstId(int copyStartID)
{
ItemInfo ii = ItemInfo.Get(copyStartID);
return ii.MyDocVersion.DocVersionAssociations[0].MyROFst;
}
private void PasteAsChild(VETreeNode tn, int copyStartID)
{
bool pasteSectIntoEmptySect = false;
ItemInfo ii = tn.VEObject as ItemInfo;
if (ii.IsStepSection) // is pasting a subsection, need to force a reload of the treeview
{
ItemInfo tmpcopy = ItemInfo.Get(copyStartID);
if (tmpcopy.IsStepSection) pasteSectIntoEmptySect = true;
}
ItemInfo.EAddpingPart pasteOpt = ItemInfo.EAddpingPart.Child;
// If parent step is open in step editor, the 'OnPasteItemInfo' event will cause
// the item to be pasted in the step editor and the tree.
if (!OnPasteItemInfo(this, new vlnTreeItemInfoPasteEventArgs(ii, copyStartID, pasteOpt, ii.MyContent.Type)))
{
// The parent step was not open in the step editor, just paste step (in data) and add treenode.
// first, check if a changeid is required.
string chgId = OnGetChangeId(this, new vlnTreeItemInfoEventArgs(ii));
ItemInfo newItemInfo = null;
newItemInfo = ii.PasteChild(copyStartID, chgId);
if (newItemInfo != null)
{
// paste enhanced steps if applicable (this code is only run if a step is pasted, not for a section).
ItemInfo.EAddpingPart addpart = ItemInfo.EAddpingPart.Child;
ItemInfo newEnhStep = newItemInfo.PasteEnhancedItems(copyStartID, ii, addpart, chgId);
}
}
if (pasteSectIntoEmptySect)
{
tn.ChildrenLoaded = false; // force a reload of treenode
tn.LoadChildren(true);
}
SelectedNode = tn;
}
private void PasteBeforeOrAfter(MenuSelections newtype, VETreeNode tn, int copyStartID)
{
// If paste-from step is open in the editor, use the OnPasteItemInfo to paste the step and add RTBItems
// to the step editor panel.
ItemInfo ii = tn.VEObject as ItemInfo;
ItemInfo.EAddpingPart pasteOpt = newtype == MenuSelections.StepBefore ? ItemInfo.EAddpingPart.Before : ItemInfo.EAddpingPart.After;
// If parent step is open in step editor, the 'OnPasteItemInfo' event will cause
// the item to be pasted in the step editor and the tree.
ItemInfo newItemInfo = null;
// F2021-009 display a message if pasting step will results in more sub-step levels than are defined in the format
if (!ii.IsProcedure)
ItemInfo.PasteStepIsWithinDefinedSubStepLevels(copyStartID, ii, false);
if (ii.IsProcedure || !OnPasteItemInfo(this, new vlnTreeItemInfoPasteEventArgs(ii, copyStartID, pasteOpt, ii.MyContent.Type)))
{
// The parent step was not open in the step editor, just paste step (in data) and add treenode.
// first, check if a changeid is required.
string chgId = OnGetChangeId(this, new vlnTreeItemInfoEventArgs(ii));
if (newtype == MenuSelections.StepBefore)
newItemInfo = ii.PasteSiblingBefore(copyStartID, chgId);
else
newItemInfo = ii.PasteSiblingAfter(copyStartID, chgId);
if (newItemInfo != null)
{
// paste enhanced steps if applicable (this code is only run if a step is pasted, not for a section).
ItemInfo.EAddpingPart addpart = ItemInfo.EAddpingPart.After;
if (newtype == MenuSelections.StepBefore) addpart = ItemInfo.EAddpingPart.Before;
ItemInfo newEnhStep = newItemInfo.PasteEnhancedItems(copyStartID, ii, addpart, chgId);
}
}
SelectedNode = (VETreeNode)((newtype == MenuSelections.StepAfter) ? tn.NextNode : tn.PrevNode);
}
private void PasteReplace(VETreeNode tn, int copyStartID)
{
VETreeNode prevtn = (VETreeNode) tn.PrevNode;
VETreeNode partn = (VETreeNode) tn.Parent;
ItemInfo ii = tn.VEObject as ItemInfo;
// F2021-009 display a message if pasting step will results in more sub-step levels than are defined in the format
ItemInfo.PasteStepIsWithinDefinedSubStepLevels(copyStartID, ii, true);
if (!OnPasteItemInfo(this, new vlnTreeItemInfoPasteEventArgs(ii, copyStartID, ItemInfo.EAddpingPart.Replace, ii.MyContent.Type)))
{
// first, check if a changeid is required.
string chgId = OnGetChangeId(this, new vlnTreeItemInfoEventArgs(ii));
ItemInfo replItemInfo = Item.PasteReplace(ii, copyStartID, chgId);
StepConfig replItemConfig = ii.MyConfig as StepConfig;
if (replItemInfo != null)
{
OnOpenItem(this, new vlnTreeItemInfoEventArgs(replItemInfo));
ItemInfo newEnhStep = replItemInfo.PasteEnhancedItems(copyStartID, ii, ItemInfo.EAddpingPart.Replace, chgId);
}
}
// B2018-047: was crashing on the following line (before change it was casting the result to a VETreeNote when the partn.FirstNode was just a TreeNode)
SelectedNode = prevtn != null ? prevtn.NextNode : partn.FirstNode;
}
private void tv_NodeCopy()
{
if (SelectedNode==null)return;
VETreeNode tn = SelectedNode as VETreeNode;
OnNodeCopy(this, new vlnTreeEventArgs(tn));
}
#endregion
#region PropertyPagesInterface
private void SetupNodeProperties()
{
VETreeNode tn = SelectedNode as VETreeNode;
if (tn==null)return;
if ((tn.VEObject as FolderInfo) != null)
OpenProperties(tn.VEObject as FolderInfo);
else if ((tn.VEObject as DocVersionInfo) != null)
{
// see if rofst is changed, if so, need to refresh any step panel values.
int rofstid = 0;
DocVersionInfo dvi = tn.VEObject as DocVersionInfo;
if (dvi != null && dvi.DocVersionAssociations != null && dvi.DocVersionAssociations.Count > 0) rofstid = dvi.DocVersionAssociations[0].MyROFst.ROFstID;
OpenProperties(tn.VEObject as DocVersionInfo);
if (dvi != null && dvi.DocVersionAssociations != null && dvi.DocVersionAssociations.Count > 0 && rofstid != dvi.DocVersionAssociations[0].MyROFst.ROFstID)
OnTabDisplay(this,new StepPanelTabDisplayEventArgs("DisplayROUpdateROFST"));
}
else if ((tn.VEObject as ProcedureInfo) != null)
OpenProperties(tn.VEObject as ProcedureInfo);
else if ((tn.VEObject as SectionInfo) != null)
OpenProperties(tn.VEObject as SectionInfo);
else if ((tn.VEObject as StepInfo) != null)
FlexibleMessageBox.Show("Open up info tab or whatever is associated with step");
if (!tn.MovedToSeparateWindow) tn.RefreshNode(); // C2015-022 don't want to rebuild tree node in the main window if it is currently in a child window
}
private void OpenProperties(FolderInfo folderInfo)
{
using (Folder folder = folderInfo.Get())
{
OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(string.Format("{0} Properties", folder.FolderConfig.Name), folder.FolderConfig));
}
}
private void OpenProperties(DocVersionInfo dvInfo)
{
using (DocVersion dv = dvInfo.Get())
{
OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(string.Format("{0} Properties", dv.DocVersionConfig.Name), dv.DocVersionConfig));
}
}
private void OpenProperties(ProcedureInfo procInfo)
{
using (Procedure proc = procInfo.Get())
{
OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(string.Format("{0} {1} Properties", proc.ProcedureConfig.Number, proc.ProcedureConfig.Title), proc.ProcedureConfig));
}
}
private void OpenProperties(SectionInfo sectInfo)
{
OnSectionShouldClose(this, new vlnTreeSectionInfoEventArgs(sectInfo));
using (Section sect = sectInfo.Get())
{
string title = null;
if (sectInfo.SectionConfig.Number.Length > 0)
title = string.Format("{0} {1} Properties", sectInfo.SectionConfig.Number, sectInfo.SectionConfig.Title);
else
title = string.Format("{0} Properties", sectInfo.SectionConfig.Title);
OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(title, sect.SectionConfig));
}
}
private void OpenProperties(StepInfo stpinfo)
{
using (Step stp = stpinfo.Get())
{
}
}
#endregion
#region OpenNode
private void tv_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
{
OpenNode();
e.Handled = true;
}
}
public void OpenNode()
{
VETreeNode tn = SelectedNode as VETreeNode;
if (tn != null)
{
if (tn.VEObject.GetType() == typeof(FolderInfo) || tn.VEObject.GetType() == typeof(DocVersionInfo) || tn.VEObject.GetType() == typeof(PartInfo))
{
if (tn.Nodes.Count > 0)
{
tn.Expand();
SelectedNode = tn.Nodes[0];
Focus();
}
}
else
OnNodeSelect(this, new vlnTreeEventArgs(SelectedNode));
}
}
#endregion
#region InsertAllLevels
public void tv_NodeNew(MenuSelections newtype)
{
VETreeNode tn = null;
if (SelectedNode == null) return;
OnPauseRefresh(this, null);
SetLastValues((VETreeNode)SelectedNode);
#region InsertFolderOrDocVersion
if (_LastFolderInfo != null)
{
using (Folder parentfolder = _LastFolderInfo.Get())
{
if (newtype == MenuSelections.DocVersion)
{
int dvid = -1; // flag to allow user to cancel from dialog & then we remove it.
using (DocVersion docversion = DocVersion.MakeDocVersion(parentfolder, "Working Draft", "Title", null, null, null))
{
ShowBrokenRules(docversion.BrokenRulesCollection);
SetLastValues(DocVersionInfo.Get(docversion.VersionID));
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("Working Draft", docversion.DocVersionConfig)) == DialogResult.OK)
{
docversion.Save();
tn = new VETreeNode(_LastDocVersionInfo);
SelectedNode.Nodes.Add(tn); // add tree node to end of list.
parentfolder.Reset_ChildFolders();
parentfolder.Reset_FolderDocVersions();
}
else
dvid = docversion.VersionID;
}
if (dvid != -1) DocVersion.Delete(dvid);
}
else if (newtype == MenuSelections.Folder)
{
int f1 = -1; // flag to allow user to cancel from dialog & then we remove it.
string uniquename = _LastFolderInfo.UniqueChildName("New Folder");
using (Folder folder = Folder.MakeFolder(parentfolder, parentfolder.MyConnection, uniquename, string.Empty, "Short Name", null, string.Empty, DateTime.Now, VlnSettings.UserID))
{
ShowBrokenRules(folder.BrokenRulesCollection);
FolderInfo fi = FolderInfo.Get(folder.FolderID);
folder.ManualOrder = fi.ManualOrder;
SetLastValues(fi);
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(uniquename, folder.FolderConfig)) == DialogResult.OK)
{
folder.Save();
tn = new VETreeNode((IVEDrillDownReadOnly)_LastFolderInfo);
SelectedNode.Nodes.Add(tn); // add new tree node to end of childlist.
}
else
f1 = folder.FolderID;
}
if (f1 != -1) Folder.Delete(f1);
}
else if (newtype == MenuSelections.FolderAfter||newtype == MenuSelections.FolderBefore)
{
int f2 = -1;
string uniquename = _LastFolderInfo.MyParent.UniqueChildName("New Folder");
int myindex = SelectedNode.Index + ((newtype == MenuSelections.FolderAfter) ? 1 : 0);
FolderInfo parfolderinfo = FolderInfo.Get(parentfolder.FolderID);
double? myorder = parfolderinfo.NewManualOrder(myindex);
using (Folder folder = Folder.MakeFolder(parentfolder.MyParent, parentfolder.MyConnection, uniquename, string.Empty, "Short Name", null, myorder, string.Empty, DateTime.Now, VlnSettings.UserID))
{
ShowBrokenRules(folder.BrokenRulesCollection);
SetLastValues(FolderInfo.Get(folder.FolderID));
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(uniquename, folder.FolderConfig)) == DialogResult.OK)
{
folder.Save();
tn = new VETreeNode((IVEDrillDownReadOnly)_LastFolderInfo);
if (newtype == MenuSelections.FolderBefore) SelectedNode.Parent.Nodes.Insert(SelectedNode.Index, tn);
if (newtype == MenuSelections.FolderAfter) SelectedNode.Parent.Nodes.Insert(SelectedNode.Index + 1, tn);
}
else
f2 = folder.FolderID;
}
if (f2 != -1) Folder.Delete(f2);
}
}
}
#endregion
#region InsertProcedure
else if (newtype == MenuSelections.Procedure)
{
int p1 = -1;
using (Procedure procedure = Procedure.MakeProcedure(_LastDocVersionInfo, _LastDocVersionInfo.Procedures.Count!=0?_LastDocVersionInfo.Procedures[_LastDocVersionInfo.Procedures.Count-1]:null, null, "New Procedure", 0))
{
ShowBrokenRules(procedure.BrokenRulesCollection);
SetLastValues(ProcedureInfo.Get(procedure.ItemID));
procedure.ProcedureConfig.CreatingNew = true;
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Procedure", procedure.ProcedureConfig)) == DialogResult.OK)
{
procedure.Save();
tn = new VETreeNode(_LastProcedureInfo);
SelectedNode.Nodes.Add(tn); // add tree node to end of list.
// The following line will allow for a refresh of the procedure list on the Working Draft's treenodes docversion (B2016-034)
if (((SelectedNode as VETreeNode).VEObject as DocVersionInfo) != null) ((SelectedNode as VETreeNode).VEObject as DocVersionInfo).ResetProcedures();
if (procedure.MyProcedureInfo.CreateEnhanced)
{
procedure.MyProcedureInfo.CreateEnhanced = false;
CreateEnhancedForProcedure(newtype, procedure, null);
}
}
else
p1 = procedure.ItemID;
}
if (p1 != -1)
DeleteItemInfoAndChildren(_LastProcedureInfo);// Delete Item and reset Previous and Next
}
else if (newtype == MenuSelections.ProcedureAfter || newtype == MenuSelections.ProcedureBefore)
{
int p2 = -1;
int tvindex = SelectedNode.Index;
// if inserting before, the parent is set in case previous is null, i.e. beginning of the list.
ProcedureInfo savLastProcedureInfo = _LastProcedureInfo;
using (Procedure procedure = Procedure.MakeProcedure((newtype == MenuSelections.ProcedureAfter) ? null : _LastProcedureInfo.ActiveParent, (newtype == MenuSelections.ProcedureAfter) ? _LastProcedureInfo : _LastProcedureInfo.MyPrevious, null, "New Procedure", 0))
{
ShowBrokenRules(procedure.BrokenRulesCollection);
SetLastValues(ProcedureInfo.Get(procedure.ItemID));
procedure.ProcedureConfig.CreatingNew = true;
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Procedure", procedure.ProcedureConfig)) == DialogResult.OK)
{
procedure.Save();
tn = new VETreeNode(_LastProcedureInfo);
TreeNode par = SelectedNode.Parent;
par.Nodes.Insert(tvindex + ((newtype == MenuSelections.ProcedureBefore) ? 0 : 1), tn);
// The following line will allow for a refresh of the procedure list on the Working Draft's treenodes docversion (B2016-034)
if (((par as VETreeNode).VEObject as DocVersionInfo) != null) ((par as VETreeNode).VEObject as DocVersionInfo).ResetProcedures();
if (procedure.MyProcedureInfo.CreateEnhanced)
{
procedure.MyProcedureInfo.CreateEnhanced = false;
CreateEnhancedForProcedure(newtype, procedure, savLastProcedureInfo);
}
}
else
p2 = procedure.ItemID;
}
if (p2 != -1)
DeleteItemInfoAndChildren(_LastProcedureInfo); // Delete Item and reset Previous and Next
}
#endregion
#region InsertSection
else if (newtype == MenuSelections.Section) // Insert subsection at end of parents section list
{
string message = string.Empty;
if (_LastProcedureInfo != null)
if (!MySessionInfo.CanCheckOutItem(_LastProcedureInfo.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
OnUnPauseRefresh(this, null);
return;
}
int s1 = -1;
if (!(_LastProcedureInfo == null) || !(_LastSectionInfo == null))
{
// May need to create 'pseudo' nodes, for the 'Steps' and 'Sections' grouping tree nodes.
// If no grouping nodes exist off a section (we are adding a subsection), then
// add a 'pseudo' node.
// If step(s) exists, but not a section, then need 'pseudo' nodes, i.e. 'Steps' and 'Sections'
// tree nodes.
// Otherwise, the 'Sections' pseudo node will exist.
// Note that this check has to be done before the section is made, otherwise the item will
// have sections, i.e. the one getting added.
bool doPseudo = false;
if (_LastItemInfo.IsSection) // if adding off of a procedure, don't add pseudo.
{
// B2017-014: removed code that was adding a 2nd section part node.
if (SelectedNode.Nodes.Count > 0)
{
// if inserting from a section that has steps, but no subsections, prompt user to let them
// know that the steps will not be visible after the subsection insert (C2016-042):
if (_LastItemInfo.Sections == null && _LastItemInfo.Steps != null && _LastItemInfo.Steps.Count > 0)
{
// C2020-016 reformatted and reworded the message.
// C2020-047 reformatted and reworded the message.
string msgstr =
"If there are already steps in the high level section, then PROMS will hide\n" +
"the steps in this section when the subsection is created.\n\n" +
"If you would like to view or copy these hidden steps you will need to go\n" +
"into the properties of this section and check the Editable Data checkbox.\n" +
"You will then be able to view and copy those steps. When finished, open\n" +
"the properties page again and uncheck the Editable Data checkbox.\n\n"+
"Do you want to continue creating the subsection?";
if (FlexibleMessageBox.Show(this, msgstr, "Subsection Insert", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return;
}
}
// Check to see if sections already exist, if so, the pseudo node will too.
bool hasMetaSubs = _LastItemInfo.Sections != null && _LastItemInfo.Sections.Count > 0;
if (!hasMetaSubs) doPseudo = true;
}
}
using(Section section = CreateNewSection())
{
ShowBrokenRules(section.BrokenRulesCollection);
SectionInfo savLastSectionInfo = _LastSectionInfo;
SetLastValues(SectionInfo.Get(section.ItemID));
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Section", section.SectionConfig)) == DialogResult.OK)
{
if (!doPseudo)
{
tn = new VETreeNode(_LastSectionInfo);
SelectedNode.Nodes.Add(tn); // add tree node to end of list.
// if the new section was flagged as either having an enhanced link for Title or Contents, create the
// Enhanced section:
Section sectiontmp = Section.Get(section.ItemID); // need to do this because of 'caching' problem.
if (sectiontmp.SectionConfig.LinkEnhanced == "T" || sectiontmp.SectionConfig.LinkEnhanced == "Y")
CreateEnhancedForSection(newtype, sectiontmp, savLastSectionInfo, sectiontmp.DisplayNumber, sectiontmp.MyContent.Text);
sectiontmp.Dispose();
OnNodeSelect(this, new vlnTreeEventArgs(tn));
}
else
{
// may have to add a 'steps' node if a step(s) already exist...
ItemInfo ii = (SelectedNode as VETreeNode).VEObject as ItemInfo;
int cpindx = 0;
if (SelectedNode.Nodes.Count>0)
{
VETreeNode vtn = SelectedNode.Nodes[0] as VETreeNode;
// B2017-014: removed code that was adding a 2nd section part node. and also select node to
// refresh display
if (vtn.FirstNode != null) OnNodeSelect(this, new vlnTreeEventArgs(vtn.FirstNode));
}
// B2017-014: removed code that was adding a 2nd section part node.
}
}
else // Properties was canceled out of:
s1 = section.ItemID;
}
if (s1 != -1)
{
DeleteItemInfoAndChildren(_LastSectionInfo);// Delete Item and reset Previous and Next
// B2020-087 refresh the tree node after canceling the creation of the subsection
_LastTreeNode.ChildrenLoaded = false;
_LastTreeNode.RefreshNode();
_LastTreeNode.Collapse();
}
}
}
else if (newtype == MenuSelections.SectionAfter || newtype == MenuSelections.SectionBefore)
{
string message = string.Empty;
if (!MySessionInfo.CanCheckOutItem(_LastSectionInfo.MyProcedure.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
OnUnPauseRefresh(this, null);
return;
}
int tvindex = SelectedNode.Index;
// if inserting before, the parent is set in case previous is null, i.e. beginning of the list.
int s2 = -1;
using (Section section = Section.MakeSection((newtype == MenuSelections.SectionAfter) ? null : _LastSectionInfo.MyParent, (newtype == MenuSelections.SectionAfter) ? _LastSectionInfo : _LastSectionInfo.MyPrevious, null, "New Section", 10000))
{
ShowBrokenRules(section.BrokenRulesCollection);
SectionInfo savLastSectionInfo = _LastSectionInfo;
SetLastValues(SectionInfo.Get(section.ItemID));
TreeNode par = SelectedNode.Parent;
if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Section", section.SectionConfig)) == DialogResult.OK)
{
int indx = tvindex + ((newtype == MenuSelections.SectionBefore) ? 0 : 1);
int itemido = (indx >= par.Nodes.Count)?-1:(((par.Nodes[indx] as VETreeNode).VEObject) as ItemInfo).ItemID;
if (indx >= par.Nodes.Count || (par.Nodes[indx] as VETreeNode).VEObject.ToString() != _LastSectionInfo.ToString() || itemido !=section.ItemID)
{
tn = new VETreeNode(_LastSectionInfo);
par.Nodes.Insert(indx, tn);
// if the new section was flagged as either having an enhanced link for Title or Contents, create the
// Enhanced section:
Section sectiontmp = Section.Get(section.ItemID); // need to do this because of 'caching' problem.
if (sectiontmp.SectionConfig.LinkEnhanced == "T" || sectiontmp.SectionConfig.LinkEnhanced == "Y")
CreateEnhancedForSection(newtype, sectiontmp, savLastSectionInfo, sectiontmp.DisplayNumber, sectiontmp.MyContent.Text);
sectiontmp.Dispose();
}
}
else
s2 = section.ItemID;
}
if (s2 != -1)
{
DeleteItemInfoAndChildren(_LastSectionInfo);// Delete Item and reset Previous and Next
// B2020-087 refresh the tree node after canceling the creation of the subsection
_LastTreeNode.ChildrenLoaded = false;
_LastTreeNode.RefreshNode();
_LastTreeNode.Collapse();
}
}
#endregion
#region InsertStep
else if (newtype == MenuSelections.Step) // insert step from section - no substeps from tree.
{
string message = string.Empty;
if (!MySessionInfo.CanCheckOutItem(_LastSectionInfo.MyProcedure.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
OnUnPauseRefresh(this, null);
return;
}
tn = InsertChildStep((VETreeNode)SelectedNode);
}
else if (newtype == MenuSelections.StepAfter || newtype == MenuSelections.StepBefore && _LastStepInfo != null)
{
string message = string.Empty;
if (!MySessionInfo.CanCheckOutItem(_LastStepInfo.MyProcedure.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
OnUnPauseRefresh(this, null);
return;
}
tn = InsertBeforeOrAfter(newtype, (VETreeNode)SelectedNode);
}
#endregion
if (tn != null)
{
SelectedNode = tn;
OnNodeNew(this, new vlnTreeEventArgs(SelectedNode));
Refresh();
OnNodeInsert(this, new vlnTreeEventArgs(SelectedNode));
}
OnUnPauseRefresh(this, null);
}
private void CreateEnhancedForProcedure(MenuSelections typ, Procedure sourceProc, ProcedureInfo lastProcedureInfo)
{
if (typ == MenuSelections.ProcedureAfter || typ == MenuSelections.ProcedureBefore) // new from procedure (before or after)
{
// The procedure that this is inserted from may not have associated enhanced procedures. Going up list, look for a procedure
// that has enhanced.
ItemInfo tmpPI = lastProcedureInfo;
EnhancedDocuments eds = null;
while (eds == null && tmpPI != null)
{
ProcedureConfig pc = tmpPI.MyConfig as ProcedureConfig;
if (pc.MyEnhancedDocuments != null && pc.MyEnhancedDocuments.Count > 0)
{
eds = pc.MyEnhancedDocuments;
break;
}
tmpPI = tmpPI.MyPrevious;
}
if (eds != null)
{
foreach (EnhancedDocument ped in eds)
{
ProcedureInfo epi = ProcedureInfo.Get(ped.ItemID);
using (Procedure newenhProcedure = Procedure.MakeProcedure((typ == MenuSelections.ProcedureAfter) ? null : epi.ActiveParent, (typ == MenuSelections.ProcedureAfter) ? epi : epi.MyPrevious, null, "New Procedure", 0))
{
SaveEnhancedForProcedure(sourceProc, newenhProcedure, ped.Type);
RefreshRelatedNode(ProcedureInfo.Get(newenhProcedure.ItemID));
}
}
return;
}
}
// do the following code if insert the procedure from docverion, or if no linked procedure was found above while doing an insert section from before/after
DocVersionConfig dvc = sourceProc.MyProcedureInfo.MyDocVersion.MyConfig as DocVersionConfig;
ProcedureConfig sourcecfg = sourceProc.ProcedureConfig;
if (dvc != null)
{
foreach (DVEnhancedDocument ded in dvc.MyEnhancedDocuments)
{
// get the enhaced docversioninfo:
DocVersionInfo enhDVInfo = DocVersionInfo.Get(ded.VersionID);
using (Procedure newenhProcedure = Procedure.MakeProcedure(enhDVInfo, enhDVInfo.Procedures.Count != 0 ? enhDVInfo.Procedures[enhDVInfo.Procedures.Count - 1] : null, null, "New Procedure", 0))
{
SaveEnhancedForProcedure(sourceProc, newenhProcedure, ded.Type);
RefreshRelatedNode(ProcedureInfo.Get(newenhProcedure.ItemID)); // this updates the treeview to include the new enhanced procedure
}
}
}
}
private void SaveEnhancedForProcedure(Procedure sourceProc, Procedure newenhProcedure, int enhtype)
{
ProcedureConfig newenhcfg = new ProcedureConfig(newenhProcedure);
newenhcfg.AddEnhancedDocument(0, sourceProc.ItemID);
newenhcfg.SaveEnhancedDocuments();
using (Content c1 = Content.Get(newenhProcedure.ContentID))
{
c1.Config = newenhcfg.ToString();
c1.Save();
}
sourceProc.ProcedureConfig.AddEnhancedDocument(enhtype, newenhProcedure.ItemID);
sourceProc.ProcedureConfig.SaveEnhancedDocuments();
using (Content cs = Content.Get(sourceProc.ContentID))
{
cs.Config = sourceProc.ProcedureConfig.ToString();
cs.Save();
}
}
private void CreateEnhancedForSection(MenuSelections typ, Section sourceSect, SectionInfo lastSectionInfo, string num, string title)
{
MenuSelections tmptyp = typ;
if (typ == MenuSelections.SectionAfter || typ == MenuSelections.SectionBefore)
{
ItemInfo tmpSI = lastSectionInfo;
EnhancedDocuments eds = null; // need to find a good list, i.e. there may be non-linked sections before/after:
while (eds == null && tmpSI != null)
{
SectionConfig sc = tmpSI.MyConfig as SectionConfig;
if (sc.MyEnhancedDocuments != null && sc.MyEnhancedDocuments.Count > 0)
{
eds = sc.MyEnhancedDocuments;
break;
}
// if had to skip unlinked sections, it becomes an 'after' a linked one:
tmptyp = MenuSelections.SectionAfter;
tmpSI = tmpSI.MyPrevious;
}
if (eds != null) // found valid enhanced ids to insert from:
{
foreach (EnhancedDocument sed in eds)
{
SectionInfo esi = SectionInfo.Get(sed.ItemID);
using (Section newenhSection = Section.MakeSection((tmptyp == MenuSelections.SectionAfter) ? null : esi.ActiveParent, (tmptyp == MenuSelections.SectionAfter) ? esi : esi.MyPrevious, num, title, 10000))
{
SaveEnhancedForSection(sourceSect, newenhSection, sed.Type);
RefreshRelatedNode(SectionInfo.Get(newenhSection.ItemID));
}
}
return;
}
}
// do the following code if insert the section from the procedure, or if no linked section was found above while doing an insert section from before/after
ProcedureConfig pc = sourceSect.MyItemInfo.MyProcedure.MyConfig as ProcedureConfig;
SectionConfig sourcecfg = sourceSect.SectionConfig;
if (pc != null)
{
foreach (EnhancedDocument ed in pc.MyEnhancedDocuments)
{
// get the enhanced procedureinfo:
ProcedureInfo enhInfo = ProcedureInfo.Get(ed.ItemID);
if (enhInfo.LastChild(E_FromType.Section) != null)
{
using (Section newenhSection = Section.MakeSection(enhInfo, (enhInfo.Sections != null && enhInfo.Sections.Count != 0) ? enhInfo.Sections[enhInfo.Sections.Count - 1] : null, num, title, 10000))
{
SaveEnhancedForSection(sourceSect, newenhSection, ed.Type);
RefreshRelatedNode(SectionInfo.Get(newenhSection.ItemID));
}
}
else
{
ItemInfo newenhSectionII = enhInfo.InsertChild(E_FromType.Section, 10000, title, num);
using (Section newenhSect = Section.Get(newenhSectionII.ItemID))
{
SaveEnhancedForSection(sourceSect, newenhSect, ed.Type);
RefreshRelatedNode(SectionInfo.Get(newenhSect.ItemID));
}
}
}
}
}
private void SaveEnhancedForSection(Section sourceSect, Section newenhSection, int enhtype)
{
SectionConfig newenhcfg = new SectionConfig(newenhSection);
newenhcfg.AddEnhancedDocument(0, sourceSect.ItemID);
newenhcfg.SaveEnhancedDocuments(); // does this save data?
using (Content c1 = Content.Get(newenhSection.ContentID))
{
c1.Config = newenhcfg.ToString();
c1.Save();
}
sourceSect.SectionConfig.AddEnhancedDocument(enhtype, newenhSection.ItemID);
sourceSect.SectionConfig.SaveEnhancedDocuments();
using (Content cs = Content.Get(sourceSect.ContentID))
{
cs.Config = sourceSect.SectionConfig.ToString();
cs.Save();
}
}
private Section CreateNewSection()
{
// B2020-087 the config for SubSection_Edit was sometimes set even when there wasn't any subsections,
// so make sure it's cleared if there are no existing subsections
SectionConfig sc = _LastItemInfo.MyConfig as SectionConfig;
if (sc != null && sc.SubSection_Edit == "Y" && _LastItemInfo.Sections == null)
{
sc.SubSection_Edit = null;
using (Section mysect = Section.Get(_LastItemInfo.ItemID))
{
mysect.MyContent.Config = sc.ToString();
mysect.Save();
}
}
if (_LastItemInfo.LastChild(E_FromType.Section) != null)
return Section.MakeSection(_LastItemInfo, _LastItemInfo.LastChild(E_FromType.Section), null, "New Section", 10000);
ItemInfo iii = _LastItemInfo.InsertChild(E_FromType.Section, 10000, "New Section", null);
return Section.Get(iii.ItemID);
}
private VETreeNode InsertChildStep(VETreeNode tn)
{
// 11/17/15: if inserted with step editor open, step gets inserted as child first child. If step editor is not
// open, step gets inserted at end (as last item in list)
// If parent step is open in editor, use the OnInsertItemInfo to insert step & add RTBItems to step editor panel
ItemInfo ii = tn.VEObject as ItemInfo;
if (OnInsertItemInfo(this, new vlnTreeItemInfoInsertEventArgs(ii, E_InsertType.Child, "New Step", 20002, E_FromType.Step)))
{
if (ii.IsStep) return null;
// if this was a section, it may have enhanced, so the enhanced steps will need to be created also.
SectionConfig scfg = ii.MyConfig as SectionConfig;
if (scfg.Section_LnkEnh != "Y") return null;
SetLastValues(StepInfo.Get(ii.Steps[0].ItemID));
}
else
{
// The parent step was not open in the step editor, just create new step(s) and add treenode.
int newId = -1;
// B2020-076: if this step has a template, insert template steps.
int topType = ii.GetSmartTemplateTopLevelIndxOfThisType(20002);
if (topType != -1)
{
ItemInfo tmp = null;
tmp = ii.InsertSmartTemplateSubStep("New Step", null, null, ItemInfo.EAddpingPart.Child, 20002, E_FromType.Step);
newId = tmp.ItemID;
}
else
{
// this line (below) adds the new step to the bottom of the section, the other line (not commented) adds it to the top. Bug fix B2016-002
//using (Step step = Step.MakeStep(_LastItemInfo, _LastItemInfo.LastChild(E_FromType.Step), null, "New Step", 20002, E_FromType.Step))
using (Step step = Step.MakeStep(_LastItemInfo, null, null, "New Step", 20002, E_FromType.Step))
{
ShowBrokenRules(step.BrokenRulesCollection);
newId = step.ItemID;
}
}
SetLastValues(StepInfo.Get(newId));
tn = new VETreeNode(_LastStepInfo);
_LastStepInfo.UpdateTransitionText();
_LastStepInfo.UpdateROText();
TreeNode par = SelectedNode;
par.Nodes.Insert(0, tn);
}
// see if enhanced related steps need created:
SectionConfig scfgE = _LastItemInfo.ActiveSection.MyConfig as SectionConfig; // C2018-003 fixed use of getting the active section
if (scfgE != null && scfgE.Section_LnkEnh=="Y")
{
// set up which item to insert from based on whether editor was open (see comment from 11/17 above).
EnhancedDocuments enhdocs = null;
ItemInfo.EAddpingPart addpart = ItemInfo.EAddpingPart.Child;
if (_LastItemInfo.MyPrevious != null) // the code above will do the MakeStep regardless of whether editor is up if this is the only step.
{
addpart = ItemInfo.EAddpingPart.After;
ItemInfo lstSrc = _LastItemInfo.MyPrevious;
StepConfig stcfg = lstSrc.MyConfig as StepConfig;
if (stcfg == null) enhdocs = scfgE.MyEnhancedDocuments;
else enhdocs = stcfg.MyEnhancedDocuments;
}
else
{
enhdocs = scfgE.MyEnhancedDocuments;
}
foreach (EnhancedDocument ed in enhdocs)
{
// the new source step's item is passed in to know what type & what to link to.
// The ed.Type & itemid show what type of enhanced document (used to create new
// config Type)
_LastItemInfo.DoAddEnhancedSteps(ed.Type, ed.ItemID, addpart);
}
}
return tn;
}
private VETreeNode InsertBeforeOrAfter(MenuSelections newtype, VETreeNode tn)
{
// If parent step is open in editor, use the OnInsertItemInfo to insert step & add RTBItems to step editor panel
ItemInfo ii = tn.VEObject as ItemInfo;
if (OnInsertItemInfo(this, new vlnTreeItemInfoInsertEventArgs(ii, (newtype == MenuSelections.StepAfter) ? E_InsertType.After : E_InsertType.Before, "New Step")))
{
tn = (VETreeNode)((newtype == MenuSelections.StepAfter) ? tn.NextNode : tn.PrevNode);
}
else
{
// The parent step was not open in the step editor, just create new step and add treenode.
int tvindex = SelectedNode.Index;
// B2020-076: if this step has a template, insert template steps.
int newid = -1;
if (ii.FormatStepData.UseSmartTemplate || ii.FormatStepData.UseOldTemplate)
{
ItemInfo tmp = ii.InsertSmartTemplateSteps("New Step", null, null, newtype == MenuSelections.StepAfter ? ItemInfo.EAddpingPart.After : ItemInfo.EAddpingPart.Before, (int)ii.MyContent.Type);
newid = tmp.ItemID;
}
else
{
// if inserting before, the parent is set in case previous is null, i.e. beginning of the list.
ItemInfo parent = (newtype == MenuSelections.StepAfter) ? null : _LastStepInfo.MyParent;
using (Step step = Step.MakeStep(parent, (newtype == MenuSelections.StepAfter) ? _LastStepInfo : _LastStepInfo.MyPrevious, null, "New Step", (int)_LastStepInfo.MyContent.Type, (E_FromType)_LastStepInfo.FirstSibling.ItemParts[0].FromType))
{
ShowBrokenRules(step.BrokenRulesCollection);
newid = step.ItemID;
}
}
SetLastValues(StepInfo.Get(newid));
tn = new VETreeNode(_LastStepInfo);
_LastStepInfo.UpdateTransitionText();
_LastStepInfo.UpdateROText();
TreeNode par = SelectedNode.Parent;
par.Nodes.Insert(tvindex + ((newtype == MenuSelections.StepBefore) ? 0 : 1), tn);
}
if (tn != null)
{
// add enhanced steps if applicable (this code is only run if a step is inserted, not for a section).
// Also, NOTE that this is not needed for InsertChildStep from tree because there is no menu item
// to support inserting a type that would have enhanced from tree.
StepConfig sib = ii.MyConfig as StepConfig;
foreach (EnhancedDocument ed in sib.MyEnhancedDocuments)
{
// create a new enhanced step and link it to this new source step.
// the new source step's item is passed in to know what type & what to link to.
// The ed.Type & itemid show what type of enhanced document (use to create new
// config Type) and itemid is the one to insert after.
ItemInfo.EAddpingPart addpart = ItemInfo.EAddpingPart.After;
if (newtype == MenuSelections.StepBefore) addpart = ItemInfo.EAddpingPart.Before;
ItemInfo newSourceStep = tn.VEObject as ItemInfo;
newSourceStep.DoAddEnhancedSteps(ed.Type, ed.ItemID, addpart);
}
}
return tn;
}
private void ShowBrokenRules(BrokenRulesCollection brs)
{
if (brs != null)
{
foreach (BrokenRule br in brs)
{
Console.WriteLine("broken rule {0}", br.Description);
}
}
}
#endregion
#region DeleteAllLevels
private bool tv_NodeDelete()
{
SetLastValues((VETreeNode)SelectedNode);
string message = string.Empty;
string typeDescription = "item";
if (_LastStepInfo != null)
{
if (!MySessionInfo.CanCheckOutItem(_LastStepInfo.MyProcedure.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
//C2020-026 specific description of what user is trying to delete
typeDescription = "\"" + _LastStepInfo.FormatStepData.StepEditData.TypeMenu.MenuItem + "\"";
if (_LastStepInfo.HasChildren) typeDescription += " and its substeps";
}
if (_LastSectionInfo != null)
{
if (!MySessionInfo.CanCheckOutItem(_LastSectionInfo.MyProcedure.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
//C2020-026 specific description of what user is trying to delete
typeDescription = "Section";
if (_LastSectionInfo.HasChildren) typeDescription += " and its steps";
}
if (_LastProcedureInfo != null)
{
if (!MySessionInfo.CanCheckOutItem(_LastProcedureInfo.ItemID, CheckOutType.Procedure, ref message))
{
FlexibleMessageBox.Show(this, message, "Item Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
typeDescription = "Procedure"; //C2020-026 specific description of what user is trying to delete
}
if (_LastDocVersionInfo != null)
{
StringBuilder sb = new StringBuilder();
foreach (ProcedureInfo pi in _LastDocVersionInfo.Procedures)
{
if (!MySessionInfo.CanCheckOutItem(pi.ItemID, CheckOutType.Procedure, ref message))
sb.AppendLine(message);
message = string.Empty;
}
if (sb.Length > 0)
{
FlexibleMessageBox.Show(this, sb.ToString(), "Items Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
typeDescription = "Procedure Set"; //C2020-026 specific description of what user is trying to delete
}
if (_LastFolderInfo != null)
{
StringBuilder sb = new StringBuilder();
if (_LastFolderInfo.FolderDocVersionCount > 0)
{
foreach (DocVersionInfo dvi in _LastFolderInfo.FolderDocVersions)
{
foreach (ProcedureInfo pi in dvi.Procedures)
{
if (!MySessionInfo.CanCheckOutItem(pi.ItemID, CheckOutType.Procedure, ref message))
sb.AppendLine(message);
message = string.Empty;
}
}
}
if (sb.Length > 0)
{
FlexibleMessageBox.Show(this, sb.ToString(), "Items Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
typeDescription = "Folder"; //C2020-026 specific description of what user is trying to delete
}
//C2020-026 added standardized wording when attempting to delete
DialogResult result = DialogResult.No;
if (_LastProcedureInfo == null)
{
result = FlexibleMessageBox.Show("Are you sure you want to delete this " + typeDescription + "?", "Verify Delete",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
}
if (_LastProcedureInfo != null || result == DialogResult.Yes)
{
if (_LastFolderInfo != null)
{
Folder.Delete(_LastFolderInfo.FolderID);
_LastFolderInfo = null;
return true;
}
else if (_LastDocVersionInfo != null)
{
// if this has enhanced linked DocVersions, delete them first.
DocVersionConfig dvc = _LastDocVersionInfo.MyConfig as DocVersionConfig;
if (dvc != null && dvc.MyEnhancedDocuments != null && dvc.MyEnhancedDocuments.Count > 0)
{
foreach (DVEnhancedDocument dve in dvc.MyEnhancedDocuments)
{
if (dve.Type != 0)
DocVersion.Delete(dve.VersionID);
else
{
// B2018-025: for the input source docversion (id), clear out its enhanced document link information
// dvi is the source, remove this (_LastDocVersionInfo) background link from the source's config
DocVersionInfo dvi = DocVersionInfo.Get(dve.VersionID);
DocVersionConfig dvci = dvi.MyConfig as DocVersionConfig;
dvci.RemoveEnhancedLink(_LastDocVersionInfo.VersionID);
string dvccfg = dvci.ToString();
using (DocVersion dv = dvi.Get())
{
dv.Config = dvccfg;
dv.Save();
DocVersionInfo.Refresh(dv);
}
}
}
}
DocVersion.Delete(_LastDocVersionInfo.VersionID);
_LastDocVersionInfo = null;
(((VETreeNode)SelectedNode.Parent).VEObject as FolderInfo).RefreshFolderDocVersions(); // B2018-082 tell tree node that it no longer has a working draft
return true;
}
else if (_LastProcedureInfo != null)
{
dlgDelProcReason dlgDPA = new dlgDelProcReason(this); // C2020-038: prompt user for reason
DialogResult res = dlgDPA.ShowDialog(this);
if (res == DialogResult.OK)
{
//If there are enhanced, they will also need deleted, save the ids so that they
// can be deleted after this item gets deleted.
List<int> enhIds = new List<int>();
// C2020-038: request reason for delete procedure so this can be saved in database
ProcedureConfig prc = _LastProcedureInfo.MyConfig as ProcedureConfig;
prc.General_DelProcReason = DelProcReason;
using (Item itm = Item.Get(_LastProcedureInfo.ItemID))
{
itm.MyContent.Config = prc.ToString();
itm.UserID = Volian.Base.Library.VlnSettings.UserID;
itm.Save();
}
foreach (EnhancedDocument ed in prc.MyEnhancedDocuments)
if (ed.Type != 0) enhIds.Add(ed.ItemID);
// always return false because an event gets fired to delete tree nodes.
if (!DeleteItemInfoAndChildren(_LastProcedureInfo)) return false;
_LastProcedureInfo = null;
foreach (int enhId in enhIds)
{
ProcedureInfo pi = ProcedureInfo.Get(enhId);
// if the item was displayed in the editor, the 'DeleteItemInfoAndChildren' call
// above will go through user interface code that deletes the enhanced, so 'Get'
// will return a null (i.e. the data no longer exists).
if (pi != null)
{
if (!DeleteItemInfoAndChildren(pi)) Console.WriteLine("do an error log item");
}
}
return false;
}
}
else if (_LastSectionInfo != null)
{
// For sections, there are a number of things to check for if enhanced is active:
// 1) in a source and the enhanced link can be none, title or contents.
// 2) if none, just delete
// 3) If just title and in source, clear links in enhanced back to this source
// before delete.
// 4) If in enhanced, by source has link type set to title, can delete this
// section, but first clear source's links
//If there are enhanced, they will also need deleted, save the ids so that they
// can be deleted after this item gets deleted.
List<int> enhIds = new List<int>();
SectionConfig sec = _LastSectionInfo.MyConfig as SectionConfig;
if (_LastSectionInfo.IsEnhancedSectionTitleOnly)
{
_LastSectionInfo.ClearEnhancedSectionFromSource(sec.MyEnhancedDocuments[0].ItemID);
}
else if (sec.Section_LnkEnh == "Y")
{
foreach (EnhancedDocument ed in sec.MyEnhancedDocuments)
if (ed.Type != 0) enhIds.Add(ed.ItemID);
}
else if (sec.Section_LnkEnh == "T")
{
// just clear enhanced links back
_LastSectionInfo.ClearEnhancedSectionLink();
}
OnSectionShouldClose(this, new vlnTreeSectionInfoEventArgs(_LastSectionInfo,true));
// always return false because an event gets fired to delete tree nodes.
if (!DeleteItemInfoAndChildren(_LastSectionInfo))
{
return false;
}
// B2020-087 refresh the tree node after the delete - needed when deleting the last subsection or canceling the creation of the first subsection
(this.SelectedNode as VETreeNode).ChildrenLoaded = false;
(this.SelectedNode as VETreeNode).RefreshNode();
(this.SelectedNode as VETreeNode).Collapse();
WordSectionEventArgs args = new WordSectionEventArgs(_LastSectionInfo);
OnWordSectionDeleted(this, args);
_LastSectionInfo = null;
foreach (int enhId in enhIds)
{
SectionInfo si = SectionInfo.Get(enhId);
// if the item was displayed in the editor, the 'DeleteItemInfoAndChildren' call
// above will go through user interface code that deletes the enhanced, so 'Get'
// will return a null (i.e. the data no longer exists).
if (si != null)
{
if (!DeleteItemInfoAndChildren(si)) Console.WriteLine("do an error log item");
}
}
return false;
}
else if (_LastStepInfo != null)
{
//If there are enhanced, they will also need deleted, save the ids so that they
// can be deleted after this item gets deleted. Note that if the step(s) were
// displayed in step editor, that code deletes the enhanced steps.
List<int> enhIds = new List<int>();
StepConfig sc = _LastStepInfo.MyConfig as StepConfig;
foreach (EnhancedDocument ed in sc.MyEnhancedDocuments)
if (ed.Type != 0) enhIds.Add(ed.ItemID);
// always return false because an event gets fired to delete tree nodes.
if (!DeleteItemInfoAndChildren(_LastStepInfo)) return false;
_LastStepInfo = null;
foreach (int enhId in enhIds)
{
StepInfo si = StepInfo.Get(enhId);
// if the item was displayed in the editor, the 'DeleteItemInfoAndChildren' call
// above will go through user interface code that deletes the enhanced, so 'Get'
// will return a null (i.e. the data no longer exists).
if (si != null)
{
if (!DeleteItemInfoAndChildren(si)) Console.WriteLine("do an error log item");
}
}
return false;
}
}
return false;
}
private bool DeleteItemInfoAndChildren(ItemInfo ii)
{
DateTime dtStart = DateTime.Now;
try
{
ItemInfo pii = ii.MyParent;
bool deletedSection = ii.IsSection;
// send an event to frmVeproms that sends an event to the stepeditor to
// do delete using RTBItem - this manages windowing from the step editor.
// If the procedure is open & you're deleting procedure, you want to close open
// window - this is done in DisplayTabControl-DeleteStepTabItem.
OnProcessing(true,"Deleting");
if (!OnDeleteItemInfo(this, new vlnTreeItemInfoEventArgs(ii)))
Item.DeleteItemAndChildren(ii);
OnProcessing(false,"Deleted");
OnProcessingComplete(dtStart,"Deleted");
if (deletedSection)
{
// B2020-087 if we deleted the last sub section, then clear the SubSection_Edit in the parent's config
SectionConfig sc = pii.MyConfig as SectionConfig;
if (sc != null && sc.SubSection_Edit == "Y" && pii.Sections == null) // B2020-103: Added null check
{
sc.SubSection_Edit = null;
using (Section mysect = Section.Get(pii.ItemID))
{
mysect.MyContent.Config = sc.ToString();
mysect.Save();
}
}
}
return true;
}
catch (System.Data.SqlClient.SqlException ex)
{
OnProcessing(false,"Delete Failed");
OnProcessingComplete(dtStart,"Delete Failed");
// C2020-033: Support delete to bring up Search/Incoming Transitions panel
if (ex.Message.Contains("has External Transitions"))
{
ItemInfo iis = ItemInfo.Get(ii.ItemID);
OnSearchIncTransIn(this, new vlnTreeItemInfoEventArgs(iis));
iis = ii.HandleSqlExceptionOnDelete(ex);
}
else
{
ItemInfo iii = ii.HandleSqlExceptionOnDelete(ex);
if (iii != null) OnOpenItem(this, new vlnTreeItemInfoEventArgs(iii));
}
return false;
}
}
public event vlnTreeViewTimeEvent ProcessingComplete;
private void OnProcessingComplete(DateTime dtStart, string message)
{
if (ProcessingComplete != null)
ProcessingComplete(this, new vlnTreeTimeEventArgs(dtStart,message));
}
public event vlnTreeViewStatusEvent Processing;
private void OnProcessing(bool status, string message)
{
if (Processing != null)
Processing(this, new vlnTreeStatusEventArgs(status,message));
}
#endregion
#region SetLastValuesAndSaveIfChangedStuff
private void SetLastValues(VETreeNode node)
{
_LastTreeNode = node;
SetLastValues(node.VEObject);
}
private void SetLastValues(IVEDrillDownReadOnly veobject)
{
_LastFolderInfo = veobject as FolderInfo;
_LastDocVersionInfo = veobject as DocVersionInfo;
_LastProcedureInfo = veobject as ProcedureInfo;
_LastSectionInfo = veobject as SectionInfo;
_LastStepInfo = veobject as StepInfo;
_LastItemInfo = veobject as ItemInfo;
}
#endregion
#region Cursor
private bool SetupDragCursor(ImageList il, TreeNode tn)
{
// Reset image list used for drag image
il.Images.Clear();
int howBig = tn.Bounds.Size.Width + this.Indent;
if (howBig > 256) howBig = 256;
il.ImageSize = new Size(howBig, tn.Bounds.Height);
// Create new bitmap
// This bitmap will contain the tree node image to be dragged
Bitmap bmp = new Bitmap(tn.Bounds.Width + this.Indent, tn.Bounds.Height);
// Get graphics from bitmap
Graphics gfx = Graphics.FromImage(bmp);
// Draw node icon into the bitmap
if (this.ImageList != null) gfx.DrawImage(this.ImageList.Images[0], 0, 0);
// Draw node label into bitmap
gfx.DrawString(tn.Text, this.Font, new SolidBrush(this.ForeColor),
// new SolidBrush(Color.Blue),
(float)this.Indent, 1.0f);
// Add bitmap to imagelist
_dragImageList.Images.Add(bmp);
// Get mouse position in client coordinates
Point p = this.PointToClient(Control.MousePosition);
// Compute delta between mouse position and node bounds
int dx = p.X + this.Indent - tn.Bounds.Left;
int dy = p.Y - tn.Bounds.Top;
// Begin dragging image
return DragHelper.ImageList_BeginDrag(_dragImageList.Handle, 0, dx, dy);
}
private void tv_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
{
if (_doingCollapseNode)
{
_doingCollapseNode = false;
return;
}
// Get drag node and select it
try
{
TreeNode dragNode = (TreeNode)e.Item;
Type t = dragNode.GetType();
//if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Item Drag {0} - {1}", t.FullName, t.BaseType.FullName);
Type t2 = Type.GetType(t.FullName);
//if(t2 != null)
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Item Drag {0} - {1}", t2.FullName, t2.BaseType.FullName);
this.SelectedNode = dragNode;
ItemInfo iidrag = ((VETreeNode)dragNode).VEObject as ItemInfo;
FolderInfo fdrag = ((VETreeNode)dragNode).VEObject as FolderInfo;
DocVersionInfo ddrag = ((VETreeNode)dragNode).VEObject as DocVersionInfo;
if ((iidrag == null && fdrag == null && ddrag == null))
{
FlexibleMessageBox.Show("Cannot drag/drop a grouping node.");
return;
}
// don't put up message, message kept coming up on any selection of node (to copy, properties, etc)
//if (iidrag != null && iidrag.IsStep) return;
if (SetupDragCursor(_dragImageList, dragNode))
{
this.DoDragDrop(dragNode, DragDropEffects.Move | DragDropEffects.Copy);// Begin dragging
DragHelper.ImageList_EndDrag();// End dragging image
}
}
catch (Exception ex)
{
if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_ItemDrag", ex);
}
}
#endregion
#region DragDrop
ImageList _dragImageList = new ImageList();
public enum DropPosition : int
{
Child = 0, Before = 1, After = 2
}
private class DropLocation
{
#region Business Methods
private TreeNode _dropNode;
public TreeNode DropNode
{
get { return _dropNode; }
set { _dropNode = value; }
}
private int _index;
public int Index
{
get { return _index; }
set { _index = value; }
}
private DropPosition _position;
public DropPosition Position
{
get { return _position; }
set { _position = value; }
}
DateTime _lastScroll;
public DateTime LastScroll
{
get { return _lastScroll; }
}
private string _location = string.Empty;
#endregion
#region Constructors
public DropLocation(TreeView tv, System.Windows.Forms.DragEventArgs e, DateTime lastScroll)
{
_lastScroll = lastScroll;
_dropNode = tv.GetNodeAt(tv.PointToClient(new Point(e.X, e.Y)));
if (_dropNode == null) return;
int OffsetY = tv.PointToClient(Cursor.Position).Y - _dropNode.Bounds.Top;
if (OffsetY < _dropNode.Bounds.Height / 3) // First Third - Before
{
_index = _dropNode.Index;
_dropNode = _dropNode.Parent;
_position = DropPosition.Before;
_location = string.Format("Before1 {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY);
}
else if ((OffsetY / 2) < _dropNode.Bounds.Height / 3) // Second Third - Child
{
_location = string.Format("Child {0} y={1}", _dropNode.Text, OffsetY);
_position = DropPosition.Child;
_index = 0;
//if (_dropNode.Parent == null)
//{
// if(_MyLog.IsInfoEnabled)_MyLog.Info("Root Node");
//}
}
else // Last Third - After Now I need to check the X value
{
if (_dropNode.NextVisibleNode != null && _dropNode.Nodes.Count > 0 && _dropNode.IsExpanded)// Has Children & Expanded - Insert first child
{
// _dropNode = _dropNode.Nodes[0];
_index = 0;
_position = DropPosition.Before;
_location = string.Format("Before2 {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY);
}
else // No Children or Children Collapsed - Insert Next at various levels depending upon horizontal location.
{
Point pt = tv.PointToClient(new Point(e.X, e.Y));
TreeNode nextParent = _dropNode.NextNode;
if (nextParent != null) nextParent = nextParent.Parent;
do
{
_index = _dropNode.Index;
_dropNode = _dropNode.Parent;
} while (pt.X < _dropNode.Bounds.X && _dropNode != nextParent);
_location = string.Format("After {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY);
_position = DropPosition.After;
}
}
LimitMoves(e);
}
public void LimitMoves(DragEventArgs e)
{
if ((e.KeyState & 8) == 0)
{
//TreeNode dragNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
//TreeNode dragNode = (TreeNode)e.Data.GetData("TreeTest.FolderTreeNode");
TreeNode dragNode = vlnTreeView.GetTreeNodeFromData(e.Data);
switch (_position)
{
case DropPosition.Before:
if (dragNode == _dropNode.Nodes[_index] || dragNode == _dropNode.Nodes[_index].PrevNode)
{
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Before {0} {1} {2} {3} {4}", dragNode.Text ,_position.ToString() , _dropNode.Nodes[_index].Text
// ,_dropNode.Nodes[_index].PrevNode,_dropNode.Nodes[_index].NextNode);
_dropNode = null;
}
break;
case DropPosition.Child:
if (dragNode.Parent == _dropNode)
{
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Child {0} {1} {2} {3} {4} {5}", dragNode.Text ,_position.ToString() , _dropNode.Nodes[_index].Text
// ,_dropNode.Nodes[_index].PrevNode,_dropNode.Nodes[_index].NextNode,DateTime.Now);
_dropNode = null;
}
break;
case DropPosition.After:
if (dragNode == _dropNode.Nodes[_index] || dragNode == _dropNode.Nodes[_index].NextNode)
{
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("After {0} {1} {2} {3} {4}", dragNode.Text ,_position.ToString() , _dropNode.Nodes[_index].Text
// ,_dropNode.Nodes[_index].PrevNode,_dropNode.Nodes[_index].NextNode);
_dropNode = null;
}
break;
}
}
}
#endregion
public override string ToString()
{
return string.Format("{0}[{1}].{2}", _dropNode.Text, _index, _position.ToString());
}
#region Drawing
private void TreeNodeTriangle(Graphics g)
{
Rectangle r = _dropNode.Bounds;
int RightPos = r.Right + 6;
Point[] RightTriangle = new Point[]{
new Point(RightPos, r.Y ),
new Point(RightPos - (r.Height / 2), r.Y + (r.Height / 2)),
new Point(RightPos, r.Y + r.Height),
new Point(RightPos - (r.Height / 3), r.Y + (r.Height / 2))
};
g.FillPolygon(System.Drawing.Brushes.Black, RightTriangle);
}
private void InsertPointer(TreeNode tn, Graphics g)
{
TreeView tv = _dropNode.TreeView;
Rectangle r2 = _dropNode.Nodes[_index].Bounds;
Rectangle r3 = tn.Bounds;
int y = (_position == DropPosition.Before ? r2.Y : r3.Bottom);
int x = r2.Left;
if (y == 0)
{
return;
}
//if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Line at {0} Node {1}[{2}] {3}", _location, _dropNode.Text, _index, _position.ToString());
// Changed the color of the drag indicator to always be red
Color lc = (_position == DropPosition.After ? Color.Red : Color.Red);
Brush lb = (_position == DropPosition.After ? Brushes.Red : Brushes.Red);
Point[] RightTriangle;
if (_position == DropPosition.After)
{
RightTriangle = new Point[]{
new Point(x, y ),
new Point(x+4, y+4),
new Point(x+8, y)};
}
else
{
RightTriangle = new Point[]{
new Point(x, y),
new Point(x+4, y-4),
new Point(x+8, y)};
}
g.DrawLine(new System.Drawing.Pen(lc, 2), new Point(r2.Left, y), new Point(tv.Width - 8, y));
g.FillPolygon(lb, RightTriangle);
}
public void ShowLocation(System.Windows.Forms.DragEventArgs e, bool ScrollOnly)
{
//if (e.Effect == DragDropEffects.None) return;
if (_dropNode != null)
{
// if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("ShowLocation1 {0} {1}", e.Effect.ToString(), DateTime.Now.Millisecond);
DragHelper.ImageList_DragShowNolock(false);
TreeView tv = _dropNode.TreeView;
TreeNode tmp = tv.GetNodeAt(tv.PointToClient(new Point(e.X, e.Y)));
// if (!ScrollOnly)
// {
if (ScrollTreeView(tmp) || !ScrollOnly)
{
//if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("ShowLocation2 {0} {1}", e.Effect.ToString(), DateTime.Now.Millisecond);
tv.Refresh();
if (e.Effect != DragDropEffects.None)
{
//tv.SelectedNode = dropNode;
Graphics g = tv.CreateGraphics();
TreeNodeTriangle(g);
if (_position != DropPosition.Child)InsertPointer(tmp, g);
}
}
// }
// else ScrollTreeView(tmp);
DragHelper.ImageList_DragShowNolock(true);
}
}
#endregion
public void ShowLocation()
{
//if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("{0}[{1}] {2}", _dropNode.Text, _index, _position.ToString());
}
#region AutoScroll
private bool ScrollTreeView(TreeNode tn)
{
bool retval = false;
TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - _lastScroll.Ticks);
if (ts.Milliseconds > 100)// This controls the scroll speed
{
int top = tn.Bounds.Top;
_lastScroll = DateTime.Now;
if (tn.TreeView.ClientSize.Height < tn.Bounds.Bottom) tn.EnsureVisible();// Make sure that the current node is visible
if (tn.NextVisibleNode != null && tn.TreeView.ClientSize.Height < tn.NextVisibleNode.Bounds.Bottom)
tn.NextVisibleNode.EnsureVisible();// Make sure that the next node is visible
else
if (tn.PrevVisibleNode != null && tn.PrevVisibleNode.PrevVisibleNode != null && tn.PrevVisibleNode.PrevVisibleNode.IsVisible == false)
tn.PrevVisibleNode.PrevVisibleNode.EnsureVisible();// Make sure that the previous node is visible }
else
if (tn.PrevVisibleNode != null && tn.PrevVisibleNode.IsVisible == false)
tn.PrevVisibleNode.EnsureVisible();// Make sure that the previous node is visible
retval = (top != tn.Bounds.Top);
// if (retval) if(_MyLog.IsInfoEnabled)_MyLog.Info("Scroll");
}
return retval;
}
#endregion
public bool Equals(DropLocation dl)
{
return (dl != null && _lastScroll.Equals(dl.LastScroll) && _dropNode.Equals(dl.DropNode) &&
_position.Equals(dl.Position));
}
}
private DropLocation _LastDropLocation = null;
private void tv_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
try
{
TreeNode dragNode = GetTreeNodeFromData(e.Data);
if (dragNode == null) return;
// Compute drag position and move image
Point formP = this.FindForm().PointToClient(new Point(e.X, e.Y));
DragHelper.ImageList_DragMove(formP.X - this.Left, formP.Y - this.Top);
DropLocation dl = new DropLocation(this, e, _LastDropLocation == null ? DateTime.Now : _LastDropLocation.LastScroll);
string s = string.Empty;
if (dl.DropNode == null || !AllowedToMove((VETreeNode)dragNode))
{
e.Effect = DragDropEffects.None;
}
else
{
DragDropEffects ee = e.Effect;
if (e.KeyState == 13) // Shift and Control Keys to do a move.
ee = DragDropEffects.Move;
else
ee = DragDropEffects.None; // Default - Do nothing
if (IsChild(dragNode, dl.DropNode)) // Don't copy or move to a child node
ee = DragDropEffects.None;
else if (IsDocVersion((VETreeNode)dragNode)) // Don't move docversions
ee = DragDropEffects.None;
else if (IsFolder((VETreeNode)dragNode)) // Folder move is only valid if moving to folder with NO docversions
{
FolderInfo fdropi = ((VETreeNode)dl.DropNode).VEObject as FolderInfo;
if (fdropi == null || fdropi.FolderDocVersionCount > 0) ee = DragDropEffects.None;
}
else if (IsSection((VETreeNode)dragNode))
{
// A section can be moved within a procedure or to a section within the same procedure...
// For HLP, just move within the same procedure
// TODO: allow for section move within subsections.
ProcedureInfo pdropi = ((VETreeNode)dl.DropNode).VEObject as ProcedureInfo;
if (pdropi == null || (dragNode.Parent != dl.DropNode)) ee = DragDropEffects.None;
}
else if (!IsFolder((VETreeNode)dragNode) && (dragNode.Parent != dl.DropNode))
ee = DragDropEffects.None;
if (e.Effect != ee) e.Effect = ee;
dl.ShowLocation(e, dl.Equals(_LastDropLocation));
_LastDropLocation = dl;
}
}
catch (Exception ex)
{
if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_DragOver", ex);
}
}
private bool IsSection(VETreeNode vETreeNode)
{
SectionInfo sectInfo = vETreeNode.VEObject as SectionInfo;
if (sectInfo != null) return true;
return false;
}
private bool IsProcedure(VETreeNode vETreeNode)
{
ProcedureInfo procInfo = vETreeNode.VEObject as ProcedureInfo;
if (procInfo != null) return true;
return false;
}
private bool IsDocVersion(VETreeNode dragNode)
{
DocVersionInfo dvInfo = dragNode.VEObject as DocVersionInfo;
if (dvInfo != null) return true;
return false;
}
private bool AllowedToMove(VETreeNode dragNode)
{
DocVersionInfo dvInfo = null;
if (IsFolder(dragNode))
{
FolderInfo fi = dragNode.VEObject as FolderInfo;
return (MyUserInfo.IsAdministrator() || MyUserInfo.IsSetAdministrator(fi));
}
else if (IsDocVersion(dragNode))
dvInfo = dragNode.VEObject as DocVersionInfo;
else if (IsProcedure(dragNode))
dvInfo = (dragNode.VEObject as ProcedureInfo).MyDocVersion;
else if (IsSection(dragNode))
dvInfo = (dragNode.VEObject as SectionInfo).MyDocVersion;
// Bug fix B2016-274 if an Admin user also had Reviewer or ROEditor settings, admin could not move the tree node
if (dvInfo != null) return (MyUserInfo.IsAdministrator() || MyUserInfo.IsSetAdministrator(dvInfo)) || MyUserInfo.IsWriter(dvInfo);
return false;
}
private static TreeNode GetTreeNodeFromData(IDataObject datobj)
{
foreach (string s in datobj.GetFormats())
{
try
{
// B2021-006: dragging text from Microsoft Word onto the tree view was crashing PROMS
// This included dragging text from the Word doc editor within PROMS. Check object type:
Object tmp = datobj.GetData(s);
if (!(tmp is TreeNode)) return null;
return (TreeNode)datobj.GetData(s);
}
catch (Exception ex)
{
if(_MyLog.IsErrorEnabled)_MyLog.Error("GetTreeNodeFromData", ex);
}
}
return null;
}
private bool IsFolder(VETreeNode veTreeNode)
{
return (veTreeNode.VEObject.GetType() == typeof(FolderInfo));
}
private void tv_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
try
{
TreeNode dragNode = GetTreeNodeFromData(e.Data);
DragHelper.ImageList_DragLeave(this.Handle);
int index = _LastDropLocation.Index + (_LastDropLocation.Position == DropPosition.After ? 1 : 0);
int myIndex = index;
if (dragNode.Parent == _LastDropLocation.DropNode && dragNode.Index <= _LastDropLocation.Index) index--;
if (e.Effect == DragDropEffects.Move)// If Move Remove drag node from parent
dragNode.Remove();
else
dragNode = Clone(dragNode);
_LastDropLocation.DropNode.Nodes.Insert(index, dragNode);
this.SelectedNode = dragNode;
FolderInfo fdragi = ((VETreeNode)dragNode).VEObject as FolderInfo;
FolderInfo fdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as FolderInfo;
if (fdragi != null && fdropi != null && fdropi.FolderDocVersionCount==0)
{
using (Folder fdrag = fdragi.Get())
{
using (Folder fdrop = fdropi.Get())
{
fdrag.ManualOrder = fdropi.NewManualOrder(myIndex);
fdrag.MyParent = fdrop;
fdrag.Save();
}
}
return;
}
// No drag/drop supported for document versions.
// Allow drag/drop of procedures within a Document Version (must have same parent). Note that drop location
// may either be a document version or a procedure depending on where the user wants to position the procedure.
ProcedureInfo pdragi = ((VETreeNode)dragNode).VEObject as ProcedureInfo;
ProcedureInfo pdropi = null;
if (pdragi != null) // moving a procedure
{
pdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as ProcedureInfo;
if (pdropi != null && pdragi.ActiveParent == pdropi.ActiveParent)
{
pdragi.MoveProcedure(pdragi.ActiveParent, myIndex);
return;
}
DocVersionInfo dvdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as DocVersionInfo;
DocVersionInfo dvdragpar = pdragi.ActiveParent as DocVersionInfo;
if (dvdropi != null && dvdragpar.VersionID == dvdropi.VersionID)
{
pdragi.MoveProcedure(dvdropi, myIndex);
return;
}
}
// Allow drag/drop of sections within the same procedure or same section (if subsection) (must have same parent)
SectionInfo sdragi = ((VETreeNode)dragNode).VEObject as SectionInfo;
SectionInfo sdropi = null;
if (sdragi != null) // moving a section
{
sdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as SectionInfo;
if (sdropi != null && sdragi.ActiveParent == sdropi.ActiveParent)
{
sdragi.MoveSection(sdragi, myIndex);
return;
}
pdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as ProcedureInfo;
if (pdropi != null && ((ItemInfo)(sdragi.ActiveParent)).ItemID == pdropi.ItemID)
{
sdragi.MoveSection(pdropi, myIndex);
sdragi.Moving = true;
OnNodeSelect(dragNode, new vlnTreeEventArgs(dragNode));
return;
}
}
// Allow drag/drop of steps within the same parent only
StepInfo stdragi = ((VETreeNode)dragNode).VEObject as StepInfo;
StepInfo stdropi = null;
if (stdragi != null) // moving a step
{
stdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as StepInfo;
if (stdropi != null && stdragi.ActiveParent == stdropi.ActiveParent)
{
stdragi.MoveStep(stdragi.ActiveParent, myIndex);
return;
}
sdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as SectionInfo;
if (sdropi != null && stdragi.MyParent.ItemID == sdropi.ItemID)
{
stdragi.MoveStep(stdragi.ActiveParent, myIndex);
return;
}
// the following handles items under the app nodes of 'steps', 'notes', 'cautions', etc.
if (sdropi == null && dragNode.Parent == _LastDropLocation.DropNode)
{
stdragi.MoveStep(stdragi.ActiveParent, myIndex);
return;
}
}
}
catch (Exception ex)
{
if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_DragDrop", ex);
}
}
// private void DumpMembers(object o)
// {
// Type t = o.GetType();
// //if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("\r\n\r\nMembers for type {0}", t.ToString());
// MemberInfo[] mis = t.GetMembers();
// int i = 0;
// foreach (MemberInfo mi in mis)
// {
// i++;
// try
// {
// //if(mi.MemberType != MemberTypes.Method)
// //if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("{0} {1} {2}", i, mi.Name, mi.MemberType);
//// if (fi.Name == "TreeView")
//// fi.SetValue(o, null);
// }
// catch (Exception ex)
// {
// if(_MyLog.IsErrorEnabled)_MyLog.Error("DumpMembers", ex);
// }
// }
// }
private TreeNode Clone(TreeNode tn)
{
TreeNode tmp = (TreeNode)tn.Clone();
ExpandMatch(tmp,tn);
return tmp;
}
private void tv_DragDropOld(object sender, System.Windows.Forms.DragEventArgs e)
{
TreeNode dragNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");// Get the drag node
DragHelper.ImageList_DragLeave(this.Handle);
TreeNode cloneNode = (TreeNode)dragNode.Clone();// copy the source node
ExpandMatch(cloneNode, dragNode);
_LastDropLocation.DropNode.Nodes.Insert(_LastDropLocation.Index + (_LastDropLocation.Position == DropPosition.After ? 1 : 0), cloneNode);
if (e.Effect == DragDropEffects.Move)// If Move Remove drag node from parent
dragNode.Remove();
this.SelectedNode = cloneNode;
}
private void tv_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
DragHelper.ImageList_DragEnter(this.Handle, e.X - this.Left, e.Y - this.Top);
}
private void tv_DragLeave(object sender, System.EventArgs e)
{
DragHelper.ImageList_DragLeave(this.Handle);
this.Refresh();
}
private void ExpandMatch(TreeNode tn1, TreeNode tn2)
{
if (tn2.IsExpanded) tn1.Expand();
foreach (TreeNode tc in tn2.Nodes) ExpandMatch(tn1.Nodes[tc.Index], tc);
}
private bool IsChild(TreeNode parent, TreeNode child)
{
if (parent.Equals(child)) return true;// Check against self
foreach (TreeNode tc in parent.Nodes) if (IsChild(tc, child)) return true;//Check all children
return false;// Must not be a child at this level
}
#endregion
private bool _AdjustingTree = false;
public void AdjustTree(ItemInfo selectedItem)
{
// start at the top parent and walk down the nodes to find child
if (selectedItem == null) return;
VETreeNode node = FindNodeAndExpand(selectedItem);
if (node != null)
{
_AdjustingTree = true;
this.SelectedNode = node;
_AdjustingTree = false;
}
}
public VETreeNode FindNodeAndExpand(IVEDrillDownReadOnly selectedItem)
{
if (selectedItem.ActiveParent == null)
{
return (VETreeNode)this.Nodes[0]; // Return the top node
}
if (selectedItem == ((VETreeNode)this.Nodes[0]).VEObject) return (VETreeNode)this.Nodes[0]; // C2015-022 check needed for tree in child windows
VETreeNode parent = FindNodeAndExpand(selectedItem.ActiveParent);
if (parent == null) return null;
if (!parent.IsExpanded)
parent.Expand();
VETreeNode child = GetChildNode(selectedItem, parent);
if (child != null)
return child;
parent.ChildrenLoaded = false;
parent.RefreshNode();
child = GetChildNode(selectedItem, parent);
return child;
}
public VETreeNode FindNode(IVEDrillDownReadOnly selectedItem, TreeNodeCollection tnc)
{
foreach (TreeNode tn in tnc)
if (tn is VETreeNode)
{
if ((tn as VETreeNode).VEObject is ItemInfo && (selectedItem is ItemInfo) && ((tn as VETreeNode).VEObject as ItemInfo).ItemID == (selectedItem as ItemInfo).ItemID)
return tn as VETreeNode;
else
{
VETreeNode cn = FindNode(selectedItem, tn.Nodes);
if (cn != null)
return cn;
}
}
return null;
}
public VETreeNode RefreshRelatedNode(IVEDrillDownReadOnly selectedItem)
{
Console.WriteLine("vlntreeview:refreshrelatednote:start");
VETreeNode child = FindNode(selectedItem, this.Nodes);
if (child == null) return null;
if (!child.IsExpanded)
child.Expand();
child.ChildrenLoaded = false;
child.RefreshNode();
Console.WriteLine("vlntreeview:refreshrelatednote:end");
return child;
}
// B2021-066: refresh the procedure numbers within Working Draft (docversion) for applicability changed
public void RefreshDocVersion()
{
VETreeNode vetn = SelectedNode as VETreeNode;
if (vetn != null)
{
DocVersionInfo dvi = vetn.VEObject as DocVersionInfo;
if (dvi != null)
{
if (SelectedNode.Nodes != null && SelectedNode.Nodes.Count > 0 && SelectedNode.Nodes[0] is VETreeNode)
{
foreach (VETreeNode tn in SelectedNode.Nodes)
{
tn.RefreshNode();
}
}
}
}
}
private VETreeNode GetChildNode(IVEDrillDownReadOnly selectedItem, VETreeNode parent)
{
foreach (TreeNode childNode in parent.Nodes)
{
VETreeNode child = childNode as VETreeNode;
if (child != null && CompareVEObject(child.VEObject, selectedItem))
return child;
}
foreach (TreeNode childNode in parent.Nodes)
{
VETreeNode child = childNode as VETreeNode;
if (child.VEObject is PartInfo)
foreach (VETreeNode grandchild in child.Nodes)
if (CompareVEObject(grandchild.VEObject, selectedItem))
return grandchild;
}
return null;
}
public bool CompareVEObject(IVEDrillDownReadOnly obj1, IVEDrillDownReadOnly obj2)
{
if (obj1.GetType().Name != obj2.GetType().Name)
{
// see if both can be cast as ItemInfo, because 1st check may be comparing ItemInfo & ProcedureInfo and returns
// false even though they are same base object type (fixes bug B2016-094)
ItemInfo ii1 = obj1 as ItemInfo;
ItemInfo ii2 = obj2 as ItemInfo;
if (ii1 == null || ii2 == null) return false;
}
ItemInfo myItem = obj1 as ItemInfo;
if (myItem != null)
if (myItem.ItemID == ((ItemInfo)obj2).ItemID) return true;
DocVersionInfo myDV = obj1 as DocVersionInfo;
if (myDV != null)
if (myDV.VersionID == ((DocVersionInfo)obj2).VersionID) return true;
FolderInfo myFolder = obj1 as FolderInfo;
if (myFolder != null)
if (myFolder.FolderID == ((FolderInfo)obj2).FolderID) return true;
return false;
}
}
#region DragHelper
public class DragHelper
{
[DllImport("comctl32.dll")]
public static extern bool InitCommonControls();
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
public static extern bool ImageList_BeginDrag(IntPtr himlTrack, int
iTrack, int dxHotspot, int dyHotspot);
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
public static extern bool ImageList_DragMove(int x, int y);
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
public static extern void ImageList_EndDrag();
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
public static extern bool ImageList_DragEnter(IntPtr hwndLock, int x, int y);
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
public static extern bool ImageList_DragLeave(IntPtr hwndLock);
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
public static extern bool ImageList_DragShowNolock(bool fShow);
static DragHelper()
{
InitCommonControls();
}
}
#endregion
}