4683 lines
		
	
	
		
			192 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			4683 lines
		
	
	
		
			192 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 vlnTreeViewItemInfoDeleteFolderEvent(object sender, vlnTreeFolderDeleteEventArgs 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; }
 | |
| 		}
 | |
| 
 | |
| 		//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
 | |
| 		//AnnotationType that would be doing an export for
 | |
| 		private int _AnnotationTypeId = -1;
 | |
| 		public int AnnotationTypeId
 | |
| 		{
 | |
| 			get { return _AnnotationTypeId; }
 | |
| 			set { _AnnotationTypeId = 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;
 | |
| 		}
 | |
| 		public vlnTreeEventArgs(TreeNode node, TreeNode destination, int index, int annTypeId)
 | |
| 		{
 | |
| 			_Node = node;
 | |
| 			_Destination = destination;
 | |
| 			_Index = index;
 | |
| 			_AnnotationTypeId = annTypeId;
 | |
| 		}
 | |
| 		//jcb multiunit
 | |
| 		public vlnTreeEventArgs(TreeNode node, TreeNode destination, int index, string unit, int unitIndex)
 | |
| 		{
 | |
| 			_Node = node;
 | |
| 			_Destination = destination;
 | |
| 			_Index = index;
 | |
| 			_Unit = unit;
 | |
| 			_UnitIndex = unitIndex;
 | |
| 		}
 | |
| 		public vlnTreeEventArgs(TreeNode node, TreeNode destination, int index, string unit, int unitIndex, int annTypeId)
 | |
| 		{
 | |
| 			_Node = node;
 | |
| 			_Destination = destination;
 | |
| 			_Index = index;
 | |
| 			_Unit = unit;
 | |
| 			_UnitIndex = unitIndex;
 | |
| 			_AnnotationTypeId = annTypeId;
 | |
| 		}
 | |
| 		//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 class vlnTreeFolderDeleteEventArgs : EventArgs
 | |
| 	{
 | |
| 		public int FolderId { get; }
 | |
| 
 | |
| 		public vlnTreeFolderDeleteEventArgs(int folderId)
 | |
| 		{
 | |
| 			FolderId = folderId;
 | |
| 		}
 | |
| 	}
 | |
| 	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 vlnTreeViewItemInfoDeleteFolderEvent DeleteFolder;
 | |
| 		private bool OnDeleteFolder(object sender, vlnTreeFolderDeleteEventArgs args)
 | |
| 		{
 | |
| 			if (DeleteItemInfo != null) return DeleteFolder(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 QPrintSection;
 | |
| 		private void OnQPrintSection(object sender, vlnTreeEventArgs args)
 | |
| 		{
 | |
| 			if (QPrintSection != null) QPrintSection(sender, args);
 | |
| 		}
 | |
| 		public event vlnTreeViewEvent PrintAllProcedures;
 | |
| 		private void OnPrintAllProcedures(object sender, vlnTreeEventArgs args)
 | |
| 		{
 | |
| 			if (PrintAllProcedures != null) PrintAllProcedures(sender, args);
 | |
| 		}
 | |
| 		public event vlnTreeViewEvent PrintAllApprovedProcedures; //C2025-017 print all approved procedures
 | |
| 		private void OnPrintAllApprovedProcedures(object sender, vlnTreeEventArgs args)
 | |
| 		{
 | |
| 			if (PrintAllApprovedProcedures != null) PrintAllApprovedProcedures(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));
 | |
| 								//AddEPExport(cm.MenuItems, 0, null);
 | |
| 							}
 | |
| 							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");
 | |
| 								MenuItem mir = new MenuItem("Print All Approved Procedures for"); // C2025-017 print all approved procedures
 | |
| 								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 mr = mir.MenuItems.Add(s, new EventHandler(miMultiUnit_Click)); // C2025-017 print all approved procedures
 | |
| 									mr.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);
 | |
| 								cm.MenuItems.Add(mir); // C2025-017 print all approved procedures
 | |
| 							}
 | |
| 							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("Print All Approved 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);
 | |
| 							//C2025-024 Proms XML Output - if have any EP Format files, add dropdown menu for exporting EP formats
 | |
| 							if (pri.ActiveFormat.PlantFormat.EPFormatFiles.Count > 0)
 | |
| 								AddEPExport(cm.MenuItems, pri.MyDocVersion.MultiUnitCount, pri.MyDocVersion.UnitNames, pri.ActiveFormat.PlantFormat.EPFormatFiles);
 | |
| 						}
 | |
| 						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)
 | |
| 									{
 | |
| 										if (!si2.IsSubsection)
 | |
| 										{
 | |
| 											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);
 | |
| 
 | |
| 											//C2025-028 Add a Quick Print Section option
 | |
| 											MenuItem mps_qp = new MenuItem("Quick Print Section");
 | |
| 											int k_qp = 0;
 | |
| 											foreach (string s in si2.MyDocVersion.UnitNames)
 | |
| 											{
 | |
| 												k_qp++;
 | |
| 												MenuItem mp_qp = mps_qp.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
 | |
| 												mp_qp.Tag = k_qp;
 | |
| 											}
 | |
| 											cm.MenuItems.Add(mps_qp);
 | |
| 										}
 | |
| 									}
 | |
| 									else
 | |
| 									{
 | |
| 										if (!si2.IsSubsection)
 | |
| 										{
 | |
| 											cm.MenuItems.Add("Print Section", new EventHandler(mi_Click));
 | |
| 											cm.MenuItems.Add("Quick 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));
 | |
| 						//	cm.MenuItems.Add("Quick Print Section", new EventHandler(mi_Click));
 | |
| 						//}
 | |
| 						if (i.HasWordContent)
 | |
| 						{
 | |
| 							if (i.MyDocVersion.MultiUnitCount > 1)
 | |
| 							{
 | |
| 								if (!i.IsSubsection)
 | |
| 								{
 | |
| 									MenuItem mps = new MenuItem("Print Section");
 | |
| 									MenuItem mqps = new MenuItem("Quick Print Section");
 | |
| 									int k = 0;
 | |
| 									foreach (string s in i.MyDocVersion.UnitNames)
 | |
| 									{
 | |
| 										k++;
 | |
| 										MenuItem mp = mps.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
 | |
| 										mp.Tag = k;
 | |
| 										MenuItem mqp = mqps.MenuItems.Add(s, new EventHandler(miMultiUnit_Click));
 | |
| 										mqp.Tag = k;
 | |
| 									}
 | |
| 									cm.MenuItems.Add(mps);
 | |
| 									cm.MenuItems.Add(mqps);
 | |
| 								}
 | |
| 							}
 | |
| 							else
 | |
| 							{
 | |
| 								cm.MenuItems.Add("Print Section", new EventHandler(mi_Click));
 | |
| 								cm.MenuItems.Add("Quick 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));
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
 | |
| 		// Add context menu for exporting Electronic Procedures
 | |
| 		// if has an Electronic procedure
 | |
| 		// then loop through and add an Export for each EP Viewer
 | |
| 		private void AddEPExport(Menu.MenuItemCollection menuItems, int MultiUnitCount, string[] UnitNames, EPFormatFiles EPFiles)
 | |
| 		{
 | |
| 			//add outer menu
 | |
| 			MenuItem mi = menuItems.Add("Electronic Procedure Viewer Export");
 | |
| 			foreach (EPFormatFile epAnnType in EPFiles)
 | |
| 			{
 | |
| 
 | |
| 				//Add item for each individual EP Viewer
 | |
| 				MenuItem mv = mi.MenuItems.Add(epAnnType.AnnotationName());
 | |
| 
 | |
| 				//tag will be of format:
 | |
| 				//{EP Annotation Type ID},{Unit}
 | |
| 				//if not multi-unit, unit will be zero.
 | |
| 				if (MultiUnitCount > 1)
 | |
| 				{
 | |
| 					//if multi-unit, add menu item for each unit
 | |
| 					int k = 0;
 | |
| 					foreach (string s in UnitNames)
 | |
| 					{
 | |
| 						k++;
 | |
| 						MenuItem multiunit_mv = mv.MenuItems.Add(s);
 | |
| 						multiunit_mv.Tag = $"{epAnnType.AnnotationTypeID},{k}";
 | |
| 						multiunit_mv.Click += new EventHandler(miEP_Click);
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					mv.Tag = $"{epAnnType.AnnotationTypeID},0";
 | |
| 					mv.Click += new EventHandler(miEP_Click);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		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.RevisionID;
 | |
| 						mirp.Click += new EventHandler(MultiUnitApprovedRevision_Click);
 | |
| 					}
 | |
| 					if (ri.LatestVersion.SummaryPDF != null)
 | |
| 					{
 | |
| 						MenuItem mirs = mir.MenuItems.Add("View Summary of Changes");
 | |
| 						mirs.Tag = ri.RevisionID;
 | |
| 						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.RevisionID;
 | |
| 						miri.Click += new EventHandler(MultiUnitImportProcedure_Click); //B2024-024 Parent Child Create Approved Import file
 | |
| 					}
 | |
| 
 | |
| 					//end added jcb 20111031
 | |
| 					mv.Tag = lastApprovedRevisionID;
 | |
| 				}
 | |
| 				ril = null;
 | |
| 			}
 | |
| 		}
 | |
| 		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)
 | |
| 		{
 | |
| 			//B2024-024 restored the line below from prior change - didn't work for non parent/childs sets - created a new click event method (below) for parent/child sets.
 | |
| 			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);
 | |
| 		}
 | |
| 
 | |
| 		//B2024-024 create import file for parent/child procedure set
 | |
| 		void MultiUnitImportProcedure_Click(object sender, EventArgs e)
 | |
| 		{
 | |
| 			//RevisionInfo ri = (sender as MenuItem).Tag as RevisionInfo;
 | |
| 			RevisionInfo ri = RevisionInfo.Get(int.Parse((sender as MenuItem).Tag.ToString()));
 | |
| 			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);
 | |
| 		}
 | |
| 
 | |
| 		//C2025-015 Get a partial folder path. This will be used in building the PDF file name when viewing Approved procedures
 | |
| 		string ProcFolderPathforApprovedPDF(string fullPath)
 | |
| 		{
 | |
| 			string rtnStr = "";
 | |
| 			try
 | |
| 			{
 | |
| 				// the fullPath string that is passed in ends with the Working Draft node. We want to trim that off
 | |
| 				string[] strParts = fullPath.Substring(0, fullPath.LastIndexOf("\\")).Split('\\'); //fullPath.Replace("\\Working Draft","").Split('\\');
 | |
| 				int lastPart = Math.Max(strParts.Length - 1, 0);
 | |
| 				rtnStr = strParts[lastPart];
 | |
| 				if (rtnStr.ToUpper().StartsWith("UNIT"))
 | |
| 				{
 | |
| 					rtnStr = strParts[lastPart - 1] + "_" + rtnStr;
 | |
| 				}
 | |
| 			}
 | |
| 			catch
 | |
| 			{
 | |
| 				rtnStr = fullPath.Replace("\\", "_"); // just return the full path with _ intead of backslashes
 | |
| 			}
 | |
| 			return rtnStr;
 | |
| 		}
 | |
| 
 | |
| 		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;
 | |
| 			}
 | |
| 			ProcedureInfo prcInfo = ProcedureInfo.Get(ri.ItemID);
 | |
| 			// C2025-015 build a file name that includes a partial folder path and approved revision number
 | |
| 			string approvedPDFName = string.Format("{0}_{1} Revision {2}", ProcFolderPathforApprovedPDF(prcInfo.SearchDVPath_clean), prcInfo.PDFNumber,ri.RevisionNumber);
 | |
| 			vlnTreeViewPdfArgs args = new vlnTreeViewPdfArgs(Volian.Base.Library.TmpFile.CreateFileName(approvedPDFName), 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;
 | |
| 			string childName = "";
 | |
| 			//RevisionInfo ri = mi.Tag as RevisionInfo;
 | |
| 			RevisionInfo ri = RevisionInfo.Get(int.Parse(mi.Tag.ToString()));
 | |
| 			{
 | |
| 				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;
 | |
| 			// C2025_015 get the child's name to append to file name
 | |
| 				mip = mip.Parent as MenuItem;
 | |
| 				if (mip != null)
 | |
| 				{
 | |
| 					childName = "_"  + mip.Text;
 | |
| 				}
 | |
| 			}
 | |
| 			ItemInfo ii = ItemInfo.Get(ri.ItemID);
 | |
| 			ii.MyDocVersion.DocVersionConfig.SelectedSlave = ri.MyConfig.Applicability_Index;
 | |
| 			ProcedureInfo prcInfo = ProcedureInfo.Get(ri.ItemID);
 | |
| 			if (prcInfo.MyContent.Number.ToUpper().Contains("<U") || ii.MyDocVersion.DocVersionConfig.Unit_ProcedureNumber.Contains("#"))
 | |
| 				childName = ""; // unit identification already part of procedure number-no need to add the child name to the PDF file name
 | |
| 			// C2025-015 build a file name that includes a partial folder path, the child name and approved revision number
 | |
| 			string approvedPDFName = string.Format("{0}{1}_{2} Revision {3}", ProcFolderPathforApprovedPDF(prcInfo.SearchDVPath_clean),childName, prcInfo.PDFNumber, ri.RevisionNumber);
 | |
| 			vlnTreeViewPdfArgs args = new vlnTreeViewPdfArgs(Volian.Base.Library.TmpFile.CreateFileName(approvedPDFName), ri.LatestVersion.PDF, superceded ? "Superceded" : "");
 | |
| 			OnViewPDF(sender, args);
 | |
| 		}
 | |
| 		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;
 | |
| 			RevisionInfo ri = RevisionInfo.Get(int.Parse(mi.Tag.ToString()));
 | |
| 			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)
 | |
| 						{
 | |
| 							// B2024-028 Do not allow paste of non-enhanced into enhanced set 
 | |
| 							//	(consistent with paste before/after, i.e. don't allow)
 | |
| 							canPaste = false;
 | |
| 							cm.MenuItems.Add("CANNOT PASTE HERE,  Click for more information...", new EventHandler(mi_Click));
 | |
| 						}
 | |
| 						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 so cannot do Replace
 | |
| 							//		3) 'to' section is 'source' and 'from' section is same docversion 'source'
 | |
| 							//				can do Before/After (B2024-038 removes replace)
 | |
| 							//		4) 'to' section is not 'source' and 'from' section is source
 | |
| 							//				can do  Before/After but not replace - would have to manage
 | |
| 							//				links for 'from' section (B2024-038 added this case)
 | |
| 
 | |
| 							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)
 | |
| 								okToReplace = false;
 | |
| 							}
 | |
| 							else if (!secToIsSource && secFromIsSource)
 | |
| 							{
 | |
| 								secCanPaste = true; // 4
 | |
| 								okToReplace = false;
 | |
| 							}
 | |
| 							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 Section":
 | |
| 					OnPrintSection(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, mi.Text, (int)mi.Tag));
 | |
| 					break;
 | |
| 				case "Quick Print Section":
 | |
| 					OnQPrintSection(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;
 | |
| 				case "Print All Approved Procedures for": //C2025-017 print all approved procedures
 | |
| 					OnPrintAllApprovedProcedures(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 "Quick Print Section":
 | |
| 					VETreeNode tn2qp = SelectedNode as VETreeNode;
 | |
| 					OnQPrintSection(this, new vlnTreeEventArgs(tn2qp 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 "Paste Procedure After":
 | |
| 				case "Paste Section":
 | |
| 				case "Paste Section Before":
 | |
| 				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 "Replace Existing Section":
 | |
| 					//C2025-032 - Add check if user is sure want to paste replace section
 | |
| 					DialogResult ovewriteExPS = FlexibleMessageBox.Show("This will overwrite the selected section with the one you copied, would you like to overwrite it?\r\n\r\nSelecting 'Cancel' will cancel the paste action.", "Overwrite the section?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
 | |
| 
 | |
| 					if (ovewriteExPS == DialogResult.Cancel) break;
 | |
| 					else
 | |
| 					{
 | |
| 						tv_NodePaste(mi.Text);
 | |
| 						break;
 | |
| 					}
 | |
| 				case "Replace Existing Procedure":
 | |
| 					DialogResult ovewriteEx = FlexibleMessageBox.Show("This will overwrite the selected procedure with the one you copied, would you like to overwrite it?\r\n\r\nSelecting 'Cancel' will cancel the paste action.", "Overwrite the procedure?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);// == DialogResult.Yes;
 | |
| 
 | |
| 					if (ovewriteEx == DialogResult.Cancel) break;
 | |
| 					else
 | |
| 					{
 | |
| 						TreeNode treenodeDirectory = SelectedNode.Parent;
 | |
| 						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...":
 | |
| 					// B2024-028 clarify message
 | |
| 					FlexibleMessageBox.Show("You have copied a document that is NOT linked to an Enhanced Document.\n\n" +
 | |
| 						"You cannot paste a Non-Enhanced Procedure into an Enhanced Procedure Set.", "Cannot Paste Here");
 | |
| 					break;
 | |
| 				//case "Check Out Procedure Set":
 | |
| 				//  CheckOutDocVersion(SelectedNode as VETreeNode);
 | |
| 				//  break;
 | |
| 				//case "Check In Procedure Set":
 | |
| 				//  CheckInDocVersion(SelectedNode as VETreeNode);
 | |
| 				//  break;
 | |
| 				case "Print All Approved Procedures": //C2025-017 print all approved procedures
 | |
| 					OnPrintAllApprovedProcedures(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0));
 | |
| 					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;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
 | |
| 		// Handles clicking of items in the context menu
 | |
| 		// for exporting Electronic Procedures
 | |
| 		//   tag will be of format:
 | |
| 		//   {EP Annotation Type ID},{Unit}
 | |
| 		//   if not multi-unit, unit will be zero.
 | |
| 		void miEP_Click(object sender, EventArgs e)
 | |
| 		{
 | |
| 			MenuItem mi = sender as MenuItem;
 | |
| 			int annTypeid = int.Parse(((string)mi.Tag).Split(',')[0]);
 | |
| 			int unit = int.Parse(((string)mi.Tag).Split(',')[1]);
 | |
| 			if (unit == 0)
 | |
| 				OnExportImportProcedureSets(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, annTypeid));
 | |
| 			else
 | |
| 				OnExportImportProcedureSets(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0, "", unit, annTypeid));
 | |
| 		}
 | |
| 		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)
 | |
| 			{
 | |
| 				bool OnlyProc = iiPaste.IsProcedure && iiPaste.MyPrevious == null && (iiPaste.NextItems == null || iiPaste.NextItems.Count == 0);
 | |
| 				VETreeNode tmp = null;
 | |
| 				if (OnlyProc)
 | |
| 				{
 | |
| 					VETreeNode tnp = SelectedNode as VETreeNode;
 | |
| 					tmp = tnp == null ? null : tnp.Parent as VETreeNode;
 | |
| 				}
 | |
| 				ItemInfo repitem = PasteReplace(tn, iiClipboard.ItemID);
 | |
| 				// B2024-045, 049 and 050:  The treenode was passed into the business object's replace but sometimes it was null. And this
 | |
| 				//   wasn't working if it was a single procedure in a working Draft. Adjust the tree here if single procedure in working draft.
 | |
| 				if (OnlyProc && repitem != null && tmp != null)
 | |
| 				{
 | |
| 					VETreeNode tn1 = new VETreeNode(repitem);
 | |
| 					tmp.Nodes.Add(tn1);
 | |
| 					SelectedNode = tn1;
 | |
| 				}
 | |
| 			}
 | |
| 			else  // paste as child
 | |
| 				PasteAsChild(tn, iiClipboard.ItemID);
 | |
| 
 | |
| 
 | |
| 			//if (p.IndexOf("Replace") <= -1)
 | |
| 			this.Cursor = Cursors.Default;
 | |
| 		}
 | |
| 
 | |
| 		public 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 ItemInfo 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);
 | |
| 			ItemInfo replItemInfo = null;
 | |
| 			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));
 | |
| 				replItemInfo = Item.PasteReplace(ii, copyStartID, chgId);
 | |
| 
 | |
| 				StepConfig replItemConfig = ii.MyConfig as StepConfig;
 | |
| 				if (replItemInfo != null)
 | |
| 				{
 | |
| 					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;
 | |
| 			return replItemInfo;
 | |
| 
 | |
| 		}
 | |
| 		public void PasteRepalceEmpty(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 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);
 | |
| 						//B2025-018 Issues with folder order in tree view
 | |
| 						//since before/after folder is at same level as current folder
 | |
| 						//so need to use the parents order to determine where to place it
 | |
| 						using (FolderInfo parfolderinfo = FolderInfo.Get(parentfolder.MyParent.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));
 | |
| 							// B2024-023: when inserting a source section, the associated
 | |
| 							//	enhanced section did not appear in tree view or in edit window (if it
 | |
| 							//	was displayed in editor).  Add to tree view and close the enhanced
 | |
| 							//	procedure edit window. Note that closing of edit window was done to
 | |
| 							//	be consistent on what happens upon delete of source w/ and enhanced
 | |
| 							//	section.
 | |
| 							SectionInfo tmpsi = SectionInfo.Get(newenhSection.ItemID);
 | |
| 							RefreshRelatedNode(ProcedureInfo.Get(tmpsi.MyParent.ItemID));
 | |
| 							OnSectionShouldClose(this, new vlnTreeSectionInfoEventArgs(tmpsi, true));
 | |
| 						}
 | |
| 					}
 | |
| 					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, "")))
 | |
| 			{
 | |
| 				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;
 | |
| 		}
 | |
| 
 | |
| 		public void RemoveFolder(int folderId)
 | |
| 		{
 | |
| 			TreeNode nodeToRemove = FindNodeById(folderId, this.Nodes);
 | |
| 			if (nodeToRemove != null)
 | |
| 			{
 | |
| 				// Perform the removal logic
 | |
| 				nodeToRemove.Remove(); // This removes the node from its parent
 | |
| 			}
 | |
| 		}
 | |
| 		private TreeNode FindNodeById(int folderId, TreeNodeCollection nodes)
 | |
| 		{
 | |
| 			foreach (TreeNode node in nodes)
 | |
| 			{
 | |
| 				VETreeNode vetNode = node as VETreeNode;
 | |
| 				if (vetNode != null)
 | |
| 				{
 | |
| 					FolderInfo folderInfo = vetNode.VEObject as FolderInfo;
 | |
| 					if (folderInfo != null && folderInfo.FolderID == folderId)
 | |
| 					{
 | |
| 						return node;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						TreeNode foundNode = FindNodeById(folderId, node.Nodes);
 | |
| 						if (foundNode != null)
 | |
| 						{
 | |
| 							return foundNode;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		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
 | |
| }
 |