mschill 378653c536 C2025-011 PROMS – RO Update Admin Tool Memory Enhancements
The purpose of this upgrade is to improve the user experience when using the Admin tool to Update ROs. Currently for larger RO dbs (like Barakah) we can run up against memory constraints that do not allow all the ROs to be updated at one time. This is based upon some initial resource where some places were identified where we could improve memory usage.  Some of these should benefit PROMS as a whole while others will be specific to the RO Update option in Admin Tools.
2025-02-04 13:23:21 -05:00

9039 lines
308 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("- - - - - -");
}
//C2025-011 RO Update Admin Tool Memory Enhancements
//clears everything in cache - to run between sections in the Admin Tool to reclaim memory
public static void ClearItemCache()
{
_CacheByPrimaryKey.Clear();
while (_CacheList.Count > 0)
{
_CacheList[0].DisposeOfContent = true;
_CacheList[0].Dispose();
}
}
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
{
//C2025-011 RO Update Admin Tool Memory Enhancements
//clears everything in cache - to run between sections in the Admin Tool to reclaim memory
public static void ClearItemInfoCache()
{
while (_CacheByPrimaryKey.Count > 0)
{
var ii = _CacheByPrimaryKey.FirstOrDefault();
while (ii.Value.Count > 0)
{
if (ii.Value[0]?.MyContent?.ContentParts != null)
{ foreach (PartInfo pi in ii.Value[0]?.MyContent?.ContentParts) pi.Dispose(); }
ii.Value[0].Dispose();
}
_CacheByPrimaryKey.Remove(ii.Key);
}
while (_CacheList.Count > 0)
{
if (_CacheList[0]?.MyContent?.ContentParts != null)
{foreach (PartInfo pi in _CacheList[0]?.MyContent?.ContentParts) pi.Dispose(); }
_CacheList[0].Dispose();
}
}
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)
{
using (ItemInfoList myitems = Lookup((int)partType))
{
if (myitems != null) return myitems[myitems.Count - 1];
return null;
}
}
public ItemInfo FirstChild(E_FromType partType)
{
using (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
public System.Collections.IList GetChildren()
{
using (PartInfoList _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)
{
using (PartInfoList _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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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
{
using (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.
using (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 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
}
}