using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Text.RegularExpressions; using Csla; using Csla.Data; namespace VEPROMS.CSLA.Library { public partial class TransitionInfo { //for transition search private int _Level = 0; public int Level { get { return _Level; } set { _Level = value; } } //end for transition search private bool _NewTransToUnNumberedItem = false; public bool NewTransToUnNumberedItem { get { return _NewTransToUnNumberedItem; } set { _NewTransToUnNumberedItem = value; } } public string PathTo { get { return MyItemToID.Path; } } public string PathFrom { get { return MyContent.ContentItems[0].Path; } } public override string ToString() { return string.Format("ID: {0} From: {1} To: {2}", TransitionID, FromID, ToID); } [NonSerialized] private TransitionConfig _TransitionConfig; public TransitionConfig TransitionConfig { get { if (_TransitionConfig == null) { _TransitionConfig = new TransitionConfig(this); } return _TransitionConfig; } } public bool HasPageNum { get { return TransitionConfig.Transition_Formatted.ToUpper() == "TRUE"; } } public string ResolvePathTo(FormatInfo fi, ItemInfo itminfo, int tranType, ItemInfo toitem, ItemInfo rangeitem, bool hasPageNum) { try { return TransitionText.GetResolvedText(fi, itminfo, tranType, toitem, rangeitem, HasPageNum); } catch (Exception ex) { if (tranType == 2 && ex.Message == "Cannot find Next Item") return TransitionText.GetResolvedText(fi, itminfo, tranType, toitem, toitem, HasPageNum); _MyLog.Error("Error Processing Transition Text", ex); return "(Resolved Transition Text)"; } } public string ResolvePathTo(FormatInfo fi, ItemInfo itminfo, int tranType, ItemInfo toitem, ItemInfo rangeitem) { try { return TransitionText.GetResolvedText(fi, itminfo, tranType, toitem, rangeitem, HasPageNum); } catch (Exception ex) { if (tranType == 2 && ex.Message == "Cannot find Next Item") return TransitionText.GetResolvedText(fi, itminfo, tranType, toitem, toitem, HasPageNum); _MyLog.Error("Error Processing Transition Text", ex); return "(Resolved Transition Text)"; } } public string ResolvePathTo() { MyContent.RefreshContentItems(); ItemInfo item = MyContent.ContentItems[0]; //Console.WriteLine("Format = {0}", item.ActiveFormat); //Console.WriteLine("item = {0}", item.ItemID); //Console.WriteLine("TranType = {0}", TranType); //Console.WriteLine("MyItemToID = {0}", MyItemToID); //Console.WriteLine("MyItemRangeID = {0}", MyItemRangeID); return ResolvePathTo(item.ActiveFormat, item, TranType, MyItemToID, MyItemRangeID); } public string ResolvePathTo(TransitionLookup tranLookup) { MyContent.RefreshContentItems(); ItemInfo item = MyContent.ContentItems[0]; ItemInfo myItemToID = MyItemToID; if (tranLookup.ContainsKey(item.ItemID)) item = tranLookup[item.ItemID]; bool hasPageNum = false; if (item.ActiveFormat.PlantFormat.FormatData.TransData.UseTransitionModifier || item.ActiveFormat.PlantFormat.FormatData.TransData.UseSpecificTransitionModifier) { TransitionConfig tc = new TransitionConfig(Config); if (tc != null && tc.Transition_Formatted.ToUpper() == "TRUE") hasPageNum = true; } if (tranLookup.ContainsKey(ToID)) { myItemToID = tranLookup[ToID]; } else { //different proc //_MyLog.WarnFormat("Transition May Not Be Correct at Location From {0} To {1}", item.SearchPath, myItemToID.SearchPath); if (!tranLookup.MyLookups.ContainsKey(myItemToID.MyProcedure.ItemID)) tranLookup.AddProcLookup(myItemToID.MyProcedure.ItemID, ProcedureInfo.GetNewLookup(tranLookup, new TransitionLookupEventArgs(myItemToID.MyProcedure.ItemID, tranLookup.ApplicabilityUnit, MyItemToID.MyDocVersion, tranLookup)).MyLookup); if (tranLookup.ContainsKey(ToID)) myItemToID = tranLookup[ToID]; else _MyLog.WarnFormat("Invalid Unit Transition: from,to '{0}','{1}'", MyContent.ContentItems[0].ShortPath, myItemToID.ShortPath); } ItemInfo myItemRangeID = MyItemRangeID; if (tranLookup.ContainsKey(RangeID)) myItemRangeID = tranLookup[RangeID]; else { //different proc //_MyLog.WarnFormat("Transition May Not Be Correct at Location From {0} To {1}", item.SearchPath, myItemRangeID.SearchPath); if (!tranLookup.MyLookups.ContainsKey(MyItemRangeID.MyProcedure.ItemID)) tranLookup.AddProcLookup(MyItemRangeID.MyProcedure.ItemID, ProcedureInfo.GetNewLookup(tranLookup, new TransitionLookupEventArgs(MyItemRangeID.MyProcedure.ItemID, tranLookup.ApplicabilityUnit, MyItemRangeID.MyDocVersion, tranLookup)).MyLookup); if (tranLookup.ContainsKey(RangeID)) myItemRangeID = tranLookup[RangeID]; else if (myItemRangeID.ItemID != myItemToID.ItemID) _MyLog.WarnFormat("Invalid Unit Range Transition: from,to '{0}','{1}'", MyContent.ContentItems[0].ShortPath, myItemRangeID.ShortPath); //Console.WriteLine("Format = {0}", item.ActiveFormat); //Console.WriteLine("item = {0}", item.ItemID); //Console.WriteLine("TranType = {0}", TranType); //Console.WriteLine("MyItemToID = {0}", MyItemToID); //Console.WriteLine("MyItemRangeID = {0}", MyItemRangeID); } return ResolvePathTo(item.ActiveFormat, item, TranType, myItemToID, myItemRangeID, hasPageNum); } } #region AffectedTransitons public partial class TransitionInfoList { //transition report stuff public static TransitionInfoList GetTransitionReportData(int versionID, int procedureID) { try { TransitionInfoList tmp = DataPortal.Fetch(new TransitionReportDataCriteria(versionID, procedureID)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetTransitionReportData", ex); } } [Serializable()] protected class TransitionReportDataCriteria { private int _VersionID; public int VersionID { get { return _VersionID; } } private int _ProcedureID; public int ProcedureID { get { return _ProcedureID; } } public TransitionReportDataCriteria(int versionID, int procedureID) { _VersionID = versionID; _ProcedureID = procedureID; } } private void DataPortal_Fetch(TransitionReportDataCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_Fetch", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_GetTransitionReportData"; cm.Parameters.AddWithValue("@VersionID", criteria.VersionID); cm.Parameters.AddWithValue("@ProcedureID", criteria.ProcedureID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { TransitionInfo ti = new TransitionInfo(dr); ti.Level = dr.GetInt32("level"); this.Add(ti); } IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_Fetch", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } //end transition report stuff [Serializable()] private class AffectedTransitonsCriteria { public AffectedTransitonsCriteria(int itemID) { _ItemID = itemID; } private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } } public static TransitionInfoList GetAffected(int itemID) { try { TransitionInfoList tmp = DataPortal.Fetch(new AffectedTransitonsCriteria(itemID)); TransitionInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetAffected", ex); } } private void DataPortal_Fetch(AffectedTransitonsCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_FetchAffected", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getAffectedTransitions"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new TransitionInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_FetchAffected", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } public string Summarize() { StringBuilder sb = new StringBuilder(""); foreach (TransitionInfo trans in this) sb.Append("\r\n" + trans.PathFrom); return sb.ToString(); } #endregion #region ExternalTransitionsToChildren private class ExternalTransitionsToChildrenCriteria { public ExternalTransitionsToChildrenCriteria(int itemID) { _ItemID = itemID; } private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } } public static TransitionInfoList GetExternalTransitionsToChildren(int itemID) { try { TransitionInfoList tmp = DataPortal.Fetch(new ExternalTransitionsToChildrenCriteria(itemID)); TransitionInfo.AddList(tmp); tmp.AddEvents(); if (tmp.Count == 0) return GetExternalTransitions(itemID); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetExternalTransitionsToChildren", ex); } } private void DataPortal_Fetch(ExternalTransitionsToChildrenCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_FetchExternalTransitionsToChildren", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getExternalTransitionsToChildren"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new TransitionInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_FetchExternalTransitionsToChildren", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region ExternalTransitions private class ExternalTransitionsCriteria { public ExternalTransitionsCriteria(int itemID) { _ItemID = itemID; } private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } } public static TransitionInfoList GetExternalTransitions(int itemID) { try { TransitionInfoList tmp = DataPortal.Fetch(new ExternalTransitionsCriteria(itemID)); TransitionInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetExternalTransitions", ex); } } private void DataPortal_Fetch(ExternalTransitionsCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_FetchExternalTransitions", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getExternalTransitions"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new TransitionInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_FetchExternalTransitions", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region PastedAffectedTransitions private class PastedAffectedTransitonsCriteria { public PastedAffectedTransitonsCriteria(int itemID) { _ItemID = itemID; } private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } } internal static TransitionInfoList GetPastedAffected(int itemID) { try { TransitionInfoList tmp = DataPortal.Fetch(new PastedAffectedTransitonsCriteria(itemID)); TransitionInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetPastedAffected", ex); } } private void DataPortal_Fetch(PastedAffectedTransitonsCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_FetchPastedAffected", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getPastedAffectedTransitions"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new TransitionInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_FetchPastedAffected", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region TransitionsToDisconnected private class TransitionsToDisconnectedCriteria { public TransitionsToDisconnectedCriteria(string docVersionList) { _DocVersionList = docVersionList; } private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } } public static TransitionInfoList GetTransitionsToDisconnected(string docVersionList) { try { TransitionInfoList tmp = DataPortal.Fetch(new TransitionsToDisconnectedCriteria(docVersionList)); TransitionInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetTransitionsToDisconnected", ex); } } private void DataPortal_Fetch(TransitionsToDisconnectedCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_FetchTransitionsToDisconnected", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getTransitionsToDisconnected"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new TransitionInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_FetchTransitionsToDisconnected", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion #region TransitionsToNonEditable private class TransitionsToNonEditableCriteria { public TransitionsToNonEditableCriteria(string docVersionList) { _DocVersionList = docVersionList; } private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } } public static TransitionInfoList GetTransitionsToNonEditable(string docVersionList) { try { TransitionInfoList tmp = DataPortal.Fetch(new TransitionsToNonEditableCriteria(docVersionList)); TransitionInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on TransitionInfoList.GetTransitionsToNonEditable", ex); } } private void DataPortal_Fetch(TransitionsToNonEditableCriteria criteria) { this.RaiseListChangedEvents = false; if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] TransitionInfoList.DataPortal_FetchTransitionsToNonEditable", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "getTransitionsToNonEditable"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DocVersionList); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) this.Add(new TransitionInfo(dr)); IsReadOnly = true; } } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("TransitionInfoList.DataPortal_FetchTransitionsToNonEditable", ex); throw new DbCslaException("TransitionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #endregion } public class TransitionBuilder { private StringBuilder _Results = new StringBuilder(); public FormatData _FormatData; public string _TransFormat; public E_TransUI _TransUI; public ItemInfo _FromItem; public int _TranType; public ItemInfo _ToItem; public ItemInfo _RangeItem; public bool _UsedRangeAncestor; private string _Token; public string _UnitProcSetString; public bool SectNumWithStepNum; private int _SectionNumberLength = 0; public int SectionNumberLength { get { return _SectionNumberLength; } set { _SectionNumberLength = value; } } private string _StepPrefix = ""; public string StepPrefix { get { return _StepPrefix; } set { _StepPrefix = value; } } private List _SectionsUsed = new List(); public List SectionsUsed { get { return _SectionsUsed; } } public string Token { get { return _Token; } set { _Token = value; } } private string _Prefix; public string Prefix { get { return _Prefix; } set { if(_Prefix==null)_Prefix = value; } } public void ResetPrefix(string str) { _Prefix = str; } public bool HasText { get { return _Results.Length > 0; } } public StringBuilder Append(string str) { return _Results.Append(str); } public StringBuilder ReplaceToken(string str) { if (str == null || str == "") return _Results; if (_FormatData.TransData.XchngTranSpForHard && str[0]!=',' && str[0] != ' ') { int indx = str.IndexOf(' '); // 16 bit code only processes 1st occurance if (indx > -1) // Not a while loop in 16 bit. { // (see \promsnt\lib\edit\gettran.c:TransitionCat) str = str.Remove(indx, 1); str = str.Insert(indx, @"\u160?"); } } if (_Results.ToString().ToUpper().EndsWith("STEP ") && str.ToUpper().StartsWith("STEP ")) return _Results.Append(str.Substring(5).Trim(" :".ToCharArray())); else return _Results.Append(str.TrimEnd(" :".ToCharArray())); } public override string ToString() { return _Results.ToString(); } public StringBuilder Remove(int startIndex, int length) { return _Results.Remove(startIndex, length); } public int Length { get { return _Results.Length; } } public void AppendPrefix() { if (Prefix == null) return; // no Prefix text to add if (HasText) { if (!_Results.ToString().EndsWith(_Prefix)) //existing transition text does not end with Prefix text, OK to append _Results.Append(Prefix); _Prefix = null; } else if (_TranType == 4 && _ToItem.MoreThanOneStepSection()) { // WEP (Point Beach) is no longer a customer - commented out //if (!HasText && Prefix.ToUpper().StartsWith(", STEP") // && _FromItem.ActiveFormat.Name.StartsWith("WEP")) //{ // Console.WriteLine("Format,'{0}'", _FromItem.ActiveFormat.Name); // _Prefix = null; // return; //} _Results.Append(Prefix); _Prefix = null; } // If the prefix contains an open paren, we want to add the open paren regardless // of whether there already is text in the resulting string. else if (!HasText && Prefix.Contains("(")) { _Results.Append(Prefix.TrimStart(" ".ToCharArray())); // since no text in result, trim starting space. _Prefix = null; } else if (!HasText && Prefix.StartsWith(", ")) { _Results.Append(Prefix.TrimStart(", ".ToCharArray()));// no preceeding text, remove comma and space _Prefix = null; } else if (!HasText && Prefix.StartsWith(",")) { _Results.Append(Prefix.TrimStart(",".ToCharArray())); // no preceeding text, remove comma _Prefix = null; } else { _Results.Append(Prefix); // append prefix as is _Prefix = null; } } public string OverridePrefix { set { _Prefix = value; } } internal void AppendStepPrefix() { string myPrefix = StepPrefix; StepPrefix = ""; if (Length != SectionNumberLength) return; if (Length == 0) return; if (myPrefix == "") return; if (_Results.ToString().EndsWith(myPrefix)) return; Append(myPrefix); } } public static class TransitionText { private delegate bool TransitionAppendFunction(TransitionBuilder tb); private static Dictionary _AppendMethods; private static void SetupMethods() { _AppendMethods = new Dictionary(); _AppendMethods.Add("{Proc Num}", AddTransitionProcNum); _AppendMethods.Add("{?.Proc Num}", AddOptionalTransitionProcNum); _AppendMethods.Add("{Proc Title}", AddTransitionProcTitle); _AppendMethods.Add("{?.Proc Title}", AddOptionalTransitionProcTitle); _AppendMethods.Add("{First Step}", AddStepNumber); _AppendMethods.Add("{Step Number}", AddStepNumber); // WCN2, tran type 6 _AppendMethods.Add("{Last Step}", AddRangeStepNumber); _AppendMethods.Add("{.}", AddIncludedStepNumber); _AppendMethods.Add("{Sect Hdr}", AddTranGetSectionHdr); _AppendMethods.Add("{?.Sect Hdr}", AddOptionalTranGetSectionHdr); _AppendMethods.Add("{Sect Title}", AddTranGetSectionTitle); _AppendMethods.Add("{?.Sect Title}", AddOptionalTranGetSectionTitle); _AppendMethods.Add("{?.Sect Num}", AddOptionalTranGetSectionNum); _AppendMethods.Add("{Sect Num}", AddTranGetSectionNumber); _AppendMethods.Add("{Sect Num All}", AddTranGetAllSectionNumber); _AppendMethods.Add("{Sect Number}", AddTranGetSectionNumber); // WCN2, tran type 6 _AppendMethods.Add("{Page Num}", AddPageNumber); _AppendMethods.Add("{Step Text}", AddStepText); } public static string GetResolvedText(ItemInfo fromInfo, int tranType, ItemInfo toItem, ItemInfo rangeItem, bool hasPageNum) { return GetResolvedText(fromInfo.ActiveFormat, fromInfo, tranType, toItem, rangeItem, hasPageNum); } private static Regex RegFixVCS = new Regex(@"Section ([0-9.]+)(.0)? Step \1"); // Find Section xxx followed by Step xxx public static string GetResolvedText(FormatInfo formatInfo, ItemInfo fromInfo, int tranType, ItemInfo toItem, ItemInfo rangeItem, bool pagenum) { if (!pagenum) { TransitionInfo ct = fromInfo.MyContent.ContentTransitionCount > 0 ? fromInfo.MyContent.ContentTransitions[0] : null; int trIU = -1; string cfg = string.Empty; if (ct != null) { trIU = fromInfo.MyContent.ContentTransitions[0].MyTransitionInfoUnique; cfg = fromInfo.MyContent.ContentTransitions[0].Config; } else { string pattern = string.Format(@"( [0-9]*){{1,2}}\[END>"); //string pattern = string.Format(@".*\\v ( [0-9]*){{1,2}}\[END>"); Match m = Regex.Match(fromInfo.MyContent.Text, pattern); if (m.Groups.Count > 1 && m.Groups[1].Value.ToUpper().Contains("(PAGE ~)")) // B2020-089, check for upper case Page ~ in case step was upper cased pagenum = true; } } if (toItem == null || rangeItem == null || toItem.IsDeleted || rangeItem.IsDeleted) return "Invalid Transition Destination"; TransitionBuilder tb = SetupTransitionBuilder(formatInfo, fromInfo, tranType, toItem, toItem.ItemID==rangeItem.ItemID && !toItem.IsHigh?toItem.LastSibling:rangeItem); if (pagenum) { // The tranType parameter is really the index. For page number transitions, get the transition // type (holdover from 16bit, used to define whether transitions are range) for range transitions, the page number goes after the 1st step. int strantype = tranType < tb._FromItem.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList.MaxIndex ? (int)tb._FromItem.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[tranType].Type : 0; if ((strantype == 1 || strantype == 2 || strantype == 4) && !tb._TransFormat.Contains("{Page Num}")) { // if range transition, the page number token needs to go after the first step, else it's at the end: if (strantype == 2 && tb._TransFormat.Contains("{First Step")) { tb._TransFormat = tb._TransFormat.Insert(tb._TransFormat.IndexOf("{First Step}")+12, " {Page Num}"); } else tb._TransFormat = tb._TransFormat + " {Page Num}"; } } if(_AppendMethods==null) SetupMethods(); if (toItem.MyDocVersion == null) return "?"; string retval = BuildString(tb); if(tb._FromItem.ActiveFormat.Name.ToUpper().StartsWith("VCB")) retval = RegFixVCS.Replace(retval,"Step $1");//Remove the Section portion if the step portion repeats the section portion only for VCB // Added for transitions to un-numbered steps if (retval == string.Empty) { retval = toItem.Ordinal.ToString(); fromInfo.NewTransToUnNumberedItem = true; //Volian.Base.Library.vlnStackTrace.ShowStackLocal("Setting Flag", 3, 10); //using (Item itm = fromInfo.Get()) //{ // ItemAnnotation ia = itm.ItemAnnotations.Add(AnnotationType.GetByName("Verifcation Required")); // ia.SearchText = "Transition to Un-Numbered Step"; //itm.Save(); //} } //if (Regex.IsMatch(retval, @".*\[[BP][0-9]{4,4}\].*") // && tb._ToItem.ActiveFormat != null // && tb._ToItem.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert ) // retval = Regex.Replace(retval, @" *(\[[BP][0-9]{4,4}\])+",""); //return retval; if (Regex.IsMatch(retval, @".* *\[([A-Z0-9 ]|\\u160\?)+\] *.*") && tb._ToItem.ActiveFormat != null && tb._ToItem.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) retval = Regex.Replace(retval, @" *(\[([A-Z0-9 ]|\\u160\?)+\])+ *", ""); if (Regex.IsMatch(retval, @".* *\(([A-Z ]|\\u160\?)+\) *.*") && tb._ToItem.ActiveFormat != null && tb._ToItem.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) retval = Regex.Replace(retval, @" *(\(([A-Z ]|\\u160\?)+\))+ *", ""); return retval; } private static TransitionBuilder SetupTransitionBuilder(FormatInfo formatInfo, ItemInfo fromInfo, int tranType, ItemInfo toItem, ItemInfo rangeItem) { TransitionBuilder tb = new TransitionBuilder(); tb._FormatData = formatInfo.PlantFormat.FormatData; // get the format of the transition string based on this transition's index into the TransData part of // format.... if (tranType >= tb._FormatData.TransData.TransTypeList.MaxIndex) // found during fixing of B2016-176 B2016-197 fixes invalid index error during import of procedure tranType = 0; // Replace 3 tokens ", {.}, {.}, {.}" with a single token "{.}" tb._TransFormat = tb._FormatData.TransData.TransTypeList[tranType].TransFormat.Replace(", {.}, {.}, {.}", "{.}"); if (formatInfo.PlantFormat.FormatData.TransData.UpcaseTranAnd) tb._TransFormat = tb._TransFormat.Replace("and", "AND"); tb._TransUI = (E_TransUI)tb._FormatData.TransData.TransTypeList[tranType].TransUI; tb._FromItem = fromInfo; tb._TranType = tranType; tb._ToItem = toItem; tb._RangeItem = rangeItem; tb._UnitProcSetString = tb._FormatData.TransData.TransTypeList[tranType].UnitProcSetString; return tb; } private static string BuildString(TransitionBuilder tb) { //Invalid Transition Check if (tb._ToItem.ActiveParent == null || tb._RangeItem.ActiveParent == null) return "?"; if (tb._TransFormat == "{Proc Num}, {Proc Title}, Step {First Step}" && tb._ToItem.IsSection && tb._ToItem.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && tb._FromItem.MyProcedure.ItemID == tb._ToItem.MyProcedure.ItemID) { tb._TransFormat = @"{Sect Num}, \ul {Sect Title}\ulnone "; tb._TranType = 4; } int startIndex = 0; int index = -1; int rexIndex = -1; string prefix = null; string prevToken = null; bool lastAdded = false; MatchCollection mc = Regex.Matches(tb._TransFormat, @"{(Proc Num|\?\.Proc Num|Proc Title|\?\.Proc Title|" + @"First Step|Step Number|Last Step|\.|Sect Hdr|\?\.Sect Hdr|Sect Title|\?\.Sect Title|\?\.Sect Num|Sect Num|" + @"Sect Number|Page Num|Step Text|Sect Num All)}"); foreach (Match m in mc) { string tmppref = prefix; prefix = null; rexIndex = m.Index; int rexEndToken = m.Index + m.Length - 1; if (rexIndex > startIndex) prefix = tb._TransFormat.Substring(startIndex, rexIndex - startIndex); if (prefix == null) prevToken = null; // if the last token did not add anything to the buffer, still want to put the text prefix in: if (!lastAdded && prefix == null) prefix = tmppref; if (startIndex == 0 && prefix != null && prefix.Length > 0) { tb.Append(prefix); prefix = ""; } string token = tb._TransFormat.Substring(rexIndex, rexEndToken - rexIndex + 1); // we need to flag condition where the step number already has the section number in it. For example, Wolf Creek // using WCN2, has some sections whose section number is 'D' and the step number is 'D1', or 'D2'. The resolved // transition text was coming out as 'DD1'. The format's HLS tab format contains '{Section Prefix}' whose implementation // adds the section number to the tab. if (token.Contains("Sect Num") && tb._TransFormat.Length > rexEndToken + 1) { int nxtTokenS = tb._TransFormat.IndexOf("{", rexEndToken); if (nxtTokenS > -1 && nxtTokenS == rexEndToken + 1) // the {step} token has to immediately follow the section num token { int nxtTokenE = tb._TransFormat.IndexOf("}", nxtTokenS); string nxtToken = tb._TransFormat.Substring(nxtTokenS, nxtTokenE - nxtTokenS + 1); tb.SectNumWithStepNum = tb._ToItem.IsStep && nxtToken.Contains("Step") && tb._ToItem.MyHLS.FormatStepData.TabData.IdentPrint.Contains("{Section Prefix}"); } } if (token == "{.}" && tb._ToItem.ItemID == tb._RangeItem.ItemID) { startIndex = tb._TransFormat.Length; // skip the rest of the trans format break; } if (_AppendMethods.ContainsKey(token)) { tb.Token = token; if (token[1] == '?') // If it's a conditional token, only update the prefix if the prefix is null tb.Prefix = prefix; else // If not conditional, force the prefix to be updated tb.OverridePrefix = prefix; lastAdded = _AppendMethods[token](tb); } else tb.Append("\\" + token.Substring(0, token.Length - 1) + "\\}"); startIndex = rexEndToken + 1; prevToken = token; if (startIndex >= tb._TransFormat.Length) { // F2023-029 the prefix contains the ending quotes followed by the prefix text for a step number // we need to strip off the prefix for the step number and append the text before it // B2023-017 added checks for Step followed by a regular space and if there isn't a space // F2023-076 the changes (F2023-029 & B2023-017) caused an extra ')' to be put out in the PromsManual1 format // The following code was modified to look for the quote that the Beaver Valley format uses and also adds // code to fix when the step number is also included, i.e. when transition is to a section or procedure, // don't include ', Step' but leave the quote, when transition is to a step remove quote too and the step // with number gets added elsewhere if (prefix != null && prefix.Contains("\", Step")) { if (tb._ToItem.IsSection || tb._ToItem.IsProcedure) { if (prefix.EndsWith(", Step\xA0")) // sometimes ends with a hardspace when {Step} token is used prefix = prefix.Remove(prefix.LastIndexOf(", Step\xA0")); if (prefix.EndsWith(", Step "))// sometimes ends with a normal space when {Step Number} token is used prefix = prefix.Remove(prefix.LastIndexOf(", Step ")); if (prefix.EndsWith(", Step"))// in case it doesn't end with any type of space prefix = prefix.Remove(prefix.LastIndexOf(", Step")); } else // transition to is a step, remove the ending quote along with word 'Step' that would appear at end of step. { if (prefix.EndsWith("\", Step\xA0")) // sometimes ends with a hardspace when {Step} token is used prefix = prefix.Remove(prefix.LastIndexOf("\", Step\xA0")); if (prefix.EndsWith("\", Step "))// sometimes ends with a normal space when {Step Number} token is used prefix = prefix.Remove(prefix.LastIndexOf("\", Step ")); if (prefix.EndsWith("\", Step"))// in case it doesn't end with any type of space prefix = prefix.Remove(prefix.LastIndexOf("\", Step")); } prefix = prefix.Trim(); if (prefix.Length > 0) tb.Append(prefix); } break; // jump put of the foreach loop } } if ((startIndex < tb._TransFormat.Length) && lastAdded) tb.Append(tb._TransFormat.Substring(startIndex, tb._TransFormat.Length - startIndex)); string myReturn = Regex.Replace(tb.ToString(), @"\.+", "."); return myReturn; } private static bool AddTransitionProcNum(TransitionBuilder tb) // Coded for HLP { string retstr = tb._ToItem.MyProcedure.MyContent.Number; // start with UnitSpecific procedure number. string unitnum = null; if (tb._ToItem.MyDocVersion != null && tb._ToItem.MyDocVersion.DocVersionConfig != null) unitnum = tb._ToItem.MyDocVersion.DocVersionConfig.Unit_ProcedureNumber; if (unitnum != null && unitnum.Length > 0) { unitnum = unitnum.Replace("-", @"\u8209?"); // B2022-004: Remove Proc PC/PC token from transition text. The '#' token was in the text 4 times, one for each applicable unit, so trans text had proc title 4 times: if (tb._FromItem.ActiveFormat != null && tb._FromItem.ActiveFormat.PlantFormat.FormatData.TransData.ProcLevelPCPC && unitnum.Contains("#")) unitnum = "#"; retstr = unitnum.Replace("#", retstr); } // B2022-004: Remove Proc PC/PC token from transition text. // F2024-030 for Vogtle Units 3 & 4, added KeepOnePCPCTag flag to keep one of the PC/PC tokens when editing if (tb._FromItem.ActiveFormat != null && !tb._FromItem.ActiveFormat.PlantFormat.FormatData.TransData.KeepOnePCPCTag && tb._FromItem.ActiveFormat.PlantFormat.FormatData.TransData.ProcLevelPCPC && retstr.ToUpper().StartsWith(""); retstr = retstr.Substring(indx + 1); if (retstr.StartsWith(@"\u8209?")) retstr = retstr.Substring(7); // don't start transition text with a '-' } // B2019-072: use si & psi as a prefix to the transition string outsideprefix = null; if (tb._ToItem.MyDocVersion != tb._FromItem.MyDocVersion) // doc versions not equal means it is an outside transition { if (tb._FromItem.ActiveFormat.PlantFormat.FormatData.PrintData.OutSideTransSetName) // must have format flag to include prefix { bool foundnull = false; if (tb._UnitProcSetString != null && tb._UnitProcSetString != "") // must have a string on transition to use as format { // get the type/token strings from the format so that can grab si or psi info. An example format // as used by AEP is: UnitProcSetString ="{PSI:UNITCOM}-{SI:SETNAME}-{PSI:SETID}-" string findMatch = "{.*?}"; MatchCollection ms = Regex.Matches(tb._UnitProcSetString,findMatch); string txt = tb._UnitProcSetString; FolderConfig fc = tb._ToItem.MyDocVersion.MyFolder.FolderConfig as FolderConfig; ProcedureConfig pc = new ProcedureConfig(tb._ToItem.MyProcedure.MyContent.Config); // Use a dictionary to get all of the tokens from the format string, then // go through all dictionary entries to make the replacements. Dictionary repStr = new Dictionary(); foreach (Match mtch in ms) { int offset = mtch.Index; string str = tb._UnitProcSetString.Substring(mtch.Index, mtch.Length); int indxcn = str.IndexOf(":"); string pt1 = str.Substring(1, indxcn - 1); string pt2 = str.Substring(indxcn+1, str.Length - 2 - indxcn); string defval = null; if (pt2.IndexOf('|')>-1) // C2019-023: allow default value on outside transition proc set specific info data { if (pt2.Length>pt2.IndexOf('|')+1) defval = pt2.Substring(pt2.IndexOf('|')+1); pt2 = pt2.Substring(0, pt2.IndexOf('|')); } string add = null; if (pt1.StartsWith("SI")) // B2019-076: SI fields go to the procedure set specific information (folder or working draft level, SI) add = DocVersionInfo.GetInheritedSIValue(tb._ToItem.MyProcedure, pt2); else add = pc.GetValue(pt1, pt2); if (add == null || add == "") { if (defval != null) add = defval; else foundnull = true; // don't do prefix if any of the fields are null and don't have a default value } if (!foundnull) repStr.Add(str, add); } if (!foundnull) { outsideprefix = tb._UnitProcSetString; foreach (string key in repStr.Keys) outsideprefix = outsideprefix.Replace(key, repStr[key]); outsideprefix = outsideprefix.Replace("-", @"\u8209?"); // use unicode for dashes } } } } // LATER: Format Flag TruncateProcNmAfter1stSpace (dropped plants) // LATER: Format Flag HardSpTranProcNumb (active plants) tb.AppendPrefix(); if (outsideprefix != null) retstr = outsideprefix + retstr; if (tb._FormatData.TransData.HardSpTranProcNumb) retstr = retstr.Replace(" ", @"\u160?"); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } private static bool AddOptionalTransitionProcNum(TransitionBuilder tb) { // token is passed in for future use, i.e. if text is placed between "?" and "." to // request other processing. // for now the only test is to check if the toitem is in the current procedure. if (tb._FromItem.MyProcedure.ItemID == tb._ToItem.MyProcedure.ItemID) return false; // tb.TextAdded; return AddTransitionProcNum(tb); } private static bool AddTransitionProcTitle(TransitionBuilder tb)// Coded for HLP { tb.AppendPrefix(); // if can't find procedure, just put in a question mark. if (tb._ToItem.PreviousID == null && tb._ToItem.ItemPartCount == 0 && tb._ToItem.ItemDocVersionCount == 0) { if (tb._ToItem.ActiveParent is ItemInfo && (tb._ToItem.ActiveParent as ItemInfo).Steps[0].ItemID == tb._ToItem.ItemID) { // If the transition is to the first applicable step, then use the location rather than outputting a question mark. } else { tb.Append("?"); return true; // (tb.TextAdded = true); } } string parenstr = tb._ToItem.MyProcedure.MyContent.Text; parenstr = parenstr.Replace("\\LINE ", " ").Replace("\r\n", " "); // B2022-061: \line (new line) in procedure title was putting a line in transition text in editor & actually // printing '\line' parenstr = parenstr.Replace("\\line ", ""); StringBuilder lretstr = new StringBuilder(); // LATER: For an else - Do I need to strip underlining here? See promsnt\lib\edit\gettran.c if (parenstr != "" || tb._FormatData.ProcData.PrintNoTitle) { lretstr.Append(tb._FormatData.TransData.DelimiterForTransitionTitle); lretstr.Append(tb._FormatData.TransData.CapsTransitions ? parenstr.ToUpper().Replace(@"\U", @"\u") : tb._FormatData.TransData.Cap1stCharTrans ? CapFirstLetterOnly(parenstr, 0) : parenstr); lretstr.Append(tb._FormatData.TransData.DelimiterForTransitionTitle); } tb.ReplaceToken(lretstr.ToString()); return (lretstr.Length != 0); } private static bool AddOptionalTransitionProcTitle(TransitionBuilder tb) { // token is passed in for future use, i.e. if text is placed between "?" and "." to // request other processing. // for now the only test is to check if the toitem is in the current procedure. if (tb._FromItem.MyProcedure.ItemID == tb._ToItem.MyProcedure.ItemID) return false; // tb.TextAdded; return AddTransitionProcTitle(tb); } private static string Tab(ItemInfo item, bool doStep) { // if this section has the DSS_AddDotZeroStdHLS, then we need to account for this when // concatenating text onto the tabs. bool hasDotZero = !item.IsProcedure && (item.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_AddDotZeroStdHLS) == E_DocStructStyle.DSS_AddDotZeroStdHLS; if (item.IsStep) hasDotZero |= item.MyHLS.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) if (item == null) return ""; string sret = ""; switch (item.MyContent.Type / 10000) { case 0: //procedure sret = ProcedureInfo.Get(item.ItemID).MyTab.CleanText; break; case 1: // section sret = SectionInfo.Get(item.ItemID).MyTab.CleanText; break; case 2: // step ItemInfo pitem = item; bool hasDelim = item.ActiveFormat.PlantFormat.FormatData.TransData.StepSubstepDelimeter != null; List DelimList = null; if (!hasDelim) { DelimList = new List(); SeqTabFmtList seqtabs = item.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.SeqTabFmtList; foreach (SeqTabFmt seqtab in seqtabs) { string delim = seqtab.PrintTabFormat.Replace("{seq}", ""); DelimList.Add(delim.Trim()); } } while (!pitem.IsHigh) { //string thisTab = StepInfo.Get(pitem.ItemID).MyTab.CleanText; string thisTab = pitem.MyTab.CleanText;// StepInfo.Get(pitem.ItemID).MyTab.CleanText; // remove delimiters of '.' and ')' in tab. if (!hasDelim) { // get list of delimiters to remove from the format: foreach (string rmvDelim in DelimList) thisTab = thisTab.Replace(rmvDelim, ""); } if (pitem.IsRNOPart) { if (thisTab == null || thisTab == "") sret = "RNO." + sret; else { thisTab = thisTab.Trim(" ".ToCharArray()); sret = "RNO." + thisTab + sret; } } else { if (thisTab != null && thisTab != "") { thisTab = thisTab.Trim(" ".ToCharArray()); if (hasDelim && !thisTab.EndsWith(".") && !thisTab.EndsWith(")")) thisTab = thisTab + "."; if (hasDotZero && thisTab.EndsWith(".0.")) thisTab = thisTab.Substring(0, thisTab.Length - 2); } // RHM 20130326 2039 - I added the logic to limit the addition of the section tab to // the existing tab if it starts the same. // Westinghouse/System Procs/WRS-101/Add6/4.2.7 Transition to 4.2.5 if(sret == "" || !sret.StartsWith(thisTab)) sret = thisTab + sret; } pitem = pitem.ActiveParent as ItemInfo; if (pitem == null) break; } // add hls tab if it's not already in the tab. doStep was added to handle the TStepNoFlag // which is used to define whether the step number is included in the range transition text // if the 'to' transition is a substep. Note that only skip the following if going to a substep // thus change 'doStep' to true if the 'to' transition is a hls. if (!doStep && item.IsHigh) doStep = true; if (doStep && pitem.IsHigh) { Tab myTab = pitem.MyDocVersion.DocVersionConfig.SelectedSlave == 0 ? StepInfo.Get(pitem.ItemID).MyTab : pitem.MyTab; string hlsTab = myTab.BasicTab ?? myTab.CleanTextNoSymbols; // C2017-026: have visual indicator for CAS Step (but remove for transitions): if (pitem.FormatStepData.TabData.IdentEdit.Contains("*. ")) hlsTab = hlsTab.Replace("*", ""); if (!sret.StartsWith(hlsTab.Trim(" ".ToCharArray()))) { if (!hasDelim) foreach (string rmvDelim in DelimList) hlsTab = hlsTab.Replace(rmvDelim, ""); hlsTab = hlsTab.Trim(" ".ToCharArray()); if (hasDelim && !hlsTab.EndsWith(".") && !hlsTab.EndsWith(")")) hlsTab = hlsTab + "."; if (hasDotZero) { if (item.IsHigh) hlsTab = hlsTab.Substring(0, hlsTab.Length - 1); else if (hlsTab.EndsWith(".0.")) hlsTab = hlsTab.Substring(0, hlsTab.Length - 2); if (sret == "" || !sret.StartsWith(hlsTab)) sret = hlsTab + sret; } else sret = hlsTab + sret; } } break; } sret = sret.Trim(" .".ToCharArray()); if(!sret.Contains("("))sret = sret.Trim(" .)".ToCharArray()); return sret; } private static bool AddPageNumber(TransitionBuilder tb) { //At some point, add a property off a section 'IsFoldout' and use the next two lines: //if ((myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts && mySection.MyContent.Number.ToUpper() == "FOLDOUT") //|| (myProcedure.ActiveFormat.PlantFormat.FormatData.PrintData.AlternateFloatingFoldout && mySection.MyContent.Text.ToUpper().Contains("FOLDOUT"))) if (tb._ToItem.PageNumber != -1 && (tb._FromItem.PageNumber != -1 || (tb._FromItem.ActiveSection.MyConfig as SectionConfig).Section_IsFoldout == "Y")) //C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box { int pgoffset = tb._ToItem.PageNumber - tb._FromItem.PageNumber; tb._ToItem.PageNumberUsed = tb._ToItem.PageNumber; // if the plant does not want to use the 'Next Page' or 'Previous Page' text, reset the // pgoffset so that the specific page number is always printed even if it is next or previous page: if (tb._ToItem.ActiveFormat.PlantFormat.FormatData.TransData.UseSpecificPageNo) pgoffset = -2; switch (pgoffset) { case 1: tb.Append(" (Next Page)"); break; case -1: tb.Append(" (Previous Page)"); break; case 0: break; default: //F2024-048 use a hard space (\\u160;) instead of a space in the page number text // to keep that text together on the page //B2024-026: hard space unicode ends with '?' not ';' tb.Append(string.Format(" (Page{0}{1})", "\\u160?", tb._ToItem.PageNumber + 1)); break; } } else { tb.Append(" (Page ~)"); } return true; } private static bool AddStepNumber(TransitionBuilder tb) { // If we're on a step put out the step number. ItemInfo secitm = TranGetSectionItem(tb._ToItem); if ((!((tb._TransUI & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone)) || tb._ToItem.MyContent.Type > 20000) { if (tb._FormatData.PrintData.SpecialCaseCalvertAlarm && tb._ToItem.IsHigh && tb._ToItem.FormatStepData.StepEditData.TypeMenu.MenuItem.ToUpper().Contains("WINDOW")) { //use text rather than tab: (BGE Alarm window transitions - C2014-006) tb.ReplaceToken(Tab(tb._ToItem, true) + ' ' + tb._ToItem.DisplayText); return true; } else if (tb.HasText) { // check for transition that goes to a procedure step section with title of 'Procedure steps' followed // by ', Step'. This should output as 'Procedure step xyz' rather than 'Procedure steps, step xyz' // TODO: NEED TO USE A FORMAT VARIABLE TO CONTROL THE FOLLOWING if ((tb._FormatData.TransData.AdjustStepTransitionText || tb._ToItem.ActiveFormat.Name.StartsWith("OHLP")) && !tb._TransFormat.Contains("{Last Step}") && tb.Prefix != null && tb.Prefix.ToUpper().Contains(", STEP") && tb.ToString().ToUpper().EndsWith("PROCEDURE STEPS")) { tb.Remove(tb.Length - 15, 15); // remove "procedure steps" tb.Append("procedure Step"); tb.ResetPrefix(" "); // just setting = to a space wasn't resetting prefix. } string tmpStr = tb.ToString(); if (tmpStr.ToUpper().EndsWith(", STEP ") && (tb.Prefix.ToUpper().EndsWith(", STEP "))) tb.Remove(tb.Length - 7, 7); // 7 is length of ", Step " tb.AppendPrefix(); } //else if (tb._TranType == 4 && tb._ToItem.MoreThanOneStepSection()) else if (tb._TranType == 4 && tb._ToItem.MoreThanOneStepSection() || tb._TranType == 5) { tb.AppendPrefix(); } if (tb._ToItem.PreviousID == null && tb._ToItem.ItemPartCount == 0 && tb._ToItem.ItemDocVersionCount == 0) { // Logic added for handling applicability. If the first item is not applicable, then the second item will effectively become // the first item but it's itempartcount will be zero if (tb._ToItem.ActiveParent is ItemInfo && (tb._ToItem.ActiveParent as ItemInfo).Steps[0].ItemID == tb._ToItem.ItemID) { tb.AppendStepPrefix(); tb.ReplaceToken(Tab(tb._ToItem, true)); } else tb.Append("?"); } else { tb.AppendStepPrefix(); tb.ReplaceToken(Tab(tb._ToItem, true)); } return true; } else if ((tb._ToItem.IsSection || tb._ToItem.IsProcedure) && ((tb._TransUI & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone)) { string tmpStr = tb.ToString(); if (tmpStr.ToUpper().EndsWith(", STEP ")) tb.Remove(tb.Length - 7, 7); // 7 is length of ", Step " else if (tb.Prefix != null && tb.Prefix.StartsWith(")") && (tb.ToString().IndexOf("(") > -1)) tb.Append(")"); return true; } else return false; } private static bool AddRangeStepNumber(TransitionBuilder tb) { tb.AppendPrefix(); if (tb._RangeItem.PreviousID == null && tb._RangeItem.ItemPartCount == 0 && tb._RangeItem.ItemDocVersionCount == 0) tb.Append("?"); else tb.ReplaceToken(Tab(tb._RangeItem, tb._RangeItem.ActiveFormat.PlantFormat.FormatData.TransData.TStepNoFlag)); return true; } private static bool AddIncludedStepNumber(TransitionBuilder tb) { Dictionary rangeAncestors = GetAncestors(tb._RangeItem); tb.AppendPrefix(); bool usedRangeAncestor = false; // Refresh Next Items tb._ToItem.RefreshNextItems(); ItemInfo next = GetNextItem(tb._ToItem, rangeAncestors, ref usedRangeAncestor); string lastTab = Tab(tb._RangeItem, tb._RangeItem.ActiveFormat.PlantFormat.FormatData.TransData.TStepNoFlag); while (next.ItemID != tb._RangeItem.ItemID) { string thisTab = Tab(next, tb._RangeItem.ActiveFormat.PlantFormat.FormatData.TransData.TStepNoFlag); if (lastTab == thisTab) break; tb.ReplaceToken(", " + thisTab); next = GetNextItem(next, rangeAncestors, ref usedRangeAncestor); } tb._UsedRangeAncestor = usedRangeAncestor; return true; } private static bool AddStepText(TransitionBuilder tb) { tb.AppendPrefix(); string txt = tb._ToItem.MyContent.Text; tb.Append(txt); return true; } private static Dictionary GetAncestors(ItemInfo itemInfo) { Dictionary retval = new Dictionary(); while (!itemInfo.IsHigh) { ItemInfo parent = itemInfo.MyActiveParent as ItemInfo; retval.Add(parent.ItemID, itemInfo.FirstSibling); itemInfo = parent; } return retval; } private static ItemInfo GetNextItem(ItemInfo next, Dictionary rangeAncestors, ref bool usedRangeAncestor) { if (rangeAncestors.ContainsKey(next.ItemID)) return rangeAncestors[next.ItemID]; if (next.MyDocVersion.DocVersionConfig.SelectedSlave == 0) { while (next.NextItem == null) { next = next.ActiveParent as ItemInfo; if (next == null) throw (new Exception("Cannot find Next Item")); } return next.NextItem; } while (next.NextItem == null) { next = next.ActiveParent as ItemInfo; if(next == null) throw(new Exception("Cannot find Next Item")); } return next.NextItem; } private static bool AddOptionalTranGetSectionHdr(TransitionBuilder tb) { // first handle 'to' non-step section. Always add it. if (tb._ToItem.IsSection && !tb._ToItem.IsStepSection) return AddTranGetSectionHdr(tb); int cntsect = 0; ItemInfo sect = TranGetSectionItem(tb._ToItem); if (tb._ToItem.MyProcedure.Sections == null) tb._ToItem.MyProcedure.MyContent.RefreshContentParts(); foreach (ItemInfo ii in tb._ToItem.MyProcedure.Sections) if (ii.IsStepSection) cntsect++; // If Procedure going to has only 1 step section, do not add it. if (cntsect == 1) return false; // tb.TextAdded; // If procedure going to has more than 1 step section and is NOT same procedure // and going to default section, do not add it. if (tb._ToItem.MyProcedure.ItemID != tb._FromItem.MyProcedure.ItemID && sect != null && sect.IsDefaultSection) return false; // tb.TextAdded; // if in same procedure and same section do not add it. if (tb._ToItem.MyProcedure.ItemID == tb._FromItem.MyProcedure.ItemID && sect == TranGetSectionItem(tb._FromItem) && ! tb._ToItem.IsSection) return false; // If a 'thru' range, only put out the section if it's to a different section // that is not the default section. if (((tb._TransUI & E_TransUI.StepLast) == E_TransUI.StepLast) && ((tb._TransUI & E_TransUI.SectMenuStep) == E_TransUI.SectMenuStep)) { ItemInfo fi = tb._FromItem; while (!fi.IsSection)fi = fi.ActiveParent as ItemInfo; ItemInfo ti = tb._ToItem; while (!ti.IsSection) ti = ti.ActiveParent as ItemInfo; if (fi.ItemID == ti.ItemID || ti.IsDefaultSection) return false; // tb.TextAdded; } return AddTranGetSectionHdr(tb); } private static bool AddTranGetSectionHdr(TransitionBuilder tb) { // output from 16-bit code looks like section header // if this is a step section & the default section, just return //if (TranGetSectionItem(itminfo).IsDefaultSection) return; StringBuilder retstr = new StringBuilder(); //B2016-003 Transitions to sections whose number has a leading space was causing errors in transition text retstr.Append(TrimSectNumber(TranGetSectionNumber(tb,false))); string txt; if(retstr.Length > 0) txt = TranGetSectionTitle(tb,tb._ToItem); else txt = TranGetSectionTitle(tb,tb._ToItem, true); if (retstr.Length > 0 && (txt!=null && txt.Length > 0)) retstr.Append(", "); retstr.Append(txt); tb.AppendPrefix(); tb.ReplaceToken(retstr.ToString()); return (retstr.Length != 0); } private static bool AddOptionalTranGetSectionTitle(TransitionBuilder tb) { // token is passed in for future use, i.e. if text is placed between "?" and "." to // request other processing. // for now the only test is to check if the toitem is in the current section. if (TranGetSectionItem(tb._FromItem).ItemID == TranGetSectionItem(tb._ToItem).ItemID) return false; // tb.TextAdded; tb.AppendPrefix(); string retstr = TranGetSectionTitle(tb,tb._ToItem); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } private static bool AddOptionalTranGetSectionNum(TransitionBuilder tb) { if (TranGetSectionItem(tb._FromItem).ItemID == TranGetSectionItem(tb._ToItem).ItemID) return false; if (tb.SectNumWithStepNum) return false; if (tb._ToItem.IsSection) return false; tb.AppendPrefix(); //B2016-003 Transitions to sections whose number has a leading space was causing errors in transition text string retstr = TrimSectNumber(TranGetSectionNumber(tb, false)); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } private static bool AddTranGetSectionTitle(TransitionBuilder tb) { // LATER: Cap1stSectionTitle, CapFirstLetterOnly if (tb._FormatData.TransData.UseSecTitles) { string retstr = TranGetSectionTitle(tb,tb._ToItem); tb.AppendPrefix(); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } return false; } private static bool AddTranGetSectionNumber(TransitionBuilder tb) { return AddTranGetSectionNumber(tb, false); } private static bool AddTranGetAllSectionNumber(TransitionBuilder tb) { return AddTranGetSectionNumber(tb, true); } private static bool AddTranGetSectionNumber(TransitionBuilder tb, bool allLevels) { if (tb._TranType == 1 && tb._ToItem.ActiveSection.ItemID == tb._FromItem.ActiveSection.ItemID) return false; if (tb.SectNumWithStepNum) return false; if (tb._TranType == 0 && (tb._ToItem.IsSection || tb._ToItem.IsProcedure) && ((tb._TransUI & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone)) { string tmpStr = tb.ToString(); if (tmpStr.ToUpper().EndsWith(", STEP ")) tb.Remove(tb.Length - 7, 7); // 7 is length of ", Step " else if (tb.Prefix != null && tb.Prefix.StartsWith(")")) tb.Append(")"); return true; } if (tb.SectionsUsed.Contains(tb._ToItem.ItemID)) return false; //B2016-003 Transitions to sections whose number has a leading space was causing errors in transition text string retstr = TrimSectNumber(TranGetSectionNumber(tb, allLevels)); tb.SectionsUsed.Add(tb._ToItem.ItemID); if (retstr != null && retstr != "") { int indx = retstr.IndexOf(' '); // 16 bit code only processes 1st occurance if (indx > -1) // Not a while loop in 16 bit. { // (see \promsnt\lib\edit\gettran.c:TransitionCat) retstr = retstr.Remove(indx, 1); retstr = retstr.Insert(indx, @"\u160?"); } } // *** DO NOT DELETE - to fix a problem where the word ,step was appearing twice when there was no // section tab. //if (retstr!=null&&retstr!="") tb.AppendPrefix(); tb.AppendPrefix(); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } //B2016-003 Transitions to sections whose number has a leading space was causing errors in transition text private static string TrimSectNumber(string str) { if (str == null) return str; return str.TrimStart(); } private static string FixTitleCase(Match m) { if (Regex.IsMatch(m.Value, @"^[A-Za-z]+\.?$")) { // don't title case "words" that have no vowles if (Regex.IsMatch(m.Value.ToUpper(), @"^[BCDFGHJKLMNPQRSTVWXZ]+\.?$")) return m.Value; string part1 = m.Value.Substring(0, 1); string part2 = m.Value.Substring(1); return part1.ToUpper() + part2.ToLower(); } return m.Value; } private static string CapFirstLetterOnly(string retstr, int p) { // LATER: write code to capitalize first letter (active plants) // F2021-037: Support title case include '/' as separator (added '/' to regex replace) string lretstr = Regex.Replace(retstr, @"([^ ,/]+)", new MatchEvaluator(FixTitleCase)); return lretstr; } // TODO: Section methods are not complete.... private static ItemInfo TranGetSectionItem(ItemInfo itminfo) { ItemInfo tmpitm = itminfo; if(itminfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) return tmpitm.IsSection ? tmpitm : (tmpitm.ActiveSection ?? tmpitm); while (tmpitm.MyContent.Type >= 20000) tmpitm = tmpitm.MyParent; return tmpitm; } private static string TranGetSectionNumber(ItemInfo itminfo) { ItemInfo tmpitm = TranGetSectionItem(itminfo); if (!tmpitm.IsSection) return ""; string str = tmpitm.MyContent.Number; // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(itminfo.MyDocVersion, str); return (str); } private static string TranGetSectionNumber(TransitionBuilder tb, bool allLevels) { //if (tb._FromItem.MyContent.InList(5322)) Console.WriteLine("Here"); string str1 = TranGetSectionNumber(tb._ToItem); // F2024-008 added flag to title case the section number in transitions if (tb._FormatData.TransData.Cap1stCharTransSectionNumber) str1 = CapFirstLetterOnly(str1, 0); if(!tb._ToItem.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) return str1; List FromSections = GetSections(tb._FromItem.ActiveSection); List ToSections = GetSections(tb._ToItem.ActiveSection); if (!allLevels && tb._FromItem.MyProcedure.ItemID == tb._ToItem.MyProcedure.ItemID && tb._FromItem.ActiveSection.ItemID != tb._ToItem.ItemID) { while (ToSections.Count > 1 && FromSections.Count > 1 && ToSections[0].ItemID == FromSections[0].ItemID) { ToSections.RemoveAt(0); FromSections.RemoveAt(0); if (ToSections.Count == 1 && ToSections[0].ItemID == tb._ToItem.ItemID) break; } } //string str = tmpitm.MyContent.Number; string str = BuildSectionPath(ToSections); // B2024-025 - process all of the applicability token (, , ) str = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(tb._ToItem.MyDocVersion, str); //if (!str.EndsWith(".") && tb._ToItem.ItemID != tb._ToItem.ActiveSection.ItemID) tb.StepPrefix = "."; tb.SectionNumberLength = str.Length; return (str); } private static string BuildSectionPath(List ToSections) { StringBuilder sb = new StringBuilder(); string lastPart=""; string sep = ""; foreach (ItemInfo si in ToSections) { string thisPart = si.MyContent.Number.Trim(); if (lastPart.EndsWith(".0")) { if(thisPart.StartsWith( lastPart.Substring(0,lastPart.Length-1))) lastPart=""; } if (si.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && thisPart == lastPart && IsRoman(lastPart)) lastPart = ""; if (si.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && thisPart.StartsWith(lastPart+".")) lastPart = ""; sb.Append(sep + lastPart.TrimEnd(" .".ToCharArray())); if (sb.Length > 0) sep = "."; lastPart = thisPart; } sb.Append(sep + lastPart.TrimEnd(" ".ToCharArray())); return sb.ToString(); } private static bool IsRoman(string number) { return Regex.IsMatch(number,@"[IVXLCDM]+\.?"); } private static List GetSections(ItemInfo myItemInfo) { List retval = new List(); while (myItemInfo != null && myItemInfo.IsSection) { retval.Insert(0, myItemInfo); myItemInfo = myItemInfo.ActiveParent as ItemInfo; } return retval; } private static string TranGetSectionTitle(TransitionBuilder tb, ItemInfo itminfo) { // LATER: Cap1stSectionTitle, CapFirstLetterOnly if (tb._FormatData.TransData.UseSecTitles) { ItemInfo tmpitm = TranGetSectionItem(itminfo); string sectionTitle = tmpitm.MyContent.Text; sectionTitle = (tb._FormatData.TransData.CapsTransitionsSection ? sectionTitle.ToUpper().Replace(@"\U", @"\u") : tb._FormatData.TransData.Cap1stCharTransSection ? CapFirstLetterOnly(sectionTitle, 0) : sectionTitle); // F2024-008 Added flag to surround the section title with parenthesis in transitions if (tb._FormatData.TransData.ParensAroundSectionTitle) sectionTitle = string.Format("({0})", sectionTitle); // B2017-236 Replace embedded returns with spaces and trim the spaces from the end of the section title. return TrimSectionTitle(sectionTitle); } return null; } // B2017-236 Replace embedded returns with spaces and trim the spaces from the end of the section title. private static string TrimSectionTitle(string sectionTitle) { if (sectionTitle == null) return sectionTitle;//Check for null sectionTitle = Regex.Replace(sectionTitle, @"(\\(line|par) ?)+", " ");//replace hard and soft returns with spaces return sectionTitle.TrimEnd();//Trim the spaces for the end of the section title } private static string TranGetSectionTitle(TransitionBuilder tb, ItemInfo itminfo, bool overRide) { // LATER: Cap1stSectionTitle, CapFirstLetterOnly if (overRide) { ItemInfo tmpitm = TranGetSectionItem(itminfo); string sectionTitle = tmpitm.MyContent.Text; sectionTitle = (tb._FormatData.TransData.CapsTransitionsSection ? sectionTitle.ToUpper().Replace(@"\U", @"\u") : tb._FormatData.TransData.Cap1stCharTransSection ? CapFirstLetterOnly(sectionTitle, 0) : sectionTitle); // B2017-236 Replace embedded returns with spaces and trim the spaces from the end of the section title. return TrimSectionTitle(sectionTitle); } return null; } } }