9061 lines
310 KiB
C#

#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<Item> 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<ItemInfo> 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<ItemInfo>)parentInfo.Lookup((int)partType);
}
else
children = (IList<ItemInfo>)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("<Setting MyPrevious Null {0}", ItemID);
}
// newPreviousInfo == null if moving into first child, and wasfirstchild == true if moving out of first child.
// This will require adjusting the DocVersion to point to the correct first child if a procedure is moved.
if (newPreviousInfo == null || wasfirstchild)
{
if (parentInfo != null) // Moving Item within procedure, i.e. moving a section or step
{
using (Item parentItem = parentInfo.Get())
{
// moving first child out... reset parent to point to the original next item
if (wasfirstchild)
{
parentItem.MyContent.ContentParts[(int)partType].MyItem = origNextItem;
newPreviousInfo.RefreshItemParts();
}
else
parentItem.MyContent.ContentParts[(int)partType].MyItem = this;
parentItem.Save();
}
}
else if (parentInfoDV != null) // Moving Item (Procedure) within DocVersion
{
using (DocVersion parentItemDV = parentInfoDV.Get())
{
ItemInfo firstinfo = parentInfoDV.FirstChild();
parentItemDV.MyItem = wasfirstchild ? parentInfoDV.Procedures[1].Get() : this;
parentItemDV.Save();
if (!wasfirstchild && firstinfo != null)
{
using (Item firstchild = firstinfo.Get())
{
firstchild.MyPrevious = this;
firstchild.Save();
}
}
}
}
if (!wasfirstchild)
{
this.MyPrevious = null;
this.Save();
}
if (origNextItem != null) origNextItem.Dispose();
if (parentInfo != null)
parentInfo.MyContent.RefreshContentParts();
}
//ShowItemAndSections("After MoveItem", pInfo as ItemInfo);
if (parentInfoDV != null)
DocVersionInfo.ResetProcedures(parentInfoDV.VersionID);
if (parentInfo != null)
ItemInfo.ResetParts(parentInfo.ItemID);
//ShowItemAndSections("After Refresh", pInfo as ItemInfo);
}
//private static string StringIt(byte[] _LastChanged)
//{
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < _LastChanged.Length; i++)
// sb.Append(string.Format("{0:X2}",_LastChanged[i]));
// return sb.ToString();
//}
//private void ShowItemAndSections(string title, ItemInfo pinfo)
//{
//
// pinfo.ShowThis(title + "-Parent");
// int i=0;
// foreach (ItemInfo child in pinfo.Sections)
// child.ShowThis(title + string.Format("-Child {0}", ++i));
//}
protected static int MakeNewItem(IVEDrillDownReadOnly parentInfoDD, ItemInfo previousInfo, string number, string title, int type, E_FromType partType)
{
int newitemid = 0;
if (parentInfoDD == null)
parentInfoDD = previousInfo.ActiveParent;
ItemInfo parentInfo = parentInfoDD as ItemInfo;
DocVersionInfo parentInfoDV = parentInfoDD as DocVersionInfo;
using (Content cont = Content.New(number, title, type, null, null))
{
using (Item fromitem = previousInfo == null ? null : previousInfo.Get())
{
ItemInfo nextInfo = null; // Check to see if the item is being inserted in the middle of some items.
if (previousInfo != null)
nextInfo = previousInfo.GetNext();
using (Item itm = Item.MakeItem(fromitem, cont))
{
newitemid = itm.ItemID;
if (nextInfo != null)
{
using (Item nextItem = nextInfo.Get())
{
nextItem.MyPrevious = itm;// Aim the next item back at the new item.
nextItem.Save();
}
}
if (fromitem == null)
{
if (parentInfo != null) // Adding Item to Procedure, Section or Step
{
using (Item parentItem = parentInfo.Get())
{
ItemInfo firstinfo = parentInfo.FirstChild(partType);
if (firstinfo != null)
{
using (Item firstchild = firstinfo.Get())
{
parentItem.MyContent.ContentParts[(int)partType].MyItem = itm;// First update the parent to point to the new first child
parentItem.Save();
firstchild.MyPrevious = itm;// Aim the old first child to point to the new first child.
firstchild.Save();
}
}
else
{
parentItem.MyContent.ContentParts.Add((int)partType, itm);// update the parent to point to the new first child
parentItem.Save();
}
}
}
if (parentInfoDV != null) // Adding Item (Procedure) to DocVersion
{
using (DocVersion parentItemDV = parentInfoDV.Get())
{
int? oldItemID = parentItemDV.ItemID;
parentItemDV.MyItem = itm;// First update the parent to point to the new first child
parentItemDV.Save();
if (oldItemID != null)
{
using (Item firstchild = Item.Get((int)oldItemID))
{
firstchild.MyPrevious = itm;// Aim the old first child to point to the new first child.
firstchild.Save();
}
}
}
}
}
}
}
}
if (parentInfo != null)
parentInfo.MyContent.RefreshContentParts();
if (parentInfoDV != null)
parentInfoDV.ResetProcedures();
return newitemid;
}
}
#endregion
#region ItemInfo
public partial class ItemInfo : IVEDrillDownReadOnly
{
private bool _PrintAllAtOnce = false;
public bool PrintAllAtOnce
{
get { return _PrintAllAtOnce; }
set { _PrintAllAtOnce = value; }
}
public SectionInfo GetSectionInfo()
{
if (this is SectionInfo) return this as SectionInfo;
return SectionInfo.Get(ItemID);
}
public StepInfo GetStepInfo()
{
if (this is StepInfo) return this as StepInfo;
return StepInfo.Get(ItemID);
}
public ProcedureInfo GetProcedureInfo()
{
if (this is ProcedureInfo) return this as ProcedureInfo;
return ProcedureInfo.Get(ItemID);
}
private string _EnhType = null;
public string EnhType
{
get
{
if (_EnhType != null) return _EnhType;
if (!IsSection)
_EnhType = "";
else
{
// get the section's enhtype from the config
SectionConfig sc = MyConfig as SectionConfig;
_EnhType = sc.Section_LnkEnh;
}
return _EnhType;
}
}
public bool EnhAllowMod()
{
// C2019-045: For enhanced procedures, allow modifications of number & text. This method checks whether the
// user selected to allow for modifications, i.e. the value in the docversion config, 'Enhanced_AllowMods' is true.
// Note that the flag is set on the enhanced doc versions, not the source, so that each enhanced can have its own setting.
if (!IsProcedure) return false;
if (MyDocVersion.DocVersionConfig.Enhanced_AllowMods) return true;
return false;
}
public bool InList(params int[] IDs)
{
foreach (int id in IDs)
if (id == ItemID) return true;
return false;
}
public static bool IsInCache(int itemID)
{
return _CacheByPrimaryKey.ContainsKey(itemID.ToString());
}
public static string ReplaceLinkWithNewID(string tmpForLink)
{
tmpForLink = Regex.Replace(tmpForLink, @"#Link:ReferencedObject:[0-9]+ ", @"#Link:ReferencedObject:<NewID> ");
tmpForLink = Regex.Replace(tmpForLink, @"#Link:Transition:([0-9]+) [0-9]+ ", @"#Link:Transition:$1 <NewID> ");
tmpForLink = Regex.Replace(tmpForLink, @"#Link:TransitionRange:([0-9]+) [0-9]+ ", @"#Link:TransitionRange:$1 <NewID> ");
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;
}
}
}
/// <summary>
/// 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).
/// </summary>
/// <returns></returns>
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("<CTID=-"))
{
//CSM C2024-028 - Bad Transition Link - Make an annotation
using (Item itm = Item.Get(itemInfo.ItemID))
{
TranCantFixCount++;
Annotation.MakeAnnotation(itm, AnnotationType.GetByNameOrCreate("Bad Transition Link"), "", $"Invalid Transition Link: ({ItemInfo.ConvertToDisplayText(newValue)})", null);
}
}
}
}
}
}
// // B2018-002 - Invalid Transitions - Method to check for invalid transitions and convert them to text
public static bool ConvertInvalidTransitionsToText(ItemInfo itemInfo)
{
bool retval = true;
RemoveEmptyTransitions(itemInfo);//B2018-043 Cleanup Empty Transitions
MatchCollection mc = Regex.Matches(itemInfo.MyContent.Text, @"\#Link\:Transition");
if (itemInfo.MyContent.ContentTransitionCount <= 0 || mc.Count > 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 |)\<START\]\#Link\:Transition(|Range)\:[0-9]+ [0-9]+ [0-9]+(| [0-9]+)\[END\>(\\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("<U\\U8209?OTHER")) // proc number has <u-otherxxx> 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<ItemInfo> myCache = new List<ItemInfo>();
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;
}
}
/// <summary>
/// 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.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
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<ItemInfo>(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<ItemInfo>(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<int, ItemInfo> lookup = new Dictionary<int, ItemInfo>(); ;
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<ItemInfo> 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;
}
}
/// <summary>
/// FormatStepType - Maps to step type in format file. All types map directly from step type in content
/// to step type in format
/// </summary>
public int FormatStepType
{
get
{
return (((int)MyContent.Type) % 10000);
}
}
/// <summary>
/// returns the format's stepdata for the given content type.
/// </summary>
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<StepData> 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 (<U-xxx>, <U>, <ID>)
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 (<U-xxx>, <U>, <ID>)
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 (<U-xxx>, <U>, <ID>)
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 (<U-xxx>, <U>, <ID>)
str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str);
}
else
{
_MyLog.WarnFormat("Disconnected Data - ItemID = {0}", ItemID);
}
return ConvertToDisplayText(str);
}
}
static Dictionary<string, string> _SpecialCharacters = null;
static Dictionary<string, string> SpecialCharacters
{
get
{
// B2022-081 needed to add clock symbol so that it properly translate over to enhanced document
if (_SpecialCharacters==null){
_SpecialCharacters = new Dictionary<string, string>();
_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 (<U-xxx>, <U>, <ID>)
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 (<U-xxx>, <U>, <ID>)
str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(MyDocVersion, str);
}
else
{
str = "*" + str;
_MyLog.WarnFormat("Disconnected Data - ItemID = {0}", ItemID);
}
//if (str.Contains("<U-ID>"))
// str = str.Replace("<U-ID>", MyDocVersion.DocVersionConfig.Unit_ID);
//if (str.Contains(@"<S\u8209?ID>"))
// str = str.Replace(@"<S\u8209?ID>", 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 "<u>" in section number
// B2024-025 - process all of the applicability token (<U-xxx>, <U>, <ID>)
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("<root/>");
// 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;
/// <summary>
/// MyActiveSection is used to determine if _ActiveSection is null or not.
/// </summary>
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
// <!diamond> - draws a diamond around the stepnumber
// <!diamond1> - A macro
// <!asterisk>
// <> - ignored
// \241 - circle macro around step, same as <!circle>
// 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<Macro> _MyMacros;
protected bool _MacrosSetup = false;
public List<Macro> 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<Macro> tmp = new List<Macro>();
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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfo> SortedList(bool sortbyFoundRoid = false)
{
List<ItemInfo> tmp = new List<ItemInfo>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<ItemInfoList>(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<int, Dictionary<int, ItemInfo>> _MyLookups;
public Dictionary<int, Dictionary<int, ItemInfo>> 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<int, ItemInfo> mylookup)
{
_MyLookups = new Dictionary<int, Dictionary<int, ItemInfo>>();
_MyLookups.Add(procID, mylookup);
_ApplicabilityUnit = applicabilityUnit;
}
public void AddProcLookup(int procID, Dictionary<int, ItemInfo> mylookup)
{
if (!_MyLookups.ContainsKey(procID))
{
_MyLookups.Add(procID, mylookup);
//Console.WriteLine("AddProcLookup: {0}", procID);
}
}
public ItemInfo this[int itemID]
{
get
{
foreach (Dictionary<int, ItemInfo> mylookup in MyLookups.Values)
{
if (mylookup != null && mylookup.ContainsKey(itemID))
return mylookup[itemID];
}
return null;
}
}
public bool ContainsKey(int itemID)
{
foreach (Dictionary<int, ItemInfo> 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<int, ItemInfo> 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<int, ItemInfo> 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<ProcedureInfo>(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<ProcedureInfo>(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<ProcedureInfo>(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<int, ItemInfo> lookup = new Dictionary<int, ItemInfo>(); ;
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<ProcedureInfo>(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<int, ItemInfo> lookup = new Dictionary<int, ItemInfo>(); ;
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<ProcedureTransitionsCountCommand>(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<Procedure>(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<DataTable>(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<DisplayTabs>(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<int, List<int>> _LookupStepSectPageBreaksForSupInfo = new Dictionary<int, List<int>>();
public static void ResetLookupStepSectPageBreaksForSupInfo()
{
_LookupStepSectPageBreaksForSupInfo.Clear();
}
public List<int> StepSectPageBreaksForSupInfo
{
get
{
if (!_LookupStepSectPageBreaksForSupInfo.ContainsKey(ItemID)) _LookupStepSectPageBreaksForSupInfo.Add(ItemID, new List<int>());
return _LookupStepSectPageBreaksForSupInfo[ItemID];
}
}
// Keeps track of step section itemids where page breaks occur
private static Dictionary<int, List<int>> _LookupStepSectPageBreaks = new Dictionary<int, List<int>>();
public static void ResetLookupStepSectPageBreaks()
{
_LookupStepSectPageBreaks.Clear();
}
public List<int> StepSectPageBreaks
{
get
{
if (!_LookupStepSectPageBreaks.ContainsKey(ItemID)) _LookupStepSectPageBreaks.Add(ItemID, new List<int>());
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<SectionInfo>(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<Section>(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<StepInfo>(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<Step>(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
}
}