#define ItemWithContent using System; using System.Collections.Generic; using System.Text; using Csla; using Csla.Data; using System.Data; using System.Data.SqlClient; using System.Xml; using System.Drawing; using System.Text.RegularExpressions; using Volian.Base.Library; using System.Linq; namespace VEPROMS.CSLA.Library { #region Item public partial class Item : IVEDrillDown { // put in for debug //public static int CacheCountPrimaryKey //{ get { return _CacheByPrimaryKey.Count; } } //public static int CacheCountList //{ get { return _CacheList.Count; } } public string DisplayNumber { get { return ItemInfo.ConvertToDisplayText(MyContent.Number); } } public ItemInfo MyItemInfo /* Return Info version of the current Item */ { get { return ItemInfo.Get(ItemID); } } public static void ShowAllocated(string title) { Console.WriteLine("{0} - {1} Items in the dictionary", title, _CacheByPrimaryKey.Count); foreach (List itmlst in _CacheByPrimaryKey.Values) foreach (Item itm in itmlst) Console.WriteLine("Item {0} UniqueID {1}", itm.ItemID, itm.MyItemUnique); Console.WriteLine("- - - - - -"); } public override string ToString() { return string.Format("{0} {1}", MyContent.Number, MyContent.Text).Trim(); } // TODO: Move to ItemInfo Extension #region IVEDrillDown //public System.Collections.IList GetChildren() //{ // return this.MyContent.ContentParts; //} //public bool HasChildren //{ // get { return this.MyContent.ContentPartCount > 0; } //} //public Item MyProcedure //{ // get // { // // Walk up active parents until the parent is not an item // Item tmp = this; // while (tmp.ActiveParent.GetType() != typeof(DocVersion)) tmp = (Item)tmp.ActiveParent; // return tmp; // } //} //private IVEDrillDown _ActiveParent = null; //public IVEDrillDown ActiveParent //{ // get // { // if (_ActiveParent == null) // { // if (MyPrevious != null) // _ActiveParent = _MyPrevious.ActiveParent; // else // { // if (ItemDocVersionCount > 0) // _ActiveParent = this.ItemDocVersions[0].MyDocVersion; // else // { // if (this.ItemParts == null || this.ItemPartCount == 0) // _ActiveParent = this; // else // _ActiveParent = this.ItemParts[0].MyContent.ContentItems[0].MyItem; // } // } // } // return _ActiveParent == this ? null : _ActiveParent; // } //} //private Format _ActiveFormat = null;// Added to cache ActiveFormat //public Format ActiveFormat //{ // get // { // if (_ActiveFormat == null) // _ActiveFormat = (LocalFormat != null ? LocalFormat : ActiveParent.ActiveFormat); // return _ActiveFormat; // } // set // { // _ActiveFormat = null; // Reset // } //} //public Format LocalFormat //{ // get { return MyContent.MyFormat; } //} public ConfigDynamicTypeDescriptor MyConfig { get { return null; } } #endregion public void MoveItem(IVEDrillDownReadOnly pInfo, int index) { bool wasfirstchild = false; ItemInfo parentInfo = pInfo as ItemInfo; DocVersionInfo parentInfoDV = pInfo as DocVersionInfo; IList children = null; E_FromType partType = 0; // this is needed later to determine sub-group type. if (parentInfo != null) { // this may have subgroups, need to use part type to get children list... ItemInfo thisinfo = ItemInfo.Get(ItemID); partType = thisinfo.FirstSibling.ItemParts[0].PartType; children = (IList)parentInfo.Lookup((int)partType); } else children = (IList)parentInfoDV.GetChildren(); int numChild = children.Count; if (this.PreviousID == null) wasfirstchild = true;//Use PreviousID rather than MyPrevious so the item is not cached Item origNextItem = null; // First, remove from this item from its list. To do this, get the current item's next point and redirect it's myprevious // to this item's previous... if (NextItems != null && NextItems.Count > 0) { origNextItem = NextItems.Items[0]; origNextItem.MyPrevious = this.MyPrevious; this.Save(); } // check to see if the item is being moved into the middle of some items. newPreviousItem is the item defined // by index-1, i.e. inserting below newPreviousItem. ItemInfo newPreviousInfo = (index == 0) ? null : children[index - 1]; ItemInfo newNextInfo = (index == children.Count) ? null : children[index]; // Adjust the new next proc to be me. if (newNextInfo != null) { using (Item newNextItem = newNextInfo.Get()) { newNextItem.MyPrevious = this; newNextItem.Save(); } } // adjust the previous node, i.e. may either be at same level or, if first in list, adjust the parent... // if 'newPreviousItem' isn't null, then adding to the middle of the list. if (newPreviousInfo != null) { using (Item newPreviousItem = newPreviousInfo.Get()) { MyPrevious = newPreviousItem; Save(); } } else// RHM 2/20/2013 Moving Change { MyPrevious = null; // Console.WriteLine(">Setting MyPrevious Null {0}", ItemID); Save(); // Console.WriteLine("'Moved','e{0}','u{1}','{2}',{3}", ItemID, _MyItemUnique, StringIt(_LastChanged), index); ItemInfo.RefreshParent(this, parentInfo); //Console.WriteLine(" "); tmpForLink = Regex.Replace(tmpForLink, @"#Link:Transition:([0-9]+) [0-9]+ ", @"#Link:Transition:$1 "); tmpForLink = Regex.Replace(tmpForLink, @"#Link:TransitionRange:([0-9]+) [0-9]+ ", @"#Link:TransitionRange:$1 "); tmpForLink = tmpForLink.Replace(@"\u8212 \'96", @"-"); // Replace EM Dash with hyphen tmpForLink = tmpForLink.Replace(@"\u8211 \'96", @"-"); // Replace EN Dash with hyphen tmpForLink = tmpForLink.Replace(@"\u8212 ", @"-"); // Replace EM Dash with hyphen tmpForLink = tmpForLink.Replace(@"\u8211 ", @"-"); // Replace EN Dash with hyphen return tmpForLink; } //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. // This will be used to simulate the non-high level part of a tab // for case where sorting and all other fields match // Note: This is cut down to improve the sort's performance // but congruent to Volian.Print.Library.PDFReport-> BuildStepTab(ItemInfo item) public string BuildStepTab() { StringBuilder sret = new StringBuilder(); ItemInfo pitem = this; while (!pitem.IsSection && !pitem.IsHigh) { using (StepInfo stpinfo = StepInfo.Get(pitem.ItemID)) { string thisTab = stpinfo.MyTab.CleanText; string typeName = stpinfo.FormatStepData.StepEditData.TypeMenu.MenuItem; if (!string.IsNullOrEmpty(thisTab)) { thisTab = thisTab.Trim(); } // if the tab is null or // if the the tab is not a letter or number OR // the tab is an AND or OR type and is the letter "o" // then reset the tab an empty string so that the type name along with the count of that type // (ex. "AND 2", "OR 3") if (string.IsNullOrEmpty(thisTab) || (thisTab != string.Empty && (!(char.IsLetterOrDigit(thisTab[0])) || ((pitem.IsAnd || pitem.IsOr || pitem.IsCaution || pitem.IsNote) && thisTab.Contains("o"))))) { thisTab = string.Empty; } if (pitem.IsRNOPart) { if (string.IsNullOrEmpty(thisTab)) { sret.Insert(0, "RNO."); } else { thisTab = thisTab.Trim(); if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) { thisTab += "."; } sret.Insert(0, "RNO." + thisTab); } } else if (pitem.IsCaution || pitem.IsNote) { // add the Caution or Note count to the tab (ex "Caution 1", "Note 2") if (string.IsNullOrEmpty(thisTab)) { sret.Append("{" + typeName + " " + pitem.Ordinal.ToString() + "}"); } else { thisTab = thisTab.Trim(" ".ToCharArray()); sret.Append(thisTab + " " + pitem.Ordinal.ToString() + sret); } } else { if (!string.IsNullOrEmpty(thisTab)) { thisTab = thisTab.Trim(" ".ToCharArray()); if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) { thisTab += "."; } } else { thisTab = "{" + typeName + " " + pitem.Ordinal.ToString() + "}."; } sret.Insert(0, thisTab); } } pitem = pitem.ActiveParent as ItemInfo; if (pitem == null) break; } return sret.ToString().Trim(" .)".ToCharArray()); } public void SetHeader(VE_Font myFont, string myText) { _MyHeader = new MetaTag(myFont); _TagsSetup = true; _MyHeader.CleanText = myText; _MyHeader.Text = myText; _MyHeader.Justify = ContentAlignment.MiddleCenter; } public void MoveItem(IVEDrillDownReadOnly pInfo, int index) { using (ItemInfoList movedItems = ItemInfoList.GetMoveItem(ItemID, index)) { foreach (ItemInfo itm in movedItems) ItemInfo.Refresh(itm); } DocVersionInfo parentInfoDV = pInfo as DocVersionInfo; if (parentInfoDV != null) DocVersionInfo.ResetProcedures(parentInfoDV.VersionID); ItemInfo parentInfo = pInfo as ItemInfo; if (parentInfo != null) ItemInfo.ResetParts(parentInfo.ItemID); } public static void Refresh(ItemInfo tmp) { string key = tmp.ItemID.ToString(); ConvertListToDictionary(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (ItemInfo tmpInfo in _CacheByPrimaryKey[key]) tmpInfo.RefreshFields(tmp); } protected virtual void RefreshFields(ItemInfo tmp) { if (_PreviousID != tmp.PreviousID) { if (MyPrevious != null) MyPrevious.RefreshNextItems(); // Update List for old value _PreviousID = tmp.PreviousID; // Update the value } _MyPrevious = null; // Reset list so that the next line gets a new list if (MyPrevious != null) MyPrevious.RefreshNextItems(); // Update List for new value //if (_ContentID != tmp.ContentID) //{ if (MyContent != null) MyContent.RefreshContentItems(); // Update List for old value _ContentID = tmp.ContentID; // Update the value //} _MyContent = null; // Reset list so that the next line gets a new list if (MyContent != null) MyContent.RefreshContentItems(); // Update List for new value _DTS = tmp.DTS; _UserID = tmp.UserID; _ItemInfoExtension.Refresh(this); OnChange();// raise an event } private bool _Moving = false; public bool Moving { get { return _Moving; } set { _Moving = value; } } public static void RefreshParent(Item tmp, ItemInfo pInfo) { string key = tmp.ItemID.ToString(); ConvertListToDictionary(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (ItemInfo tmpInfo in _CacheByPrimaryKey[key]) { tmpInfo._ActiveParent = pInfo; tmpInfo.RefreshItemParts(); } } private string _HighLevelStepTabPageList = null; public string HighLevelStepTabPageList { get { return _HighLevelStepTabPageList; } set { _HighLevelStepTabPageList = value; } } private bool _NewTransToUnNumberedItem = false; public bool NewTransToUnNumberedItem { get { return _NewTransToUnNumberedItem; } set { _NewTransToUnNumberedItem = value; } } // put in for debugging //public static int CacheCountPrimaryKey //{ get { return _CacheByPrimaryKey.Count; } } //public static int CacheCountList //{ get { return _CacheList.Count; } } //public override bool Equals(object obj) //{ // ItemInfo ii = obj as ItemInfo; // if (ii != null) // return ii._ItemID == _ItemID; // return false; //} internal static void SetFromType(ItemInfo myItemInfo) { myItemInfo.PrintAllAtOnce = true; if (myItemInfo.MyContent.ContentPartCount > 0) { foreach (PartInfo pi in myItemInfo.MyContent.ContentParts) { ItemInfo il = null; switch ((E_FromType)pi.FromType) { case E_FromType.Procedure: myItemInfo._Procedures = pi.MyItems; break; case E_FromType.Section: myItemInfo._Sections = pi.MyItems; break; case E_FromType.Step: myItemInfo._Steps = pi.MyItems; break; case E_FromType.Caution: myItemInfo._Cautions = pi.MyItems; break; case E_FromType.Note: myItemInfo._Notes = pi.MyItems; break; case E_FromType.RNO: myItemInfo._RNOs = pi.MyItems; break; case E_FromType.Table: myItemInfo._Tables = pi.MyItems; break; case E_FromType.SupInfo: myItemInfo._SupInfos = pi.MyItems; break; } foreach (ItemInfo ii in pi.MyItems) { ii.FromType = (E_FromType)pi.FromType; SetFromType(ii); ii.MyPrevious = il; il = ii; } } } } internal static void SetParentSectionAndDocVersion(ItemInfo itemInfo, IVEDrillDownReadOnly itemParent, SectionInfo sectionInfo, ProcedureInfo procInfo, DocVersionInfo docVersionInfo, bool isAutomatic = false) { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Optional Parameter "bool isAutomatic = false" to disable the RofstLoadingStatus pop-up screen when printing baselines if (itemInfo == null) return; itemInfo.LoadAllAtOnce = true; itemInfo.ActiveParent = itemParent; itemInfo.MyParent = itemParent as ItemInfo; // Fix for Active Section when printing. BGE_OI4 OI27D-2 if (itemInfo.IsSection && !itemInfo.IsStepSection) // If a Word Section use the current section B2016-227 itemInfo.ActiveSection = (itemInfo as SectionInfo) ?? sectionInfo;// - possible fix for not accessing correct format else itemInfo.ActiveSection = sectionInfo;// If not a Word Section use the parent itemInfo.ActiveFormat = itemInfo.MyContent.MyFormat != null ? itemInfo.MyContent.MyFormat : sectionInfo == null ? itemParent.ActiveFormat : sectionInfo.ActiveFormat; itemInfo.MyProcedure = procInfo; itemInfo.MyDocVersion = docVersionInfo; if (itemInfo.IsStep) { ItemInfo ip = itemParent as ItemInfo; int profileDepth = ProfileTimer.Push(">>>> itemInfo.CombinedTab"); itemInfo.CombinedTab = (ip == null) ? itemInfo.MyTab.CleanText.Trim() : GetCombinedTab(itemInfo, ip.CombinedTab); ProfileTimer.Pop(profileDepth); } if (itemInfo.MyContent.ContentGridCount > 0) { int profileDepth1 = ProfileTimer.Push(">>>> itemInfo.MyContent.LoadNonCachedGrid"); itemInfo.MyContent.LoadNonCachedGrid(); ProfileTimer.Pop(profileDepth1); } if (itemInfo.MyContent.ContentPartCount > 0) foreach (PartInfo pi in itemInfo.MyContent.ContentParts) { //ItemInfo il = null; foreach (ItemInfo ii in pi.MyItems) { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Parameter "isAutomatic" to disable the RofstLoadingStatus pop-up screen when printing baselines SetParentSectionAndDocVersion(ii, itemInfo, (itemInfo as SectionInfo) ?? sectionInfo, procInfo, docVersionInfo, isAutomatic); //if (ii._MyPrevious == null && il!=null) //ii.MyPrevious = il; //if (il != null) il.NextItem = ii; //il = ii; } } } /// /// The following method is used only in print because the 'printed' data is loaded into /// memory before printing. Find the next item from memory (do not go out to database). /// /// public ItemInfo GetNextItem() { ItemInfo mypar = this.MyParent as ItemInfo; if (mypar == null) return null; if (mypar.MyContent.ContentPartCount > 0) foreach (PartInfo pi in mypar.MyContent.ContentParts) { bool foundMe = false; foreach (ItemInfo ii in pi.MyItems) { if (foundMe) return ii; if (ii.ItemID == ItemID) // found the current item for which we want to get next. foundMe = true; } } return null; } public static void ResetTranCounters() { TranCheckCount = 0; TranFixCount = 0; TranCantFixCount = 0; TranConvertCount = 0;// B2018-002 - Invalid Transitions - Initialize Transition Conversion Count } public static int TranCheckCount = 0; public static int TranFixCount = 0; public static int TranConvertCount = 0;// B2018-002 - Invalid Transitions - Declare Transition Conversion Count public static int TranCantFixCount = 0; internal static TransitionInfoList TransitionsToDisconnected; internal static TransitionInfoList TransitionsToNonEditable; internal static void MyRefreshTransitions(ItemInfo itemInfo, IVEDrillDownReadOnly itemParent, SectionInfo sectionInfo, ProcedureInfo procInfo, DocVersionInfo docVersionInfo, TransitionLookup tranLookup) { if (itemInfo == null) return; if (itemInfo.MyContent.ContentPartCount > 0) { foreach (PartInfo pi in itemInfo.MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) { MyRefreshTransitions(ii, itemInfo, (itemInfo as SectionInfo) ?? sectionInfo, procInfo, docVersionInfo, tranLookup); } } } // B2018-002 - Invalid Transitions - Convert Invalid Transitions to Text // An invalid transition is a transition embedded in the content text that does not match the transition table record. if(ConvertInvalidTransitionsToText(itemInfo)) { itemInfo.ResetOrdinal(); foreach (TransitionInfo traninfo in itemInfo.MyContent.ContentTransitions) { bool forceConvertToText = false; TranCheckCount++; if (!forceConvertToText) { if (traninfo.MyItemToID.ActiveSection != null) { SectionConfig sc = traninfo.MyItemToID.ActiveSection.MyConfig as SectionConfig; forceConvertToText = (sc.SubSection_Edit == "N" && traninfo.MyItemToID.IsStep); // Bug fix B2016-081 also check if transition is to a step element } if (forceConvertToText) { TranFixCount++; itemInfo.MyContent.FixTransitionText(traninfo, itemInfo, "Reason for Change: Transition to Non-Editable Step"); using (Content content = Content.Get(itemInfo.MyContent.ContentID)) //B2024-006 free up content memory when done { content.FixTransitionText(traninfo, true); content.Save(); } } } if (!forceConvertToText) { if (itemInfo.MyProcedure.ItemID != traninfo.MyItemToID.MyProcedure.ItemID) //different proc { if (!itemInfo.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[traninfo.TranType].TransMenu.Contains("Proc")) //internal format { if (!itemInfo.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[traninfo.TranType].TransMenu.Contains("other proc")) //B2017-068 paste with transition fix { forceConvertToText = true; TranFixCount++; itemInfo.MyContent.FixTransitionText(traninfo, itemInfo, "Reason for Change: Transition to External Procedure using Internal Format"); using (Content content = Content.Get(itemInfo.MyContent.ContentID)) //B2024-006 free up content memory when done { content.FixTransitionText(traninfo, true); content.Save(); } } } } } if (!forceConvertToText) { if (itemInfo.MyDocVersion != null && traninfo.MyItemToID.MyDocVersion != null && itemInfo.MyDocVersion.VersionID != traninfo.MyItemToID.MyDocVersion.VersionID) //different doc version { if (!itemInfo.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[traninfo.TranType].TransMenu.Contains("Proc")) //internal format { if (!itemInfo.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[traninfo.TranType].TransMenu.Contains("other proc")) //B2017-068 paste with transition fix { forceConvertToText = true; TranFixCount++; itemInfo.MyContent.FixTransitionText(traninfo, itemInfo, "Reason for Change: Transition to Outside Procedure using Internal Format"); using (Content content = Content.Get(itemInfo.MyContent.ContentID)) //B2024-006 free up content memory when done { content.FixTransitionText(traninfo, true); content.Save(); } } } } } if (!forceConvertToText) { string oldText = itemInfo.MyContent.Text; itemInfo.MyContent.FixTransitionText(traninfo, itemInfo); string newText = itemInfo.MyContent.Text; // B2017-165 added check of newValue (special case for old 16-bit transition that was not fixed by the customer) string newValue = traninfo.ResolvePathTo(itemInfo.ActiveFormat, itemInfo, traninfo.TranType, traninfo.MyItemToID, traninfo.MyItemRangeID); if (newText != oldText || newValue == "?") { TranFixCount++; using (Content content = Content.Get(itemInfo.MyContent.ContentID)) //B2024-006 free up content memory when done { content.FixTransitionText(traninfo); content.Save(); } } else if (newText.Contains(" itemInfo.MyContent.ContentTransitionCount) { retval = false; if (itemInfo.MyContent.Text.Contains("Link:Transition")) { Content content = Content.Get(itemInfo.MyContent.ContentID); if (itemInfo.MyContent.ContentTransitions != null) { foreach (TransitionInfo ct in itemInfo.MyContent.ContentTransitions) { Transition.Delete(ct.TransitionID); } } itemInfo.MyContent.RefreshContentTransitions(); while (content.Text.Contains("Link:Transition")) { TranCheckCount++; TranConvertCount++; if (content.FixTransitionText(null, true)) { ContentInfo.OnStaticContentInfoChange(itemInfo, new StaticContentInfoEventArgs("", "", "")); if (itemInfo.MyContent.MyGrid != null) { content.ConvertTransitionToTextInGrid(null, null); } content.Save(); } else // B2018-043 Eliminate infinite loop for invalid transition structure { // Add annotation for Invalid Transition AddInvalidTransitionAnnotation(itemInfo,"Invalid Transition Format"); break; } } } } // B2021-008: Delete the transition record if there is no link in the text if (mc.Count == 0 && itemInfo.MyContent.ContentTransitionCount > 0) { TranCheckCount++; TranFixCount++; if (itemInfo.MyContent.ContentTransitions != null) { foreach (TransitionInfo ct in itemInfo.MyContent.ContentTransitions) { Transition.Delete(ct.TransitionID); } } itemInfo.MyContent.RefreshContentTransitions(); } return retval; } private static void AddInvalidTransitionAnnotation(ItemInfo itemInfo, string msg) { bool hasAnnotation = false; AnnotationType myType = AnnotationType.GetByNameOrCreate("Link Converted To Text"); if (itemInfo.ItemAnnotations != null) { foreach (AnnotationInfo anot in itemInfo.ItemAnnotations) { if (anot.TypeID == myType.TypeID && anot.SearchText == msg) hasAnnotation = true; } if (!hasAnnotation) { using (Item myItem = itemInfo.Get()) { Annotation.MakeAnnotation(myItem, myType, "", msg, null); } } } } private static void RemoveEmptyTransitions(ItemInfo itemInfo) { ContentInfo myContent = itemInfo.MyContent; string txt = myContent.Text; string regDelete = @"(\\v |)\(\\v0 |)"; string txt2=txt; do{ txt = txt2; txt2 = Regex.Replace(txt, regDelete, ""); } while(txt2 != txt); if(txt2 != myContent.Text) { using(Content tmp = myContent.Get()) { tmp.Text = txt2; tmp.Save(); } AddInvalidTransitionAnnotation(itemInfo, "Removed Empty Transition Text"); } } private static bool IsTransitionToNonEditable(TransitionInfo ti) { foreach (TransitionInfo til in TransitionsToNonEditable) { if (ti.TransitionID == til.TransitionID) return true; } return false; } public static void ResetROCounters() { ROCheckCount = 0; ROFixCount = 0; } //C2022-028 used during check of RO links in procedure text public static int CheckROLinksCount = 0; public static int BadROLinksCount = 0; public static int FixedROLinksCount = 0; public static void ResetCheckROLinkCounters() { CheckROLinksCount = 0; BadROLinksCount = 0; FixedROLinksCount = 0; } public static int ROCheckCount = 0; public static int ROFixCount = 0; private static AnnotationType _VolianCommentType = null; // Using this to flag ro value issues with byron to braidwood public static AnnotationType VolianCommentType { get { if (_VolianCommentType == null) _VolianCommentType = AnnotationType.GetByName("Volian Comment"); if (_VolianCommentType == null) _VolianCommentType = AnnotationType.MakeAnnotationType("Volian Comment", null); return _VolianCommentType; } } public void UpdateROText() { if (this.MyDocVersion.DocVersionAssociationCount == 0) return; ROFstInfo rofstinfo = this.MyDocVersion.DocVersionAssociations[0].MyROFst; ROFSTLookup lookup = rofstinfo.GetROFSTLookup(this.MyDocVersion); lookup.MyItemInfo = this; // B2022-020 to pass information into error log if needed if (this.MyContent.ContentRoUsageCount > 0) { foreach (RoUsageInfo rousage in this.MyContent.ContentRoUsages) { if (this.ActiveSection != null) { string oldText = this.MyContent.Text; string roval = lookup.GetTranslatedRoValue(rousage.ROID, this.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, this.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, false, this); ROFSTLookup.rochild roch = lookup.GetRoChild(rousage.ROID); this.MyContent.FixContentText(rousage, roval, roch.type, rofstinfo, this); string newText = this.MyContent.Text; if (newText != oldText) { Content content = Content.Get(this.MyContent.ContentID); if (roval == "?") { oldText = content.ConvertROToText(rousage, roval, roch.type, rofstinfo); using (Item myitem = content.ContentItems[0].MyItem) // so that myitem does not stay in cache B2016-153 { myitem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed - part of B2017-060 // B2016-225 (follow through) added more descriptive Annotation Type when RO is converted to text Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", string.Format("RO value ({0}) converted to text", ItemInfo.ConvertToDisplayText(oldText)), null); } } else { content.FixContentText(rousage, roval, roch.type, rofstinfo); } content.Save(); } } } } } // B2022-026 RO Memory Reduction code - pass in ROFstInfo internal static void MyRefreshReferenceObjects(ItemInfo itemInfo, IVEDrillDownReadOnly itemParent, SectionInfo sectionInfo, DocVersionInfo docVersionInfo, ROFstInfo origROFst) { if (itemInfo.MyContent.ContentPartCount > 0) { foreach (PartInfo pi in itemInfo.MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) { MyRefreshReferenceObjects(ii, itemInfo, (itemInfo as SectionInfo) ?? sectionInfo, docVersionInfo, origROFst); } } } // B2022-026 RO Memory Reduction code - get ROLookup from passed in ROFstInfo ROFSTLookup lookup = origROFst.GetROFSTLookup(docVersionInfo); lookup.MyItemInfo = itemInfo; // B2022-020 to pass information into error log if needed if (itemInfo.MyContent.ContentRoUsageCount > 0) { foreach (RoUsageInfo rousage in itemInfo.MyContent.ContentRoUsages) { if (sectionInfo != null) { ROCheckCount++; string oldText = itemInfo.MyContent.Text; string roval = lookup.GetTranslatedRoValue(rousage.ROID, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, false, sectionInfo); ROFSTLookup.rochild roch = lookup.GetRoChild(rousage.ROID); itemInfo.MyContent.FixContentText(rousage, roval, roch.type, origROFst, itemInfo); string newText = itemInfo.MyContent.Text; if (DifferentROtext(newText, oldText)) { //ShowDifference(oldText, newText); // debug - display in Visual Studio Output window ROFixCount++; using (Content content = Content.Get(itemInfo.MyContent.ContentID)) //B2024-006 free up content memory when done { if (roval == "?") { oldText = content.ConvertROToText(rousage, roval, roch.type, origROFst); using (Item myitem = content.ContentItems[0].MyItem) // so that myitem does not stay in cache B2016-153 { myitem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed - part of B2017-060 // B2016-225 (follow through) added more descriptive Annotation Type when RO is converted to text Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", string.Format("RO value ({0}) converted to text", ItemInfo.ConvertToDisplayText(oldText)), null); } } else { content.FixContentText(rousage, roval, roch.type, origROFst); } content.UserID = Volian.Base.Library.VlnSettings.UserID; content.DTS = DateTime.Now; content.Save(); } } } } } } //C2022-028 check the RO link text - compare with RO Usage information, annotate RO links that are bad internal static void MyCheckROLinks(ItemInfo itemInfo) { // spin through all of the parts of this IntemInfo if (itemInfo.MyContent.ContentPartCount > 0) { foreach (PartInfo pi in itemInfo.MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) { MyCheckROLinks(ii); } } } using (Content content = Content.Get(itemInfo.MyContent.ContentID)) { content.CheckROLinkTextandUsage(ref BadROLinksCount, ref CheckROLinksCount, ref FixedROLinksCount); } /*** comment out for now incase we decide to fix bad RO links Content content = Content.Get(itemInfo.MyContent.ContentID); if (content.CheckROLinkTextandUsage(ref BadROLinksCount, ref CheckROLinksCount, ref FixedROLinksCount)) { content.UserID = Volian.Base.Library.VlnSettings.UserID; content.DTS = DateTime.Now; content.Save(); } ***/ } private static bool DifferentROtext(string newText, string oldText) { string nt = newText.Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " "); string ot = oldText.Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " "); if (nt.Equals(ot)) { return false; } // B2023-037: Handle <=, >=, +-, -> and <- symbols. Previous code changes replaced these symbol pairs with their // unicode representation, thus link text data may have the Unicode character. This code update keeps the double // character sequences in the link text (the RO text as is) and just converts when needing the output. When // updating ROs need to check for unicode characters too since some data may have that nt = nt.Replace(@"\u8594?", "->"); // Right Arrow ot = ot.Replace(@"\u8594?", "->"); // Right Arrow nt = nt.Replace(@"\u8592?", "<-"); // Left Arrow ot = ot.Replace(@"\u8592?", "<-"); // Left Arrow nt = nt.Replace(@"\u8804?", "<="); // Less than or Equal ot = ot.Replace(@"\u8804?", "<="); // Less than or Equal nt = nt.Replace(@"\u8805?", ">="); // Greater than or Equal ot = ot.Replace(@"\u8805?", ">="); // Greater than or Equal nt = nt.Replace(@"\u8805?", ">="); // Greater than or Equal ot = ot.Replace(@"\u8805?", ">="); // Greater than or Equal nt = nt.Replace(@"\u8594?", "+-"); // plus minus ot = ot.Replace(@"\u8594?", "+-"); // plus minus nt = nt.Replace(@"\'b1", "+-"); ot = ot.Replace(@"\'b1", "+-"); if (nt.Equals(ot)) { return false; } return true; } #region Debug Code //private static void ShowDifference(string oldText, string newText) //{ // string nt = newText.Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " "); // string ot = oldText.Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " "); // ShowText("OldText", ot); // ShowText("NewText", nt); //} //private static void ShowText(string title, string newText) //{ // StringBuilder sb = new StringBuilder(); // foreach (char c in newText) // { // if(c<' ' || c> '\x7F') // sb.Append(string.Format("\\x{0:X2}",((int) c))); // else // sb.Append(c); // } // Console.WriteLine("{0}='{1}'",title,sb.ToString()); //} #endregion // debug internal static void SetParentSectionAndDocVersionPageNum(ItemInfo itemInfo, IVEDrillDownReadOnly itemParent, SectionInfo sectionInfo, ProcedureInfo procInfo, DocVersionInfo docVersionInfo, TransitionLookup tranLookup) { if (itemInfo.MyContent.ContentPartCount > 0) { foreach (PartInfo pi in itemInfo.MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) { SetParentSectionAndDocVersionPageNum(ii, itemInfo, (itemInfo as SectionInfo) ?? sectionInfo, procInfo, docVersionInfo, tranLookup); } } } if (itemInfo.MyContent.ContentTransitionCount > 0) { foreach (TransitionInfo traninfo in itemInfo.MyContent.ContentTransitions) { itemInfo.MyContent.FixTransitionText(traninfo, tranLookup, itemInfo); } } } public static string GetCombinedTab(ItemInfo itemInfo, string parTab) { string pTab = parTab == null ? "" : parTab; int profileDepth = ProfileTimer.Push(">>>> itemInfo.MyTab.CleanText.Trim"); string thisTab = itemInfo.MyTab.CleanText.Trim(); ProfileTimer.Pop(profileDepth); //The following will include '(x)' where 'x' is stepnumber for VC Summer Unit 2 & 3 (vcb) Note & Caution tabs bool vcbHeaderCheck = itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.CombinedTabIncludeParenTabs && thisTab != null && thisTab != "" && thisTab.Length > 1 && char.IsLetterOrDigit(thisTab[1]); // for supplemental information, bulleted tabs need to be included in the tab. The 'isletterordigit' should not occur for supinfo items - // and this includes the parent of the supinfo since that is the tab used for supinfo concatenated with its parent. (B2017-120) // // B2020-154: Added check for the tab to start with '(', tabs that started with this were not included in the combined tab if (thisTab != null && thisTab != "" && (!char.IsLetterOrDigit(thisTab[0]) && thisTab[0] != '(') && !vcbHeaderCheck && !itemInfo.IsInSupInfo && (itemInfo.SupInfos == null || itemInfo.SupInfos.Count <= 0 )) return pTab; if (itemInfo.FormatStepData.NumberWithLevel) pTab = itemInfo.MyHLS.MyTab.CleanText.Trim(); // if the parent tab ends with a alphanumeric and this tab is alphanumeric, add a '.' to separate them // also, include use the separator for bullets if doing the supplemental information tab (B2017-120) bool ms = pTab != "" && char.IsLetterOrDigit(pTab.TrimEnd()[pTab.Length - 1]); // parent tab ends with alphanumeric bool mn = thisTab.TrimStart().Length > 0 && ((itemInfo.IsInSupInfo || (itemInfo.SupInfos != null && itemInfo.SupInfos.Count > 0)) || char.IsLetterOrDigit(thisTab.TrimStart()[0]));// this starts with alpha if (ms && mn) pTab = pTab.TrimEnd() + "."; // remove ending '.' (if this is a hls, don't remove the '.') if (!itemInfo.IsHigh && thisTab.EndsWith(".")) thisTab = thisTab.Substring(0, thisTab.Length - 1); if (itemInfo.HasParentTab) return thisTab.Trim(); // F2020-023: if tab includes parent tab already, don't concatenate it return pTab + thisTab.Trim(); } internal static void SetParentSectionAndDocVersion(ItemInfo itemInfo, IVEDrillDownReadOnly itemParent, SectionInfo sectionInfo, DocVersionInfo docVersionInfo, TransitionLookup tranLookup, bool isAutomatic = false) { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Optional Parameter "bool isAutomatic = false" to disable the RofstLoadingStatus pop-up screen when printing baselines if (itemInfo == null) return; itemInfo.LoadAllAtOnce = true; itemInfo.ActiveParent = itemParent; itemInfo.MyParent = itemParent as ItemInfo; // itemInfo.ActiveSection = (itemInfo as SectionInfo) ?? sectionInfo; itemInfo.ActiveSection = sectionInfo; itemInfo.ActiveFormat = itemInfo.MyContent.MyFormat != null ? itemInfo.MyContent.MyFormat : sectionInfo == null ? itemParent.ActiveFormat : sectionInfo.ActiveFormat; itemInfo.MyDocVersion = docVersionInfo; if (itemInfo.IsStep) { ItemInfo ip = itemParent as ItemInfo; itemInfo.CombinedTab = (ip == null) ? itemInfo.MyTab.CleanText.Trim() : GetCombinedTab(itemInfo, ip.CombinedTab); } if (docVersionInfo.DocVersionAssociationCount == 1) { string otherChildUnit = null; ROFstInfo rofstinfo = docVersionInfo.DocVersionAssociations[0].MyROFst; //rofstinfo.docVer = docVersionInfo; string rawPrcNum = itemInfo.MyProcedure.MyContent.Number; // C2022-001 see if we need to get the Other child info from ROLookUp if (rawPrcNum.ToUpper().StartsWith(" in its definiation (procedure property page) { string procnum = itemInfo.MyProcedure.DisplayNumber; // get the cooked (resolved) procedure number int idx = procnum.IndexOf('-'); otherChildUnit = procnum.Substring(0, idx); // we need to get RO info for the Other child applicability - this gets child's number } // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Parameter "isAutomatic" to disable the RofstLoadingStatus pop-up screen when printing baselines ROFSTLookup lookup = rofstinfo.GetROFSTLookup(docVersionInfo, otherChildUnit, !isAutomatic); lookup.MyItemInfo = itemInfo; // B2022-020 to pass information into error log if needed if (itemInfo.MyContent.ContentGridCount > 0) itemInfo.MyContent.LoadNonCachedGrid(); if (itemInfo.MyContent.ContentRoUsageCount > 0) { foreach (RoUsageInfo rousage in itemInfo.MyContent.ContentRoUsages) { if (sectionInfo != null) { // B2023-037: loading print text, resolve the RO symbols bool GTLT = !itemInfo.IsTable && sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertGTELTEPMinROValue; bool GLTArrows = !itemInfo.IsTable && sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseDashGreaterLessThenForArrowsInROValue; string roval = lookup.GetTranslatedRoValue(rousage.ROID, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, sectionInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, GTLT || GLTArrows, itemInfo); ROFSTLookup.rochild roch = lookup.GetRoChild(rousage.ROID); itemInfo.MyContent.FixContentText(rousage, roval, roch.type, rofstinfo, itemInfo); } } } } else { // Force Error Message docVersionInfo.GetROFst(0); } if (itemInfo.MyContent.ContentPartCount > 0) { foreach (PartInfo pi in itemInfo.MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Parameter "isAutomatic" to disable the RofstLoadingStatus pop-up screen when printing baselines SetParentSectionAndDocVersion(ii, itemInfo, (itemInfo as SectionInfo) ?? sectionInfo, docVersionInfo, tranLookup, isAutomatic); } } } if (itemInfo.MyContent.ContentTransitionCount > 0) { foreach (TransitionInfo traninfo in itemInfo.MyContent.ContentTransitions) { itemInfo.MyContent.FixTransitionText(traninfo, tranLookup, itemInfo); } } } private int _PrintBias = 0; public int PrintBias { get { return _PrintBias; } set { _PrintBias = value; } } private int _OffsetTab = 0; public int OffsetTab { get { return _OffsetTab; } set { _OffsetTab = value; } } // F2020-023: tab includes parent tab private bool _HasParentTab = false; public bool HasParentTab { get { return _HasParentTab; } set { _HasParentTab = value; } } private int _PrintLevel = 0; public int PrintLevel { get { if (_PrintLevel != 0) return _PrintLevel; int _PrintBias = 0; _PrintLevel = GetStepLevel(); //ref _PrintBias); return _PrintLevel; } set { _PrintLevel = value; } } // The following properties track the page number that this item is on if the resolved // transition text has a Page Number associated with it. Formats that have this either // have the UseTransitionModfier flag or have '{Page Num}' in respective transition formats. // If the format requires page numbers in transitions text, two passes are run through the // data for printing. The first determines page numbers, the seconds resolves the transition // text. The PageNumberUsed value is used to determine if the page number in 1st & 2nd passes // are different. This can be caused by the page number text causing different heights of // the step that causes change in pagination. If this occurs, the user is presented with a // dialog box that shows the step that causes the problem & a manual change will be necessary. // This is a rare occurence so it was decided that the amount of coding effort to fix this // would be so much in comparison to having the user fix manually (RHM/KBR Feb 2014). private int _PageNumber = -1; public int PageNumber { get { return _PageNumber; } set { _PageNumber = value; } } private int _PageNumberUsed = 0; public int PageNumberUsed { get { return _PageNumberUsed; } set { _PageNumberUsed = value; } } private int _PageNumberNextPass = 0; public int PageNumberNextPass { get { return _PageNumberNextPass; } set { _PageNumberNextPass = value; } } private float _MSWordPageCount = 0; public float MSWordPageCount { get { if (_MSWordPageCount == 0) // C2018-011 Get the proper word page count from the saved pdf attachment if (MyContent.MyEntry != null && MyContent.MyEntry.MyDocument != null) { PdfInfo pi = PdfInfo.Get(this, false); if(pi != null) _MSWordPageCount = (float)pi.PageCount;// B2018-071 Don't crash on invalid MS Word section } return _MSWordPageCount; } set { _MSWordPageCount = value; } } public event ItemInfoEvent OrdinalChanged; private void OnOrdinalChange() { if (OrdinalChanged != null) OrdinalChanged(this); } public static void OnOrdinalChange(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) { // Create a temporary list to process cache entries then use // the temporary list which may have a side effect on the cache entries, // thus the need for the temporary list. List myCache = new List(); foreach (ItemInfo item in _CacheByPrimaryKey[key]) myCache.Add(item); foreach (ItemInfo item in myCache) item.OnOrdinalChange(); } } public bool IsFirstSubStep { get { if (!IsStepPart) return false; if (IsHigh) return false; return (MyPrevious == null); } } public bool IsAutoTOCSection { get { if (!IsSection) return false; if (MyDocStyle.StructureStyle.Style == null) return false; return ((ActiveFormat.PlantFormat.FormatData.PurchaseOptions & E_PurchaseOptions.AutoTableOfContents) == E_PurchaseOptions.AutoTableOfContents && (MyDocStyle.StructureStyle.Style & E_DocStructStyle.TableOfContents) == E_DocStructStyle.TableOfContents); } } public bool IsPlacekeeperSection { get { if (!IsSection) return false; if (MyDocStyle.StructureStyle.Style == null) return false; return ((ActiveFormat.PlantFormat.FormatData.PurchaseOptions & E_PurchaseOptions.AutoPlacekeeper) == E_PurchaseOptions.AutoPlacekeeper && (MyDocStyle.StructureStyle.Style & E_DocStructStyle.Placekeeper) == E_DocStructStyle.Placekeeper); } } public bool CanSetPlacekeeper { get { if (IsProcedure) return false; SectionConfig scfg = ActiveSection.MyConfig as SectionConfig; if (MyDocStyle.StructureStyle.Style == null || scfg == null) return false; bool PlacekeepOption = ((ActiveFormat.PlantFormat.FormatData.PurchaseOptions & E_PurchaseOptions.AutoPlacekeeper) == E_PurchaseOptions.AutoPlacekeeper) && scfg.Section_Placekeeper.Equals("Y"); //return (PlacekeepOption && IsHigh); return (PlacekeepOption); } } public bool MoreThanOneStepSection() { if (IsProcedure || IsSection) return false; // If 'toitem' is a step, get to section. ItemInfo par = MyParent; while (par != null && !par.IsSection) par = par.MyParent; if (par == null) return false; par = par.FirstSibling; int cntStepSect = 0; while (par != null) { if (par.IsStepSection) cntStepSect++; par = par.NextItem; } if (cntStepSect > 1) return true; return false; } #region StepLevel private int _StepLevel = -2;// Not yet calculated public int StepLevel { get { if (_StepLevel == -2) { _StepLevel = CalcStepLevel(this); //ItemInfo parent = ActiveParent as ItemInfo; //Console.WriteLine("{0},{1},{2},{3},{4},{5},{6}",ItemID, DBSequence, _StepLevel, MyContent.Type % 10000, parent.MyContent.Type % 10000,HasCautionOrNote ? 1 : 0, parent.Cautions == null? 0 : 1); } return _StepLevel; } set { _StepLevel = value; } } public string ToolTip { get { if (IsStep) return FormatStepData.StepEditData.TypeMenu.MenuItem; //FormatStepData.Type; else if (IsSection) return MyDocStyle.Name; return "Procedure Title"; } } public bool HasCautionOrNote { get { return Cautions != null || Notes != null; } } private static Regex regexDBSeqPass1 = new Regex("([^.]*)[.]S([^.]*)[.]S([0-9]*)[.](.*)"); private static Regex regexDBSeqPass2 = new Regex("[.](.)([^.]*)[.]"); public string DBSequence { get { Match m1 = regexDBSeqPass1.Match(ShortPath); MatchCollection m2s = regexDBSeqPass2.Matches(m1.Groups[4].Value); StringBuilder retval = new StringBuilder(string.Format("\"{0}\"\t\"{1}\"\t\"{2}\"", m1.Groups[1].Value, m1.Groups[2].Value, m1.Groups[3].Value)); string prefix = "S"; string suffix = ""; foreach (Match m2 in m2s) { int i = ((int)'0') + int.Parse(m2.Groups[2].Value); char c = (char)i; suffix = c.ToString(); switch (m2.Groups[1].Value) { case "S": break; case "R": prefix += "$"; suffix = ""; break; case "C": prefix = "!"; break; case "N": prefix = "*"; break; case "T": prefix += "#"; suffix = ""; break; default: break; } retval.Append(prefix + suffix); prefix = ""; } retval.Append(prefix + "'"); //Volian.Base.Library.DebugText.WriteLine("'{0}','{1}','{2}'", retval, ShortPath, Path); return retval.ToString(); } } // B2019-121 tell us if the step item in part of a caution or note type public bool HasAncestorCautionOrNote { get { ItemInfo item = this.ActiveParent as ItemInfo; while (item is ItemInfo && !item.IsHigh) { if (item.IsInCautionOrNote) return true; item = item.ActiveParent as ItemInfo; } return false; } } private static int CalcStepLevel(ItemInfo item) { if (item == null) return 0; int id = 0; // Determines the substep level. int level = CountLevels(item); // PaginateOnFirstSubstep allows orphans, first child can be separated from its parent. int firstInc = item.ActiveFormat.MyStepSectionLayoutData.PaginateOnFirstSubstep ? 0 : 1; ItemInfo parent = item.ActiveParent as ItemInfo; if (item.IsExactType("And") || item.IsExactType("Or") || item.IsExactType("ImplicitOr")) level++; //if (item.ParentAndOr) // level++; level += item.ParentAndOrCount; // First substep, this is where it uses the orphan logic from above. // The check for the parent.IsNote was added for Calvert OI3/OI-1A, section 5, step H. This is a // very long step with a very long note (multiple notes each having 1 or more ANDs). Without // the addition of the parent.IsNote, the note was breaking between 2 ANDs (the 1st AND was a // steplevel of 5, but the 2nd was a steplevel of 4). If something similar is seen with Cautions, // that check could be added. if (!item.IsRNOPart && !item.IsHigh && (item.MyPrevious == null || (((item.ActiveFormat.PlantFormat.FormatData.PurchaseOptions & E_PurchaseOptions.EnhancedBackgrounds) != E_PurchaseOptions.EnhancedBackgrounds) && item.MyParent != null && item.MyParent.IsNote))) level += firstInc; else firstInc = 0; // Try not to paginate on a step that has Cautions & Notes, keep the Caution/Note with // the step. if (item.IsStepPart) { if (item.Cautions != null || item.Notes != null) level += 2; else if (item.HasAncestorCautionOrNote) // B2019-121 step part is in a caution or note level += 3; } // Paginate before first caution, not between cautions. else if (item.IsCautionPart) { if (item.MyPrevious == null) level -= (1 + firstInc); else level += 3; } // Paginate before first note, if the step does not have a caution. // Otherwise, try to keep the notes together. else if (item.IsNotePart) { if (parent.Cautions == null && item.MyPrevious == null) level -= (1 + firstInc); else level += 3; } // Try not to paginate on a table. else if (item.IsTablePart) { level += 2; } // For an RNO to the right, make it the same level as the AER item. else if (item.IsRNOPart) { level = (item.ActiveParent as ItemInfo).StepLevel + item.RNOLevel - item.ColumnMode; // RHM Change 20140522 //level = (item.ActiveParent as ItemInfo).StepLevel;// +item.RNOLevel - item.ColumnMode; } return level; } // B2020-081 used in HasSecondRNOThatWillFit() in pagination.cs // Get the total number of RNO levels in the step public int GetMaxRNOLevels { get { if (MyHLS == null) return 0; return MyHLS.GetMaxRNOLevelsFromChildren; } } private int GetMaxRNOLevelsFromChildren { get { int maxRNOLevel = RNOLevel; if (MyContent.ContentParts != null) { foreach (PartInfo pi in MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) maxRNOLevel = Math.Max(maxRNOLevel, ii.GetMaxRNOLevelsFromChildren); } } return maxRNOLevel; } } private bool ParentAndOr { get { ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) return false; // B2018-104: Make the following check consistent with what is in CalcStepLevel (added ImplicitOr) if (parent.IsExactType("And") || parent.IsExactType("Or") || parent.IsExactType("ImplicitOr")) return true; return parent.ParentAndOr; } } private int ParentAndOrCount { get { ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) return 0; // B2018-104: Make the following check consistent with what is in CalcStepLevel (added ImplicitOr) if (parent.IsExactType("And") || parent.IsExactType("Or") || parent.IsExactType("ImplicitOr")) return 1 + parent.ParentAndOrCount; return parent.ParentAndOrCount; } } /// /// Count all levels, including substeps within RNOs. Ignore RNOs that are to the right of /// the AER, but count those that are below higher level RNOs. /// /// /// private static int CountLevels(ItemInfo item) { int level = 0; if (item.IsProcedure) return 0; int ignoreRNOs = item.ActiveSection.ColumnMode; while (item != null && !item.IsHigh) { if (ignoreRNOs > 0 && item.IsRNOPart) ignoreRNOs--; else level++; item = item.ActiveParent as ItemInfo; } return level; } // B2017-070 - when retoring a step that once had enhanced links, remove the link info for the notes and cautions as well public void RemoveEnhancedFromConfig() { RemoveEnhancedFromConfig(false); } public void RemoveEnhancedFromConfig(bool doOneStepOnly) { XmlDocument xd = new XmlDocument(); if (this.MyContent.Config == null || this.MyContent.Config == "") return; // B2017-164 & B2017-172 check for null or empty config xd.LoadXml(this.MyContent.Config); XmlNode xn = xd.DocumentElement.SelectSingleNode("Enhanced"); if (xn != null) { xn.ParentNode.RemoveChild(xn); string config = xd.OuterXml; using (Content ctmp = this.MyContent.Get()) { ctmp.Config = config; ctmp.Save(); ContentInfo.Refresh(ctmp); _MyConfig = null; // refresh the memory value } } if (doOneStepOnly) return; if (this.IsHigh) { if (this.Cautions != null) foreach (ItemInfo chld in this.Cautions) { chld.RemoveEnhancedFromConfig(false); } if (this.Notes != null) foreach (ItemInfo chld in this.Notes) { chld.RemoveEnhancedFromConfig(false); } } } #endregion public bool HasHeader { get { if (MyHeader == null) return false; if (MyHeader.CleanText == null) return false; if (MyHeader.CleanText == "") return false; return true; } } protected void ExtensionRefreshFields(Item tmp) { _ActiveParent = null; } #region LoadAtOnce2 public static ItemInfo GetItemAndChildren2(int? itemID) { try { ItemInfo tmp = DataPortal.Fetch(new ItemAndChildrenCriteria2(itemID)); AddToCache(tmp); if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetItemAndChildren2", ex); } } // Criteria to get Item and children [Serializable()] private class ItemAndChildrenCriteria2 { public ItemAndChildrenCriteria2(int? itemID) { _ItemID = itemID; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } } // Data Portal to Get Item and Children private void DataPortal_Fetch(ItemAndChildrenCriteria2 criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { ApplicationContext.LocalContext["cn"] = cn; using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getItem"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { if (!dr.Read()) { _ErrorMessage = "No Record Found"; return; } ReadData(dr); } } SpinThroughChildren(); // removing of item only needed for local data portal if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client) ApplicationContext.LocalContext.Remove("cn"); } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } RemoveFromCache(this); } private void SpinThroughChildren() { if (MyContent.ContentPartCount > 0) foreach (PartInfo partInfo in MyContent.ContentParts) foreach (ItemInfo itemInfo in partInfo.MyItems) itemInfo.SpinThroughChildren(); } #endregion #region LoadAtOnce // Method to Get Item and children public static ItemInfo GetItemAndChildren(int? itemID, int? parentID) { try { ItemInfo tmp = DataPortal.Fetch(new ItemAndChildrenCriteria(itemID, parentID)); AddToCache(tmp); if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } // Criteria to get Item and children [Serializable()] private class ItemAndChildrenCriteria { public ItemAndChildrenCriteria(int? itemID, int? parentID) { _ItemID = itemID; _ParentID = parentID; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } private int? _ParentID; public int? ParentID { get { return _ParentID; } set { _ParentID = value; } } } // Data Portal to Get Item and Children private void DataPortal_Fetch(ItemAndChildrenCriteria criteria) { //ItemInfo tmp = null; Dictionary lookup = new Dictionary(); ; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ListItemAndChildren"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.Parameters.AddWithValue("@ParentID", criteria.ParentID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { if (dr.GetInt32("Level") == 0) { //tmp = itemInfo; ReadData(dr); AddContent(dr); lookup[this.ItemID] = this; } else { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; case 2: itemInfo = new StepInfo(dr); break; } // Load Children itemInfo.AddContent(dr); ItemInfo parent = lookup[dr.GetInt32("ParentID")]; itemInfo._ActiveParent = parent; itemInfo._ActiveSection = (itemInfo.IsSection ? itemInfo : parent._ActiveSection); parent.AddPart(dr, itemInfo); lookup.Add(itemInfo.ItemID, itemInfo); } } //Console.WriteLine("I'm here {0}",this.MyContent.ContentPartCount); } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } } internal void AddPart(SafeDataReader dr, ItemInfo itemInfo) { // Either a new PartInfo or an existing PartInfo if (dr.IsDBNull(dr.GetOrdinal("PreviousID"))) { //PartInfo prt = new PartInfo(dr, itemInfo); _MyContent.AddPart(dr, itemInfo); } else { foreach (PartInfo pi in MyContent.ContentParts) { if (dr.GetInt32("FromType") == (int)pi.PartType) { if (pi._MyItems == null) pi._MyItems = new ItemInfoList(itemInfo); else pi.MyItems.AddItem(itemInfo); } } } } #endregion #region IsType private E_FromType? _FromType = null; public E_FromType? FromType { get { //if (ItemID == 95759 && _FromType == null) // Console.WriteLine("\"Null FromType\",{0},{1},\"{2}\",{3}", ItemID, MyContent.Type, DisplayNumber, MyItemInfoUnique); return _FromType; } set { _FromType = value; } } public bool IsFirstCautionPart { get { if (FromType != null) return (MyPrevious == null && FromType == E_FromType.Caution); return ((ItemPartCount > 0) && (ItemParts[0].PartType == E_FromType.Caution)); } } public bool IsFirstNotePart { get { if (FromType != null) return (MyPrevious == null && FromType == E_FromType.Note); return ((ItemPartCount > 0) && (ItemParts[0].PartType == E_FromType.Note)); } } public bool IsCautionPart { get { if (FromType != null) return (FromType == E_FromType.Caution); return ((FirstSibling.ItemPartCount > 0) && (FirstSibling.ItemParts[0].PartType == E_FromType.Caution)); } } public bool IsNotePart { get { if (FromType != null) return (FromType == E_FromType.Note); return ((FirstSibling.ItemPartCount > 0) && (FirstSibling.ItemParts[0].PartType == E_FromType.Note)); } } // B2017-004 check to see if step part is inside a Caution or Note (used to determin which Table types to include in the change step type list) public bool IsInCautionOrNote { get { bool rval = false; ItemInfo itm = this; while (itm != null &&!itm.IsHigh && !rval) { rval = itm.IsCautionOrNotePart; if (!rval) itm = itm.MyParent; } return rval; } } public bool IsType(string type) { if ((int)MyContent.Type < 20000) return false; int stepType = ((int)MyContent.Type) % 10000; StepDataList sdlist = ActiveFormat.PlantFormat.FormatData.StepDataList; if (stepType > sdlist.MaxIndex) { Console.WriteLine("Error getting type - contentid = {0}", MyContent.ContentID); return false; } StepData sd = sdlist[stepType]; while (sd.Index != 0) { if (sd.Type == type) return true; sd = sdlist[sd.ParentType]; } return false; } public bool IsExactType(string type) { if ((int)MyContent.Type < 20000) return false; int stepType = ((int)MyContent.Type) % 10000; StepDataList sdlist = ActiveFormat.PlantFormat.FormatData.StepDataList; if (stepType > sdlist.MaxIndex) { Console.WriteLine("Error getting type - contentid = {0}", MyContent.ContentID); return false; } StepData sd = sdlist[stepType]; return (sd.Type == type); } // determine if the the current step should automatically be placed on the Continuous Action Summary // Note, this logic only checks the format setting of the step. We will check the value of the Tag's Check Box later on. public bool IncludeOnContActSum { get { bool includeOnCAS = false; if ((int)MyContent.Type < 20000) return includeOnCAS; int stepType = ((int)MyContent.Type) % 10000; StepDataList sdlist = ActiveFormat.PlantFormat.FormatData.StepDataList; if (stepType > sdlist.MaxIndex) { //Console.WriteLine("IncludeOnContActSum - Error getting type - contentid = {0}", MyContent.ContentID); _MyLog.InfoFormat(string.Format("IncludeOnContActSum - Error getting type - contentid = {0}", MyContent.ContentID)); return false; } // By default the PROMS step types that are initally identified as a Continuous Action type will return True, // unless the format flag "ExcludeFromContActSum" is set on that step type StepData sd = sdlist[stepType]; switch (stepType) { case 9: // Continuous Action High Level Step case 44: // Continuous Action Sequential sub-step case 45: // Continuous Action AND sub-step case 46: // Continuous Action OR sub-step case 47: //Continuous Actoin Paragraph sub-step includeOnCAS = !sd.ExcludeFromContActSum; // if flag is not set then Automatically include this step/sub-step on the Continuous Action Summary break; default: includeOnCAS = !sd.ExcludeFromContActSum; //false; // don't automatically include this step/sub-step on the Continuous Action Summary break; } return includeOnCAS; } } // F2022-024 Time Critical Action Step // determine if the the current step should automatically be placed on the Time Critical Action Summary // Note, this logic only checks the format setting of the step. We will check the value of the Tag's Check Box later on. public bool IncludeOnTimeCriticalActionSum { get { bool includeOnTCAS = false; if ((int)MyContent.Type < 20000) return includeOnTCAS; int stepType = ((int)MyContent.Type) % 10000; StepDataList sdlist = ActiveFormat.PlantFormat.FormatData.StepDataList; if (stepType > sdlist.MaxIndex) { _MyLog.InfoFormat(string.Format("IncludeOnTimeCriticalActionSum - Error getting type - contentid = {0}", MyContent.ContentID)); return false; } // By default the PROMS step types that are initally identified as a Time Critical Action type will return True, // unless the format flag "ExcludeFromTimeCriticalActSum" is set on that step type StepData sd = sdlist[stepType]; switch (stepType) { case 60: // Time Critical Action High Level Step includeOnTCAS = !sd.ExcludeFromTimeCriticalActSum; // if flag is not set then Automatically include this step/sub-step on the Time Critical Action Summary break; default: includeOnTCAS = !sd.ExcludeFromTimeCriticalActSum; ; // don't automatically include this step/sub-step break; } return includeOnTCAS; } } public bool IsSameType(ItemInfo cmpItmInfo) { return (((int)MyContent.Type) % 10000) == (((int)cmpItmInfo.MyContent.Type) % 10000); } public bool IsCautionOrNotePart { get { return (IsCautionPart || IsNotePart); } } public bool IsCaution { get { return IsType("Caution"); } } public bool IsCaution2 { get { return IsType("Caution2"); } } public bool IsCaution1 { get { return IsType("Caution1"); } } public bool IsNote { get { return IsType("Note"); } } public bool IsNote1 { get { return IsType("Note1"); } } public bool IsFootnote { get { if (!ActiveFormat.PlantFormat.FormatData.ProcData.NotesToFootnotes) return false; if (!IsStep) return false; // BGEVL had notes as footnotes, and also had HorizontalSubsteps flag if (ActiveFormat.PlantFormat.FormatData.PrintData.HorizontalSubsteps && IsType("Note")) return true; if (IsType("Note2")) return true; // BGEEOP had note2's as footnotes return false; } } public bool IsTable { get { return IsType("Table"); } } public bool IsFigure { get { return IsType("Figure"); } } public bool IsOr { get { return IsType("Or"); } } public bool IsAnd { get { return IsType("And"); } } public bool IsEquipmentList { get { return IsType("EquipmentList"); } } public bool IsTitle { get { return IsType("Title"); } } public bool IsAccPages { get { return IsType("AccPages"); } } public bool IsParagraph { get { return IsType("Paragraph"); } } public bool IsDefault { get { return IsType("Default"); } } public bool IsContAcSequential { get { return IsType("ContAcSequential"); } } private bool? _IsHigh = null; public bool IsHigh { get { if (_IsHigh != null) return (bool)_IsHigh; int profileDepth = ProfileTimer.Push(">>>> BeginIsHigh"); // check to see if ActiveParent is a section, if so it is a high level step if (MyContent.Type / 10000 != 2) _IsHigh = false; else { ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) _IsHigh = false; // IsHigh was returning true if this item is a caution or note off of a section.. // from the (parent.MyContent.Type / 1000) == 1. else if ((parent.MyContent.Type / 10000) != 1) _IsHigh = false; else if (IsCaution || IsNote) _IsHigh = false; else _IsHigh = true; } ProfileTimer.Pop(profileDepth); return (bool)_IsHigh; } } public bool IsSequential { get { if ((MyContent.Type / 10000) != 2) return false; string tabstr = FormatStepData.TabData.IdentPrint; if (tabstr.Contains("{seq}")) return true; return false; } } public bool IsNumbered { get { if ((MyContent.Type / 10000) != 2) return true; string tabstr = FormatStepData.TabData.IdentPrint; if (tabstr.Contains("{seq}")) return true; if (tabstr.Contains("{ALPHA}")) return true; if (tabstr.Contains("{ROMAN}")) return true; if (tabstr.Contains("{numeric}")) return true; return false; } } public bool IsTablePart { get { if (FromType != null) return (FromType == E_FromType.Table); return ((ItemPartCount > 0) && (ItemParts[0].PartType == E_FromType.Table)); } } public bool IsRNOPart { get { if (FromType != null) return (FromType == E_FromType.RNO); bool retval = ((ItemPartCount > 0) && (ItemParts[0].PartType == E_FromType.RNO)); return retval; } } public bool IsSupInfoPart { get { if (FromType != null) return (FromType == E_FromType.SupInfo); bool retval = ((ItemPartCount > 0) && (ItemParts[0].PartType == E_FromType.SupInfo)); return retval; } } public bool IsInRNO { get { if (IsHigh) return false; if (IsRNOPart) return true; ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) return false; return parent.IsInRNO; } } public bool IsInSupInfo { get { if (IsHigh) return false; if (IsSupInfoPart) return true; ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) return false; return parent.IsInSupInfo; } } public bool IsRtfRaw { get { return (MyContent.Type > 20999); } } public bool IsInCalvertConditionResponse { get { ItemInfo itmifo = this; bool rtn = false; if (ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm) { // TemplateChildColumnMode is set to 2 for the TitleWithTextBelow step type // we want to stop searching at this level while (!rtn && itmifo != null && itmifo.IsStep && !itmifo.TemplateChildColumnMode.Equals(2)) { rtn = itmifo.TemplateColumnMode.Equals(2); itmifo = itmifo.MyParent; } } return rtn; } } #endregion #region Level Columns Relationships public int RNOLevel { get { return ((IsProcedure || IsSection || IsHigh) ? 0 : (IsRNOPart ? 1 : 0) + ((ItemInfo)ActiveParent).RNOLevel); } } public void CheckColumnMode(int itemID) { List lst = _CacheByPrimaryKey[itemID.ToString()]; foreach (ItemInfo ii in lst) { Console.WriteLine("{0} - {1}", ii.MyItemInfoUnique, (ii.ActiveSection as SectionInfo).SectionConfig.Section_ColumnMode); } } public int ColumnMode { get { // if Calvert Alarms, the column mode may be defined in the template code - check // for this 1st. if (ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm) if (TemplateColumnMode != -1) return TemplateColumnMode; // check config value on my section, if null/default use Pmode of active format if (ActiveSection != null) { SectionInfo si = null; if (IsSection) si = this as SectionInfo; else si = ActiveSection as SectionInfo; if (si == null) si = SectionInfo.Get(ActiveSection.ItemID); //ActiveSection as SectionInfo; if (si != null) { // there is no longer a "default" ENUM item - SectionConfig will return format default if needed //if (si.SectionConfig.Section_ColumnMode != SectionConfig.SectionColumnMode.Default) return (int)si.SectionConfig.Section_ColumnMode - 1; } //Console.WriteLine("PMode={0}, si.ColumnMode={1}, ColumnMode={2}", ActiveFormat.MyStepSectionLayoutData.PMode ,si.ColumnMode,(ActiveFormat.MyStepSectionLayoutData.PMode ?? 2) - 1); } return (ActiveFormat.MyStepSectionLayoutData.PMode ?? 2) - 1; } } /// /// FormatStepType - Maps to step type in format file. All types map directly from step type in content /// to step type in format /// public int FormatStepType { get { return (((int)MyContent.Type) % 10000); } } /// /// returns the format's stepdata for the given content type. /// public StepData FormatStepData { get { if ((int)MyContent.Type < 20000) return null; int typ = (int)MyContent.Type - 20000; foreach (StepData sd in ActiveFormat.PlantFormat.FormatData.StepDataList) { if (sd.Index == typ) return sd; } // Handle inheritance (step data may not be in current format, may inherit from parents: IFormatOrFormatInfo parentFormat = ActiveFormat.PlantFormat.FormatData.MyParentFormat; while (parentFormat != null) { vlnIndexedFormatList InheritedList = parentFormat.PlantFormat.FormatData.StepDataList; if (InheritedList != null) { foreach (StepData sdi in InheritedList) { if (sdi.Index == typ) return sdi; } } parentFormat = parentFormat.PlantFormat.FormatData.MyParentFormat; } return null; } } public ItemInfo FirstSibling { get { ItemInfo temp = this; while (temp.MyPrevious != null) temp = temp.MyPrevious; return temp; } } public ItemInfo LastSibling { get { ItemInfo temp = this; ItemInfo last = this; while (temp != null) { last = temp; temp = temp.GetNext(); } return last; } } public ItemInfo LastChild(E_FromType partType) { ItemInfoList myitems = Lookup((int)partType); if (myitems != null) return myitems[myitems.Count - 1]; return null; } public ItemInfo FirstChild(E_FromType partType) { ItemInfoList myitems = Lookup((int)partType); if (myitems != null) return myitems[0]; return null; } public bool HasAncestor(ItemInfo ancestor) { if (ancestor == null) return false; ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) return false; if (ancestor.ItemID == parent.ItemID) return true; return parent.HasAncestor(ancestor); } #endregion public int FoldoutIndex() { if (ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts && (((ActiveSection.MyDocStyle.StructureStyle.Style ?? 0) & E_DocStructStyle.UseSectionFoldout) != 0)) return 0; // now check for floating foldouts. If there is a floating foldout, also find which one it uses. // This is data off of the ? if (ActiveFormat.PlantFormat.FormatData.PrintData.AlternateFloatingFoldout && ActiveSection.IsDefaultSection) { StepConfig sc = MyConfig as StepConfig; int iiForFoldout = sc != null ? sc.Step_FloatingFoldout : -1; if (iiForFoldout <= 0) return -1; int fldid = sc.Step_FloatingFoldout; if (fldid == 0) return 0; int indxOfFoldout = 0; foreach (ItemInfo sect in MyProcedure.Sections) { SectionConfig scfe = sect.MyConfig as SectionConfig; if (sect.ItemID == fldid) return indxOfFoldout; if (scfe.Section_IsFoldout == "Y") indxOfFoldout++; // C2019-042 Section_ISFoldout will check for section number "FOLDOUT" or if check box is checked } return 0; } return -1; // does not have a foldout } #region More IsType public bool IsProcedurePart { get { if (FromType != null) return (FromType == E_FromType.Procedure); return ((FirstSibling.ItemPartCount > 0) && (FirstSibling.ItemParts[0].PartType == E_FromType.Procedure)); } } public bool IsSectionPart { get { if (FromType != null) return (FromType == E_FromType.Section); return ((FirstSibling.ItemPartCount > 0) && (FirstSibling.ItemParts[0].PartType == E_FromType.Section)); } } public bool IsStepPart { get { if (FromType != null) return (FromType == E_FromType.Step); return ((FirstSibling.ItemPartCount > 0) && (FirstSibling.ItemParts[0].PartType == E_FromType.Step)); } } public bool IsEnhancedStep { get { if (!IsStep) return false; StepConfig sc = MyConfig as StepConfig; if (sc.MyEnhancedDocuments != null && sc.MyEnhancedDocuments.Count == 1 && sc.MyEnhancedDocuments[0].Type == 0) return true; return false; } } public bool IsEnhancedSection { get { if (!IsSection) return false; SectionConfig sc = MyConfig as SectionConfig; if (sc.MyEnhancedDocuments != null && sc.MyEnhancedDocuments.Count == 1 && sc.MyEnhancedDocuments[0].Type == 0) return true; return false; } } public bool IsEnhancedSectionTitleOnly // this is an enhanced document (sectionitem) but only the title is linked. { get { if (!IsSection) return false; SectionConfig sc = MyConfig as SectionConfig; // go back to source & see what type is: if (sc.MyEnhancedDocuments != null && sc.MyEnhancedDocuments.Count == 1 && sc.MyEnhancedDocuments[0].Type == 0) { SectionInfo siSource = SectionInfo.Get(sc.MyEnhancedDocuments[0].ItemID); if (siSource == null) return true; //B2018-142 null check to allow deletion of unlinked background procedure SectionConfig scs = siSource.MyConfig as SectionConfig; if (scs.Section_LnkEnh == "T") return true; } return false; } } public bool IsEnhancedProcedure // this is NOT a source, it is enhanced, i.e. background or deviation { get { if (!IsProcedure) return false; ProcedureConfig pc = MyConfig as ProcedureConfig; if (pc.MyEnhancedDocuments != null && pc.MyEnhancedDocuments.Count == 1 && pc.MyEnhancedDocuments[0].Type == 0) return true; return false; } } public bool IsInSubStep { get { if (IsHigh) return false; if (IsStepPart) return true; ItemInfo parent = ActiveParent as ItemInfo; if (parent == null) return false; return parent.IsInSubStep; } } public bool IsInFirstLevelSubStep { get { ItemInfo temp = FirstSibling; if (temp.ActiveParent.IsDocVersion) return false; if (temp.MyParent.IsSection) return false; // already at hls if (temp.IsProcedure || temp.IsSection) return false; while (((ItemInfo)temp.ActiveParent).IsHigh == false) temp = ((ItemInfo)temp.ActiveParent).FirstSibling; return temp.IsStepPart; } } public bool IsStepSection { get { //override docstyle based on content of the section. If the section has word content then return false if (IsSection && MyContent.ContentEntryCount == 0 && MyDocStyle.IsStepSection) return true; return false; } } public bool IsSection { get { if ((MyContent.Type / 10000) == 1) return true; return false; } } public bool IsDefaultSection { get { // check to see if ActiveParent is a section, if so it is a high level step if (MyContent.Type / 10000 != 1) return false; // get procedure section and then ItemInfo parent = (ItemInfo)ActiveParent; if (!parent.IsProcedure) return false; ProcedureConfig pc = (ProcedureConfig)parent.MyConfig; int sectstartid = -1; string ss = pc == null ? null : pc.SectionStart; if (ss != null && ss != "") sectstartid = System.Convert.ToInt32(ss); else return false; if (ItemID == sectstartid) return true; SectionInfo si = SectionInfo.Get(sectstartid); if (si == null) return false; if (si.MyProcedure.ItemID == MyProcedure.ItemID) return false; if (si.DisplayNumber == DisplayNumber && si.DisplayText == DisplayText) { using (Procedure p = Procedure.Get(parent.ItemID)) { if (p.ProcedureConfig.SectionStart != ItemID.ToString()) { p.ProcedureConfig.SectionStart = ItemID.ToString(); p.Save(); } } return true; } return false; } } public bool IsSubsection { get { if (!IsSection) return false; ItemInfo par = ActiveParent as ItemInfo; if (par == null || !par.IsSection) return false; return true; } } public bool IsSubsectionNumber { // returns whether the subsection number is derived from section number, // for example 6.9 is subsectionnumber of 6.0. B is not a subsectionnumber of 6.9 get { if (!IsSection) return false; ItemInfo par = ActiveParent as ItemInfo; if (par == null || !par.IsSection) return false; string parNumber = par.DisplayNumber; string myNumber = DisplayNumber; if (parNumber == null || myNumber == null) return false; ItemInfo par2 = par.ActiveParent as ItemInfo; if (par2 != null && par2.IsSection) { // check for 6.1 (parent) and 6.1.1. if (DisplayNumber.StartsWith((ActiveParent as ItemInfo).DisplayNumber.Trim())) return true; } if (!parNumber.Trim().EndsWith(".0")) return false; return (myNumber.Trim().StartsWith(parNumber.Trim().Substring(0, parNumber.Length - 1))); } } public bool IsSeparateSubsection { get { return (IsSubsection && !IsSubsectionNumber); } } public bool IsFolder { get { return false; } } public bool IsDocVersion { get { return false; } } public bool IsProcedure { get { if ((MyContent.Type / 10000) == 0) return true; return false; } } public bool IsStep { get { if ((MyContent.Type / 10000) == 2) return true; return false; } } private E_FromType ItemType { get { if (MyContent.Type == 0) return E_FromType.Procedure; if (MyContent.Type < 20000) return E_FromType.Section; return E_FromType.Step; } } public Item GetByType() { Item tmp = null; switch (ItemType) { case E_FromType.Procedure: tmp = Procedure.Get(_ItemID); break; //case E_FromType.Section: // itemInfo = new Section(dr); // break; //default: // itemInfo = new Step(dr); // break; } return tmp; } #endregion #region Ordinal CslaType and Tostring //[NonSerialized] internal int? _Ordinal; public int Ordinal { get { if (_Ordinal == null) { if (MyPrevious != null) _Ordinal = MyPrevious.Ordinal + 1; else _Ordinal = 1; } return (int)_Ordinal; } } public bool IsSubStep { get { return IsStep && !IsHigh && !IsTable && !IsFigure; } } public string CslaType { get { return this.GetType().FullName; } } public override string ToString() { //Item editable = Item.GetExistingByPrimaryKey(_ItemID); //return string.Format("{0}{1} {2}", (editable == null ? "" : (editable.IsDirty ? "* " : "")), // (MyContent.Type >= 20000 ? Ordinal.ToString() + "." : MyContent.Number), MyContent.Text); ContentInfo cont = MyContent; //string number = cont.Number; string number = DisplayNumber; //if (cont.Type >= 20000) number = Ordinal.ToString() + "."; if ((cont.Type == 20036 || cont.Type == 20037 || cont.Type == 20038 || cont.Type == 20039))// && !RO { if (MyContent.ContentRoUsages == null || MyContent.ContentRoUsages.Count == 0) return "Embedded Image"; } if (IsRtfRaw) return "Equation"; if (cont.Type >= 20000) number = MyTab == null ? "" : MyTab.CleanText; return string.Format("{0} {1}", number, DisplayText).Trim(); // Need TrimEnd(); for IP3 //return string.Format("{0} {1}", number, cont.Text).Trim(); //return string.Format("{0} {1}", cont.Number, cont.Text); } //public string ToString(string str,System.IFormatProvider ifp) //{ // return ToString(); //} #endregion #region UnlinkEnhanced // B2022-049: Copy/paste of enhanced procedure and bad links between source and enhanced // Add parameters to be passed down to query to only remove links from current procedure public void DoUnlinkEnhanced(ItemInfo enhii, int enhType, bool onlyCur) { try { using (ContentInfoList cil = ContentInfoList.DoEnhancedUnlink(enhii.ItemID, enhType, onlyCur)) { foreach (ContentInfo ci in cil) { using (Content c = ci.Get()) { // first refresh configs because the ContentInfo.Refresh causes events to occur that refresh screen // and if configs aren't done first, the screen refresh, if based on config data, will not be correct. foreach (ItemInfo ii in ci.ContentItems) ii.RefreshConfig(); ContentInfo.Refresh(c); } } } RefreshFields(enhii); // B2021-042: Crash on link/unlink/link - refresh cache } catch (Exception ex) { throw new DbCslaException("Error on ProcedureInfo:DoUnlinkEnhanced", ex); } } #endregion UnlinkEnhanced #region Search //CSM C2024-025 Removing the strange tall box characters that appear in the search results tree //Create cleaned version of variable for use in DisplaySearch //This is the Function that does the cleaning public string CleanSearchString(string value) { // \u000C = PageBreak // \u0009 = Tab // \u160? = Hard Space // \u0007 = Bell (Separates Parent Path and Child Path) // \u0011 - Separates DisplayNumber & DisplayText of Step if (value == null) return null; string tmp = value.Replace("\a", "\\").Replace("\u0007", "\\"); tmp = tmp.Replace("\u000C", " ").Replace("\u0009", " ").Replace(@"\u160?", " ").Replace("\u0011", " "); if (tmp.StartsWith("\\")) tmp = tmp.Substring(1); return tmp; } internal string _SearchDVPath; public string SearchDVPath { get { if (_SearchDVPath == null) { if (ActiveParent != null) _SearchDVPath = ActiveParent.SearchDVPath; else // RHM 20151026 - B2015-171 This was added to handle an error in the Library Document Report _SearchDVPath = string.Format("Disconnected Data {0}", ItemID); } return _SearchDVPath; } } //CSM C2024-025 Removing the strange tall box characters that appear in the search results tree //Create cleaned version of variable for use in DisplaySearch public string SearchDVPath_clean => CleanSearchString(SearchDVPath); internal string _SearchPath; public string SearchPath { get { if (_SearchPath == null) { if (IsProcedure) _SearchPath = ActiveParent.SearchPath + "\u0007" + (DisplayNumber ?? "") + "\u0011" + DisplayText; else if (IsSection) _SearchPath = ActiveParent.SearchPath + "\u0007" + (DisplayNumber ?? "") + "\u0011" + DisplayText; else { PartInfo myPart = FirstSibling.ItemPartCount > 0 ? FirstSibling.ItemParts[0] : null; if (myPart != null) _SearchPath = myPart.SearchPath + (!IsHigh ? "." : "\u0007") + Ordinal.ToString(); else _SearchPath = ActiveParent.SearchPath + (!IsHigh ? "." : "\u0007") + Ordinal.ToString(); } } return _SearchPath; } } //CSM C2024-025 Removing the strange tall box characters that appear in the search results tree //Create cleaned version of variable for use in DisplaySearch public string SearchPath_clean => CleanSearchString(SearchPath); public string ShortSearchPath { get { string dtext = ConvertToDisplayText(Regex.Replace(SearchPath ?? "", "\x11.*?\x07", "\x07")); if (IsFigure && dtext.EndsWith("Table.")) dtext = dtext.Substring(0, dtext.Length - "Table.".Length) + "Figure."; else if (IsRtfRaw && dtext.EndsWith("Table.") && FormatStepData.Type.Contains("Equation")) dtext = dtext.Substring(0, dtext.Length - "Table.".Length) + "Equation."; return dtext; } } //CSM C2024-025 Removing the strange tall box characters that appear in the search results tree //Create cleaned version of variable for use in DisplaySearch public string ShortSearchPath_clean => CleanSearchString(ShortSearchPath); // B2021-076: Proms search results are not presented in order when printed to PDF internal string _SearchDefaultSort; public string SearchDefaultSort { get { if (_SearchDefaultSort == null) { if (IsProcedure) _SearchDefaultSort = "FLD" + MyDocVersion.MyFolder.ManualOrder.ToString().PadLeft(5, '0') + string.Format(".PRC{0}", Ordinal.ToString().PadLeft(5, '0')); else if (IsSection) _SearchDefaultSort = ActiveParent.SearchDefaultSort + string.Format(".SEC{0}", Ordinal.ToString().PadLeft(5, '0')); else { PartInfo myPart = FirstSibling.ItemPartCount > 0 ? FirstSibling.ItemParts[0] : null; if (myPart != null) _SearchDefaultSort = string.Format("{0}{1}", myPart.SearchDefaultSort, Ordinal.ToString().PadLeft(5, '0')); else _SearchDefaultSort = ActiveParent.SearchDefaultSort + string.Format(".SUB{0}", Ordinal.ToString().PadLeft(5, '0')); } } return _SearchDefaultSort; } } internal int _SearchAnnotationID; public int SearchAnnotationID { get { return _SearchAnnotationID; } set { _SearchAnnotationID = value; } } internal string _SearchAnnotationText; public string SearchAnnotationText { get { return _SearchAnnotationText; } set { _SearchAnnotationText = value; } } internal string _SearchAnnotationType; public string SearchAnnotationType { get { return _SearchAnnotationType; } } #endregion #region Reports internal string _FoundROID; public string FoundROID { get { return _FoundROID; } } #endregion #region ProcedureConfig [NonSerialized] private ProcedureConfig _ProcedureConfig = null; public PrintChangeBar PrintChangeBar { get { if (_ProcedureConfig == null) SetProcedureConfig(); return _ProcedureConfig.Print_ChangeBar; } } public PrintChangeBarLoc PrintChangeBarLoc { get { if (_ProcedureConfig == null) SetProcedureConfig(); return _ProcedureConfig.Print_ChangeBarLoc; } } public PrintChangeBarText PrintChangeBarText { get { if (_ProcedureConfig == null) SetProcedureConfig(); return _ProcedureConfig.Print_ChangeBarText; } } public string PrintChangeBarUsrMsg1 { get { if (_ProcedureConfig == null) SetProcedureConfig(); return _ProcedureConfig.Print_UserCBMess1; } } public string PrintChangeBarUsrMsg2 { get { if (_ProcedureConfig == null) SetProcedureConfig(); return _ProcedureConfig.Print_UserCBMess2; } } private void SetProcedureConfig() { // Walk up tree until find my procedure. Then get its change bar (default will // get inherited information if not set at this level). // Find the procedure level and its config. ItemInfo tmpitm = this; while (tmpitm.MyContent.Type != 0) tmpitm = tmpitm.MyParent; ProcedureInfo pi = ProcedureInfo.Get(tmpitm.ItemID); if (pi == null) return; _ProcedureConfig = pi.MyConfig as ProcedureConfig; } #endregion #region Formatting of Text //jcb added inherited applicability public bool IsApplicable(int apple) { if (apple == -1) return true; ItemInfo parent = this.ActiveParent as ItemInfo; IItemConfig cfg = this.MyConfig as IItemConfig; if (IsProcedure) // C2021-027: Procedure level PC/PC. if procedure, don't go to parent. { return (cfg.MasterSlave_Applicability.GetFlags().Count == 0 || cfg.MasterSlave_Applicability.GetFlags().Contains(apple)); } return (parent.IsApplicable(apple)) && (cfg.MasterSlave_Applicability.GetFlags().Count == 0 || cfg.MasterSlave_Applicability.GetFlags().Contains(apple)); } //end jcb added inherited applicability public string FormattedDisplayText { get { string str = MyContent.Text; // B2022-035: resolve unit specific designators // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(this.MyDocVersion, str); return ConvertToDisplayText(str, false, " "); // B2024-013 added " " to replace hard returns with a space instead of semi-colon } } // B2024-013 added for Vogtle Units 3 & 4, used with {TOPSECTIONTITLE} pagelist item // this will format the text and keep the hard return command public string FormattedDisplayTextKeepHardReturn { get { string str = MyContent.Text; // B2022-035: resolve unit specific designators // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(this.MyDocVersion, str); return ConvertToDisplayText(str, false, ""); // pass in empty string for hard retun char will keep hard return } } // Used in Comanche Peak EOP and Flex formats for step designators. Will allow a hard return to be used that that caution type. // need to use the SameRowAsParentMultiLines format flag in that step type. // regular DisplayText will convert the hard return to a semi-colon. public string MulitLineStepDesignatorDisplayText { get { string str = MyContent.Text; if (MyDocVersion != null) { // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str); } else { _MyLog.WarnFormat("Disconnected Data - ItemID = {0}", ItemID); } return ConvertToMulitLineStepDesignatorDisplayText(str); } } public string DisplayText { get { if (IsRtfRaw) return ("Equation"); if (IsFigure) return ("Figure"); // Added for B2016-236 string str = MyContent.Text; if (MyDocVersion != null) { // B2022-035: resolve unit specific designators // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str); } else { _MyLog.WarnFormat("Disconnected Data - ItemID = {0}", ItemID); } return ConvertToDisplayText(str); } } static Dictionary _SpecialCharacters = null; static Dictionary SpecialCharacters { get { // B2022-081 needed to add clock symbol so that it properly translate over to enhanced document if (_SpecialCharacters==null){ _SpecialCharacters = new Dictionary(); _SpecialCharacters.Add(@"\u916?", "{Delta}"); _SpecialCharacters.Add(@"\line", "{Hard Return1}"); _SpecialCharacters.Add("\r\n", "{Hard Return2}"); _SpecialCharacters.Add(@"\'b0", "{Degree1}"); _SpecialCharacters.Add(@"\'B0", "{Degree2}"); _SpecialCharacters.Add(@"\u9586?","{backslash}"); _SpecialCharacters.Add(@"\u8805?","{greater than or equal}"); _SpecialCharacters.Add(@"\u8804?","{less than or equal}"); _SpecialCharacters.Add(@"\'b1","{plus minus}"); _SpecialCharacters.Add(@"\u931?","{sigma}"); _SpecialCharacters.Add(@"\u947?","{gamma}"); _SpecialCharacters.Add(@"\'bd","{half}"); _SpecialCharacters.Add(@"\u9604?","{accum}"); _SpecialCharacters.Add(@"\u9679?","{bullet}"); _SpecialCharacters.Add(@"\u8776?","{approx eq}"); _SpecialCharacters.Add(@"\u8773?","{similar eq}"); _SpecialCharacters.Add(@"\'f7","{division}"); _SpecialCharacters.Add(@"\u8730?","{square root}"); _SpecialCharacters.Add(@"\u961?","{rho}"); _SpecialCharacters.Add(@"\u960?","{pi}"); _SpecialCharacters.Add(@"\u956?","{micro}"); _SpecialCharacters.Add(@"\u948?","{lower case delta}"); _SpecialCharacters.Add(@"\u963?","{lower case sigma}"); _SpecialCharacters.Add(@"\'bc","{quarter}"); _SpecialCharacters.Add(@"\'d8","{dist zero}"); _SpecialCharacters.Add(@"\u274?","{energy}"); _SpecialCharacters.Add(@"\'ec","{grave}"); _SpecialCharacters.Add(@"\u9474?","{bar}"); _SpecialCharacters.Add(@"\u949?","{epsilon}"); _SpecialCharacters.Add(@"\u952?","{theta}"); _SpecialCharacters.Add(@"\u8857?","{dot in oval}"); _SpecialCharacters.Add(@"\u964?","{tau}"); _SpecialCharacters.Add(@"\u9830?","{diamond}"); _SpecialCharacters.Add(@"\u8593?","{Up Arrow}"); _SpecialCharacters.Add(@"\u8595?","{Down Arrow}"); _SpecialCharacters.Add(@"\u9774?","{Clock}"); } return _SpecialCharacters; } } public string DisplayTextKeepSpecialChars { get { string str = MyContent.Text; if (MyDocVersion != null) { // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str); } else { _MyLog.WarnFormat("Disconnected Data - ItemID = {0}", ItemID); } foreach (string key in SpecialCharacters.Keys) str = str.Replace(key, SpecialCharacters[key]); string retval = ConvertToDisplayText(str); foreach (string key in SpecialCharacters.Keys) retval = retval.Replace(SpecialCharacters[key],key); return retval; } } public string DisplayNumber { get { string str = MyContent.Number; if (MyDocVersion != null) { // call to UnitSpecific 0 is all, need what is applicable if (IsProcedure) { // B2021-066: show Procedure level applicability in tree view if (ActiveFormat.PlantFormat.FormatData.ProcData.ProcAppl) str = MyDocVersion.UnitSpecific(MyContent.Number, 1, this); else str = MyDocVersion.UnitSpecific(MyContent.Number, 1); } else str = MyContent.Number; // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str); } else { str = "*" + str; _MyLog.WarnFormat("Disconnected Data - ItemID = {0}", ItemID); } //if (str.Contains("")) // str = str.Replace("", MyDocVersion.DocVersionConfig.Unit_ID); //if (str.Contains(@"")) // str = str.Replace(@"", MyDocVersion.DocVersionConfig.Unit_ID); str = ConvertToDisplayText(str); if (MyDocVersion != null) // B2020-086 check for null doc version - happens if item we are trying to open is no longer there (disconnected) // B2017-019 - process "" in section number // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str); return str; } //get { return ConvertToDisplayText(MyContent.Number); } } //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. //Get Numeric part of HLS Tab //Used for Certain sorting situations //If no numeric part then use 999 (will be at end of that level of the sort if there are other items with numbered HLS) public int NumericSortNumber { get { string numericpart = null; if (MyHLS != null) numericpart = new string(MyHLS?.MyTab?.CleanTextNoSymbols.TakeWhile(Char.IsDigit).ToArray()); if (!string.IsNullOrEmpty(numericpart) && numericpart.All(char.IsNumber)) return int.Parse(numericpart); else return 999; } } // for step designators (a redefined caution type used in Comanche Peak with the SameRowAsParentMultiLines format flag) // we what to allow for a hard return to allow for multiple designator lines - jsj 5/21/2015 public static string ConvertToMulitLineStepDesignatorDisplayText(string txt) { string retval = txt; if (!string.IsNullOrEmpty(retval)) { retval = StripRtfFormatting(retval); retval = StripLinks(retval); retval = ReplaceSpecialCharacters(retval); retval = retval.Replace("\u2011", "-"); retval = retval.Replace("\r\n", @"\line"); retval = retval.Replace("\n", @"\line"); } return retval; } public static string ConvertToDisplayText(string txt) { return ConvertToDisplayText(txt, true); } // B2024-013 This allos us to control "what with" or "whether to" replace hard returns // Semi-colons where printing on auto table of contents for section titles with hard returns // added HardReturnChar string to parameter. The default is to use the semi-colon, for auto table of contents // we replace it with a space, for Vogtle Unit 3 & 4 we retain the hard return when printing the section public static string ConvertToDisplayText(string txt, bool stripRTF, string HardReturnChar = ";") { string retval = txt; if (!string.IsNullOrEmpty(retval)) { if (stripRTF) retval = StripRtfFormatting(retval); retval = StripLinks(retval); retval = ReplaceSpecialCharacters(retval); retval = retval.Replace("\u2011", "-"); retval = retval.Replace("\u2572", @"\"); // replace backslash symbol with a backslash if (HardReturnChar != "") // B2024-013 if a null string don't replace the hard return { retval = Regex.Replace(retval, @"\\line ?", HardReturnChar); // better handing of hard returns - replace with semi-colon for use on tree view retval = retval.Replace("\r\n", HardReturnChar); retval = retval.Replace("\n", HardReturnChar); //added for consistency checking with approved version } } return retval; } public static string StripRtfFormatting(string rtf) { string retval = rtf; if (!string.IsNullOrEmpty(retval)) { // B2022-082: underline/bold of word removes space between 2 words in DisplayText retval = Regex.Replace(retval, @"\\ulnone\\b0 ?", ""); retval = Regex.Replace(retval, @"\\b0\\ulnone ?", ""); retval = Regex.Replace(retval, @"\\b0 ?", ""); retval = Regex.Replace(retval, @"\\b ?", ""); retval = Regex.Replace(retval, @"\\ulnone ?", ""); retval = Regex.Replace(retval, @"\\ul0 ?", ""); retval = Regex.Replace(retval, @"\\ul ?", ""); retval = Regex.Replace(retval, @"\\i0 ?", ""); retval = Regex.Replace(retval, @"\\i ?", ""); //retval = Regex.Replace(retval, @"\\super ?", ""); //retval = Regex.Replace(retval, @"\\sub ?", ""); //retval = Regex.Replace(retval, @"\\nosupersub ?", ""); retval = Regex.Replace(retval, @"\\up[320] ?", ""); retval = Regex.Replace(retval, @"\\dn[320] ?", ""); retval = Regex.Replace(retval, @"\\li[0-9]+ ?", ""); // changed the * to a + to "\\line " for hard returns part of bug fix B2015-140 retval = Regex.Replace(retval, @"\\fi-[0-9]+ ?", ""); retval = Regex.Replace(retval, @"\\fs[0-9]+ ?", ""); // B2020-065: removed font size definition (introduced when allowing font sizes in tables) } return retval; } public static string StripLinks(string rtf) { string retval = rtf; if (!string.IsNullOrEmpty(retval)) { retval = Regex.Replace(retval, @"\\v.*?\\v0 ?", ""); retval = retval.Replace("\u252C", "");// Unicode 9516 Transition retval = retval.Replace("\u2566", "");// Unicode 9574 Transition retval = retval.Replace("\u0015", "");// Unicode 21 RO } return retval; } private static string ReplaceSpecialCharacter(Match m) { StringBuilder sb = new StringBuilder(); int i = int.Parse(m.ToString().Substring(2, m.ToString().Length - 3)); sb.Append((char)i); return sb.ToString(); } private static string ReplaceSpecialHexCharacter(Match m) { StringBuilder sb = new StringBuilder(); int i = int.Parse(m.ToString().Substring(2), System.Globalization.NumberStyles.HexNumber); sb.Append((char)i); return sb.ToString(); } private static string ReplaceSpecialCharacters(string rtf) { string retval = rtf; if (!string.IsNullOrEmpty(retval)) { retval = retval.Replace("`", "\u00B0");// Degree retval = Regex.Replace(retval, @"\\u[0-9]+[?]", new MatchEvaluator(ReplaceSpecialCharacter)); retval = Regex.Replace(retval, @"\\'[0-9A-Fa-f][0-9A-Fa-f]", new MatchEvaluator(ReplaceSpecialHexCharacter)); } return retval; } //public void ShowThis(string title) //{ // Console.WriteLine("'{0}',,,,'i{1}','u{2}',{3},'{4}','{5}','{6}','{7}'", title, ItemID, MyItemInfoUnique, PreviousID, this, _MyPrevious, _MyParent, _ActiveParent); //} public VE_Font GetItemFont() { /* FormatInfo fmt = ActiveFormat; if (fmt == null) { ShowThis(); if (MyPrevious != null) { MyPrevious.ShowThis(); if (MyPrevious.ActiveFormat == null) { _ActiveParent = MyPrevious.MyParent; MyPrevious._ActiveParent = _ActiveParent; fmt = _ActiveParent.ActiveFormat; MyPrevious._ActiveFormat = fmt; Console.WriteLine("OOPS!"); } else if (MyParent != null) { _ActiveParent = MyParent; fmt = _ActiveParent.ActiveFormat; } } } */ return GetItemFont(ActiveFormat); } public VE_Font GetItemFont(FormatInfo fmt) { VE_Font font = null; try { FormatInfo format = (LocalFormat != null || fmt == null) ? LocalFormat : fmt;//_MyItemInfo.ActiveFormat; int type = (int)MyContent.Type;//_MyItemInfo.MyContent.Type; switch (type / 10000) { case 0: // procedure font = format.PlantFormat.FormatData.Font; break; case 1: // section // B2019-158 Added the OnlyBoldTopSect format flag to control whether the sub-section heading are bolded // The following logic will turn off the Bolding and/or underlining of sub-section headings // This logic assumes that the top section header is both bolded and underlined if ((format.PlantFormat.FormatData.SectData.SectionHeader.OnlyUnderlineTopSect || format.PlantFormat.FormatData.SectData.SectionHeader.OnlyBoldTopSect) && MyParent.IsSection) { VE_Font hdrFont = format.PlantFormat.FormatData.SectData.SectionHeader.Font; E_Style es = (E_Style)hdrFont.Style; if (format.PlantFormat.FormatData.SectData.SectionHeader.OnlyUnderlineTopSect) es = es & E_Style.Bold; // only keep the underline (turn off the bold) if (format.PlantFormat.FormatData.SectData.SectionHeader.OnlyBoldTopSect) es = es & E_Style.Underline; // only keep the bold (turn off underline) font = new VE_Font(hdrFont.Family, (int)hdrFont.Size, es, (float)hdrFont.CPI); } else font = format.PlantFormat.FormatData.SectData.SectionHeader.Font; break; case 2: // step types int typindx = type - 20000; // what to do for other types rather than steps font = format.PlantFormat.FormatData.StepDataList[typindx].Font; if (typindx == _ParagraphType) font = AdjustForTextSubFollowsTextStyle(format, typindx, font); if (IsRNOPart && MyParent.IsHigh && FormatStepData.BoldHighLevel) font = BoldTextStyle(font); break; } } catch (Exception ex) { Console.WriteLine("GetItemFont(): {0} - {1}", ex.GetType(), ex.Message); } return font; } private VE_Font BoldTextStyle(VE_Font font) { E_Style myStyle = (E_Style)font.Style; myStyle |= E_Style.Bold; if (myStyle != font.Style) font = new VE_Font(font.Family, (int)font.Size, myStyle, (float)font.CPI); return font; } private const int _ParagraphType = 24; protected VE_Font AdjustForTextSubFollowsTextStyle(VE_Font font) { return AdjustForTextSubFollowsTextStyle(ActiveFormat, this.FormatStepType, font); } private VE_Font AdjustForTextSubFollowsTextStyle(FormatInfo format, int typindx, VE_Font font) { StepData myFormatStepData = format.PlantFormat.FormatData.StepDataList[typindx]; if (myFormatStepData.TextSubFollowsTextStyle && ParentNoteOrCaution != null) { bool isBold = (myFormatStepData.Font.Style & E_Style.Bold) > 0; bool isMmBold = (myFormatStepData.Font.Style & E_Style.MmBold) > 0; myFormatStepData = format.PlantFormat.FormatData.StepDataList[ParentNoteOrCaution.FormatStepType]; font = myFormatStepData.Font; E_Style myStyle = (E_Style)font.Style; myStyle ^= (myStyle & E_Style.Bold); myStyle ^= (myStyle & E_Style.MmBold); myStyle |= isBold ? E_Style.Bold : 0; myStyle |= isMmBold ? E_Style.MmBold : 0; if (myStyle != font.Style) font = new VE_Font(font.Family, (int)font.Size, myStyle, (float)font.CPI); } return font; } private string RemoveToken(string str, string token) { // if this token is preceeded by another token and followed by a space // leave the preceeding token the ending space string retval = Regex.Replace(str, @"(\\[^ \\?\r\n\t]*)" + token + " ", "$1 "); //if (retval != str) // Show the token replacement // Console.WriteLine("Leave the preceeding token the ending space '{0}'\r\n{1}\r\n{2}",token,str,retval); // otherwise replace the token optionally followed by a space retval = Regex.Replace(retval, token + " ?", ""); return retval; } public string RemoveRtfStyles(string rtf) { return RemoveRtfStyles(rtf, ActiveFormat); } public string RemoveRtfStyles(string rtf, FormatInfo fmt) { string retval = rtf; if (!string.IsNullOrEmpty(retval)) { VE_Font TextFont = GetItemFont(fmt); if (TextFont != null) { // remove rtf commands for any styles that were added. Note that if // the entire item has a style, and also contains 'pieces' of text with // the same style, the underlying rtf box removes the embedded rtf commands, // for example, if the entire step is bolded, and 'THEN' has bold on/off // surrounding it, the rtf box removes the bold around the 'THEN' // These remove the command with a following space or the command alone, // either case may exist, because if there are rtf commands following the // style command, there will be no space character following the style command. if (((TextFont.Style & E_Style.Bold) > 0) || ((TextFont.Style & E_Style.MmBold) > 0)) { retval = RemoveToken(retval, @"\\b0"); retval = RemoveToken(retval, @"\\b"); } if ((TextFont.Style & E_Style.Underline) > 0) { retval = RemoveToken(retval, @"\\ulnone"); retval = RemoveToken(retval, @"\\ul"); } if ((TextFont.Style & E_Style.Italics) > 0) { retval = RemoveToken(retval, @"\\i0"); retval = RemoveToken(retval, @"\\i"); } } } return retval; } // used in some background document formats - all appear to be set on a Caution type. // This will place the text of this type (caution) on the same row (of the page) and to the left of its parent. // Is also used as a step designatior for Commanche Peak public bool SameRowAsParent { get { return ActiveFormat.PlantFormat.FormatData.StepDataList[FormatStepType].SameRowAsParent; } } public bool SameRowAsParentMultiLines { get { return ActiveFormat.PlantFormat.FormatData.StepDataList[FormatStepType].SameRowAsParentMultiLines; } } public string WidthOverride { get { return ActiveFormat.PlantFormat.FormatData.StepDataList[FormatStepType].WidthOverride; } } //public float? WidthOverride //{ // get // { // return ActiveFormat.PlantFormat.FormatData.StepDataList[FormatStepType].WidthOverride; // } //} #endregion #region Path and Parent public string Path { get { string number = (MyContent.Type >= 20000 ? Ordinal.ToString() + "." : ((DisplayNumber ?? "") == "" ? DisplayText : DisplayNumber)); ItemInfo parent = this; while (parent.MyPrevious != null) parent = parent.MyPrevious; if (parent.ItemPartCount == 0) return number + ", " + DisplayText; else { PartInfo partInfo = parent.ItemParts[0]; return partInfo.MyContent.ContentItems.Items[0].Path + " " + ((E_FromType)partInfo.FromType).ToString() + " " + number; } } } public string ShortPath { get { string number = (MyContent.Type >= 20000 ? Ordinal.ToString() + "." : ((DisplayNumber ?? "") == "" ? DisplayText : DisplayNumber)); ItemInfo parent = this; while (parent.MyPrevious != null) parent = parent.MyPrevious; if (parent.ItemPartCount == 0) return number; else { PartInfo partInfo = parent.ItemParts[0]; return partInfo.MyContent.ContentItems.Items[0].ShortPath + "." + ((E_FromType)partInfo.FromType).ToString().Substring(0, 1) + number; } } } public ContentInfo ParentContent { get { string number = (MyContent.Type >= 20000 ? Ordinal.ToString() + "." : ((MyContent.Number ?? "") == "" ? MyContent.Text : MyContent.Number)); ItemInfo parent = this; while (parent.MyPrevious != null) parent = parent.MyPrevious; if (parent.ItemPartCount <= 0 || parent.ItemParts.Count == 0) return null; else { return parent.ItemParts[0].MyContent; } } } internal ItemInfo _MyParent; public ItemInfo MyParent { get { if (_MyParent == null) { //if (ItemDocVersionCount > 0) return ItemDocVersions[0]; Need to create one interface to support Folders, DocVersions and Items ContentInfo parentContent = ParentContent; if (parentContent == null || parentContent.ContentItemCount == 0) return null; if (parentContent.ContentItems.Count == 0) return null; _MyParent = parentContent.ContentItems[0]; } return _MyParent; } set { _MyParent = value; } } #endregion #region Lookups and More Related private ItemInfoList Lookup(E_FromType fromType, ref ItemInfoList itemInfoList) { //Console.WriteLine(itemInfoList); if (itemInfoList == null) itemInfoList = Lookup((int)fromType); return itemInfoList; } private bool _LoadAllAtOnce; public bool LoadAllAtOnce { get { return _LoadAllAtOnce; } set { _LoadAllAtOnce = value; } } internal ItemInfoList Lookup(int fromType) { ItemInfoList itemInfoList = null; if (MyContent.ContentPartCount != 0) foreach (PartInfo partInfo in MyContent.ContentParts) if (partInfo.FromType == fromType) { if (LoadAllAtOnce) itemInfoList = partInfo._MyItems;// = ItemInfoList.GetList(partInfo.ItemID, partInfo.FromType); else itemInfoList = partInfo._MyItems = ItemInfoList.GetList(partInfo.ItemID, partInfo.FromType); return itemInfoList; } return null; } public static void ResetParts(int itemID) { string key = itemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) { bool firstContent = true; foreach (ItemInfo itm in _CacheByPrimaryKey[key]) { itm.ResetParts(); if (itm._MyContent != null && firstContent) { firstContent = false;// Only need to do this once. //RefreshContentParts looks through ContentInfo objects itm._MyContent.RefreshContentParts(); } } } } public void ResetParts() { _Procedures = null; _Sections = null; _Cautions = null; _Notes = null; _RNOs = null; _Steps = null; _Tables = null; _SupInfos = null; } private ItemInfoList _Procedures; public ItemInfoList Procedures { get { return Lookup(E_FromType.Procedure, ref _Procedures); } } private ItemInfoList _Sections; public ItemInfoList Sections { get { return Lookup(E_FromType.Section, ref _Sections); } } private ItemInfoList _Cautions; public ItemInfoList Cautions { get { return Lookup(E_FromType.Caution, ref _Cautions); } } private ItemInfoList _Notes; public ItemInfoList Notes { get { return Lookup(E_FromType.Note, ref _Notes); } } private ItemInfoList _RNOs; public ItemInfoList RNOs { get { return Lookup(E_FromType.RNO, ref _RNOs); } } private ItemInfoList _Steps; public ItemInfoList Steps { get { return Lookup(E_FromType.Step, ref _Steps); } } private ItemInfoList _Tables; public ItemInfoList Tables { get { return Lookup(E_FromType.Table, ref _Tables); } } private ItemInfoList _SupInfos; public ItemInfoList SupInfos { get { return Lookup(E_FromType.SupInfo, ref _SupInfos); } } //public void ResetChildren() //{ // _Procedures = null; // _Sections = null; // _Steps = null; // _Cautions = null; // _Notes = null; // _RNOs = null; // _Steps = null; // _Tables = null; //} //public XmlDocument ToXml() //{ // XmlDocument retval = new XmlDocument(); // retval.LoadXml(""); // return ToXml(retval.DocumentElement); //} //public void AddList(XmlNode xn,string name, ItemInfoList itemInfoList) //{ // if (itemInfoList != null) // { // XmlNode nd = xn.OwnerDocument.CreateElement(name); // xn.AppendChild(nd); // itemInfoList.ToXml(xn); // } //} //public XmlDocument ToXml(XmlNode xn) //{ // XmlNode nd = MyContent.ToXml(xn); // // Now add the children // AddList(nd, "Procedures", Procedures); // AddList(nd, "Sections", Sections); // AddList(nd, "Cautions", Cautions); // AddList(nd, "Notes", Notes); // AddList(nd, "RNOs", RNOs); // AddList(nd, "Steps", SubItems); // AddList(nd, "Tables", Tables); // return xn.OwnerDocument; //} #endregion #region UI Tab public string TabToolTip { get { if (MyContent.MyEntry == null) return DisplayNumber + " - " + DisplayText; string toolTip = MyProcedure.TabToolTip + "\r\n"; if (MyContent.Number != "") toolTip += DisplayNumber + " - " + DisplayText; else toolTip += DisplayText; DocumentInfo myDocument = MyContent.MyEntry.MyDocument; if (myDocument.LibTitle != "") { toolTip += string.Format("\r\n(Library Document - {0})\r\n", myDocument.LibTitle); toolTip += myDocument.LibraryDocumentUsage; } return toolTip.Replace('\xA0', ' ');//Replace Hardspace with a space } } public string TabTitle { get { if (MyContent.MyEntry == null) { if (DisplayNumber == string.Empty) return DisplayText.Replace("\u2011", "-").Replace("\u2572", @"\\").Split(" ,.;:-_".ToCharArray())[0] + "..."; return DisplayNumber.Replace("\u2011", "-").Replace("\u2572", @"\\"); } if (MyContent.Number != "") // Add LIB to the Section Number return ((MyContent.MyEntry.MyDocument.LibTitle ?? "") == "" ? "" : "\u1D38\u1D35\u1D2E ") + DisplayNumber; if (MyContent.MyEntry.MyDocument.LibTitle != "") { if (DisplayText.Length <= 7) return "\u1D38\u1D35\u1D2E " + DisplayText.Replace("\u2011", "-").Replace("\u2572", @"\\"); return "\u1D38\u1D35\u1D2E " + DisplayText.Replace("\u2011", "-").Split(" ,.;:-_".ToCharArray())[0] + "..."; } if (DisplayText.Length <= 10) return DisplayText.Replace("\u2011", "-").Replace("\u2572", @"\\"); return DisplayText.Replace("\u2011", "-").Replace("\u2572", @"\\").Split(" ,.;:-_".ToCharArray())[0] + "..."; } } #endregion #region Change Bar public bool HasChangeBar { get { bool chg = HasChanges; StepInfo si = this as StepInfo; if (si == null) return false; StepConfig sc = si.MyConfig as StepConfig; if (sc == null) return false; // if there is no override & return whether there was a change to the text. if (chg && ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ChangeIds && (sc.Step_ChangeID ?? "") == "") return false; // No Change ID - No Change Bar if ((sc.Step_SpellCheckerChangedText ?? "") == "NoChangeBar") return false; // Spell Checker, in editorial mode (format flag EditoralSpellCheck) , made the change and there was no change bar prior to that change B2015-024 if (sc.Step_CBOverride == null) return chg; return (sc.Step_CBOverride == "On"); } } public bool HasChanges { get { if (this.IsAccPages || this.IsProcedure || this.IsSection) return false; StepInfo si = this as StepInfo; if (si == null) return false; StepConfig sc = si.MyConfig as StepConfig; if (sc == null) return false; // go back to source & see what date it has: if (sc.MyEnhancedDocuments != null && sc.MyEnhancedDocuments.Count == 1 && sc.MyEnhancedDocuments[0].Type == 0) { ItemInfo ii = ItemInfo.Get(sc.MyEnhancedDocuments[0].ItemID); if (ii == null) return false; // when deleting a source step, this was causing a crash (null ii) return (ii.MyContent.DTS > MyProcedure.ChangeBarDate); } // B2023-015 When user sets PROMS to show changebars after a specific date, we store that in the procedure config to Print_ChangeBarDate // (ProcConfig.cs), but it actually get saved to "ChangeBarDate". Also when we get the value of Print_ChangeBarDate when processing a // Child (slave), it returns the ChangeBarDate of the child instead of the date set by the user (to show change bars after a specific // date). Print_ViewableAfterChangeBarDate was created to get only that user specified date, if it exists. If it does exist, we compare // that with the Content datetime, otherwise we proceed as before. DateTime? viewableStartingDateTime = (MyProcedure.MyConfig as ProcedureConfig).Print_ViewableStartingChangeBarDate; if (viewableStartingDateTime != null && viewableStartingDateTime > MyProcedure.ChangeBarDate) return (MyContent.DTS > viewableStartingDateTime); return (MyContent.DTS > MyProcedure.ChangeBarDate); } } #endregion #region IVEReadOnlyItem PartInfoList _PartInfoList; public System.Collections.IList GetChildren() { _PartInfoList = this.MyContent.ContentParts; if (_PartInfoList.Count == 1 && ((IsProcedure && _PartInfoList[0].ToString() == "Sections") || _PartInfoList[0].ToString() == "Steps")) return _PartInfoList[0].GetChildren(); return _PartInfoList; } public System.Collections.IList GetChildren(bool allParts) { _PartInfoList = this.MyContent.ContentParts; if (allParts) { if (_PartInfoList.Count == 1 && ((IsProcedure && _PartInfoList[0].ToString() == "Sections") || _PartInfoList[0].ToString() == "Steps")) return _PartInfoList[0].GetChildren(); return _PartInfoList; } else // Steps and Sections only { for (int i = 0; i < _PartInfoList.Count; i++) if (_PartInfoList[i].ToString() == "Sections" || _PartInfoList[i].ToString() == "Steps") return _PartInfoList[i].GetChildren(); return null; } } //public bool ChildrenAreLoaded //{ // get { return _PartInfoList == null; } //} public bool HasChildren { get { return this.MyContent.ContentPartCount > 0; } } public bool HasEnhancedLinkedStep { get { if (!IsStep) return false; StepConfig sc = MyConfig as StepConfig; if (sc.MyEnhancedDocuments != null && sc.MyEnhancedDocuments.Count > 0 && sc.MyEnhancedDocuments[0].Type != 0) return true; return false; } } public bool HasWordContent { get { return this.MyContent.MyEntry != null; } } public bool HasStepContent { get { if (MyContent.ContentPartCount == 0) return false; if (MyContent.ContentPartCount == 1 && MyContent.ContentParts[0].PartType == E_FromType.Section) return false; return true; } } // B2018-054 added check for sub sections - fixes issue of added a new section (step section) then adding sub-section, then changing main section to word section public bool HasSectionContent { get { if (MyContent.ContentPartCount == 0) return false; if (MyContent.ContentPartCount == 1 && MyContent.ContentParts[0].PartType == E_FromType.Section) return true; return false; } } private ProcedureInfo _MyProcedure; public ProcedureInfo MyProcedure { get { if (_MyProcedure == null) { // Walk up active parents until the parent is not an item ItemInfo tmp = this; while (tmp.ActiveParent != null && !tmp.ActiveParent.IsDocVersion) tmp = (ItemInfo)tmp.ActiveParent; if (tmp is ProcedureInfo) _MyProcedure = tmp as ProcedureInfo; else _MyProcedure = ProcedureInfo.Get(tmp.ItemID); } return _MyProcedure; } set { _MyProcedure = value; } } private ItemInfo _MyHLS = null; public ItemInfo MyHLS { get { if (_MyHLS == null) { if (IsHigh) _MyHLS = this; else { if (MyActiveParent is ItemInfo) _MyHLS = ((ItemInfo)MyActiveParent).MyHLS; } } return _MyHLS; } } private string _CombinedTab = null; public string CombinedTab { get { return _CombinedTab; } set { _CombinedTab = value; } } private DocVersionInfo _MyDocVersion = null; public DocVersionInfo MyDocVersion { get { if (_MyDocVersion == null) { if (ActiveParent is DocVersionInfo) _MyDocVersion = ActiveParent as DocVersionInfo; else { if (ActiveParent == null) return null; _MyDocVersion = (ActiveParent as ItemInfo).MyDocVersion; } } return _MyDocVersion; } set { _MyDocVersion = value; } } internal IVEDrillDownReadOnly _ActiveParent = null; public IVEDrillDownReadOnly MyActiveParent { get { return _ActiveParent; } } public IVEDrillDownReadOnly ActiveParent { get { //if (_ActiveParent == this)_ActiveParent = null; if (_ActiveParent == null) { if (MyPrevious != null) _ActiveParent = _MyPrevious.ActiveParent; else { if (this.ItemDocVersions != null && this.ItemDocVersions.Count > 0) _ActiveParent = this.ItemDocVersions[0]; else { //The following using command caused a cached iteminfo to be disposed. //using (ContentInfo parentContent = ParentContent) //{ ContentInfo parentContent = ParentContent; if (parentContent == null)// || parentContent.ContentItemCount == 0) _ActiveParent = this; else { int itemID = 0; if (parentContent.ContentItems.Count == 0) parentContent.RefreshContentItems(); using (ItemInfoList list = parentContent.ContentItems) itemID = list[0].ItemID; if (itemID == 0) _ActiveParent = this; else _ActiveParent = ItemInfo.Get(itemID); } //} } } } return _ActiveParent == this ? null : _ActiveParent; } internal set //set { _ActiveParent = value; } } internal ItemInfo _ActiveSection = null; /// /// MyActiveSection is used to determine if _ActiveSection is null or not. /// public ItemInfo MyActiveSection { get { return _ActiveSection; } } public ItemInfo ActiveSection { get { if (_ActiveSection == null) { if (IsSection) _ActiveSection = this; else { ItemInfo parent = ActiveParent as ItemInfo; if (parent != null) _ActiveSection = parent.ActiveSection; else _ActiveSection = this; } // B2018-018 Approval bug fix. Active section was in cache as an ItemInfo instead of a SectionInfo if (_ActiveSection != null && !(_ActiveSection is SectionInfo)) _ActiveSection = SectionInfo.Get(_ActiveSection.ItemID); } return _ActiveSection.IsSection ? _ActiveSection : null; } set { _ActiveSection = value; } } private DocStyle _MyDocStyle; public DocStyle MyDocStyle { get { if (_MyDocStyle == null && ActiveSection != null) { int typ = (int)ActiveSection.MyContent.Type; int subtyp = typ % 10000; if (ActiveFormat.PlantFormat.DocStyles.DocStyleList[subtyp] == null) foreach (DocStyle ds in ActiveFormat.PlantFormat.DocStyles.DocStyleList) { if (ActiveSection.MyContent.ContentEntryCount > 0 && !ds.IsStepSection) return _MyDocStyle = ds; else if (ds.IsStepSection) return _MyDocStyle = ds; } _MyDocStyle = ActiveFormat.PlantFormat.DocStyles.DocStyleList[subtyp]; } return _MyDocStyle; } set { _MyDocStyle = value; } } private FormatInfo _ActiveFormat = null; public FormatInfo ActiveFormat { get { if (_ActiveFormat == null || !PrintAllAtOnce) // jsj added check for NULL ActiveParent _ActiveFormat = (LocalFormat != null ? LocalFormat : (ActiveParent != null) ? ActiveParent.ActiveFormat : null); //Console.WriteLine("Active {0}", (_ActiveFormat == null) ? "_ActiveFormat is null" : _ActiveFormat.Name); return _ActiveFormat; } set { _ActiveFormat = value; } //get { return LocalFormat != null ? LocalFormat : ActiveParent.ActiveFormat; } } public FormatInfo LocalFormat { get { //Console.WriteLine("Local {0}", (MyContent.MyFormat==null)?"MYformat is null": MyContent.MyFormat.Name); return MyContent.MyFormat; } } private bool _IsDeleted = false; public bool IsDeleted { get { return _IsDeleted; } set { _IsDeleted = value; if (value == true) UpdateCacheIsDeleted(ItemID); } } private static void UpdateCacheIsDeleted(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); if (key != null && _CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] items = _CacheByPrimaryKey[key].ToArray(); foreach (ItemInfo item in items) item._IsDeleted = true; } } public ConfigDynamicTypeDescriptor _MyConfig = null; public ConfigDynamicTypeDescriptor MyConfig { get { if (_MyConfig == null) { switch (MyContent.Type / 10000) { case 0: //_MyConfig = new ProcedureConfig(MyContent.Config); _MyConfig = new ProcedureConfig(this as ProcedureInfo ?? ProcedureInfo.Get(ItemID)); break; case 1: //_MyConfig = new SectionConfig(MyContent.Config); _MyConfig = new SectionConfig(this as SectionInfo ?? SectionInfo.Get(ItemID)); break; case 2: //_MyConfig = new StepConfig(MyContent.Config); _MyConfig = new StepConfig(this as StepInfo ?? StepInfo.Get(ItemID)); break; } } return _MyConfig; } set { if (_MyConfig == null) return; _MyConfig = null; //MyContent.Config = value; } } public void RefreshConfig() { string key = ItemID.ToString(); ConvertListToDictionary(); if (_CacheByPrimaryKey.ContainsKey(key)) { foreach (ItemInfo tmpInfo in _CacheByPrimaryKey[key]) { tmpInfo.MyConfig = null; // B2020-007: 'refresh' (by making null so get reset) Procedure, Section and Step configs also. if (tmpInfo is ProcedureInfo) (tmpInfo as ProcedureInfo)._ProcedureConfig = null; if (tmpInfo is SectionInfo) (tmpInfo as SectionInfo)._SectionConfig = null; if (tmpInfo is StepInfo) (tmpInfo as StepInfo)._StepConfig = null; } } } public EnhancedDocuments GetMyEnhancedDocuments() { switch (MyContent.Type / 10000) { case 0: ProcedureConfig pConfig = MyConfig as ProcedureConfig; return pConfig.MyEnhancedDocuments; case 1: SectionConfig sConfig = MyConfig as SectionConfig; return sConfig.MyEnhancedDocuments; case 2: StepConfig stConfig = MyConfig as StepConfig; return stConfig.MyEnhancedDocuments; } return null; } //public bool HasStandardSteps() //{ return MyContent.ContentItemCount > 1; } public Color ForeColor { get { return (HasBrokenRules != null ? Color.Red : (MyContent.ContentItemCount > 1 ? Color.Blue : Color.Black)); } } public Color BackColor { get { return (ItemAnnotationCount > 0 ? Color.Yellow : Color.White); } } #endregion #region Constructor internal ItemInfo(SafeDataReader dr, bool forIRichtem) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ItemInfo.Constructor", GetHashCode()); try { ReadData(dr); AddContent(dr); // B2022-025: memory leak. Content gets added in other places - this was adding it twice. // B2022-034 & B2022-040: needed to un-comment the AddContent(), previous bug fix (B2022-025) // caused the unit designators (BNPP NOPs) to show resolved in the editor // when the procedure was printed (from tree) for a specific unit prior to editing } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemInfo.Constructor", ex); throw new DbCslaException("ItemInfo.Constructor", ex); } } internal void AddContent(SafeDataReader dr) { _MyContent = new ContentInfo(dr, true); } #endregion #region MetaTags - Tabs, Headers, Footers [NonSerialized] protected Tab _MyTab; public Tab MyTab { get { if (!_TagsSetup) SetupTags(); return _MyTab; } set { _MyTab = value; _TagsSetup = true; } } public string LinkedTab { get { EnhancedDocuments eds = GetMyEnhancedDocuments(); if (eds != null && eds.Count == 1 && eds[0].Type == 0) { ItemInfo srcItem = ItemInfo.Get(eds[0].ItemID); if (srcItem != null) // B2018-097 handle a null reference return srcItem.MyTab.ToString(); } return null; } } // B2019-126 Check the HLS of the source document (ex. EOP step) to see if it includes the section number prefix in its tab public bool LinkedTabHasSectionPrefix { get { EnhancedDocuments eds = GetMyEnhancedDocuments(); if (eds != null && eds.Count == 1 && eds[0].Type == 0) { ItemInfo srcItem = ItemInfo.Get(eds[0].ItemID); if (srcItem != null && ((srcItem.ActiveParent as ItemInfo) != null) && ((srcItem.ActiveParent) as ItemInfo).IsStep) // B2018-097 handle a null reference return ((srcItem.ActiveParent as ItemInfo).FormatStepData.TabData.IdentEdit.Contains("{Section Prefix}") && FormatStepData.TabData.IdentEdit.Contains("{Section Prefix}")); } return false; } } public int? LinkedOrdinal { get { EnhancedDocuments eds = GetMyEnhancedDocuments(); if (eds != null && eds.Count == 1 && eds[0].Type == 0) { // B2018-114 check for a null before getting the Ordinal value (code that uses this handles a Null return value from this Get ItemInfo srcItem = ItemInfo.Get(eds[0].ItemID); if (srcItem == null) return null; if (srcItem.IsHigh || srcItem.IsSection || srcItem.IsProcedure) return srcItem.Ordinal; // B2018-118: the LinkedOrdinal count must take into account cautions versus notes types: ItemInfo hls = srcItem.MyHLS; bool enIsCaution = this.IsCaution; // get the first sibling and go through list for each type - go through notes first then cautions checking for each type: // go through cautions first because these are the first parts: int? ord = 0; if (hls.Cautions != null && hls.Cautions.Count > 0) { foreach (ItemInfo caut in hls.Cautions) { if (caut.IsCaution && enIsCaution) ord++; if (caut.IsNote && !enIsCaution) ord++; if (caut.ItemID == srcItem.ItemID) return ord==0?null:ord; } } if (hls.Notes != null && hls.Notes.Count > 0) { foreach (ItemInfo note in hls.Notes) { if (note.IsCaution && enIsCaution) ord++; if (note.IsNote && !enIsCaution) ord++; if (note.ItemID == srcItem.ItemID) return ord==0?null:ord; } } } return null; } } [NonSerialized] protected MetaTag _MyHeader; public MetaTag MyHeader { get { if (!_TagsSetup) SetupTags(); return _MyHeader; } set { _MyHeader = value; } } [NonSerialized] protected MetaTag _MyFooter; public MetaTag MyFooter { get { if (!_TagsSetup) SetupTags(); return _MyFooter; } set { _MyFooter = value; } } [NonSerialized] protected bool _TagsSetup = false; public virtual void SetupTags() { if (IsStep) { MyTab = new Tab(AdjustForTextSubFollowsTextStyle(FormatStepData.TabData.Font)); _MyHeader = new MetaTag(FormatStepData.TabData.Font); _MyFooter = new MetaTag(FormatStepData.TabData.Font); SetTabText(); } else { MyTab = new Tab(ActiveFormat.PlantFormat.FormatData.Font); _MyHeader = null; _MyFooter = null; _MyTab.CleanText = DisplayNumber; } _TagsSetup = true; } public bool SupplementalInformation { get { return MyDocStyle == null ? false : MyDocStyle.SupplementalInformation; } } protected void SetTabText() { if (IsSection) // B2016-160 Support transitions to sections { _MyTab.Text = DisplayNumber; _MyTab.CleanText = DisplayNumber; return; } // this is used for edit, print uses combinedtabs in the print code. When combined tabs were used for edit, // part of the supinfo text overwrote tabs on screen. if (IsSupInfoPart) { _MyTab.Text = MyParent.MyTab.Text; _MyTab.CleanText = MyParent.MyTab.CleanText; return; } string cltext = null; int stepType = (int)(MyContent.Type % 10000); string tbformat; if ((ActiveFormat.MyStepSectionLayoutData.UseRNOParentIdent ?? "") != "" && bool.Parse(ActiveFormat.MyStepSectionLayoutData.UseRNOParentIdent)) tbformat = IsInRNO ? FormatStepData.TabData.RNOIdentPrint == "" ? this.MyParent.FormatStepData.TabData.RNOIdentPrint : FormatStepData.TabData.RNOIdentPrint : FormatStepData.TabData.IdentPrint; else tbformat = IsInRNO ? FormatStepData.TabData.RNOIdentPrint : FormatStepData.TabData.IdentPrint; string tbformate = null; // need this for background documents, to generate tab for editing. if (IsParagraph && !IsSequential) { string tstr = ""; if (tbformat.Contains("{!.+?}")) tstr = tbformat.Replace("{!.+?}", " "); // Comanche Peak Indented Paragraph _MyTab.Text = tstr; //CSM F2024 - 080: For South Texas - if format contains initial line and it is not disabled, show an initial line if (!string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroList != null && FormatStepData.TabData.MacroList.Count > 0 && !(this.IsRNOPart && FormatStepData.TabData.MacroList[0].NotInRNO) && !IsInitialLineDisabled) { if (tstr.StartsWith(" ")) tstr = tstr.Substring(1); tstr = FormatStepData.TabData.MacroEditTag + tstr; } _MyTab.CleanText = tstr; return; } if (((ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds) && ((IsHigh && FormatStepData.PageBreakOnStep) || (IsRNOPart && MyHLS.FormatStepData.PageBreakOnStep))) tbformate = IsRNOPart ? MyHLS.FormatStepData.TabData.RNOIdentEdit : FormatStepData.TabData.IdentEdit; //F2023-112 Vogtle Units 3 and 4 Backgrounds // added code to get the tbformate (this is used for the tab displayed in the step editor) for Cautions and Notes background steps // like we do for the high level steps (see the if statement above) // all plants using enhanced backgrounds will benefit from this and is adjustable in the format files if (((ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds) && ((IsCaution || IsNote) && FormatStepData.PageBreakOnStep)) tbformate = IsRNOPart ? FormatStepData.TabData.RNOIdentEdit : FormatStepData.TabData.IdentEdit; if (ActiveFormat.Name.ToUpper() == "WCNCKL" || ActiveFormat.Name.ToUpper() == "WSTCKL") { if (!IsNote && !IsCaution) tbformat = FormatStepData.TabData.IdentEdit; if (ActiveFormat.Name.ToUpper() == "WCNCKL" && FormatStepData.StepLayoutData.AlignWithParentTab) tbformat = tbformat.TrimStart(" ".ToCharArray()); } if (((ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds) || ((ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedDeviations) == E_PurchaseOptions.EnhancedDeviations)) { // LinkedOrdinal & LinkedTab (in code below) are tabs from the source and account for unlinked steps. See C2016-020 and other // references to these properties. if (tbformat.Contains("{LNK C/N Num}")) { string tb = (LinkedOrdinal==null)? "NA" : LinkedOrdinal.ToString(); tbformat = tbformat.Replace("{LNK C/N Num}", tb); if (tbformate != null) tbformate = tbformate.Replace("{LNK C/N Num}", tb); if ((ActiveParent as ItemInfo).FormatStepData.TabData.IdentEdit.Contains("{Section Prefix}") && LinkedTabHasSectionPrefix) // B2019-126 Check the HLS of the source document (ex. EOP step) to see if it includes the section number prefix in its tab { tbformat = tbformat.Replace("{Section Prefix}", ""); // B2018-141 remove duplicate section number if (tbformate != null) tbformate = tbformate.Replace("{Section Prefix}", ""); // F2023-112 replace in editor tab } if ((ActiveParent as ItemInfo).LinkedTab != null) { tbformat = tbformat.Replace("{LNK Step Num}", (ActiveParent as ItemInfo).LinkedTab.Trim(" .".ToCharArray())); if (tbformate != null) tbformate = tbformate.Replace("{LNK Step Num}", (ActiveParent as ItemInfo).LinkedTab.Trim(" .".ToCharArray())); // F2023-112 replace in editor tab } tbformat = tbformat.TrimStart(" ".ToCharArray()); if (tbformate != null) tbformate = tbformate.TrimStart(" ".ToCharArray()); // F2023-112 replace in editor tab } if (tbformat.Contains("{LNK Step Num}")) tbformat = tbformat.Replace("{LNK Step Num}", LinkedTab==null?"NA":LinkedTab.Trim(" .".ToCharArray()).PadLeft(2));//Ordinal.ToString().PadLeft(2)); if (tbformate != null && tbformate.Contains("{LNK Step Num}")) // F2023-112 replace in editor tab tbformate = tbformate.Replace("{LNK Step Num}", LinkedTab == null ? "NA" : LinkedTab.Trim(" .".ToCharArray()).PadLeft(2));//Ordinal.ToString()); if (tbformate != null && tbformate.Contains("{!Clock}")) { int macindx = tbformate.IndexOf("{!Clock}"); if (macindx > -1) //i found it - one { int endidx = tbformate.IndexOf("}", macindx); if (endidx > -1) { // F2022-024 Clock is defined in genmac as a text using the Wingding font and uses the Clock unicode character and is used when the step is printed // But for the editor screen, we use the character defined at the step tab with MacroEditTag // For Robinson's case, the MacroEditTag is an'!' character // replace the {!Clock} token with MacroEditTag - for Robinson, this will be an ! character tbformate = tbformate.Substring(0, macindx) + FormatStepData.TabData.MacroEditTag + tbformate.Substring(macindx + endidx + 1); } } } } if (tbformat.Contains("{indent}")) // Robinson Background format CPBCK tbformat = tbformat.Substring(8); // we just need to remove the "{indent}" and leave the spaces // Added the "{bullet}" token for McGuire and Catawba's Bulleted High Level Step type. // Using the bullet set in the IdentB format variable (is a solid bullet for their format) if (tbformat.Contains("{bullet}")) { string bulletChar = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB.Trim(); tbformat = tbformat.Replace("{bullet}", bulletChar); } // rno gets parent tab if (IsRNOPart && FormatStepData.NumberSubs) { try { // NumberWithLevel flag is used by BGE. It does tabbing in rno column by incrementing of rno and rno substeps if (FormatStepData.NumberWithLevel) { int ord = Ordinal - 1; string incSub = Ordinal.ToString(); // get previous's tab & increment from it. if (MyParent != null && MyParent.IsRNOPart) ord = System.Convert.ToInt32(MyParent.MyTab.CleanText.Substring(MyParent.MyTab.CleanText.LastIndexOf(".") + 1)); incSub = (ord + 1).ToString(); if (MyParent.MyTab.CleanText.Trim().EndsWith(")")) { //CSM F2024 - 080: For South Texas - if format contains initial line and it is not disabled, show an initial line string tstr = MyParent.MyTab.CleanText.Trim() + "." + incSub; if (!string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroList != null && FormatStepData.TabData.MacroList.Count > 0 && !(this.IsRNOPart && FormatStepData.TabData.MacroList[0].NotInRNO) && !IsInitialLineDisabled && !tstr.StartsWith("_")) { if (tstr.StartsWith(" ")) tstr = tstr.Substring(1); tstr = FormatStepData.TabData.MacroEditTag + tstr; } else if (IsInitialLineDisabled && tstr.StartsWith("_")) tstr = tstr.Substring(1); _MyTab.CleanText = tstr; _MyTab.Text = _MyTab.CleanText; return; } if (MyParent.MyTab.CleanText.Contains(ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB)) { //CSM F2024 - 080: For South Texas - if format contains initial line and it is not disabled, show an initial line string tstr = MyParent.MyTab.CleanText.Trim() + "." + incSub + " "; if (!string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroList != null && FormatStepData.TabData.MacroList.Count > 0 && !(this.IsRNOPart && FormatStepData.TabData.MacroList[0].NotInRNO) && !IsInitialLineDisabled && !tstr.StartsWith("_")) { if (tstr.StartsWith(" ")) tstr = tstr.Substring(1); tstr = FormatStepData.TabData.MacroEditTag + tstr; } else if(IsInitialLineDisabled && tstr.StartsWith("_")) tstr = tstr.Substring(1); _MyTab.CleanText = tstr; _MyTab.Text = _MyTab.CleanText; return; } string tmprnotab = MyParent.MyTab.CleanText.Substring(0, MyParent.MyTab.CleanText.IndexOf(".") + 1) + incSub; //CSM F2024 - 080: For South Texas - if format contains initial line and it is not disabled, show an initial line tmprnotab = tmprnotab.TrimStart(); if (!string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroList != null && FormatStepData.TabData.MacroList.Count > 0 && !(this.IsRNOPart && FormatStepData.TabData.MacroList[0].NotInRNO) && !IsInitialLineDisabled && !tmprnotab.StartsWith("_")) { if (tmprnotab.StartsWith(" ")) tmprnotab = tmprnotab.Substring(1); tmprnotab = FormatStepData.TabData.MacroEditTag + tmprnotab; } else if (IsInitialLineDisabled && tmprnotab.StartsWith("_")) tmprnotab = tmprnotab.Substring(1); _MyTab.CleanText = tmprnotab; _MyTab.Text = tmprnotab; return; } if ((((ItemInfo)ActiveParent).IsHigh && FormatStepData.NumberHighLevel) || ((!((ItemInfo)ActiveParent).IsHigh) && ((tbformat == null || tbformat == "") && (RNOLevel <= ColumnMode)))) { _MyTab.CleanText = ((ItemInfo)ActiveParent).MyTab.CleanText; _MyTab.Text = ((ItemInfo)ActiveParent).MyTab.Text; //CSM F2024 - 080: For South Texas - if format contains initial line and it is not disabled, show an initial line if (!string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroList != null && FormatStepData.TabData.MacroList.Count > 0 && !(this.IsRNOPart && FormatStepData.TabData.MacroList[0].NotInRNO) && !IsInitialLineDisabled && !_MyTab.CleanText.StartsWith("_")) { if (_MyTab.CleanText.StartsWith(" ")) _MyTab.CleanText = _MyTab.CleanText.Substring(1); _MyTab.CleanText = FormatStepData.TabData.MacroEditTag + _MyTab.CleanText; } if (IsInitialLineDisabled && _MyTab.CleanText.StartsWith("_")) { _MyTab.CleanText = _MyTab.CleanText.Substring(1); } if (IsInitialLineDisabled && _MyTab.Text.StartsWith("_")) { _MyTab.Text = _MyTab.Text.Substring(1); } _MyTab.RNOTabWidthAdjust = ((ItemInfo)ActiveParent).FormatStepData.TabData.RNOAdjustTabSize ?? 0; if (((ItemInfo)ActiveParent).MyTab.Offset != 0) _MyTab.Offset = ((ItemInfo)ActiveParent).MyTab.Offset; if (((ItemInfo)ActiveParent).FormatStepData.TabData.RNOExcludeMacros) _MyTab.Text = Regex.Replace(_MyTab.Text, "{!.+?}", " "); if (((ItemInfo)ActiveParent).FormatStepData.TabData.RNOIdentPrint.Contains("{asterisk}")) _MyTab.AsteriskOffset = -10; return; } } catch (Exception ex) { Console.WriteLine("SetTabText IsRNO error {0}", ex.Message); } } if (tbformat == null) { _MyTab.Text = ""; _MyTab.CleanText = ""; return; } // account for metasection indenting/tabbing in the 'PrintLevel', i.e. if we have metasection, we may be in // a subsection. Index into the seqtabs array has to account for metasection level. int localPrintLevel = PrintLevel; StepSectionData sd = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData; bool doMeta = false; if (sd.StepSectionLayoutData.TieTabToLevel && ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections) { if (sd.StepSectionLayoutData.ShowSectionTitles && !MyDocStyle.CancelSectTitle && !(MyDocStyle.SpecialStepsFoldout && MyDocStyle.UseColSByLevel)) localPrintLevel = PrintLevel + (((ActiveFormat.PlantFormat.FormatData.Express && IsSequential)) ? 0 : CurrentSectionLevel()); if (!ActiveFormat.PlantFormat.FormatData.Express) doMeta = true; } if (sd.StepSectionLayoutData.TieTabToLevel && ActiveFormat.PlantFormat.FormatData.SectData.CountSubSectionsForLevel) if (SectionLevel() > 1) localPrintLevel += 1; SeqTabFmtList seqtabs = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.SeqTabFmtList; // Start with basic cases of alpha/numeric/seq: // If we have metasections AND... // If the seqtabs for this given level does not get a section number, use the seqtab rather than // the ident of the step: bool useSubStepTabs = false; if (doMeta && IsHigh && !seqtabs[(localPrintLevel < 0 ? 0 : localPrintLevel) % seqtabs.MaxIndex].TabToken.Contains("{numericWpar}") && tbformat.Contains("{")) useSubStepTabs = true; // Check to be sure the parent tab should be included... If this sequential is within a note // or caution or equipment list, don't use parent tab AND always start the numbering as a numeric if (doMeta && IsSequential && (InNote() || InCaution() || (MyParent.IsEquipmentList && !MyParent.FormatStepData.TabData.IdentPrint.Contains("{seq}")))) { // if immediate parent is note, caution or equip, use numeric, otherwise use alpha. localPrintLevel = 0; int lv = 0; ItemInfo ii = MyParent; while (!ii.IsCaution && !ii.IsNote && !ii.IsEquipmentList) { lv++; ii = ii.MyParent; } lv = lv % 2; tbformat = (lv == 0) ? "{numeric}." : "{alpha}."; } bool trimTabStart = false; bool dontTrimParentTabBeforeAppending = false; // B2019-011 for Barakah Alarm format if (useSubStepTabs || tbformat.IndexOf("{seq}") > -1) { // If the document style has the flag DSS_UnNumLikeRoman, don't do the normal tab, change to alpha // and adjust level in certain conditions as shown below: if (!IsHigh && (MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_UnNumLikeRoman) == E_DocStructStyle.DSS_UnNumLikeRoman) { string myParentIdent = MyParent.FormatStepData.TabData.IdentPrint; // If there is a tab string for this step and it includes the HLS/parent tab. The HLS is numbered // with roman numerals, so don't want to continue using the roman numeral concatenated with substep tabs. // the parent has to have a roman numeral as its tab. if (myParentIdent.ToUpper().Contains("ROMAN") && tbformat != null && tbformat != "" && tbformat.ToUpper().Contains("SEQ")) localPrintLevel += 5; // tbformat = "{alpha}. "; // If the parent has no tab, adjust the level by 5 (this is taken directly from 16bit logic & is needed by FNP AOPs, U1 AOP14.0 for example) else if (tbformat != null && tbformat != "" && myParentIdent == "") localPrintLevel += 5; } int itmp = (localPrintLevel + PrintBias + OffsetTab) % seqtabs.MaxIndex; // F2018-025 Westinghouse when a high level step is used as a section number/title, // adjust the step/substep numbering where the first level substep uses the high level step tabbing format // and the following sub-substeps tabbing format are "shifted" accordingly (ex should look like ASS-101 Attachment 1 section 4 tabbing) if (!IsHigh && MyHLS != null && MyHLS.FormatStepData.AppendDotZero) { if (localPrintLevel > 1) { localPrintLevel--; itmp = (localPrintLevel + PrintBias + OffsetTab) % seqtabs.MaxIndex; } } // F2024-037 reset the seq sub-step numbering if the parent is an un-numbered high level step // F2024-049 changed to specify the level via the format file (Generic EOP and Vogtle 3&4) else if (sd.StepSectionLayoutData.ResetSeqNumberingAfterUnnumberedHLS != null && IsSequential && MyParent != null && MyParent.IsHigh && MyParent.MyTab.Text.Length == 0) { localPrintLevel = (int)sd.StepSectionLayoutData.ResetSeqNumberingAfterUnnumberedHLS; itmp = (localPrintLevel + PrintBias + OffsetTab) % seqtabs.MaxIndex; } if (!tbformat.Contains(@"{!C")) tbformat = seqtabs[itmp].PrintTabFormat; // seqtab in 16bit, i.e. '. or )' etc. else tbformat = tbformat.Replace("{seq}", seqtabs[itmp].PrintTabFormat); dontTrimParentTabBeforeAppending = seqtabs[itmp].DontTrimParentTabBeforeAppending; // B2019-011 put in for Barakah Alarm format to better align the first level sub step with the high level step string tbtoken = seqtabs[localPrintLevel % seqtabs.MaxIndex].TabToken; // seqstart in 16bit, number/letter // if the tab has a character before the token, trim the front of tab: int br = tbformat.IndexOf("{"); if (br > 0) { char isAChar = tbformat[br - 1]; if ("{} #".IndexOf(isAChar) < 0) trimTabStart = true; } tbformat = tbformat.Replace("{seq}", tbtoken); } else // reset the print level if it's not a sequential type. The code was setting printlevel // to a -1 for equipment lists, and if the step type was changed to a sequential, it kept the // -1 (the printlevel property calculates the value only if the current value == 0, // so that when the above code ran to reset the tab, it would crash because the // printlevel was not recalculated. PrintLevel = 0; // If token includes 'Wpar', the parent tab prefix's the tab. if (localPrintLevel > 0 && (tbformat.IndexOf("{numericWpar}") > -1 || tbformat.IndexOf("{alphaWpar}") > -1 || tbformat.IndexOf("{ALPHAWpar}") > -1)) { string parentTab = null; ItemInfo myparent = ActiveParent as ItemInfo; if (myparent != null && myparent.IsParagraph) { myparent = myparent.ActiveParent as ItemInfo; if (myparent.MyTab.CleanText.Trim() == "") { if ((myparent.ActiveParent as ItemInfo).MyTab.CleanText.Trim() != "") myparent = myparent.ActiveParent as ItemInfo; } } else if (myparent.IsSection || myparent.IsHigh || myparent.IsSequential || (myparent.IsRNOPart && myparent.FormatStepData.NumberHighLevel && tbformat.ToUpper().Contains("WPAR"))) { parentTab = (dontTrimParentTabBeforeAppending) ? myparent.MyTab.CleanText : myparent.MyTab.CleanText.Trim(); // B2019-011 for Barakah Alarm format adde the don't trim flag if ((((MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_AddDotZeroStdHLS) == E_DocStructStyle.DSS_AddDotZeroStdHLS) && myparent.MyContent.Type == 20002) || (myparent.IsStepPart && myparent.FormatStepData.AppendDotZero)) // F2018-022 Added step type flag to append a ".0" to the end of the high level step - put in for Westinghouse single column format (wst1), B2018-119 only do this for steps parentTab = parentTab.Replace(".0", ""); // this was added in, remove for substeps. tbformat = parentTab + (parentTab.EndsWith(".") ? "" : parentTab == "" ? "" : ".") + tbformat.TrimStart(); HasParentTab = true; // F2020-023: tab includes parent tab } else if (IsSequential && ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.SkipNonSeqTabWithPar) { // this was added for Wolf Creek WCN1: if this has a 'wpar' flag, then walk up until finding // a sequential or high and use that tab (ignore non-sequential steps when walking up parents). // Note that the format flag 'SkipNonSeqTabWithPar' was added to prevent this code being run for Westinghouse and Farley. // the following prevents the concatenation of parent tabs onto this once the indenting is // past the number of seqtabs. if (localPrintLevel < seqtabs.MaxIndex || (PrintLevel < seqtabs.MaxIndex && seqtabs[PrintLevel].TabToken.ToUpper().Contains("WPAR"))) { ItemInfo mpar = myparent; while (mpar != null && !mpar.IsSection && !mpar.IsHigh && !mpar.IsSequential) mpar = (mpar.MyParent as ItemInfo); if (mpar != null && !mpar.IsSection) { parentTab = mpar.MyTab.CleanText.Trim(); tbformat = parentTab + (parentTab.EndsWith(".") ? "" : ".") + tbformat.TrimStart(); HasParentTab = true; // F2020-023: tab includes parent tab //if (_MyLog.IsInfoEnabled) _MyLog.InfoFormat("==>PARTAB: [{0}]", ShortPath + ", " + ItemID.ToString()); } } } } if (tbformat.IndexOf("#2#") > -1 || tbformat.IndexOf("#1#") > -1) { //16 bit code limits the #2# offset logic to the docstyle cannot have the DSS_ADDDOTZEROSTDHLS & // its HLS is type std high: if (!((((MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_AddDotZeroStdHLS) == E_DocStructStyle.DSS_AddDotZeroStdHLS) && this.MyHLS.MyContent.Type == 20002) || this.FormatStepData.AppendDotZero)) // F2018-022 Added step type flag to append a ".0" to the end of the high level step - put in for Westinghouse single column format (wst1) { int indxlb = tbformat.IndexOf("#"); string ofst = tbformat.Substring(indxlb + 1, 3); _MyTab.Offset = Convert.ToInt32(ofst.Substring(0, 1)) * (int)FormatStepData.TabData.Font.CharsToTwips; } tbformat = tbformat.Replace("#2#", "").Replace("#1#", ""); } if (tbformat.IndexOf("{Pos") > -1) { int begPos = tbformat.IndexOf("{Pos"); int endPos = tbformat.IndexOf("}"); string ofst = tbformat.Substring(begPos + 4, endPos - begPos - 4); _MyTab.Position = -(Convert.ToInt32(ofst) * (int)FormatStepData.TabData.Font.CPI); tbformat = tbformat.Remove(begPos, endPos + 1); } // if this is a caution/note type determine where 'NOTE/CAUTION' tab goes, as tab or as 'header' // and also determine whether the tab itself gets converted to a bullet. if (IsCaution || IsNote) tbformat = CheckNoteCautionTab(tbformat); // if there is a section prefix, trim any spaces from the start of this tab, so we don't have // a tab that looks like "1. 1" if (!IsSection && !IsProcedure && tbformat.IndexOf("{Section Prefix}") >= 0) { string tmpsectpref = SectionPrefix(tbformat) ?? string.Empty; if (ActiveSection.MyTab!=null && ActiveSection.MyTab.CleanText != null && ActiveSection.MyTab.CleanText != "" && tmpsectpref != string.Empty) trimTabStart = true; tbformat = tbformat.Replace("{Section Prefix}", SectionPrefix(tbformat)); if (tbformate != null) tbformate = tbformate.Replace("{Section Prefix}", SectionPrefix(tbformate)); } bool isAlpha = tbformat.ToUpper().Contains("ALPHA"); int ordinal = Ordinal; bool trimSeqValue = FormatStepData.TabData.TrimSeqTabValue; // F2024-043 remove space around SEQ tab value bool useLinked = false; // if this is enhanced, and the LinkedTab isn't numeric, flag to use 'LinkedTab' for the tab. if (ActiveSection != null && ActiveSection.IsEnhancedSection) // C2018-003 fixed use of getting the active section { if (IsEnhancedStep) try { ordinal = int.Parse("0" + LinkedTab ?? "0"); } catch (Exception ex) { // use LinkedTab and don't do the AlphabeticalNumbering below. LinkedTab had alpha chars useLinked = true; } // commented out the following two lines to fix bug B2017-031, where sequental substeps where printing with an '@' instead of a number or letter in linked enhanced backgrounds //else // ordinal = 0; } // B2018-101: The section number was duplicated in the WCNOC step tab. This was fixed for edit, B2017-153, but not for print (see below). The code // used for that bug fix was duplicated here (with slight modification because the tab did not have the "WCNOC" string, thus using the active // formats, and also use tbformat rather than tbformate. // F2018-037: An additional WCN background format was added for SAMG, so the code was made more general, i.e. to make tab // change, check for formats that start with WCN and contain BCK: if (useLinked) { if (ActiveFormat.Name.ToUpper().StartsWith("WCN") && ActiveFormat.Name.ToUpper().Contains("BCK") && tbformat.Contains(LinkedTab[0].ToString() + "{numeric}")) tbformat = tbformat.Replace(LinkedTab[0].ToString() + "{numeric}", "{numeric}"); else if ((ActiveFormat.Name.ToUpper().StartsWith("WCN") && ActiveFormat.Name.ToUpper().Contains("BCK")) && tbformat.Contains(LinkedTab[0].ToString() + ".{numeric}")) tbformat = tbformat.Replace(LinkedTab[0].ToString() + ".{numeric}", "{numeric}"); tbformat = tbformat.Replace("{numeric}", LinkedTab.Trim(" .".ToCharArray()).PadLeft(2)); } string alpha = useLinked?LinkedTab.Trim():AlphabeticalNumbering(ordinal); if (trimSeqValue) alpha = alpha.Trim(); // F2024-043 trim white around SEQ tab value (for sub-steps) // B2017-211 Roman High Level steps should be followed by Uppercase alpha substeps - This is being limited to Calvert SAMG Format if (_ActiveFormat.Name =="BGESAM1" &&MyParent != null && MyParent.IsHigh && MyParent.IsStep && MyParent.FormatStepData.TabData.IdentEdit.Contains("ROMAN")) tbformat = tbformat.Replace("{alpha}", alpha); else tbformat = tbformat.Replace("{alpha}", alpha.ToLower()); tbformat = tbformat.Replace("{alphaWpar}", alpha.ToLower()); if (ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && tbformat.Contains("{ALPHA}") && alpha.Length > 1) tbformat = tbformat.Replace("{ALPHA}. ", alpha + "."); // if double chars, remove one of the space for BGE else tbformat = tbformat.Replace("{ALPHA}", alpha); tbformat = tbformat.Replace("{ALPHAWpar}", alpha); if (tbformat.ToUpper().Contains("ROMAN")) { string roman = RomanNumbering(ordinal); tbformat = tbformat.Replace("{roman}", roman.ToLower()); tbformat = tbformat.Replace("{ROMAN}", roman); tbformat = tbformat.Substring(0, tbformat.Length - ((roman.Length - 1) > 0 ? (roman.Length - 1) : 0)); } if (tbformat.Contains("{numeric}") && ((MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_AddDotZeroStdHLS) == E_DocStructStyle.DSS_AddDotZeroStdHLS) && MyContent.Type == 20002) { tbformat = tbformat.Replace("{numeric}", ordinal.ToString().PadLeft(2) + ".0"); tbformat = tbformat.Substring(0, tbformat.Length - 2); } if (tbformat.Contains("{numeric}") && (this.FormatStepData.AppendDotZero)) // F2018-022 Added step type flag to append a ".0" to the end of the high level step - put in for Westinghouse single column format (wst1) { string numtxt = ordinal.ToString().PadLeft(2) + ".0"; tbformat = tbformat.Replace("{numeric}.", numtxt).Replace("{numeric}", numtxt); } // if this is a wolf creek background, if the tbformat ends with a '.' don't add a space, // otherwise add a space. if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WolfCreekBackgroundFormat && IsBackgroundStep()) { string stpTab = null; if (useLinked) stpTab = (!tbformat.Contains(".") ? " " : "") + ((ordinal == 0) ? "NA" : LinkedTab); else stpTab = (!tbformat.Contains(".") ? " " : "") + ((ordinal == 0) ? "NA" : ordinal.ToString()); tbformat = tbformat.Replace("{numeric}", stpTab); } else // F2024-043 added trimSeqValue to trim white around SEQ tab value (for sub-steps) tbformat = tbformat.Replace("{numeric}", (trimTabStart || trimSeqValue) ? ordinal.ToString() : FormatStepData.AtLeastTwoDigits ? ordinal.ToString().PadLeft(2, '0') : ordinal.ToString().PadLeft(2)); if (tbformate != null) { if (useLinked) { // B2017-153 - WCN Emergency Backgrounds Fix Tabs for Background Document Steps within subsections // Prior to this fix Lettered attachment steps were repeating the section letter "EE1" // and numbered sections were repeating the section number "3.3.1" if (tbformate.StartsWith("WCNOC") && tbformate.Contains( LinkedTab[0].ToString() + "{numeric}")) tbformate = tbformate.Replace(LinkedTab[0].ToString() + "{numeric}","{numeric}"); else if (tbformate.StartsWith("WCNOC") && tbformate.Contains(LinkedTab[0].ToString() + ".{numeric}")) tbformate = tbformate.Replace(LinkedTab[0].ToString() + ".{numeric}", "{numeric}"); tbformate = tbformate.Replace("{numeric}", LinkedTab.Trim(" .".ToCharArray()).PadLeft(2)); } if (tbformat.Contains("NA") && ordinal == 0) tbformate = tbformate.Replace("{numeric}", "NA"); else tbformate = tbformate.Replace("{numeric}", trimTabStart ? ordinal.ToString() : FormatStepData.AtLeastTwoDigits ? ordinal.ToString().PadLeft(2, '0') : ordinal.ToString().PadLeft(2)); } tbformat = tbformat.Replace("{numericWpar}", ordinal.ToString()); if (tbformat.Contains("{asterisk}")) { // if this has a checkoff - need to set location of the asterisk - because the asterisk has to come before // the checkoff. Otherwise, it doesn't matter _MyTab.AsteriskOffset = -10; tbformat = tbformat.Replace("{asterisk}", ""); // the asteriskoffset flags a '*' to be printed at xloc - this. } // F2022-024 Clock is defined in genmac as a text using the Wingding font and uses the Clock unicode character and is used when the step is printed // But for the editor screen, we use the character defined at the step tab with MacroEditTag // For Robinson's case, the MacroEditTag is an'!' character int macroindx = tbformat.IndexOf("{!Clock}"); if (macroindx > -1) //i found it { int endidx = tbformat.IndexOf("}", macroindx); if (endidx > -1) { // replace the {!Clock} token with MacroEditTag - for Robinson, this will be an ! character cltext = cltext == null ? tbformat.Substring(0, macroindx) + FormatStepData.TabData.MacroEditTag + tbformat.Substring(macroindx + endidx + 1) : cltext.Remove(macroindx, 5); } } else { macroindx = tbformat.IndexOf("{!C"); // does the step tab use a print macro (i.e. circle around step number) if (macroindx > -1) { // F2022-051 use the MacroEditTab when set on step that uses a print macro (i.e. circle, triangle) // this will allow for a visual indicator while editing // Note could have modified logic for clock macro (above) but older logic uses the IdentEdit setting // for CAS (Continuous Action Summary steps) that have a circle printed around the step number // this is the least impact of current code/formats if (!string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag)) { int eidx = tbformat.IndexOf("}", macroindx); if (eidx > -1) { int macrolen = eidx - macroindx + 1; cltext = cltext == null ? tbformat.Remove(macroindx, macrolen) : cltext.Remove(macroindx, macrolen); cltext = cltext + " "; cltext = cltext.Substring(0, macroindx) + FormatStepData.TabData.MacroEditTag + cltext.Substring(macroindx); } } // C2017-026: have visual indicator for CAS Step else if (FormatStepData.TabData.IdentEdit.Contains("*. ")) { cltext = cltext == null ? tbformat.Substring(0, macroindx) + "*. " + tbformat.Substring(macroindx + 8) : cltext.Remove(macroindx, 5); } else { cltext = cltext == null ? tbformat.Remove(macroindx, 5) : cltext.Remove(macroindx, 5); cltext = cltext + " "; } } //CSM F2024 - 080: For South Texas - if format contains initial line and it is not disabled, show an initial line else if (macroindx == -1 && !string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroList != null && FormatStepData.TabData.MacroList.Count > 0 && !(this.IsRNOPart && FormatStepData.TabData.MacroList[0].NotInRNO) && !IsInitialLineDisabled) { if (cltext == null) cltext = tbformat; if (cltext.StartsWith(" ")) cltext = cltext.Substring(1); if (tbformat.StartsWith(" ")) tbformat = tbformat.Substring(1); cltext = FormatStepData.TabData.MacroEditTag + cltext; } } macroindx = tbformat.IndexOf("{!diamond1}"); if (macroindx > -1) //i found it { cltext = cltext == null ? tbformat.Remove(macroindx, 11) : cltext.Remove(macroindx, 11); cltext = cltext + " "; } macroindx = tbformat.IndexOf("{!diamond}"); if (macroindx > -1) //i found it { cltext = cltext == null ? tbformat.Remove(macroindx, 10) : cltext.Remove(macroindx, 10); cltext = cltext + " "; } // "{Null}" was introduced so that inheritance in format files could differentiate between an // empty string, and null. And also, so that if a tab was null but it's parent had text in the // tab, don't inherit the parent's tab, use a null. if (MyPrevious != null && FormatStepData.Sep != null && FormatStepData.Sep != "{Null}") { // check if there is font information for the separator, use it. If not use the font information // that is associated with the tab. VE_Font hdrFont = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.Separator == null ? null : ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.Separator.Font; if (hdrFont == null) hdrFont = FormatStepData.TabData.Font; if (_MyHeader == null) _MyHeader = new MetaTag(hdrFont); else _MyHeader.MyFont = hdrFont; _MyHeader.Text = FormatStepData.Sep; _MyHeader.CleanText = StripRtfFormatting(_MyHeader.Text); // per 16-bit format speadsheet, Location can have the following values: // 0 - Left // 1 - Right // 2 or greater - Center int sepLoc = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.Separator.Location ?? 2; //default to Center switch (sepLoc) { case 0: _MyHeader.Justify = ContentAlignment.MiddleLeft; break; case 1: _MyHeader.Justify = ContentAlignment.MiddleRight; break; default: _MyHeader.Justify = ContentAlignment.MiddleCenter; break; } //_MyHeader.Justify = ContentAlignment.MiddleCenter; } #region Non Converted Plants tab TODO // Position offset //"{indent}"); //"{par}"); //Macros // - draws a diamond around the stepnumber // - A macro // // <> - ignored // \241 - circle macro around step, same as // Also note, the format files had "<>", these get converted during input in this // format converter code. //wkstr = wkstr.Replace("{!asterisk}", "\\fs10 \\b*\\b0"); // was font size 20 in 16-bit //wkstr = Regex.Replace(wkstr, @"{![.*?]}", @"{!$1}"); //wkstr = wkstr.Replace("{}", ""); //if (vefont != null && vefont.HasCircleString2()) wkstr.Insert(0,"{!C0}"); //wkstr = wkstr.Replace("j", @"{Box Step}"); #endregion // if this has an alternate tab, use it. These have been used in background documents. if (!IsSection && FormatStepData.TabData.IdentAltPrint != null && FormatStepData.TabData.IdentAltPrint != "") { string newtab = null; string fmtAltPrintTab = FormatStepData.TabData.IdentAltPrint; int idxClock = -1; int idxEndClock = -1; if (fmtAltPrintTab.Contains("{!Clock}")) { idxClock = fmtAltPrintTab.IndexOf("{!Clock}"); idxEndClock = idxClock + 7; int i = idxEndClock; while (i+1 <= fmtAltPrintTab.Length && fmtAltPrintTab[i+1] == ' ') i++; // spin past any spaces after Clock idxEndClock = i; } int indxnewtab = fmtAltPrintTab.LastIndexOf('\\'); if (indxnewtab >= 0) { _MyTab.BasicTab = isAlpha ? alpha : ordinal.ToString(); newtab = fmtAltPrintTab.Substring(indxnewtab + 1); if (newtab.Contains("{numeric}") || newtab.Contains("{LNK Step Num}")) { newtab = tbformat; if (idxClock > -1) { newtab = newtab.Substring(0, idxEndClock + 1) + @"\ul " + newtab.Substring(idxEndClock + 1, newtab.IndexOf(":") + 1) + @"\ulnone " + newtab.Substring(newtab.IndexOf(":") + 1); } else { newtab = @"\ul " + newtab.Substring(0, newtab.IndexOf(":") + 1) + @"\ulnone " + newtab.Substring(newtab.IndexOf(":") + 1); } } // also see if there is the 'pagelist' string in this tab: // C2018-003 fixed use of getting the active section else if ((FormatStepData.TabData.Font.Style & E_Style.Underline) == E_Style.Underline && ActiveSection != null && ((ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListSpBckgrnd) != E_DocStructStyle.DSS_PageListSpBckgrnd)) // the reason that the underline commands were not included in format file is that the '\' character // is used as a separator and the following code will not impact other formats if (idxClock > -1) { HighLevelStepTabPageList = fmtAltPrintTab.Substring(0, idxEndClock + 1) + @"\ul " + fmtAltPrintTab.Substring(idxEndClock+1, indxnewtab - (idxEndClock+1)).Trim() + @"\ulnone " + (tbformat.StartsWith(" ") ? "" : " ") + tbformat; } else { HighLevelStepTabPageList = @"\ul " + fmtAltPrintTab.Substring(0, indxnewtab).Trim() + @"\ulnone " + (tbformat.StartsWith(" ") ? "" : " ") + tbformat; } else HighLevelStepTabPageList = fmtAltPrintTab.Substring(0, indxnewtab) + tbformat; _MyTab.AltPrintTab = newtab; if (tbformate != null && tbformate != "") tbformat = tbformate; } } // F2022-074 added a Left Justify token to the step tab definition (used in Beaver Valley) if (tbformat.Contains("{LJ}")) { tbformat = tbformat.Replace("{LJ}","").TrimStart(); if (cltext != null && cltext.Contains("{LJ}")) cltext = cltext.Replace("{LJ}", "").TrimStart(); } _MyTab.Text = tbformat; _MyTab.CleanText = cltext != null ? cltext : tbformat; } private int SectionLevel() { int level = 0; ItemInfo ii = this; while (!ii.IsProcedure) { // fix for Westinghouse single column // - increament the level on a section only if the first character is a number B2016-075 03-09-2016 // Note that 'DisplayNumber' is used rather than MyTab. MyTab was not always set. //if (ii.IsSection && (ii.MyTab.Text != null && ii.MyTab.Text.Length > 0 && char.IsNumber(ii.MyTab.Text.Trim()[0]))) level++; if (ii.IsSection && (ii.DisplayNumber != null && ii.DisplayNumber.Length > 0 && char.IsNumber(ii.DisplayNumber.Trim()[0]))) level++; ii = ii.ActiveParent as ItemInfo; } return level; } private bool InCaution() { // walk up until procedure level and if finding a caution type, return true, otherwise false. ItemInfo ii = this.MyParent; while (ii != null && !ii.IsProcedure) { if (ii.IsCaution) return true; ii = ii.MyParent; } return false; } public bool IsBackgroundStep() { if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WolfCreekBackgroundFormat) { if (IsHigh || IsCaution || IsNote) return true; if (MyParent != null && MyParent.IsStep && MyParent.FormatStepData.Type.ToUpper() == "TITLEWITHTEXTBELOW" && FormatStepData.Type.ToUpper() != "IMPLICITOR") return true; } return false; } // B2018-146 Find any steep that is part of a background step. public bool IsBackgroundStepOrChild() { if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WolfCreekBackgroundFormat) { ItemInfo tmp = this; while (tmp != null && tmp.IsStep) { if (tmp.IsHigh || tmp.IsCaution || tmp.IsNote) return true; if (tmp.MyParent != null && tmp.MyParent.IsStep && tmp.MyParent.FormatStepData.Type.ToUpper() == "TITLEWITHTEXTBELOW" && tmp.FormatStepData.Type.ToUpper() != "IMPLICITOR") return true; tmp = tmp.ActiveParent as ItemInfo; } } return false; } // Function to find if in part of a Background Step public bool IsPartOfBackgroundStep() { if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WolfCreekBackgroundFormat) { ItemInfo itm = this; while (itm.MyPrevious != null) { if (itm.MyPrevious.IsBackgroundStep()) return true; if (itm.MyPrevious != null && itm.MyPrevious.IsStep && itm.MyPrevious.FormatStepData.Type.ToUpper() == "TITLEWITHTEXTBELOW" && FormatStepData.Type.ToUpper() != "IMPLICITOR") return true; itm = itm.MyPrevious; } return false; } return false; } private bool InNote() { // walk up until procedure level and if finding a note type, return true, otherwise false. ItemInfo ii = this.MyParent; while (ii != null && !ii.IsProcedure) { if (ii.IsNote) return true; ii = ii.MyParent; } return false; } private string GetToken(string tbformat) { int stindx = tbformat.IndexOf("{"); return (tbformat.Substring(stindx, tbformat.IndexOf("}") - stindx + 1)); } public int GetStepLevel() // ref int bias) { int profileDepth = ProfileTimer.Push(">>>> GetStepLevel"); int level = 0; ItemInfo par = this; ItemInfo LastRNO = null; ItemInfo TopRNO = null; while (par != null && !par.IsSection && !par.IsProcedure && !par.IsHigh) { if (par.IsRNOPart) { LastRNO = par.MyParent; TopRNO = par; } if (!par.IsRNOPart && (par.IsSequential || (!(par.IsCaution || par.IsNote) && ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CountAllSubLevels))) level++; par = par.MyParent; } // If high level RNOs are numbered, use the next level of tabs for lower // level RNOs - unless DontOffsetTab format flag is set if (LastRNO != null && LastRNO.IsHigh && TopRNO.FormatStepData.NumberHighLevel && TopRNO.FormatStepData.OffsetTab) OffsetTab = TopRNO.FormatStepData.NumberHighLevel ? 1 : 0; _PrintBias = 0; if (par.FormatStepData != null && par.FormatStepData.TabData.IdentPrint.Contains("{ALPHA}")) level--; // ImperfectStructure is used so that the sequential numbering for substeps under an RNO is not same // numbering (alpha vs numeric), if the HLS has substeps - WCN uses this, as well as other plants. if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectStructure && IsSequential && (LastRNO != null) && LastRNO.IsHigh && LastRNO.HasChildren && LastRNO.FirstChild(E_FromType.Step) != null && LastRNO.FirstChild(E_FromType.Step).IsSequential) { level++; if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectStructurePlus4) level += 2; if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectSubstep && !ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectStructurePlus4) PrintBias = -1; } // ImperfectStructure for substeps - only good for level 1 RNOs else if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectSubstep && RNOLevel == 1) { par = this; while (!par.IsRNOPart) par = par.MyParent; // get to the rno. if (par.MyParent.HasChildren) // if parent has children? { ItemInfo tchild = par.MyParent.FirstChild(E_FromType.Step); if (tchild != null) { int typ = (int)tchild.MyContent.Type - 20000; if (ActiveFormat.PlantFormat.FormatData.StepDataList[typ].TabData.IdentPrint.Contains("{seq}")) { level++; if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectStructurePlus4) level += 1; if (!ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ImperfectStructurePlus4) PrintBias = -1; } } } } if (MyDocStyle != null && (MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_SkipOneStepLevel) == E_DocStructStyle.DSS_SkipOneStepLevel) level++; if (MyDocStyle != null && (MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_SkipTwoStepLevels) == E_DocStructStyle.DSS_SkipTwoStepLevels && level == 0) level += 2; // B2022-129: don't indent HLS when flag is on (Barakah - single column step attachment with meta sect) if (MyDocStyle != null && (MyDocStyle.AdjSectTitleLoc)) level--; if (level < 0) level = 0; ProfileTimer.Pop(profileDepth); return level; } public int CurrentSectionLevel() { int countlev = 0; if (ActiveSection != null && (ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.DSS_TreatAsTrueSectNum) != 0) // C2018-003 fixed use of getting the active section { ItemInfo ii = ActiveSection.MyParent; while (!ii.IsProcedure) { if (ii.DisplayNumber != null && ii.DisplayNumber != "") { SectionInfo si = SectionInfo.Get(ii.ItemID); if (si != null) { SectionConfig sc = new SectionConfig(si); //SectionConfig sc = ii.MyConfig as SectionConfig; if (sc != null && sc.SubSection_AutoIndent == "Y") countlev++; } } ii = ii.MyParent; } } return countlev; } private string SectionPrefix(string tbformat) { // if not metasection/tietabtolevel, return the 'section number'. (where the '.' may or may not exist) if (!ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel) { // If the Section's 'tab' is a character or has a character preceding the '.' is an alpha character, // just return the alpha (no '.') // If the character preceding the '. 'is a number, return the section tab up to and including the '.' // Otherwise, just return the section tab. // Before checking for anything, if the DisplayNumber starts with 'ATTACHMENT ', don't use that in the Section // prefix for the tabstring. // F2023-112 - added flag to use entire section number in the step tab - Vogtle 3&4 Background format (VEGPBckStp) string attNum = (ActiveSection.DisplayNumber.ToUpper().StartsWith("ATTACHMENT ") && !FormatStepData.TabData.UseEntireSectionNum) ? ActiveSection.DisplayNumber.Substring(11) : ActiveSection.DisplayNumber; Match m = Regex.Match(attNum, @"[a-zA-Z]"); // for alpha, use non-touched displaynumber int indx = -1; if (m.Success) { indx = attNum.IndexOf("."); if (indx < 0) return attNum; return attNum.Substring(0, indx); } indx = ActiveSection.MyTab.CleanText.IndexOf("."); if (indx > 0) return ActiveSection.MyTab.CleanText.Substring(0, indx + 1); // include the '.' return ActiveSection.MyTab.CleanText.TrimEnd(); } // the rest of this is for metasections (tietabtolevel format flag) SectionInfo si = SectionInfo.Get(ActiveSection.ItemID); // A 'TrueSectionNum' must have a '.' and cannot have lettters after the '.'. if (si != null && si.TrueSectionNum()) { string attNum = ActiveSection.DisplayNumber; // ActiveSection.DisplayNumber.ToUpper().StartsWith("ATTACHMENT ") ? ActiveSection.DisplayNumber.Substring(11) : ActiveSection.DisplayNumber; // If section number is of form '1.0', return '1.' if (attNum.Length > 1 && attNum[attNum.Length - 1] == '0' && attNum[attNum.Length - 2] == '.') return attNum.Substring(0, attNum.Length - 1); // If section number is of form '1', return '1.' else if (attNum.Length > 0 && attNum[attNum.Length - 1] != '.') return attNum + '.'; } // For the docstyle flag DSS_TreatAsTrueSectNum, look for last space, and if one is // found, the the Section Prefix is the text after the space with a '.' appended - for // example, 'Attachment A' becomes 'A.'. if ((MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.DSS_TreatAsTrueSectNum) != 0) { int lindx = ActiveSection.DisplayNumber.LastIndexOf(" "); if (lindx > 0) { return ActiveSection.DisplayNumber.Substring(lindx + 1) + "."; } } // If we're in a subsection, be sure there is a '.' at the end. The following uses config flags for indenting to determine CurrentSectionLevel: int subsection = CurrentSectionLevel(); if (subsection >= 1) { string tmptab = ActiveSection.MyTab.CleanText.TrimEnd(); if (tmptab.LastIndexOf(".") != tmptab.Length - 1) tmptab = tmptab + "."; return tmptab; } // If the tbformat is "{Section Prefix}{numeric}" and section prefix ends in an integer, add a '.' if (tbformat.Contains("{Section Prefix}{numeric}") && MyParent.IsSection) { string tmptab = ActiveSection.MyTab.CleanText.TrimEnd(); if (tmptab.Length > 0) { string l = tmptab.Substring(tmptab.Length - 1); if (char.IsLetterOrDigit(l[0])) { if (tmptab.LastIndexOf(".") != tmptab.Length - 1) tmptab = tmptab + "."; return tmptab; } } } return ActiveSection.MyTab.CleanText.TrimEnd(); } private string CheckNoteCautionTab(string tbformat) { tbformat = ReplaceStepToken(tbformat); string prevTbFormat = null; string nextTbFormat = null; StepData nextStepData = null; if (MyPrevious != null) { // int prevStepType = ((int)MyPrevious.MyContent.Type) % 10000; StepData prevStepData = MyPrevious.FormatStepData; // ActiveFormat.PlantFormat.FormatData.StepDataList[prevStepType]; prevTbFormat = MyPrevious.IsInRNO ? prevStepData.TabData.RNOIdentPrint : prevStepData.TabData.IdentPrint; prevTbFormat = ReplaceStepToken(prevTbFormat); } // for calvert alarms, need to check if next item is a different type, if a different type. // If it is the same type, clear the header so that the header text isn't printed two times. bool specialCalvertAlarm = false; ItemInfo nextItem = NextItem; if (ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm) { if (nextItem != null && MyContent.Type != nextItem.MyContent.Type) specialCalvertAlarm = true; } if (nextItem != null && !specialCalvertAlarm) { nextStepData = nextItem.FormatStepData; // tried to duplicate functionality from 16-bit code. nextTbFormat = nextItem.IsInRNO ? nextStepData.TabData.RNOIdentPrint : nextStepData.TabData.IdentPrint; nextTbFormat = ReplaceStepToken(nextTbFormat); } // Handle the centered tab - if this tab is centered make it a header. if (FormatStepData.TabData.Justify == "Center") { _MyHeader.Justify = ContentAlignment.MiddleCenter; _MyHeader.Text = (!FormatStepData.TabData.NoTrim) ? tbformat.Replace("\\xA0", " ").Trim() : tbformat.Replace("\\xA0", " "); _MyHeader.CleanText = StripRtfFormatting(_MyHeader.Text); // if there is only step in the group or we have a change in step type (caution/note) when there is // use of the MixCautionsAndNotes format flag - no bullet is used, if more that one replace the tab // with a bullet. Also, if only one in group and tab text ends with 'S', remove it: bool mixCandN = MixCautionNotesDiffType(); if (((MyPrevious == null || !this.IsSameType(MyPrevious)) && ((nextItem == null || !this.IsSameType(nextItem)) || specialCalvertAlarm)) || mixCandN || FormatStepData.SeparateBox) { if (_MyHeader.CleanText.ToUpper().EndsWith("S")) { string origTxt = _MyHeader.CleanText; _MyHeader.CleanText = _MyHeader.CleanText.Substring(0, _MyHeader.CleanText.Length - 1); // Text may have rtf commands: _MyHeader.Text = _MyHeader.Text.Replace(origTxt, _MyHeader.CleanText); } tbformat = ""; } else { if (MyPrevious != null) { if (tbformat == prevTbFormat) { if (MyPrevious.FormatStepData.TabData.IsTransition) { if (tbformat != nextTbFormat) { tbformat = ""; _MyHeader = null; return tbformat; } } else _MyHeader = null; } else if (nextItem == null) tbformat = ""; } if (!this.FormatStepData.SeparateBox) { // For calvert formats, if all tabs are null or empty, then don't add a bullet in. bool allnull = ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && (tbformat == null || tbformat == "") && (nextTbFormat == null || tbformat == "") && (prevTbFormat == null || prevTbFormat == ""); if (!allnull && (tbformat == nextTbFormat || tbformat == prevTbFormat)) { tbformat = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB; TabToIdentBAdjustFont(); } else if ((nextTbFormat == null || tbformat != nextTbFormat) && (prevTbFormat == null || tbformat != prevTbFormat)) { tbformat = ""; } } } // For VC Summer Unit 2 & 3 (vcb formats) include step number in Note & Caution header if (FormatStepData.TabData.IncludeStepNum && _MyHeader != null && MyParent != null) // B2016-252 changed MyHeader to _Myheader to fix stack overflow during enhanced document editing { if (MyParent.CombinedTab != null) { // if my parent is a paragraph, then don't use the paragraph tab in the header, use the parent of the paragraph: if (MyParent.IsParagraph) { MyHeader.Text = MyHeader.Text + ((MyParent == null) ? "" : " Step " + MyParent.MyParent.MyTab.CleanText.TrimEnd(".".ToCharArray())); MyHeader.CleanText = MyHeader.CleanText + ((MyParent == null) ? "" : " Step " + MyParent.MyParent.MyTab.CleanText.TrimEnd(".".ToCharArray())); } else { MyHeader.Text = MyHeader.Text + ((MyParent == null) ? "" : " Step " + MyParent.MyTab.CleanText.TrimEnd(".".ToCharArray())); MyHeader.CleanText = MyHeader.CleanText + ((MyParent == null) ? "" : " Step " + MyParent.MyTab.CleanText.TrimEnd(".".ToCharArray())); } } else if (MyParent.IsStepSection && FormatStepData.TabData.IncludeSectionNum) { ItemInfo parent = MyParent; if (parent.IsStepSection) { string parentTab = parent.MyTab.CleanText.TrimEnd(".".ToCharArray()); if (parentTab != "") { // F2016-058 Trim space after section number MyHeader.Text = MyHeader.Text + ((MyParent == null) ? "" : " Section " + parentTab.TrimEnd(" ".ToCharArray())); MyHeader.CleanText = MyHeader.CleanText + ((MyParent == null) ? "" : " Section " + parentTab.TrimEnd(" ".ToCharArray())); } } } } return tbformat; } // If this has a previous, and the tabs of this & previous match if (tbformat != null && MyPrevious != null && !FormatStepData.AlwaysTab && (!FormatStepData.MixCautionsAndNotes || (tbformat == prevTbFormat))) { // used in Ginna's Attachment format // only create bullets for multiple cautions and notes if they are all exactly the same type if (!ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.OnlyBulletSameCautionNoteType || (MyPrevious != null && MyPrevious.MyContent.Type == MyContent.Type) || (NextItem != null && nextItem.MyContent.Type == MyContent.Type)) { tbformat = tbformat + ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB; TabToIdentBAdjustFont(); } } else if (FormatStepData.TabData.IsTransition) return tbformat; // F2020-009: Farley Reorder of cautions/notes - single notes were getting a bullet else if (ActiveFormat != null && ActiveFormat.Name.ToUpper().StartsWith("FNP")) { if (tbformat != null && nextItem != null && !FormatStepData.AlwaysTab && (!FormatStepData.MixCautionsAndNotes && (FormatStepData.TabData.UsePreviousStyle && !nextStepData.TabData.UsePreviousStyle && tbformat == nextTbFormat) || ((prevTbFormat != tbformat && (nextItem.MyContent.Type == MyContent.Type))))) { tbformat = tbformat + ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB; if (TabToIdentBAdjustFont()) _MyTab.RemovedStyleUnderline = true; } } // else if this has a next else if (tbformat != null && nextItem != null && !FormatStepData.AlwaysTab && (!FormatStepData.MixCautionsAndNotes || (FormatStepData.TabData.UsePreviousStyle && !nextStepData.TabData.UsePreviousStyle && tbformat == nextTbFormat) || ((prevTbFormat != tbformat && (nextItem.MyContent.Type == (int)(MyContent.Type % 10000)))))) { tbformat = tbformat + ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB; //string bstr = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB; //int bstrlen = bstr.Length; //string tstr = tbformat.Substring(tbformat.Length - bstrlen); //bool good = true; //for (int i = 0; i < tstr.Length; i++) // good = (tstr[i] == ' '); //if (good) // tbformat = tbformat.Substring(0, tbformat.Length - bstrlen) + bstr; //else // tbformat = tbformat + ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB; if (TabToIdentBAdjustFont()) _MyTab.RemovedStyleUnderline = true; } //// Since we append the bullet (IdentB) to the Caution or Note tab (like in 16-bit code) //// we need to append blank characters when there is only one Note or Caution (thus no bullet) //// in order for the Note or Caution tab to consistantly print at the same horizontal location //else if (tbformat != null && !FormatStepData.AlwaysTab && !FormatStepData.MixCautionsAndNotes // && (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB != null // && ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB.Length > 0)) //{ // int identBLen = ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IdentB.Length; // string bbstr = new string(' ', identBLen); // tbformat = tbformat + bbstr; // if (TabToIdentBAdjustFont()) // _MyTab.RemovedStyleUnderline = true; //} return tbformat; } public bool MixCautionNotesDiffType() { // for calvert alarms, if there is a note and a warning, these are both 'IsNote', but they // have different tabs, so we want the mix to be true so that the tab code handles the // tabbing correctly. if (ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm || ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) { if (MyPrevious != null && MyContent.Type != MyPrevious.MyContent.Type) return false; if (NextItem != null && MyContent.Type != NextItem.MyContent.Type) return false; } // used in Ginna's Attachment format // treat cautions and notes as different if they are all NOT exactly the same type if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.OnlyBulletSameCautionNoteType) { if (MyPrevious != null && MyPrevious.MyContent.Type != MyContent.Type && ((MyPrevious.IsCaution && this.IsCaution) || (MyPrevious.IsNote && this.IsNote))) return true; if (NextItem != null && NextItem.MyContent.Type != MyContent.Type && ((NextItem.IsCaution && this.IsCaution) || (NextItem.IsNote && this.IsNote))) return true; } if (!FormatStepData.MixCautionsAndNotes) return false; if (IsNote && ((NextItem != null && NextItem.IsCaution) || (MyPrevious != null && MyPrevious.IsCaution))) return true; if (IsCaution && ((NextItem != null && NextItem.IsNote) || (MyPrevious != null && MyPrevious.IsNote))) return true; return false; } private string ReplaceStepToken(string tbformat) { if (!string.IsNullOrEmpty(tbformat) && tbformat.Trim().EndsWith("`")) { ItemInfo tmp = this; string sep = string.Empty; string hlsOrdinal = string.Empty; do { hlsOrdinal = tmp.MyParent.MyTab.CleanTextNoSymbols.Trim(" .".ToCharArray()) + sep + hlsOrdinal; tmp = tmp.MyParent; sep = "."; } while (!tmp.IsHigh); tbformat = tbformat.Replace("`", " " + hlsOrdinal); } return tbformat; } private bool TabToIdentBAdjustFont() { if ((FormatStepData.TabData.Font.Style & E_Style.Underline) > 0) { //FontStyle style = FontStyle.Regular; //if ((FormatStepData.TabData.Font.Style & E_Style.Bold) > 0) style |= FontStyle.Bold; //if ((FormatStepData.TabData.Font.Style & E_Style.Italics) > 0) style |= FontStyle.Italic; //_MyTab.MyFont.WindowsFont = new Font(FormatStepData.TabData.Font.WindowsFont.FontFamily, FormatStepData.TabData.Font.WindowsFont.Size, style); // clear the underlining for this tab's font: E_Style es = ((E_Style)_MyTab.MyFont.Style) & ~E_Style.Underline; _MyTab.MyFont = new VE_Font(_MyTab.MyFont.Family, (int)_MyTab.MyFont.Size, es, (float)_MyTab.MyFont.CPI); return true; } return false; } private string AlphabeticalNumbering(int number) { string retval = string.Empty; // BGE requires tabs to be 'AA', 'AB', 'AC'... 'BA', 'BB', 'BC', etc. if (ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) { if (number > 26) retval += Letter((number - 1) / 26); retval += Letter(1 + ((number - 1) % 26)); return retval; } // Westinghouse and 16bit had 'AA', 'BB', etc. Logic supports unlimited cases ('aa','aaa','aaaa', etc.) retval = retval.PadRight(1 + ((number - 1) / 26), Letter(1 + ((number - 1) % 26))[0]); return retval; } private string Letter(int number) { char c = (char)(number + 64); return c.ToString(); } private enum RomanOffset : int { Hundreds = 2, Tens = 4, Units = 6 } private static string _Romans = "MDCLXVI"; private static string RomanPart(RomanOffset offset, int value) { int iFive = value / 5; int iUnits = value % 5; int iFour = iUnits / 4; return _Romans.Substring(((int)offset), iFour) + _Romans.Substring(((int)offset) - iFive - iFour, iFive | iFour) + "".PadRight(iUnits % 4, _Romans[((int)offset)]); } public static string RomanNumbering(int number) { int thousands = number / 1000; int hundreds = (number % 1000) / 100; int tens = (number % 100) / 10; int units = number % 10; return "".PadRight(thousands, _Romans[0]) + RomanPart(RomanOffset.Hundreds, hundreds) + RomanPart(RomanOffset.Tens, tens) + RomanPart(RomanOffset.Units, units); } public static void ResetTabString(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); if (key != null && _CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] items = _CacheByPrimaryKey[key].ToArray(); foreach (ItemInfo item in items) { item._TagsSetup = false; } } } #endregion #region EnhancedSupport public void ClearEnhancedSectionFromSource(int srcId) { using (Section ssrc = Section.Get(srcId)) { SectionConfig ssrcc = ssrc.MyConfig as SectionConfig; EnhancedDocuments newEds = new EnhancedDocuments(); foreach (EnhancedDocument ed in ssrcc.MyEnhancedDocuments) { if (ed.ItemID != ItemID) newEds.Add(ed); } if (newEds.Count > 0) { ssrcc.MyEnhancedDocuments = null; ssrcc.MyEnhancedDocuments = newEds; ssrcc.SaveEnhancedDocuments(); ssrc.MyContent.Config = ssrcc.ToString(); ssrc.Save(); } } } public void ClearEnhancedSectionLink() { // for this source section, clear any enhanced flags in connected section // where the enhanced type is "T", i.e. title only if (!IsSection) return; SectionConfig sc = MyConfig as SectionConfig; if (sc.Section_LnkEnh != "T" || sc.MyEnhancedDocuments == null || sc.MyEnhancedDocuments.Count == 0) return; foreach (EnhancedDocument ed in sc.MyEnhancedDocuments) { using (Section s = Section.Get(ed.ItemID)) { // have to get config from a SectionInfo, it is null off of this section (not sure why) SectionInfo si = SectionInfo.Get(ed.ItemID); SectionConfig esc = si.MyConfig as SectionConfig; esc.MyEnhancedDocuments.Clear(); esc.SaveEnhancedDocuments(); s.MyContent.Config = esc.ToString(); s.Save(); } } sc.Section_LnkEnh = null; using (Section mysect = Section.Get(ItemID)) { mysect.MyContent.Config = sc.ToString(); mysect.Save(); } } #endregion #region ParentNoteOrCaution private bool _ParentNoteOrCautionLoaded = false; private ItemInfo _ParentNoteOrCaution; public ItemInfo ParentNoteOrCaution { get { if (!_ParentNoteOrCautionLoaded) { ItemInfo parent = ActiveParent as ItemInfo; if (parent != null) { if (parent.IsCautionPart || parent.IsNotePart) _ParentNoteOrCaution = parent; else if (!parent.IsHigh) { _ParentNoteOrCaution = parent.ParentNoteOrCaution; } } _ParentNoteOrCautionLoaded = true; } return _ParentNoteOrCaution; } } #endregion #region Macro List [NonSerialized] protected List _MyMacros; protected bool _MacrosSetup = false; public List MyMacros { get { if (!_MacrosSetup) SetupMacros(); return _MyMacros; } set { _MyMacros = value; } } private void SetupMacros() { if (FormatStepData == null) return; // see if each macro should be printed based on its attributes and the item we're on. // Attributes to check are NotInRNO, i.e. only add this macro to the result list if // the item is not in the RNO column. Also, Groupings is used to only have the macro if // there are N or more of the type in the grouping. List tmp = new List(); StepData myStepData = (FormatStepData.TextSubFollowsTextStyle && ParentNoteOrCaution != null) ? ParentNoteOrCaution.FormatStepData : FormatStepData; // foreach (Macro macro in ActiveFormat.PlantFormat.FormatData.StepDataList[FormatStepType].TabData.MacroList) foreach (Macro macro in myStepData.TabData.MacroList) { bool addToList = true; if (macro.NotInRNO && IsInRNO) addToList = false; if (((MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_DontDoCheckOffs) == E_DocStructStyle.DSS_DontDoCheckOffs) && macro.Name.ToUpper() == "CHECKOFF") addToList = false; if (macro.Grouping != null && macro.Grouping > 0) { int count = 0; ItemInfo ii = FirstSibling; while (ii != null) { if (ii.MyContent.Type == MyContent.Type) count++; ii = ii.NextItem; } if (count <= macro.Grouping) addToList = false; } //CSM F2024 - 080: For South Texas - if initial line is disabled for this step, do not add the macro if (macro.Name.ToUpper() == "CHECKOFF" && ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ShowInitialLineDisable && !string.IsNullOrEmpty(FormatStepData?.TabData?.MacroEditTag) && FormatStepData.TabData.MacroEditTag == "_" && IsInitialLineDisabled) addToList = false; if (addToList) tmp.Add(macro); } if (tmp.Count > 0) _MyMacros = tmp; } //CSM F2024 - 080: For South Texas - check if initial line is disabled for this step public bool IsInitialLineDisabled { get { if (!IsStep) return false; StepConfig sc = MyConfig as StepConfig; return sc.Step_DisableInitialLine; } } #endregion #region UseSmartTemplate // TemplateIndex is for Calvert only: private int _TemplateIndex = -2; // -2 not set; -1 not a template public int TemplateIndex { get { if (_TemplateIndex == -2) { _TemplateIndex = GetSmartTemplateTopLevelIndx(); if (_TemplateIndex != -1) { if (!IsHigh) _TemplateIndex = GetSmartTemplateIndex(_TemplateIndex, MyContent.Text); } } return _TemplateIndex; } set { _TemplateIndex = value; } } private int? _TemplateChildColumnMode = null; public int TemplateChildColumnMode { get { if (_TemplateChildColumnMode == null) { if (TemplateIndex >= 0) { _TemplateChildColumnMode = ActiveFormat.PlantFormat.FormatData.Templates[TemplateIndex].nocolm; if (_TemplateChildColumnMode == 0) _TemplateChildColumnMode = 1; // 0 is default, set to 1 column } else _TemplateChildColumnMode = -1; } return _TemplateChildColumnMode ?? -1; } } private int? _TemplateColumnMode = null; public int TemplateColumnMode { get { if (_TemplateColumnMode == null) { ItemInfo pi = ActiveParent as ItemInfo; if (pi != null) { if (!pi.IsStep) // only steps are in template _TemplateColumnMode = -1; else if (pi.FormatStepData.UseOldTemplate) _TemplateColumnMode = pi.TemplateChildColumnMode; else _TemplateColumnMode = pi.TemplateColumnMode; // go up parents until find of columnmode or section } } return _TemplateColumnMode ?? -1; } } public bool IsInTemplate() // is this step defined by template, i.e. included in template list { if (IsStep && ActiveFormat.PlantFormat.FormatData.TopTemplateTypes != null && ActiveFormat.PlantFormat.FormatData.TopTemplateTypes.ContainsKey((int)MyContent.Type - 20001)) return true; return false; } public bool IsWithInSingleColumnTemplate() // is this step within a step defined by a 'single-column' template item { if (IsStep && ActiveFormat.PlantFormat.FormatData.TopTemplateTypes != null) { ItemInfo tmp = this; while (tmp.IsStep) { if (tmp.TemplateIndex > 0) { if (ActiveFormat.PlantFormat.FormatData.Templates[tmp.TemplateIndex].nocolm == 0) return true; return false; } tmp = tmp.MyParent; } } return false; } public int GetSmartTemplateTopLevelIndxOfThisType(int oftype) // used for inserting steps { if (ActiveFormat == null) return -1; FormatData formatData = ActiveFormat.PlantFormat.FormatData; if (formatData.TopTemplateTypes == null || formatData.TopTemplateTypes.Count == 0) return -1; if (formatData.TopTemplateTypes.ContainsKey(oftype - 20001)) return formatData.TopTemplateTypes[oftype - 20001]; return -1; } public int GetSmartTemplateTopLevelIndx() { if (FormatStepData == null) return -1; FormatData formatData = ActiveFormat.PlantFormat.FormatData; if (formatData.TopTemplateTypes == null || formatData.TopTemplateTypes.Count == 0) return -1; ItemInfo tmp = this; while (!tmp.IsSection) { if (formatData.TopTemplateTypes.ContainsKey((int)tmp.MyContent.Type - 20001)) return formatData.TopTemplateTypes[(int)tmp.MyContent.Type - 20001]; tmp = tmp.MyParent; } return -1; } public int GetSmartTemplateIndex(int topIndx, int curStepType) { FormatData formatData = ActiveFormat.PlantFormat.FormatData; if (formatData.TopTemplateTypes == null || formatData.TopTemplateTypes.Count == 0) return -1; int indx = topIndx; int curType = curStepType - 20001; while (indx < formatData.Templates.Count) { // now see if we're on the topType, if so, look under this one // for the step type that we're on. If found return the index of it. if (formatData.Templates[indx].type == curType) return indx; indx++; } return -1; // didn't find this step type in the template width override list. } // GetSmartTemplateIndex(int topIndx, string strtxt): Added for Calvert Alarms since their // template also uses the text, not just the type, to find a match in the template. public int GetSmartTemplateIndex(int topIndx, string strtxt) { string txt = strtxt.Replace(@"\u160?", " "); if (ActiveFormat == null) return -1; FormatData formatData = ActiveFormat.PlantFormat.FormatData; if (formatData.TopTemplateTypes == null || formatData.TopTemplateTypes.Count == 0) return -1; int indx = topIndx; while (indx < formatData.Templates.Count) { if (IsHigh && formatData.Templates[indx].type == (MyContent.Type - 20001)) return indx; if (txt == null && formatData.Templates[indx].type == (MyContent.Type - 20001)) return indx; // now see if we're on the topType, if so, look under this one for the step type // that we're on, the TEXT ALSO NEEDS TO MATCH. If found return the index of it. if (txt != null && formatData.Templates[indx].text != null && (txt.Trim() == formatData.Templates[indx].text.Trim()) && ((MyContent.Type - 20001) == formatData.Templates[indx].type)) return indx; indx++; } return -1; // didn't find this step type in the template width override list. } #endregion #region CheckOffs private string _SectionCheckOffHeader; public string SectionCheckOffHeader { get { if (_SectionCheckOffHeader == null) { if (ActiveSection == null) return _SectionCheckOffHeader; // first check if format has checkoff data, including checkoffheaders. ProcData pd = ActiveFormat.PlantFormat.FormatData.ProcData; if (pd.CheckOffData == null || pd.CheckOffData.CheckOffHeaderList == null || pd.CheckOffData.CheckOffHeaderList.MaxIndex <= 1) _SectionCheckOffHeader = string.Empty; else { SectionConfig sc = ActiveSection.MyConfig as SectionConfig; if (sc == null) _SectionCheckOffHeader = string.Empty; else if (sc.Section_CheckoffHeaderSelection <= 0) _SectionCheckOffHeader = string.Empty; else { _SectionCheckOffHeader = pd.CheckOffData.CheckOffHeaderList[sc.Section_CheckoffHeaderSelection].CheckOffHeading; if (_SectionCheckOffHeader.Contains("{NO HEADING}")) _SectionCheckOffHeader = string.Empty; } } } return _SectionCheckOffHeader; } } public bool SectionHasCheckOffs() { // To determine if the section has a checkoff... // Section won't have checkoffs if there is no checkofflist, or ProcData pd = ActiveFormat.PlantFormat.FormatData.ProcData; int maxindx = pd.CheckOffUCF ? pd.CheckOffData.CheckOffList.MaxIndex : pd.CheckOffData.CheckOffList.MaxIndexNoInherit; if (pd.CheckOffData == null || pd.CheckOffData.CheckOffList == null || maxindx <= 0) return false; if (pd.CheckOffData.CheckOffHeaderList == null || pd.CheckOffData.CheckOffHeaderList.MaxIndex <= 1) return true; //if (pd.CheckOffData == null || pd.CheckOffData.CheckOffHeaderList == null || pd.CheckOffData.CheckOffHeaderList.Count <= 1) return false; // To find whether the step has a checkoff, first check that the section // has a check off header. If it doesn't, just return -1. // if config item is set for checkoffindex, use it. If it == 0, then use // the section default. SectionConfig sc = ActiveSection.MyConfig as SectionConfig; if (sc == null) return false; if (sc.Section_CheckoffHeaderSelection < 0) return false; return true; } public int CheckOffIndex() { StepConfig stc = MyConfig as StepConfig; if (stc == null) return 0; //section default. if (stc != null && stc.Step_CheckOffIndex == 1) return -1; // index of 1, always means 'No Checkoff' return stc.Step_CheckOffIndex; } private int SectionConfigCheckOffIndex { get { SectionConfig sc = ActiveSection.MyConfig as SectionConfig; return sc.Section_CheckoffListSelection; } } private int SectionDefaultCheckOffIndex() { ProcData pd = ActiveFormat.PlantFormat.FormatData.ProcData; int maxindx = pd.CheckOffUCF ? pd.CheckOffData.CheckOffList.MaxIndex : pd.CheckOffData.CheckOffList.MaxIndexNoInherit; if (pd.CheckOffData != null && pd.CheckOffData.CheckOffList != null && maxindx == 2) return 0; // if only two items, first is macro - use it. SectionConfig sc = ActiveSection.MyConfig as SectionConfig; return sc.Section_CheckoffListSelection; } public CheckOff GetCheckOffStep() { if (!IsStep) return null; if (SectionDefaultEnabled) return SectionDefaultEnabledCheckOff; if (!SectionHasCheckOffs()) return null; int stpCoIndx = CheckOffIndex(); // this step has a checkoff defined if (stpCoIndx == -1) return null; if (stpCoIndx > 1) { if (ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffUCF && stpCoIndx >= 100) { // get index, if greater than 100, store that - otherwise store index down list. // if this format does not have ucf signoffs, indx is just the selected index from the combo box. foreach (CheckOff co in ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList) { if (stpCoIndx == co.Index) { stpCoIndx = (int)co.Index; break; } } } return ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList[stpCoIndx]; // DO override of CheckOffList[] to get ucf } int sectCoIndx = SectionDefaultCheckOffIndex(); // no checkoff on step, see if there is a section default. if (sectCoIndx == -1) return null; if ((ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffOnHLSOnly && IsHigh) || (!ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffOnHLSOnly && IsLowestLevelStep && stpCheckOff)) // && !RNOsHighHasCheckOff())) return ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList[sectCoIndx]; return null; } private bool stpCheckOff { get { StepConfig stc = MyConfig as StepConfig; return (stc != null && stc.Step_CheckOffIndex == 0); } } private CheckOff SectionDefaultEnabledCheckOff { get { int sectCoIndx = SectionConfigCheckOffIndex; // no checkoff on step, see if there is a section default. if (IsLowestLevelStep) // && !RNOsHighHasCheckOff())) return ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList[sectCoIndx]; return null; } } private bool SectionDefaultEnabled { get { ProcData pd = ActiveFormat.PlantFormat.FormatData.ProcData; int maxindx = pd.CheckOffUCF ? pd.CheckOffData.CheckOffList.MaxIndex : pd.CheckOffData.CheckOffList.MaxIndexNoInherit; if (pd.CheckOffData != null && pd.CheckOffData.CheckOffList != null && maxindx == 2 && pd.CheckOffData.CheckOffList[0].MenuItem == "Enabled") return true; // if only two items, first is macro - use it. return false; } } private bool IsLowestLevelStep { get { return (!(IsCaution || IsNote || IsTable || IsFigure || Steps != null || MyParent.IsCaution || MyParent.IsNote)); } } private bool RNOsHighHasCheckOff() { // If this is a High Level Step's RNO, the checkoff would be placed on the HLS, not the RNO. if (IsRNOPart && MyParent.IsHigh && MyParent.CheckOffIndex() != -1) return true; return false; } #endregion #region JCB Item Status private bool _IsItemNew = false; public bool IsItemNew { get { ProcedureInfo pi = this.MyProcedure; if (pi != null) _IsItemNew = (this.DTS > pi.DTS); return _IsItemNew; } } private bool _IsItemChanged; public bool IsItemChanged { get { ProcedureInfo pi = this.MyProcedure; if (pi != null) _IsItemChanged = (this.MyContent.DTS > pi.DTS); return _IsItemChanged; } } #endregion // C2020-018 used for a more descriptive warning message when deleting Procedures, Sections, Steps that have incoming transitions pointing to them public string GetTypeDescription() { if (this != null) { if (this.IsProcedure) return "Procedure"; if (this.IsSection) return "Section"; if (this.IsHigh) return "Step"; if (this.IsSubStep) return "SubStep"; } return "Item"; } } #endregion ItemInfo #region Tab public class MetaTag { public VE_Font MyFont; public ContentAlignment Justify = ContentAlignment.MiddleLeft; private string _Text; // may include tokens, such as macros for circles/diamonds, etc public string Text { get { return _Text; } set { _Text = value; } } public string CleanText; // all tokens removed public MetaTag() { } public MetaTag(VE_Font font) { MyFont = new VE_Font(font.XmlNode); } } public class Tab : MetaTag { private string _AltPrintTab = null; public string AltPrintTab { get { return _AltPrintTab; } set { _AltPrintTab = value; } } private string _BasicTab = null; public string BasicTab { get { return _BasicTab; } set { _BasicTab = value; } } private bool _RemovedStyleUnderline = false; public bool RemovedStyleUnderline { get { return _RemovedStyleUnderline; } set { _RemovedStyleUnderline = value; } } public Tab(VE_Font font) { MyFont = font; } public override string ToString() { return this.CleanTextNoSymbols; } public int Offset; public int Position; private float _RNOTabWidthAdjust = 0; public float RNOTabWidthAdjust { get { return _RNOTabWidthAdjust; } set { _RNOTabWidthAdjust = value; } } public int AsteriskOffset; private static Regex _ReplaceSymbols = new Regex("^[^0-9A-Za-z]*"); // trim anything that isn't an ascii alpha/numeric from the beginning public string CleanTextNoSymbols { get { // this trims off any symbols at the start of the tab return _ReplaceSymbols.Replace(CleanText, "").Replace("#", ""); } } } public class Header : MetaTag { } #endregion #region ItemInfoList public partial class ItemInfoList { //public void ToXml(XmlNode xn) //{ // foreach (ItemInfo itemInfo in this) // { // itemInfo.ToXml(xn); // } //} public ItemInfoList(ItemInfo itemInfo) { AddItem(itemInfo); } public void AddItemInfo(ItemInfo ii) { AddItem(ii); } public static ItemInfoList GetMoveItem(int? itemID, int index) { try { ItemInfoList tmp = DataPortal.Fetch(new MoveItemCriteria(itemID, index)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } public static ItemInfoList GetList(int? itemID, int type) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListCriteria(itemID, type)); ItemInfo.AddList(tmp); tmp.AddEvents(); #if (!ItemWithContent) // If ItemWithContent is set, the content is returned with the ItemInfoList ContentInfoList.GetList(itemID); // Performance - Load All Content #endif return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } public static ItemInfoList GetListTranTo() { try { ItemInfoList tmp = DataPortal.Fetch(new ItemTranToListCriteria()); ItemInfo.AddList(tmp); tmp.AddEvents(); #if (!ItemWithContent) // If ItemWithContent is set, the content is returned with the ItemInfoList ContentInfoList.GetList(itemID); // Performance - Load All Content #endif return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetTranToList", ex); } } public static ItemInfoList GetListTranFrom() { try { ItemInfoList tmp = DataPortal.Fetch(new ItemTranFromListCriteria()); ItemInfo.AddList(tmp); tmp.AddEvents(); #if (!ItemWithContent) // If ItemWithContent is set, the content is returned with the ItemInfoList ContentInfoList.GetList(itemID); // Performance - Load All Content #endif return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetTranFromList", ex); } } public static ItemInfoList GetListByPartType(E_FromType fromType) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListPartTypeCriteria(fromType)); ItemInfo.AddList(tmp); tmp.AddEvents(); #if (!ItemWithContent) // If ItemWithContent is set, the content is returned with the ItemInfoList ContentInfoList.GetList(itemID); // Performance - Load All Content #endif return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. // Found various inconsistencies in the reports so adding this to manually sort //instead of binding the sort to 1 or 2 individual fields public List SortedList(bool sortbyFoundRoid = false) { List tmp = new List(this); if (sortbyFoundRoid) { // Priority of Sorting order: // 1. FoundRoid (by Referenced Object ID) // 2. SearchDVPath_clean (Which Procedure Set it is in - I.E. EOPs, Background, SAMGs, etc...) // 3. Keep in order of the Procedures within the set // 4. Keep in the order of the Section within the Procedure // 5. NumericSortNumber - numeric part of the HLS if there is one // 6. Substep Tab - will sort as a string since combined numbers/text tmp.Sort(comparison: delegate (ItemInfo x, ItemInfo y) { int cmp = 0; int FoundROID_cmp = x.FoundROID.CompareTo(y.FoundROID); switch (FoundROID_cmp) { case int result when result < 0: cmp -= 10000000; break; case int result when result == 0: break; case int result when result > 0: cmp += 10000000; break; default: break; } int DVPath_cmp = x.SearchDVPath_clean.CompareTo(y.SearchDVPath_clean); switch (DVPath_cmp) { case int result when result < 0: cmp -= 1000000; break; case int result when result == 0: break; case int result when result > 0: cmp += 1000000; break; default: break; } if (x.MyProcedure != null && y.MyProcedure != null) { cmp += (x.MyProcedure.Ordinal.CompareTo(y.MyProcedure.Ordinal) * 100000); } if (x.ActiveSection != null && y.ActiveSection != null) { cmp += (x.ActiveSection.Ordinal.CompareTo(y.ActiveSection.Ordinal) * 100000); } cmp += x.NumericSortNumber.CompareTo(y.NumericSortNumber) * 10; if (cmp == 0) { int StepTab_cmp = (x.BuildStepTab()).CompareTo(y.BuildStepTab()); switch (StepTab_cmp) { case int result when result < 0: cmp -= 1; break; case int result when result == 0: break; case int result when result > 0: cmp += 1; break; default: break; } } return cmp; }); } else { // Priority of Sorting order: // 1. SearchDVPath_clean (Which Procedure Set it is in - I.E. EOPs, Background, SAMGs, etc...) // 2. Keep in order of the Procedures within the set // 3. Keep in the order of the Section within the Procedure // 4. NumericSortNumber - numeric part of the HLS if there is one // 5. Substep Tab - will sort as a string since combined numbers/text // 6. FoundRoid (by Referenced Object ID) tmp.Sort(comparison: delegate (ItemInfo x, ItemInfo y) { int cmp = 0; int DVPath_cmp = x.SearchDVPath_clean.CompareTo(y.SearchDVPath_clean); switch (DVPath_cmp) { case int result when result < 0: cmp -= 10000000; break; case int result when result == 0: break; case int result when result > 0: cmp += 10000000; break; default: break; } if (x.MyProcedure != null && y.MyProcedure != null) { cmp += (x.MyProcedure.Ordinal.CompareTo(y.MyProcedure.Ordinal) * 1000000); } if (x.ActiveSection != null && y.ActiveSection != null) { cmp += (x.ActiveSection.Ordinal.CompareTo(y.ActiveSection.Ordinal) * 100000); } cmp += (x.NumericSortNumber.CompareTo(y.NumericSortNumber) * 100); if (cmp == 0) { int StepTab_cmp = (x.BuildStepTab()).CompareTo(y.BuildStepTab()); switch (StepTab_cmp) { case int result when result < 0: cmp -= 10; break; case int result when result == 0: break; case int result when result > 0: cmp += 10; break; default: break; } } int FoundROID_cmp = x.FoundROID.CompareTo(y.FoundROID); switch (FoundROID_cmp) { case int result when result < 0: cmp -= 1; break; case int result when result == 0: break; case int result when result > 0: cmp += 1; break; default: break; } return cmp; }); } return tmp; } [Serializable()] private class MoveItemCriteria { public MoveItemCriteria(int? itemID, int index) { _ItemID = itemID; _Index = index; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } private int _Index; public int Index { get { return _Index; } set { _Index = value; } } } [Serializable()] private class ItemListCriteria { public ItemListCriteria(int? itemID, int type) { _ItemID = itemID; _Type = type; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } private int _Type; public int Type { get { return _Type; } set { _Type = value; } } } [Serializable()] private class ItemTranToListCriteria { } [Serializable()] private class ItemTranFromListCriteria { } [Serializable()] private class ItemListPartTypeCriteria { public ItemListPartTypeCriteria(E_FromType type) { _Type = type; } private E_FromType _Type; public E_FromType Type { get { return _Type; } set { _Type = value; } } } private void DataPortal_Fetch(MoveItemCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "MoveItem"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.Parameters.AddWithValue("@Index", criteria.Index); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = new ItemInfo(dr); //switch ((E_FromType)criteria.Type) //{ // case E_FromType.Procedure: // itemInfo = new ProcedureInfo(dr); // break; // case E_FromType.Section: // itemInfo = new SectionInfo(dr); // break; // default: // itemInfo = new StepInfo(dr); // break; //} IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } private void DataPortal_Fetch(ItemListCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; #if ItemWithContent cm.CommandText = "vesp_ListItemsAndContent"; #else cm.CommandText = "vesp_ListItems"; #endif cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = null; switch ((E_FromType)criteria.Type) { case E_FromType.Procedure: itemInfo = new ProcedureInfo(dr); break; case E_FromType.Section: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } private void DataPortal_Fetch(ItemTranToListCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; #if ItemWithContent cm.CommandText = "vesp_ListItemsTranToAndContent"; #else cm.CommandText = "vesp_ListItemsTranTo"; #endif cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = new ItemInfo(dr); //switch ((E_FromType)criteria.Type) //{ // case E_FromType.Procedure: // itemInfo = new ProcedureInfo(dr); // break; // case E_FromType.Section: // itemInfo = new SectionInfo(dr); // break; // default: // itemInfo = new StepInfo(dr); // break; //} IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } private void DataPortal_Fetch(ItemTranFromListCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; #if ItemWithContent cm.CommandText = "vesp_ListItemsTranFromAndContent"; #else cm.CommandText = "vesp_ListItemsTranFrom"; #endif cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = new ItemInfo(dr); //switch ((E_FromType)criteria.Type) //{ // case E_FromType.Procedure: // itemInfo = new ProcedureInfo(dr); // break; // case E_FromType.Section: // itemInfo = new SectionInfo(dr); // break; // default: // itemInfo = new StepInfo(dr); // break; //} IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } private void DataPortal_Fetch(ItemListPartTypeCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; #if ItemWithContent cm.CommandText = "getItemsByPartTypeAndContent"; #else cm.CommandText = "getItemsByPartType"; #endif cm.Parameters.AddWithValue("@FromType", (int)criteria.Type); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = null; switch (criteria.Type) { case E_FromType.Procedure: itemInfo = new ProcedureInfo(dr); break; case E_FromType.Section: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } public void AddItem(ItemInfo itemInfo) { IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } #region EnhancedSupport #region EnhancedGetTextDifferences public static ItemInfoList GetListEnhancedTextDifferences(ItemInfo procItem) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListEnhancedTextDifferencesCriteria(procItem.ItemID)); return tmp; } catch (Exception ex) { // Don't crash on Primary Key Problem. Exception ex1 = ex; while (ex1 != null) { if (ex1.Message.Contains("PRIMARY KEY")) return null; ex1 = ex1.InnerException; } throw new DbCslaException("Error on ItemInfoList.GetListEnhancedTextDifferences", ex); } } [Serializable()] private class ItemListEnhancedTextDifferencesCriteria { private int _ProcID; public int ProcID { get { return _ProcID; } set { _ProcID = value; } } public ItemListEnhancedTextDifferencesCriteria(int procid) { _ProcID = procid; } } private void DataPortal_Fetch(ItemListEnhancedTextDifferencesCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ListItemsToRefresh"; cm.Parameters.AddWithValue("@ProcID", criteria.ProcID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = new ItemInfo(dr); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion // EnhancedGetTextDifferences #region EnhancedGetMissingEnh public static ItemInfoList GetListEnhancedForMissing(ItemInfo srcItem, int enhType) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListEnhancedMissingCriteria(srcItem.ItemID, enhType)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetListEnhancedForMissing", ex); } } [Serializable()] private class ItemListEnhancedMissingCriteria { private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } private int _EnhType; public int EnhType { get { return _EnhType; } set { _EnhType = value; } } public ItemListEnhancedMissingCriteria(int itemid, int enhtype) { _ItemID = itemid; _EnhType = enhtype; } } private void DataPortal_Fetch(ItemListEnhancedMissingCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ListUnlinkedItems"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.Parameters.AddWithValue("@EnhType", criteria.EnhType); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = new ItemInfo(dr); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion // EnhancedGetMissingEnh #endregion // EnhancedSupport #region Text Search public static ItemInfoList GetListFromTextSearch(string docVersionList, string stepTypeList, string searchString, int caseSensitive, ItemSearchIncludeLinks includeLinks, bool includeRtfFormatting, bool includeSpecialCharacters, string unitPrefix, string byWordPrefix, string byWordSuffix) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListSearchCriteria(docVersionList, stepTypeList, searchString, caseSensitive, includeLinks, includeRtfFormatting, includeSpecialCharacters, unitPrefix, byWordPrefix, byWordSuffix)); tmp.SourceOfList = "Search"; ItemInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetListFromTextSearch", ex); } } [Serializable()] private class ItemListSearchCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } private string _StepTypeList; public string StepTypeList { get { return _StepTypeList; } set { _StepTypeList = value; } } private string _SearchString; public string SearchString { get { return _SearchString; } set { _SearchString = value; } } private int _CaseSensitive; public int CaseSensitive { get { return _CaseSensitive; } set { _CaseSensitive = value; } } private ItemSearchIncludeLinks _IncludeLinks; public ItemSearchIncludeLinks IncludeLinks { get { return _IncludeLinks; } set { _IncludeLinks = value; } } private bool _IncludeRtfFormatting; public bool IncludeRtfFormatting { get { return _IncludeRtfFormatting; } set { _IncludeRtfFormatting = value; } } private bool _IncludeSpecialCharacters; public bool IncludeSpecialCharacters { get { return _IncludeSpecialCharacters; } set { _IncludeSpecialCharacters = value; } } private string _UnitPrefix; public string UnitPrefix { get { return _UnitPrefix; } set { _UnitPrefix = value; } } // C2020-009: Search - Allow search 'By Word'. // Prefix & Suffix are sql expression to use before/after search string, they limit for alpha or numeric before/after // the search string. These are set in Volian.Controls.Library.DisplaySearch.cs private string _ByWordPrefix; public string ByWordPrefix { get { return _ByWordPrefix; } set { _ByWordPrefix = value; } } private string _ByWordSuffix; public string ByWordSuffix { get { return _ByWordSuffix; } set { _ByWordSuffix = value; } } public ItemListSearchCriteria(string docVersionList, string stepTypeList, string searchString, int caseSensitive, ItemSearchIncludeLinks includeLinks, bool includeRtfFormatting, bool includeSpecialCharacters, string unitPrefix, string byWordPrefix, string byWordSuffix) { _DocVersionList = docVersionList; _StepTypeList = stepTypeList; _SearchString = searchString; _CaseSensitive = caseSensitive; _IncludeLinks = includeLinks; _IncludeRtfFormatting = includeRtfFormatting; _IncludeSpecialCharacters = includeSpecialCharacters; _UnitPrefix = unitPrefix; _ByWordPrefix = byWordPrefix; _ByWordSuffix = byWordSuffix; } } private void DataPortal_Fetch(ItemListSearchCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_SearchItemAndChildrenNewByWord"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@StepTypeList", criteria.StepTypeList); cm.Parameters.AddWithValue("@SearchString", criteria.SearchString); cm.Parameters.AddWithValue("@CaseSensitive", criteria.CaseSensitive); cm.Parameters.AddWithValue("@IncludeLinks", (int)criteria.IncludeLinks); cm.Parameters.AddWithValue("@IncludeRtfFormatting", criteria.IncludeRtfFormatting ? 1 : 0); cm.Parameters.AddWithValue("@IncludeSpecialCharacters", criteria.IncludeSpecialCharacters ? 1 : 0); cm.Parameters.AddWithValue("@UnitPrefix", criteria.UnitPrefix); cm.Parameters.AddWithValue("@ByWordPrefix", criteria.ByWordPrefix); cm.Parameters.AddWithValue("@ByWordSuffix", criteria.ByWordSuffix); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } itemInfo.AddContent(dr); itemInfo._SearchDVPath = dr.GetString("DVPath"); itemInfo._SearchPath = dr.GetString("Path"); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region RO Search public static ItemInfoList GetListFromROSearch(string docVersionList, string stepTypeList, string roSearchString, string unitPrefix) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListROSearchCriteria(docVersionList, stepTypeList, roSearchString, unitPrefix)); ItemInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } [Serializable()] private class ItemListROSearchCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } private string _StepTypeList; public string StepTypeList { get { return _StepTypeList; } set { _StepTypeList = value; } } private string _ROSearchString; public string ROSearchString { get { return _ROSearchString; } set { _ROSearchString = value; } } private string _UnitPrefix; public string UnitPrefix { get { return _UnitPrefix; } set { _UnitPrefix = value; } } public ItemListROSearchCriteria(string docVersionList, string stepTypeList, string roSearchString, string unitPrefix) { _DocVersionList = docVersionList; _StepTypeList = stepTypeList; _ROSearchString = roSearchString; _UnitPrefix = unitPrefix; } } private void DataPortal_Fetch(ItemListROSearchCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_SearchROItemAndChildren"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@StepTypeList", criteria.StepTypeList); cm.Parameters.AddWithValue("@ROSearchString", criteria.ROSearchString); cm.Parameters.AddWithValue("@UnitPrefix", criteria.UnitPrefix); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { string FoundROs = ""; while (dr.Read()) { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } itemInfo.AddContent(dr); itemInfo._SearchDVPath = dr.GetString("DVPath"); itemInfo._SearchPath = dr.GetString("Path"); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region Annotation Search public static ItemInfoList GetListFromAnnotationSearch(string docVersionList, string stepTypeList, string annotationTypeList, string searchString, bool caseSensitive, string unitPrefix) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListAnnotationSearchCriteria(docVersionList, stepTypeList, annotationTypeList, searchString, caseSensitive, unitPrefix)); ItemInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } [Serializable()] private class ItemListAnnotationSearchCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } private string _StepTypeList; public string StepTypeList { get { return _StepTypeList; } set { _StepTypeList = value; } } private string _AnnotationTypeList; public string AnnotationTypeList { get { return _AnnotationTypeList; } set { _AnnotationTypeList = value; } } private string _SearchString; public string SearchString { get { return _SearchString; } set { _SearchString = value; } } private bool _CaseSensitive; public bool CaseSensitive { get { return _CaseSensitive; } set { _CaseSensitive = value; } } private string _UnitPrefix; public string UnitPrefix { get { return _UnitPrefix; } set { _UnitPrefix = value; } } public ItemListAnnotationSearchCriteria(string docVersionList, string stepTypeList, string annotationTypeList, string searchString, bool caseSensitive, string unitPrefix) { _DocVersionList = docVersionList; _StepTypeList = stepTypeList; _AnnotationTypeList = annotationTypeList; _SearchString = searchString; _CaseSensitive = caseSensitive; _UnitPrefix = unitPrefix; } } private void DataPortal_Fetch(ItemListAnnotationSearchCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_SearchAnnotationItemAndChildren"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@StepTypeList", criteria.StepTypeList); cm.Parameters.AddWithValue("@AnnotationTypeList", criteria.AnnotationTypeList); cm.Parameters.AddWithValue("@SearchString", criteria.SearchString); cm.Parameters.AddWithValue("@CaseSensitive", criteria.CaseSensitive ? 1 : 0); cm.Parameters.AddWithValue("@UnitPrefix", criteria.UnitPrefix); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } itemInfo.AddContent(dr); itemInfo._SearchDVPath = dr.GetString("DVPath"); itemInfo._SearchPath = dr.GetString("Path"); itemInfo._SearchAnnotationID = dr.GetInt32("SearchAnnotationID"); itemInfo._SearchAnnotationText = dr.GetString("SearchText"); itemInfo._SearchAnnotationType = dr.GetString("AnnotationType"); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region Transition Search // added stepTypeList parameter to allow a transition search is selected step elements (B2015-055) public static ItemInfoList GetListFromTransitionSearch(string docVersionList, int tranType, string tranCategory, string stepTypeList) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListTransitionSearchCriteria(docVersionList, tranType, tranCategory, stepTypeList)); ItemInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetListFromTransitionSearch", ex); } } [Serializable()] private class ItemListTransitionSearchCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } } private int _TranType; public int TranType { get { return _TranType; } } private string _TranCategory; public string TranCategory { get { return _TranCategory; } } // added stepTypeList parameter to allow a transition search is selected step elements (B2015-055) private string _StepTypeList; public string StepTypeList { get { return _StepTypeList; } } public ItemListTransitionSearchCriteria(string docVersionList, int tranType, string tranCategory, string stepTypeList) { _DocVersionList = docVersionList; _TranType = tranType; _TranCategory = tranCategory; _StepTypeList = stepTypeList; } } private void DataPortal_Fetch(ItemListTransitionSearchCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_SearchTransitions"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@TranType", criteria.TranType); cm.Parameters.AddWithValue("@TranCategory", criteria.TranCategory); // added stepTypeList parameter to allow a transition search is selected step elements (B2015-055) cm.Parameters.AddWithValue("@StepTypeList", criteria.StepTypeList); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } itemInfo.AddContent(dr); itemInfo._SearchDVPath = dr.GetString("DVPath"); itemInfo._SearchPath = dr.GetString("Path"); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region RO Reports public static ItemInfoList GetListFromROReport(string docVersionList, string stepTypeList, string roSearchString, string unitPrefix) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListROReportCriteria(docVersionList, stepTypeList, roSearchString, unitPrefix)); ItemInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } [Serializable()] private class ItemListROReportCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } private string _StepTypeList; public string StepTypeList { get { return _StepTypeList; } set { _StepTypeList = value; } } private string _ROSearchString; public string ROSearchString { get { return _ROSearchString; } set { _ROSearchString = value; } } private string _UnitPrefix; public string UnitPrefix { get { return _UnitPrefix; } set { _UnitPrefix = value; } } public ItemListROReportCriteria(string docVersionList, string stepTypeList, string roSearchString, string unitPrefix) { _DocVersionList = docVersionList; _StepTypeList = stepTypeList; _ROSearchString = roSearchString; _UnitPrefix = unitPrefix; } } private void DataPortal_Fetch(ItemListROReportCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_GetROUsagesByProcedure"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@StepTypeList", criteria.StepTypeList); cm.Parameters.AddWithValue("@ROSearchString", criteria.ROSearchString); cm.Parameters.AddWithValue("@UnitPrefix", criteria.UnitPrefix); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { string FoundROs = ""; while (dr.Read()) { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } itemInfo.AddContent(dr); itemInfo._SearchDVPath = dr.GetString("DVPath"); itemInfo._SearchPath = dr.GetString("Path"); itemInfo._FoundROID = dr.GetString("FoundROID"); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region Applicability Search public static ItemInfoList GetListFromApplicabilitySearch(string docVersionList, string stepTypeList, string searchString, int caseSensitive, ItemSearchIncludeLinks includeLinks, bool includeRtfFormatting, bool includeSpecialCharacters, string unitPrefix, string applicSetting) { try { ItemInfoList tmp = DataPortal.Fetch(new ItemListApplicabilitySearchCriteria(docVersionList, stepTypeList, searchString, caseSensitive, includeLinks, includeRtfFormatting, includeSpecialCharacters, unitPrefix, applicSetting)); tmp.SourceOfList = "Search"; ItemInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetListFromApplicabilitySearch", ex); } } [Serializable()] private class ItemListApplicabilitySearchCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } private string _StepTypeList; public string StepTypeList { get { return _StepTypeList; } set { _StepTypeList = value; } } private string _SearchString; public string SearchString { get { return _SearchString; } set { _SearchString = value; } } private int _CaseSensitive; public int CaseSensitive { get { return _CaseSensitive; } set { _CaseSensitive = value; } } private ItemSearchIncludeLinks _IncludeLinks; public ItemSearchIncludeLinks IncludeLinks { get { return _IncludeLinks; } set { _IncludeLinks = value; } } private bool _IncludeRtfFormatting; public bool IncludeRtfFormatting { get { return _IncludeRtfFormatting; } set { _IncludeRtfFormatting = value; } } private bool _IncludeSpecialCharacters; public bool IncludeSpecialCharacters { get { return _IncludeSpecialCharacters; } set { _IncludeSpecialCharacters = value; } } private string _UnitPrefix; public string UnitPrefix { get { return _UnitPrefix; } set { _UnitPrefix = value; } } private string _ApplicSetting; public string ApplicSetting { get { return _ApplicSetting; } set { _ApplicSetting = value; } } public ItemListApplicabilitySearchCriteria(string docVersionList, string stepTypeList, string searchString, int caseSensitive, ItemSearchIncludeLinks includeLinks, bool includeRtfFormatting, bool includeSpecialCharacters, string unitPrefix, string applicSetting) { _DocVersionList = docVersionList; _StepTypeList = stepTypeList; _SearchString = searchString; _CaseSensitive = caseSensitive; _IncludeLinks = includeLinks; _IncludeRtfFormatting = includeRtfFormatting; _IncludeSpecialCharacters = includeSpecialCharacters; _UnitPrefix = unitPrefix; _ApplicSetting = applicSetting; } } private void DataPortal_Fetch(ItemListApplicabilitySearchCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_SearchSepcifiedApplicability"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@StepTypeList", criteria.StepTypeList); cm.Parameters.AddWithValue("@SearchString", criteria.SearchString); cm.Parameters.AddWithValue("@CaseSensitive", criteria.CaseSensitive); cm.Parameters.AddWithValue("@IncludeLinks", (int)criteria.IncludeLinks); cm.Parameters.AddWithValue("@IncludeRtfFormatting", criteria.IncludeRtfFormatting ? 1 : 0); cm.Parameters.AddWithValue("@IncludeSpecialCharacters", criteria.IncludeSpecialCharacters ? 1 : 0); cm.Parameters.AddWithValue("@UnitPrefix", criteria.UnitPrefix); cm.Parameters.AddWithValue("@ApplicSetting", criteria.ApplicSetting); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; default: itemInfo = new StepInfo(dr); break; } itemInfo.AddContent(dr); itemInfo._SearchDVPath = dr.GetString("DVPath"); itemInfo._SearchPath = dr.GetString("Path"); IsReadOnly = false; this.Add(itemInfo); IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion } #endregion #region new class TransitionLookup public delegate ProcedureInfo TransitionLookupEvent(object sender, TransitionLookupEventArgs args); public class TransitionLookupEventArgs { private int _ProcID; public int ProcID { get { return _ProcID; } set { _ProcID = value; } } private int _UnitID; public int UnitID { get { return _UnitID; } set { _UnitID = value; } } private DocVersionInfo _MyDocVersion; public DocVersionInfo MyDocVersion { get { return _MyDocVersion; } set { _MyDocVersion = value; } } private TransitionLookup _MyTranLookup; public TransitionLookup MyTranLookup { get { return _MyTranLookup; } set { _MyTranLookup = value; } } public TransitionLookupEventArgs(int procID, int unitID, DocVersionInfo dvi, TransitionLookup tl) { _ProcID = procID; _UnitID = unitID; _MyDocVersion = dvi; _MyTranLookup = tl; } } public partial class TransitionLookup { public event TransitionLookupEvent NewLookupNeeded; private Dictionary> _MyLookups; public Dictionary> MyLookups { get { return _MyLookups; } set { _MyLookups = value; } } private int _ApplicabilityUnit; public int ApplicabilityUnit { get { return _ApplicabilityUnit; } set { _ApplicabilityUnit = value; } } public TransitionLookup(int applicabilityUnit, int procID, Dictionary mylookup) { _MyLookups = new Dictionary>(); _MyLookups.Add(procID, mylookup); _ApplicabilityUnit = applicabilityUnit; } public void AddProcLookup(int procID, Dictionary mylookup) { if (!_MyLookups.ContainsKey(procID)) { _MyLookups.Add(procID, mylookup); //Console.WriteLine("AddProcLookup: {0}", procID); } } public ItemInfo this[int itemID] { get { foreach (Dictionary mylookup in MyLookups.Values) { if (mylookup != null && mylookup.ContainsKey(itemID)) return mylookup[itemID]; } return null; } } public bool ContainsKey(int itemID) { foreach (Dictionary mylookup in MyLookups.Values) { if (mylookup != null && mylookup.ContainsKey(itemID)) return true; } return false; } // B2022-025: memory crash. Dispose was added to the TransitionLookup class to dispose of contents and items loaded in when // resolving transition link text for procedures other than the current one being printed. The transition lookup code // creates objects for a procedure if a transition points (external trans) to it and never disposes of these objects. For // Barakah merged prints with alot of procedures to merge and when the procedures have external transitions, the program // would crash with out of memory. Do not dispose of objects for the current procedure (int procID parameter) - this caused // a crash. public void Dispose(int procID) { foreach (Dictionary mylookup in MyLookups.Values) { if (mylookup != null) { foreach (ItemInfo ii in mylookup.Values) { if (ii.MyProcedure.ItemID != procID) { if (ii.MyContent.ContentParts != null) { foreach (PartInfo pi in ii.MyContent.ContentParts) pi.Dispose(); ii.MyContent.ContentParts.Dispose(); } if (ii.MyContent.MyGrid != null) ii.MyContent.MyGrid.Dispose(); ii.MyContent.Dispose(); ii.Dispose(); } } mylookup.Clear(); } } MyLookups.Clear(); MyLookups = null; } } #endregion #region ProcedureInfo [Serializable()] public partial class ProcedureInfo : ItemInfo, IVEDrillDownReadOnly { public int _SelectedChildToPrint = 0; //B2023-035 for BNPP Alarms - the unit (child) that was selected to print) public int SelectedChildToPrint { get { return _SelectedChildToPrint; } set { _SelectedChildToPrint = value; } } // C2021-027: Procedure level PC/PC. these 2 methods determine whether a procedure is included, either by an integer index // or by a string name of the unit public bool ApplInclude(int ApplicabilityIndex) { if (ActiveFormat.PlantFormat.FormatData.ProcData.ProcAppl) { MyConfig = null; // force refresh ProcedureConfig cfg = MyConfig as ProcedureConfig; return (cfg.MasterSlave_Applicability.GetFlags().Count == 0 || cfg.MasterSlave_Applicability.GetFlags().Contains(ApplicabilityIndex)); } return true; } public bool ApplIncludeFromStr(string s) { // s is the unitname, find this name in list of applicabilities & then see if this one is used if (ActiveFormat.PlantFormat.FormatData.ProcData.ProcAppl) { // get index int i = 1; foreach (string str in MyDocVersion.UnitNames) { if (str == s) break; i++; } ProcedureConfig cfg = MyConfig as ProcedureConfig; return (cfg.MasterSlave_Applicability.GetFlags().Count == 0 || cfg.MasterSlave_Applicability.GetFlags().Contains(i)); } return true; } private bool? _ProcHasSupInfoData = null; public bool ProcHasSupInfoData { get { if (_ProcHasSupInfoData == null) { _ProcHasSupInfoData = GetProcHasSupInfoData(); } return (bool)_ProcHasSupInfoData; } set { _ProcHasSupInfoData = value; } } private bool GetProcHasSupInfoData() { if (Sections != null) // B2017-145 If no sections don't check { foreach (SectionInfo mySection in Sections) { if (mySection.MyDocStyle.SupplementalInformation && mySection.HasSupInfoSteps) return true; } } return false; } public bool CreateEnhanced = false; public string PDFNumber { get { string slashReplace = this.ActiveFormat.PlantFormat.FormatData.PrintData.SlashReplace ?? "_"; return DisplayNumber.Replace("/", slashReplace).Replace("\\", slashReplace).Replace("*", "Master"); } } private DateTime? _ChangeBarDate = null; public DateTime ChangeBarDate { get { if (_ChangeBarDate == null) { _ChangeBarDate = DTS; string cbDTS = (MyConfig as ProcedureConfig).Print_ChangeBarDate; if ((cbDTS ?? "") != "") _ChangeBarDate = DateTime.Parse(cbDTS); } return (DateTime)_ChangeBarDate; } set { _ChangeBarDate = value; } } public Dictionary MyLookup = null; public override void SetupTags() { base.SetupTags(); } protected override void RefreshFields(Item tmp) { base.RefreshFields(tmp); ExtensionRefreshFields(tmp); _ChangeBarDate = null; _ProcedureConfig = null; } #if ItemWithContent public ProcedureInfo(SafeDataReader dr) : base(dr, true) { } #else public ProcedureInfo(SafeDataReader dr) : base(dr) { } #endif private ProcedureInfo() : base() { ;} public new static ProcedureInfo Get(int itemID) { //if (!CanGetObject()) // throw new System.Security.SecurityException("User not authorized to view a Item"); try { ProcedureInfo tmp = GetCachedByPrimaryKey(itemID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteria(itemID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on Item.Get", ex); } } protected new static ProcedureInfo GetCachedByPrimaryKey(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (ItemInfo ii in _CacheByPrimaryKey[key]) if (ii is ProcedureInfo) return ii as ProcedureInfo; return null; } public void MoveProcedure(IVEDrillDownReadOnly pInfo, int index) { MoveItem(pInfo, index); //using (Item ii = Item.Get(this.ItemID)) //{ // ii.MoveItem(pInfo, index); //} } public new Procedure Get() { return (Procedure)(_Editable = Procedure.Get(ItemID)); } //public static void RefreshTransitions(ProcedureInfo tmp) //{ // RefreshTransitions(tmp, null, null); //} public static void RefreshTransitions(ProcedureInfo tmp)//, TransitionInfoList transitionToDisconnected, TransitionInfoList transitionsToNonEditable) { //TransitionsToDisconnected = transitionToDisconnected; //TransitionsToNonEditable = transitionsToNonEditable; TransitionLookup tranLookup = new TransitionLookup(0, tmp.ItemID, tmp.MyLookup); tranLookup.ApplicabilityUnit = tmp.MyDocVersion.DocVersionConfig.SelectedSlave; tranLookup.NewLookupNeeded += new TransitionLookupEvent(GetNewLookup); if (tmp.MyDocVersion.DocVersionConfig.SelectedSlave <= 0) MyRefreshTransitions(tmp, tmp.MyDocVersion, null, tmp, tmp.MyDocVersion, tranLookup); } // B2022-026 RO Memory Reduction code - added ROFstInfo parameter public static void RefreshReferenceObjects(ProcedureInfo tmp, ROFstInfo origROFst) { if (tmp.MyDocVersion.DocVersionConfig.SelectedSlave <= 0) MyRefreshReferenceObjects(tmp, tmp.MyDocVersion, null, tmp.MyDocVersion, origROFst); } //C2022-028 check the RO link text - compare with RO Usage information, annotate RO links that are bad public static void CheckReferenceObjectsLinks(ProcedureInfo tmp) { if (tmp.MyDocVersion.DocVersionConfig.SelectedSlave <= 0) MyCheckROLinks(tmp); } public static void RefreshPageNumTransitions(ProcedureInfo tmp) { TransitionLookup tranLookup = new TransitionLookup(0, tmp.ItemID, tmp.MyLookup); tranLookup.ApplicabilityUnit = tmp.MyDocVersion.DocVersionConfig.SelectedSlave; tranLookup.NewLookupNeeded += new TransitionLookupEvent(GetNewLookup); SetParentSectionAndDocVersionPageNum(tmp, tmp.MyDocVersion, null, tmp, tmp.MyDocVersion, tranLookup); } public void ClearChangeBarOverrides() { try { using (ContentInfoList cil = ContentInfoList.GetClearedCBOverrides(ItemID)) { foreach (ContentInfo ci in cil) { using (Content c = ci.Get()) { // first refresh configs because the ContentInfo.Refresh causes events to occur that refresh screen // and if configs aren't done first, the screen refresh, if based on config data, will not be correct. foreach (ItemInfo ii in ci.ContentItems) ii.RefreshConfig(); ContentInfo.Refresh(c); } } } } catch (Exception ex) { throw new DbCslaException("Error on ProcedureInfo:ClearChangeBarOverrides", ex); } } //jcb add 20120501 item and children by unit // B2023-035 Pass in the selected child (selectedSlave) that was selected from Print public static ProcedureInfo GetItemAndChildrenByUnit(int? itemID, int? parentID, int? unitID, bool isAutomatic = false, int selectedUnitToPrint = 0) { try { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Optional Parameter "bool isAutomatic = false" to disable the RofstLoadingStatus pop-up screen when printing baselines ProcedureInfo tmp = DataPortal.Fetch(new ItemAndChildrenByUnitCriteria(itemID, parentID, unitID)); tmp.SelectedChildToPrint = selectedUnitToPrint; //B2023-035 save the selected child selected from Print AddToCache(tmp); if (tmp.ErrorMessage == "No Record Found") tmp = null; if (tmp != null) { tmp.MyDocVersion.DocVersionConfig.SelectedSlave = (int)unitID; (tmp.MyConfig as ProcedureConfig).SelectedSlave = (int)unitID; TransitionLookup tranLookup = new TransitionLookup((int)unitID, (int)itemID, tmp.MyLookup); tranLookup.NewLookupNeeded += new TransitionLookupEvent(GetNewLookup); //ItemInfo.ResetTicks(); //DateTime dt = DateTime.Now; tmp.FromType = E_FromType.Procedure; SetFromType(tmp); // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Parameter "isAutomatic" to disable the RofstLoadingStatus pop-up screen when printing baselines SetParentSectionAndDocVersion(tmp, tmp.MyDocVersion, null, tmp.MyDocVersion, tranLookup, isAutomatic); // B2022-025: dispose cached items after setting transition text that gets done in SetParentSectionAndDocVersion & collect related garbage // B2022-076: comment out dispose. Needed to resolve page number transitions. Note that since B2022-025 was worked, memory improvements have been done for ROs //tranLookup.Dispose(tmp.ItemID); //tranLookup = null; //GC.Collect(); //TimeSpan ts = DateTime.Now.Subtract(dt); //ticksItems = ts.Ticks - (ticksROUsage + ticksTrans); //ItemInfo.ShowTicks(); } return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } public static ProcedureInfo GetNewLookup(object sender, TransitionLookupEventArgs args) { ProcedureInfo tmp = DataPortal.Fetch(new ItemAndChildrenByUnitCriteria(args.ProcID, 0, args.UnitID)); if (tmp.MyDocVersion != null) { //if (tmp.MyDocVersion.VersionID == args.MyDocVersion.VersionID) //{ // args.MyDocVersion.DocVersionConfig.SelectedSlave = args.UnitID; // (tmp.MyConfig as ProcedureConfig).SelectedSlave = args.UnitID; // ItemInfo.SetParentSectionAndDocVersion(tmp, args.MyDocVersion, null, tmp, args.MyDocVersion); //} //else //{ tmp.MyDocVersion.DocVersionConfig.SelectedSlave = args.UnitID; (tmp.MyConfig as ProcedureConfig).SelectedSlave = args.UnitID; tmp.FromType = E_FromType.Procedure; SetFromType(tmp); ItemInfo.SetParentSectionAndDocVersion(tmp, tmp.MyDocVersion, null, tmp, tmp.MyDocVersion); //} } return tmp; } // Criteria to get Item and children by unit [Serializable()] private class ItemAndChildrenByUnitCriteria { public ItemAndChildrenByUnitCriteria(int? itemID, int? parentID, int? unitID) { _ItemID = itemID; _ParentID = parentID; _UnitID = unitID; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } private int? _ParentID; public int? ParentID { get { return _ParentID; } set { _ParentID = value; } } private int? _UnitID; public int? UnitID { get { return _UnitID; } set { _UnitID = value; } } } // Data Portal to Get Item and Children by unit private void DataPortal_Fetch(ItemAndChildrenByUnitCriteria criteria) { //ItemInfo tmp = null; Dictionary lookup = new Dictionary(); ; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandTimeout = Database.DefaultTimeout; cm.CommandText = "vesp_ListItemAndChildrenByUnit"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.Parameters.AddWithValue("@ParentID", criteria.ParentID); cm.Parameters.AddWithValue("@UnitID", criteria.UnitID); DateTime start = DateTime.Now; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { if (dr.GetInt32("Level") == 0) { //tmp = itemInfo; ReadData(dr); AddContent(dr); lookup[this.ItemID] = this; } else { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; case 2: itemInfo = new StepInfo(dr); break; } // Load Children itemInfo._Ordinal = dr.GetInt32("Ordinal") + 1; itemInfo.AddContent(dr); ItemInfo parent = lookup[dr.GetInt32("ParentID")]; itemInfo._ActiveParent = parent; itemInfo._MyParent = parent; itemInfo._ActiveSection = (itemInfo.IsSection ? itemInfo : parent._ActiveSection); parent.AddPart(dr, itemInfo); lookup.Add(itemInfo.ItemID, itemInfo); } } //Console.WriteLine("I'm here {0}",this.MyContent.ContentPartCount); } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } MyLookup = lookup; } //jcb end add 20120501 item and children by unit #region EnhancedProcedureRefreshTextDifferences public ItemInfoList FindEnhancedProcedureTextDifferences() { // for this enhanced procedure, get a list of differences of text between it and its source document. // Return list is list of items in ENHANCED procedure that need their text refreshed. // first check if enhanced: EnhancedDocuments eds = GetMyEnhancedDocuments(); if (eds == null || eds.Count == 0) return null; if (eds[0].Type != 0) return null; // now get its enhtype from the source: int enhtype = -1; ItemInfo sourceProc = ItemInfo.Get(eds[0].ItemID); if (sourceProc == null) return null; //B2018-142 to allow an un-linked background procedure to be deleted EnhancedDocuments sourceProcEds = sourceProc.GetMyEnhancedDocuments(); foreach (EnhancedDocument spe in sourceProcEds) { if (spe.ItemID == ItemID) enhtype = spe.Type; } if (enhtype == -1) return null; // something went wrong (it should never get to here) // get list of differences from sql. This list does not resolve links and may have other rtf commands. // also this list is source items, not enhanced. ItemInfoList iil = ItemInfoList.GetListEnhancedTextDifferences(this); if (iil == null || iil.Count == 0) return null; // no differences were found. // from sql list, get display text of source items & compare to this procedure's items. This // will determine true 'text' differences. Then return this list. ItemInfoList retiil = null; // new ItemInfoList(null); foreach (ItemInfo ii in iil) { EnhancedDocuments seds = ii.GetMyEnhancedDocuments(); if (seds != null && seds.Count != 0) { ItemInfo srcItem = ItemInfo.Get(seds[0].ItemID); // B2022-049: Copy/paste of enhanced procedure and bad links between source and enhanced. Null reference check if (srcItem != null && srcItem.DisplayTextKeepSpecialChars != ii.DisplayTextKeepSpecialChars) { if (retiil == null) retiil = new ItemInfoList(ii); else retiil.AddItem(ii); } } } return retiil; } public void EnhancedProcedureRefreshTextDifferences(ItemInfoList iil) { // the input list is a list of enhanced items within a procedure where // the text is different between the source and this enhanced item. Refresh // the text in the enhanced item based on the displaytext of the source item. foreach (ItemInfo ii in iil) { // C2019-045: if allowing mods for procedure num/text we don't want to update the enhanced text so only do if not allowing mods: if (!ii.EnhAllowMod()) { EnhancedDocuments seds = ii.GetMyEnhancedDocuments(); if (seds != null && seds.Count != 0) { ItemInfo srcItem = ItemInfo.Get(seds[0].ItemID); using (Item enhItem = Item.Get(ii.ItemID)) { enhItem.MyContent.Text = srcItem.DisplayTextKeepSpecialChars; enhItem.Save(); } } } } return; } #endregion // EnhancedProcedureRefreshTextDifferences #region ProcedureConfig [NonSerialized] private ProcedureConfig _ProcedureConfig; public ProcedureConfig ProcedureConfig { get { if (_ProcedureConfig == null) { _ProcedureConfig = new ProcedureConfig(this); this.MyContent.Changed += new ContentInfoEvent(MyContent_Changed); } return _ProcedureConfig; // return (_ProcedureConfig != null ? _ProcedureConfig : _ProcedureConfig = new ProcedureConfig(this)); } } void MyContent_Changed(object sender) { this.MyContent.Changed += new ContentInfoEvent(MyContent_Changed); } #endregion public new ConfigDynamicTypeDescriptor MyConfig { get { return ProcedureConfig; } set { _ProcedureConfig = null; } } public DocVersionInfo MyDocVersion { get { return ActiveParent as DocVersionInfo; } } public static ProcedureInfo GetItemAndChildren(int? itemID, bool isAutomatic = false) { try { // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Optional Parameter "bool isAutomatic = false" to disable the RofstLoadingStatus pop-up screen when printing baselines ProcedureInfo tmp = DataPortal.Fetch(new ItemAndChildrenCriteria(itemID)); //AddToCache(tmp); if (tmp.ErrorMessage == "No Record Found") tmp = null; if (tmp != null) { int profileDepth = ProfileTimer.Push(">>>> SetParentSectionAndDocVersion"); tmp.FromType = E_FromType.Procedure; SetFromType(tmp); // B2022-107: Display Progress Bar Messages/Statuses when a new ROFST binary file is loaded into the database // Added Parameter "isAutomatic" to disable the RofstLoadingStatus pop-up screen when printing baselines SetParentSectionAndDocVersion(tmp, tmp.MyDocVersion, null, tmp, tmp.MyDocVersion, isAutomatic); ProfileTimer.Pop(profileDepth); } return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } [Serializable()] private class ItemAndChildrenCriteria { public ItemAndChildrenCriteria(int? itemID) { _ItemID = itemID; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } } // Data Portal to Get Item and Children private void DataPortal_Fetch(ItemAndChildrenCriteria criteria) { //ItemInfo tmp = null; Dictionary lookup = new Dictionary(); ; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ListItemAndChildren"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.Parameters.AddWithValue("@ParentID", 0); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { if (dr.GetInt32("Level") == 0) { //tmp = itemInfo; ReadData(dr); AddContent(dr); lookup[this.ItemID] = this; } else { ItemInfo itemInfo = null; int itemType = dr.GetInt32("Type") / 10000; switch (itemType) { case 0: itemInfo = new ProcedureInfo(dr); break; case 1: itemInfo = new SectionInfo(dr); break; case 2: itemInfo = new StepInfo(dr); break; } // Load Children itemInfo.AddContent(dr); ItemInfo parent = lookup[dr.GetInt32("ParentID")]; itemInfo._ActiveParent = parent; itemInfo._ActiveSection = (itemInfo.IsSection ? itemInfo : parent._ActiveSection); parent.AddPart(dr, itemInfo); lookup.Add(itemInfo.ItemID, itemInfo); } } //Console.WriteLine("I'm here {0}",this.MyContent.ContentPartCount); } } } } catch (Exception ex) { Database.LogException("ItemInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ItemInfoList.DataPortal_Fetch", ex); } MyLookup = lookup; } } [Serializable()] public class ProcedureTransitionsCountCommand : CommandBase { private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private int _ProcedureTransitionsCount; public int ProcedureTransitionsCount { get { return _ProcedureTransitionsCount; } } private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } #region Factory Methods public static int Execute(int itemID) { ProcedureTransitionsCountCommand cmd = new ProcedureTransitionsCountCommand(); cmd.ItemID = itemID; cmd = DataPortal.Execute(cmd); return cmd.ProcedureTransitionsCount; } private ProcedureTransitionsCountCommand() { /* require use of factory methods */ } #endregion #region Server-Side code protected override void DataPortal_Execute() { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cmd = new SqlCommand("vesp_ProcedureTransitionsCount", cn)) { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandTimeout = Database.SQLTimeout; cmd.Parameters.AddWithValue("ItemID", _ItemID); _ProcedureTransitionsCount = (int)cmd.ExecuteScalar(); } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ProcedureTransitionsCountCommand Error", ex); throw new ApplicationException("Failure on ProcedureTransitionsCountCommand", ex); } } #endregion } #endregion #region Procedure [Serializable()] public partial class Procedure : Item { public ProcedureInfo MyProcedureInfo /* Return Info version of the current Item */ { get { return ProcedureInfo.Get(ItemID); } } public new static Procedure Get(int itemID) { if (!CanGetObject()) throw new System.Security.SecurityException("User not authorized to view a Item"); try { Item itm = GetCachedByPrimaryKey(itemID); Procedure tmp = itm as Procedure; //Procedure tmp = (Procedure)GetExistingByPrimaryKey(itemID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteria(itemID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on Item.Get", ex); } } public new Procedure Save() { return (Procedure)base.Save(); } public static Procedure MakeProcedure(IVEDrillDownReadOnly parentInfo, ItemInfo previousInfo, string procNumber, string procTitle, int procType) { int newitemid = MakeNewItem(parentInfo, previousInfo, procNumber, procTitle, procType, E_FromType.Procedure); return Procedure.Get(newitemid); } #region ProcedureConfig [NonSerialized] private ProcedureConfig _ProcedureConfig; public ProcedureConfig ProcedureConfig { get { if (_ProcedureConfig == null) { _ProcedureConfig = new ProcedureConfig(this); _ProcedureConfig.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_ProcedureConfig_PropertyChanged); } return _ProcedureConfig; } } private void _ProcedureConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { MyContent.Config = _ProcedureConfig.ToString(); } #endregion public class DisplayTabs { private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } private string _DisplayTabID; public string DisplayTabID { get { return _DisplayTabID; } set { _DisplayTabID = value; } } private string _DisplayTabName; public string DisplayTabName { get { return _DisplayTabName; } set { _DisplayTabName = value; } } public SafeDataReader Dr { get; } public DisplayTabs() { } public DisplayTabs(int itemID, String displayTabID, String displayTabName) { _ItemID = itemID; _DisplayTabID = displayTabID; _DisplayTabName = displayTabName; } public DisplayTabs(SafeDataReader dr) { Dr = dr; } } public static DataTable GetDisplayTabs(int itemID) //, string displayTabID, string displayTabName) { try { DataTable tmp = DataPortal.Fetch(new DisplayTabs(itemID, "", "")); //, displayTabID, displayTabName)); //ItemInfo.AddList(tmp); //tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } private DataTable dt = new DataTable(); private DataTable DataPortal_Fetch(DisplayTabs criteria) { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { try { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "GetDisplayTabData"; cm.CommandTimeout = Database.DefaultTimeout; SqlDataAdapter da = new SqlDataAdapter(cm); da.Fill(dt); cn.Close(); da.Dispose(); return dt; } catch (Exception ex) { //if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemExt.DataPortal_Fetch", ex); throw new DbCslaException("ItemExt.DataPortal_Fetch", ex); } } } } //public static void AddDisplayTabsState(int itemID, string displayTabID, string displayTabName) //{ // try // { // //DisplayTabs tmp = // DataPortal.Fetch(new DisplayTabs(itemID, displayTabID, displayTabName)); //, displayTabID, displayTabName)); // //ItemInfo.AddList(tmp); // //tmp.AddEvents(); // //return tmp; // } // catch (Exception ex) // { // throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); // } //} //private DataTable dt = new DataTable(); //private void DataPortal_Fetch(int itemID, string displayTabID, string displayTabName) //{ // using (SqlConnection cn = Database.VEPROMS_SqlConnection) // { // using (SqlCommand cm = cn.CreateCommand()) // { // try // { // cm.CommandType = CommandType.StoredProcedure; // cm.CommandText = "AddDisplayTabState"; // cm.CommandTimeout = Database.DefaultTimeout; // cm.Parameters.AddWithValue("@ItemID", ItemID); // cm.Parameters.AddWithValue("@displayTabID", displayTabID); // cm.Parameters.AddWithValue("@displayTabName", displayTabName); // cm.ExecuteNonQuery(); // //SqlDataAdapter da = new SqlDataAdapter(cm); // //da.Fill(dt); // //cn.Close(); // //da.Dispose(); // //return dt; // fix // } // catch (Exception ex) // { // //if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemExt.DataPortal_Fetch", ex); // throw new DbCslaException("ItemExt.DataPortal_Fetch", ex); // } // } // } //} public static void AddDisplayTabsState(int itemID, string displayTabID, string displayTabName) //private void DataPortal_Fetch(int itemID, string displayTabID, string displayTabName) { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { try { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "AddDisplayTabState"; cm.CommandTimeout = Database.DefaultTimeout; cm.Parameters.AddWithValue("@ItemID", itemID); cm.Parameters.AddWithValue("@displayTabID", displayTabID); cm.Parameters.AddWithValue("@displayTabName", displayTabName); cm.ExecuteNonQuery(); //SqlDataAdapter da = new SqlDataAdapter(cm); //da.Fill(dt); //cn.Close(); //da.Dispose(); //return dt; // fix } catch (Exception ex) { //if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemExt.AddDisplayTabsState", ex); throw new DbCslaException("ItemExt.AddDisplayTabsState", ex); } } } } } #endregion #region SectionInfo [Serializable()] public partial class SectionInfo : ItemInfo, IVEDrillDownReadOnly { // B2017-192: The two dictionaries were introduced so that the lists off of the section were always found // by the print code that determines what sup info steps go on the facing pages (the code was accessing the // incorrect cached step section sometimes, so the list was not found. // Keeps track of itemids for supplemental info steps where their associated steps would have page breaks. private static Dictionary> _LookupStepSectPageBreaksForSupInfo = new Dictionary>(); public static void ResetLookupStepSectPageBreaksForSupInfo() { _LookupStepSectPageBreaksForSupInfo.Clear(); } public List StepSectPageBreaksForSupInfo { get { if (!_LookupStepSectPageBreaksForSupInfo.ContainsKey(ItemID)) _LookupStepSectPageBreaksForSupInfo.Add(ItemID, new List()); return _LookupStepSectPageBreaksForSupInfo[ItemID]; } } // Keeps track of step section itemids where page breaks occur private static Dictionary> _LookupStepSectPageBreaks = new Dictionary>(); public static void ResetLookupStepSectPageBreaks() { _LookupStepSectPageBreaks.Clear(); } public List StepSectPageBreaks { get { if (!_LookupStepSectPageBreaks.ContainsKey(ItemID)) _LookupStepSectPageBreaks.Add(ItemID, new List()); return _LookupStepSectPageBreaks[ItemID]; } } // Determine if this section contains any Supplemental information steps. This is used for print to determine // whether some of the supinfo processing needs to occur. private bool? _HasSupInfoSteps = null; public bool HasSupInfoSteps { get { if (_HasSupInfoSteps == null) { _HasSupInfoSteps = GetSupInfoSteps(this); } return (bool)_HasSupInfoSteps; } set { _HasSupInfoSteps = value; } } private static bool GetSupInfoSteps(ItemInfo ii) { if (ii.SupInfos != null && ii.SupInfos.Count > 0) return true; if (ii.MyContent.ContentParts != null) foreach (PartInfo pi in ii.MyContent.ContentParts) foreach (ItemInfo iic in pi.MyItems) if (GetSupInfoSteps(iic)) return true; return false; } private bool? _HasStepCheckOffs = null; public bool HasStepCheckOffs { get { if (_HasStepCheckOffs == null) { _HasStepCheckOffs = GetStepCheckOff(this); //Console.WriteLine("{0},'{1}','{2}'", ItemID, ShortPath, _HasStepCheckOffs); } return (bool)_HasStepCheckOffs; } } public bool HasInitials { get { SectionConfig sectCfg = MyConfig as SectionConfig; int sc = sectCfg.Section_CheckoffListSelection; return (sc > 1 || HasStepCheckOffs); } } private static bool GetStepCheckOff(ItemInfo ii) { if (ii is StepInfo && ((ii as StepInfo).MyConfig as StepConfig).Step_CheckOffIndex > 1) return true; if (ii.MyContent.ContentParts != null) foreach (PartInfo pi in ii.MyContent.ContentParts) foreach (ItemInfo iic in pi.MyItems) if (GetStepCheckOff(iic)) return true; return false; } //private int? _TemplateColumnMode public override void SetupTags() { VE_Font font; // F2021-057 used in BNPP1 format if we are only bolding the top section title (header) and this is not the top section title (1st level), // then turn off the bolding of the section tab as well if (ActiveFormat.PlantFormat.FormatData.SectData.SectionHeader.OnlyBoldTopSect && MyParent.IsSection) { VE_Font hdrFont = ActiveFormat.PlantFormat.FormatData.SectData.SectionNumber.Font; font = new VE_Font(hdrFont.Family, (int)hdrFont.Size, E_Style.None, (float)hdrFont.CPI); } else font = ActiveFormat.PlantFormat.FormatData.SectData.SectionNumber.Font; //MyTab = new Tab(ActiveFormat.PlantFormat.FormatData.SectData.SectionNumber.Font); MyTab = new Tab(font); string sectTab = GetSectionTab(false); _MyTab.Text = sectTab; _MyTab.CleanText = sectTab.PadRight(20); MyHeader = new MetaTag(ActiveFormat.PlantFormat.FormatData.SectData.SectionHeader.Font); _MyHeader.Text = null; MyFooter = null; _TagsSetup = true; } private string GetSectionTab(bool underline) { if (DisplayNumber == null || DisplayNumber == "" || !IsStepSection) return DisplayNumber; // added DontParseSectionNumber flag so that the section number is used as is if (MyDocStyle.SpecialStepsFoldout || MyDocStyle.DontParseSectionNumber) return DisplayNumber; if (ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel) { if (underline) return @"\ul " + DisplayNumber + @"\ul0 "; else return DisplayNumber; } // if displaynumber ends with a '.', don't worry about catching the condition that a tab can be made such as // 'x. x', i.e. space between the . and the rest of tab. This was added for BGEEOPs. if (DisplayNumber.LastIndexOf('.') == DisplayNumber.Length - 1) return DisplayNumber; string retStr = null; string ch = DisplayNumber != null && DisplayNumber != "" ? DisplayNumber.Substring(0, 1) : null; int Snum = GetSectionNum(); if (Snum == -1) { if (ch[0] == ' ') ch = DisplayNumber != null && DisplayNumber.TrimStart() != "" ? DisplayNumber.TrimStart().Substring(0, 1) : null; retStr = ch + "."; } else if (Snum == -2) // -2 flags to just use display number as is, don't prepend the parent's number. { string tmp = DisplayNumber.Trim(); if (underline) retStr = @"\ul " + DisplayNumber.Trim() + @"\ul0 "; else retStr = DisplayNumber.Trim(); } else { string tmp = DisplayNumber.IndexOf(".") > -1 ? DisplayNumber.Substring(0, DisplayNumber.IndexOf(".")) : DisplayNumber; if (underline) retStr = @"\ul " + tmp + "." + Snum.ToString() + @"\ul0 "; else retStr = tmp + "." + Snum.ToString(); } return retStr; } private int GetSectionNum() { int indx = -1; if (DisplayNumber != null && DisplayNumber != "" && (indx = DisplayNumber.IndexOf(".")) > -1) { // if there is a number after the '.', return it as a number. For example if it is 001, return a 1: string tmpstr = indx + 1 < DisplayNumber.Length ? DisplayNumber.Substring(indx + 1) : null; // if the section's tab is a letter, we don't want a 0 on the section.... for example A.0. if (IsSection && tmpstr == null && System.Char.IsLetter(DisplayNumber.TrimStart(), 0)) return -1; if (tmpstr != null && tmpstr.IndexOf('-') >= 0) return -1; if (tmpstr == null) return 0; Int32 x; if (Int32.TryParse(tmpstr, out x)) return x; // flag the case where the current section's tab already has prefixed in the parent's tab: // (without this, BGE's section headers were coming up as 6.1.6.1.1...) if (IsSection && ActiveParent.IsSection) { if (DisplayNumber.StartsWith((ActiveParent as SectionInfo).DisplayNumber.Trim())) return -2; } return -1; } return (-1); } public bool TrueSectionNum() { int indx = DisplayNumber.IndexOf("."); if (indx < 0 || indx + 1 == DisplayNumber.Length) return false; // for it to be a 'TrueSectionNum', there can be no letters after the '.' for (int lindx = indx + 1; lindx < DisplayNumber.Length - 1; lindx++) if (DisplayNumber[lindx] < '0' || DisplayNumber[lindx] > '9') return false; return true; } // the following returns the 'index' into the format's CheckOffHeaderList. // It returns a -1 if not set or none exist. public int CheckOffHeadingIndex() { if (ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList == null || ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList.MaxIndex == 0) return -1; SectionConfig sc = MyConfig as SectionConfig; if (sc == null) return -1; return sc.Section_CheckoffHeaderSelection; } public bool IsSeparatePagination() { VEPROMS.CSLA.Library.SectionConfig.SectionPagination sp = VEPROMS.CSLA.Library.SectionConfig.SectionPagination.Separate; try { if (SectionConfig != null) sp = SectionConfig.Section_Pagination; } catch (Exception ex) { sp = VEPROMS.CSLA.Library.SectionConfig.SectionPagination.Separate; } if (sp == VEPROMS.CSLA.Library.SectionConfig.SectionPagination.Separate) return true; return false; } protected override void RefreshFields(Item tmp) { base.RefreshFields(tmp); ExtensionRefreshFields(tmp); } #if ItemWithContent public SectionInfo(SafeDataReader dr) : base(dr, true) { } #else public SectionInfo(SafeDataReader dr) : base(dr) { } #endif private SectionInfo() : base() { ;} public new static SectionInfo Get(int itemID) { //if (!CanGetObject()) // throw new System.Security.SecurityException("User not authorized to view a Item"); try { SectionInfo tmp = GetCachedByPrimaryKey(itemID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteria(itemID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on Item.Get", ex); } } protected new static SectionInfo GetCachedByPrimaryKey(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (ItemInfo ii in _CacheByPrimaryKey[key]) if (ii is SectionInfo) return ii as SectionInfo; return null; } public void MoveSection(IVEDrillDownReadOnly pInfo, int index) { MoveItem(pInfo, index); //using (Item ii = Item.Get(this.ItemID)) //{ // ii.MoveItem(pInfo, index); //} } public new Section Get() { return (Section)(_Editable = Section.Get(ItemID)); } #region SectionConfig [NonSerialized] public SectionConfig _SectionConfig; public SectionConfig SectionConfig { get { return (_SectionConfig != null ? _SectionConfig : _SectionConfig = new SectionConfig(this)); } } #endregion public new ConfigDynamicTypeDescriptor MyConfig { get { return SectionConfig; } set { _SectionConfig = null; } } } #endregion #region Section [Serializable()] public partial class Section : Item { public SectionInfo MySectionInfo /* Return Info version of the current Item */ { get { return SectionInfo.Get(ItemID); } } public new static Section Get(int itemID) { if (!CanGetObject()) throw new System.Security.SecurityException("User not authorized to view a Item"); try { Section tmp = GetCachedByPrimaryKey(itemID) as Section; if (tmp == null) { tmp = DataPortal.Fetch
(new PKCriteria(itemID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on Item.Get", ex); } } public new Section Save() { return (Section)base.Save(); } public static Section MakeSection(IVEDrillDownReadOnly parentInfo, ItemInfo previousInfo, string sectNumber, string sectTitle, int sectType) { int newitemid = MakeNewItem(parentInfo, previousInfo, sectNumber, sectTitle, sectType, E_FromType.Section); return Section.Get(newitemid); } #region SectionConfig [NonSerialized] private SectionConfig _SectionConfig; public SectionConfig SectionConfig { get { if (_SectionConfig == null) { _SectionConfig = new SectionConfig(this); _SectionConfig.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_SectionConfig_PropertyChanged); } return _SectionConfig; } } private void _SectionConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { MyContent.Config = _SectionConfig.ToString(); } #endregion } #endregion #region StepInfo [Serializable()] public partial class StepInfo : ItemInfo { #region StepConfig public StepConfig _StepConfig; public StepConfig StepConfig { get { return (_StepConfig != null ? _StepConfig : _StepConfig = new StepConfig(this)); } } #endregion #region Tab public override void SetupTags() { _TagsSetup = true; // B2016-160 Support transitions to sections VE_Font fnt = new VE_Font("Arial", 10, E_Style.None, 10); if (FormatStepData != null) fnt = FormatStepData.TabData.Font; MyTab = new Tab(AdjustForTextSubFollowsTextStyle(fnt)); MyHeader = new MetaTag(fnt); MyFooter = new MetaTag(fnt); SetTabText(); } #endregion protected override void RefreshFields(Item tmp) { base.RefreshFields(tmp); ExtensionRefreshFields(tmp); } //public override string ToString() //{ // return "Step " + base.ToString(); //} #if ItemWithContent public StepInfo(SafeDataReader dr) : base(dr, true) { } #else public StepInfo(SafeDataReader dr) : base(dr) { } #endif private StepInfo() : base() { ;} public new static StepInfo Get(int itemID) { //if (!CanGetObject()) // throw new System.Security.SecurityException("User not authorized to view a Item"); try { StepInfo tmp = GetCachedByPrimaryKey(itemID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteria(itemID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on Item.Get", ex); } } protected new static StepInfo GetCachedByPrimaryKey(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (ItemInfo ii in _CacheByPrimaryKey[key]) if (ii is StepInfo) return ii as StepInfo; return null; } public void MoveStep(IVEDrillDownReadOnly pInfo, int index) { MoveItem(pInfo, index); //using (Item ii = Item.Get(this.ItemID)) //{ // ii.MoveItem(pInfo, index); //} } public new Step Get() { return (Step)(_Editable = Step.Get(ItemID)); } //public E_FromType FromType //{ get { return E_FromType.Step; } } } #endregion #region Step [Serializable()] public partial class Step : Item { public new static Step Get(int itemID) { if (!CanGetObject()) throw new System.Security.SecurityException("User not authorized to view a Item"); try { Step tmp = (Step)GetCachedByPrimaryKey(itemID); if (tmp == null) { tmp = DataPortal.Fetch(new PKCriteria(itemID)); AddToCache(tmp); } if (tmp.ErrorMessage == "No Record Found") tmp = null; return tmp; } catch (Exception ex) { throw new DbCslaException("Error on Item.Get", ex); } } // TODO :MakeCaution; // TODO :MakeNote; // TODO :MakeRNO; // TODO :MakeSection; // TODO :MakeSubStep; // TODO :MakeTable; public static Step MakeStep(IVEDrillDownReadOnly parentInfo, ItemInfo previousInfo, string stepNumber, string stepTitle, int stepType, E_FromType fromType) { int newitemid = MakeNewItem(parentInfo, previousInfo, stepNumber, stepTitle, stepType, fromType); return Step.Get(newitemid); } //#region StepConfig //[NonSerialized] //private StepConfig _StepConfig; //public StepConfig StepConfig //{ // get // { // if (_StepConfig == null) // { // _StepConfig = new StepConfig(this); // _StepConfig.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_StepConfig_PropertyChanged); // } // return _SectionConfig; // } //} //private void _StepConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) //{ // MyContent.Config = _StepConfig.ToString(); //} //#endregion } #endregion public enum ItemSearchIncludeLinks { Nothing = 0, Value = 1, Everything = 2 } }