using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using Csla; using Csla.Data; namespace VEPROMS.CSLA.Library { public partial class TransitionInfo { public string PathTo { get { return MyItemToID.Path; } } public string PathFrom { get { return MyContent.ContentItems[0].Path; } } public string ResolvePathTo(FormatInfo fi, ItemInfo itminfo, int tranType, ItemInfo toitem, ItemInfo rangeitem) { return TransitionText.GetResolvedText(fi, itminfo, tranType, toitem, rangeitem); } public string ResolvePathTo() { 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); } } #region AffectedTransitons public partial class TransitionInfoList { [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); 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(); 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); 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); 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); 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 } 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 Token { get { return _Token; } set { _Token = value; } } private string _Prefix; public string Prefix { get { return _Prefix; } set { if(_Prefix==null)_Prefix = value; } } 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.Remove(indx, 1); str.Insert(indx, @"\u160?"); } } return _Results.Append(str); } 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 (HasText && Prefix != null) { _Results.Append(Prefix); _Prefix = null; } } public string OverridePrefix { set { _Prefix = value; } } } 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("{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}", AddTranGetSectionNumber); } public static string GetResolvedText(ItemInfo fromInfo, int tranType, ItemInfo toItem, ItemInfo rangeItem) { return GetResolvedText(fromInfo.ActiveFormat, fromInfo, tranType, toItem, rangeItem); } public static string GetResolvedText(FormatInfo formatInfo, ItemInfo fromInfo, int tranType, ItemInfo toItem, ItemInfo rangeItem) { TransitionBuilder tb = SetupTransitionBuilder(formatInfo, fromInfo, tranType, toItem, toItem.ItemID==rangeItem.ItemID && !toItem.IsHigh?toItem.LastSibling:rangeItem); if(_AppendMethods==null) SetupMethods(); return BuildString(tb); } 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.Count) tranType = 0; // Replace 3 tokens ", {.}, {.}, {.}" with a single token "{.}" tb._TransFormat = tb._FormatData.TransData.TransTypeList[tranType].TransFormat.Replace(", {.}, {.}, {.}", "{.}"); tb._TransUI = (E_TransUI)tb._FormatData.TransData.TransTypeList[tranType].TransUI; tb._FromItem = fromInfo; tb._TranType = tranType; tb._ToItem = toItem; tb._RangeItem = rangeItem; return tb; } private static string BuildString(TransitionBuilder tb) { int startIndex = 0; int index = -1; string prefix = null; bool lastAdded = false; while ((index = tb._TransFormat.IndexOf("{", startIndex)) > -1) { if (index > startIndex) prefix = tb._TransFormat.Substring(startIndex, index - startIndex); if (startIndex == 0 && prefix != null && prefix.Length > 0) { tb.Append(prefix); prefix = ""; } int endtokn = tb._TransFormat.IndexOf("}", index); string token = tb._TransFormat.Substring(index, endtokn - index + 1); 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 = endtokn + 1; if (startIndex >= tb._TransFormat.Length) break; } if (startIndex < tb._TransFormat.Length) tb.Append(tb._TransFormat.Substring(startIndex, tb._TransFormat.Length - startIndex - 1)); return (tb.ToString()); } // TODO: TStepNoFlag, i.e. include step number in range items. // TODO: TStepNoFlag, i.e. include step number in range items. // TODO: For hlp: LowerCaseTranNumber - lower case substep numbers in transitions private static bool AddTransitionProcNum(TransitionBuilder tb) // Coded for HLP { string retstr = tb._ToItem.MyProcedure.MyContent.Number; // LATER: start with UnitSpecific procedure number. // LATER: Format Flag TruncateProcNmAfter1stSpace (dropped plants) // LATER: Format Flag HardSpTranProcNumb (active plants) tb.AppendPrefix(); 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) { tb.Append("?"); return true; // (tb.TextAdded = true); } string parenstr = tb._ToItem.MyProcedure.MyContent.Text; 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); } // LATER: if (DoSectionTransitions && GetSTepNO(TSeq1)) TransitionCat(AddCommaStep", Step")); 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) { 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; while (!pitem.IsHigh) { string thisTab = StepInfo.Get(pitem.ItemID).MyTab.CleanText; 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 (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) thisTab = thisTab + "."; } sret = thisTab + sret; } pitem = pitem.ActiveParent as ItemInfo; if (pitem == null) break; } // add hls tab. if (pitem.IsHigh) { string hlsTab = StepInfo.Get(pitem.ItemID).MyTab.CleanText; hlsTab = hlsTab.Trim(" ".ToCharArray()); if (!hlsTab.EndsWith(".") && !hlsTab.EndsWith(")")) hlsTab = hlsTab + "."; sret = hlsTab + sret; } break; } sret = sret.Trim(" .)".ToCharArray()); return sret; } 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.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' if (!tb._TransFormat.Contains("{Last Step}") && 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.Prefix = " "; } tb.AppendPrefix(); } if (tb._ToItem.PreviousID == null && tb._ToItem.ItemPartCount == 0 && tb._ToItem.ItemDocVersionCount == 0) tb.Append("?"); else tb.ReplaceToken(Tab(tb._ToItem)); 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)); return true; } private static bool AddIncludedStepNumber(TransitionBuilder tb) { Dictionary rangeAncestors = GetAncestors(tb._RangeItem); tb.AppendPrefix(); bool usedRangeAncestor = false; ItemInfo next = GetNextItem(tb._ToItem, rangeAncestors, ref usedRangeAncestor); while (next.ItemID != tb._RangeItem.ItemID) { tb.ReplaceToken(", " + Tab(next)); // TODO: Intermediate Range. next = GetNextItem(next, rangeAncestors, ref usedRangeAncestor); } tb._UsedRangeAncestor = usedRangeAncestor; 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]; while (next.NextItem == null) next = next.ActiveParent as ItemInfo; 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); 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 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(); retstr.Append(TranGetSectionNumber(tb._ToItem)); string txt = TranGetSectionTitle(tb,tb._ToItem); if (retstr.Length > 0 && 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 AddTranGetSectionTitle(TransitionBuilder tb) { // LATER: Cap1stSectionTitle, CapFirstLetterOnly if (tb._FormatData.TransData.UseSecTitles) { string retstr = TranGetSectionTitle(tb,tb._FromItem); tb.AppendPrefix(); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } return false; } private static bool AddTranGetSectionNumber(TransitionBuilder tb) { string retstr = TranGetSectionNumber(tb._ToItem); tb.AppendPrefix(); tb.ReplaceToken(retstr); return (retstr != null && retstr != ""); } private static string CapFirstLetterOnly(string retstr, int p) { string lretstr = retstr; // LATER: write code to capitalize first letter (active plants) return lretstr; } // TODO: Section methods are not complete.... private static ItemInfo TranGetSectionItem(ItemInfo itminfo) { ItemInfo tmpitm = itminfo; while (tmpitm.MyContent.Type >= 20000) tmpitm = tmpitm.MyParent; return tmpitm; } private static string TranGetSectionNumber(ItemInfo itminfo) { ItemInfo tmpitm = TranGetSectionItem(itminfo); return (tmpitm.MyContent.Number); } private static string TranGetSectionTitle(TransitionBuilder tb, ItemInfo itminfo) { // LATER: Cap1stSectionTitle, CapFirstLetterOnly if (tb._FormatData.TransData.UseSecTitles) { ItemInfo tmpitm = TranGetSectionItem(itminfo); return (tmpitm.MyContent.Text); } return null; } } }