using System; using System.Collections.Generic; using System.Text; using Csla; using Csla.Data; using System.Xml; using System.Data.SqlClient; using System.Data; using System.Text.RegularExpressions; namespace VEPROMS.CSLA.Library { public partial class Content { public string LastChangedString { get { return ContentInfo.FormatByteArray(_LastChanged); } } public override string ToString() { return string.Format("{0} {1}", Number, Text); } public bool FixTransitionText(TransitionInfo tran) // B2017-076 return whether Transitions were processed (used when importing a procedure) { return FixTransitionText(tran, false); } public bool FixTransitionText(TransitionInfo tran, bool forceConvertToText) { bool didFixATransition = false; // B2017-076 return whether Transitions were processed (used when importing a procedure) //string transText = tran.ResolvePathTo(); //string lookFor = string.Format(@"", tran.TranType, tran.TransitionID); ////string lookFor = string.Format(@"", tran.TranType, tran.TransitionID); //Match m = Regex.Match(Text, lookFor); //if (m != null && m.Groups.Count > 1) //{ // System.Text.RegularExpressions.Group g = m.Groups[3]; // if (g.ToString() != transText) // Text = Text.Substring(0, g.Index) + transText + Text.Substring(g.Index + g.Length); //} string newvalue = tran != null ? tran.ResolvePathTo() : string.Empty; if (forceConvertToText) newvalue = "?"; string findLink = @""; // B2019-084: Procedure number change not updated in pasted transition - there were 2 '", rousg.ROUsageID); string lookFor; if (tran == null) { // B2018-002 - Invalid Transitions - Handle Range Transitions int loc1 = Text.IndexOf("#Link:Transition:", 0); if (loc1 > 0) loc1 += ("#Link:Transition:").Length; else loc1 = Text.IndexOf("#Link:TransitionRange:", 0) + ("#Link:TransitionRange:").Length; ; int loc2 = Text.IndexOf(" ", loc1); string trantype = Text.Substring(loc1, loc2 - loc1); loc1 = loc2 + 1; loc2 = Text.IndexOf(" ", loc1); string tranid = Text.Substring(loc1, loc2 - loc1); lookFor = string.Format(@"^", trantype, tranid); } else lookFor = string.Format(@"^", tran.TranType, tran.TransitionID); foreach (Match mm in ms) { Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = Text.Substring(myIndex, myLength); newvalue = newvalue.Replace("{", @"\{").Replace("}", @"\}"); if (newvalue == "?") // B2017-165 used to also check if gg and newvalue were different AND newvalue = '?'. Had case where gg also was = '?' (from 16-bit conversion) { string rv = ConvertTransitionToText(tran, newvalue); //Text = Text.Substring(0, myIndex - 14) + gg + Text.Substring(myIndex + myLength); using (Item myitem = this.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 transition is converted to text] //Check for validity // B2018-002 - Invalid Transitions - Add a prefix of invalid if the transition record is missing string prefix = ""; if (tran == null) prefix = "Invalid "; Annotation.MakeAnnotation(myitem, AnnotationType.GetByNameOrCreate("Link Converted To Text"), "", prefix + string.Format("Transition ({0}) converted to text", ItemInfo.ConvertToDisplayText(gg)), null); } if (tran != null) Transition.Delete(tran.TransitionID); didFixATransition = true; // B2017-076 return Transitions were processed (used when importing a procedure) break; } //else if ((gg.Contains("\\u8209?") ? gg.Replace("\\u8209?", "-") : gg) != (newvalue.Contains("\\u8209?") ? newvalue.Replace("\\u8209?", "-") : newvalue)) else if ((gg.Replace(@"\u8209?", "-").Replace(@"\u9568?", @"\\")) != (newvalue.Replace(@"\u8209?", "-").Replace(@"\u9568?", @"\\"))) { Text = Text.Substring(0, myIndex) + newvalue + Text.Substring(myIndex + myLength); didFixATransition = true; // B2017-076 return Transitions were processed (used when importing a procedure) break; // Text has been processed } } } // see if there is a grid to update too. if (tran != null && tran.MyContent.MyGrid != null) { //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* ([^#]*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:Transition[^:]*?:{0} {1}( [0-9]*){{1,2}}\[END>", tran.TranType, tran.TransitionID); //Match mg = Regex.Match(MyGrid.Data, lookForXml); //if (mg != null && mg.Groups.Count > 1) //{ // System.Text.RegularExpressions.Group g = mg.Groups[3]; // if (g.ToString() != transText) // MyGrid.Data = MyGrid.Data.Substring(0, g.Index) + transText + MyGrid.Data.Substring(g.Index + g.Length); //} string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v '?\\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>", rousg.ROUsageID); string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:Transition[^:]*?:{0} {1}( [0-9]*){{1,2}}\[END>", tran.TranType, tran.TransitionID); MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); foreach (Match mmg in msg) { Match mg = Regex.Match(mmg.Value, lookForXml);// Regex.Match(MyGrid.Data, lookForXml); if (mg != null && mg.Groups.Count > 1) { int myIndex = mg.Groups[4].Index + mmg.Index; int myLength = mg.Groups[4].Length; if (mg.Groups[3].Value != " ") { myIndex = mg.Groups[3].Index + mmg.Index; myLength += mg.Groups[3].Length; } string gg = MyGrid.Data.Substring(myIndex, myLength); if (newvalue.Contains(@"\u8209?")) // process dash newvalue = ProcessSpecChar(gg, newvalue, @"\u8209?", "-"); if (newvalue.Contains(@"\u8593?")) // process carrot/delta newvalue = ProcessSpecChar(gg, newvalue, @"\u8593?", "^"); if (newvalue.Contains(@"\u9586?")) // process backslash newvalue = ProcessSpecChar(gg, newvalue, @"\u9586?", @"\\"); if (gg != newvalue) { if (newvalue == "?") ConvertTransitionToTextInGrid(tran, newvalue); else MyGrid.Data = MyGrid.Data.Substring(0, myIndex) + newvalue + MyGrid.Data.Substring(myIndex + myLength); didFixATransition = true; // B2017-076 return Transitions were processed (used when importing a procedure) } } } } return didFixATransition; } private string ProcessSpecChar(string orgText, string newValue, string specChar, string kbChar) { Match m = Regex.Match(newValue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); { if (m == null)// || (m.Groups[1].Value == "" && m.Groups[3].Value == "")) newValue = newValue.Replace(specChar, kbChar); else { // look for rtf font command and insert it around the special char (i.e. symbol char) int ii = orgText.IndexOf(specChar); int fnt1 = -1; int fnt2 = -1; if (ii > -1) { fnt1 = orgText.LastIndexOf(@"\f", ii); fnt2 = orgText.IndexOf(@"\f", ii); if (fnt1 != -1 && fnt2 != -1) newValue = newValue.Replace(specChar, orgText.Substring(fnt1, 3) + specChar + orgText.Substring(fnt2, 3) + " "); } } } GC.Collect(); // regex has a memory leak return newValue; // could not find rtf font spec so just return the newValue as is } public void ConvertTransitionToTextInGrid(TransitionInfo tran, string value) { string newvalue = value; string findLink = @"<START\].*?\[END>"; MatchCollection ms = Regex.Matches(MyGrid.Data, findLink); string lookFor; if (tran == null) { // B2018-002 - Invalid Transitions - Added code to support range transitions int loc1 = MyGrid.Data.IndexOf("#Link:Transition:", 0); if (loc1 > 0) loc1 += ("#Link:Transition:").Length; else loc1 = MyGrid.Data.IndexOf("#Link:TransitionRange:", 0) + ("#Link:TransitionRange:").Length; ; //int loc1 = MyGrid.Data.IndexOf("#Link:Transition:", 0) + ("#Link:Transition:").Length; int loc2 = MyGrid.Data.IndexOf(" ", loc1); string trantype = MyGrid.Data.Substring(loc1, loc2 - loc1); loc1 = loc2 + 1; loc2 = MyGrid.Data.IndexOf(" ", loc1); string tranid = MyGrid.Data.Substring(loc1, loc2 - loc1); lookFor = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}~\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}}~ \\]+)*\\v(\\[^v \\]+)* #Link:Transition[^:]*?:{0} {1}( [0-9]*){{1,2}}\[END>", trantype, tranid); } else lookFor = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}~\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}}~ \\]+)*\\v(\\[^v \\]+)* #Link:Transition[^:]*?:{0} {1}( [0-9]*){{1,2}}\[END>", tran.TranType, tran.TransitionID); int lastIndex = 0; string newText = MyGrid.Data; foreach (Match mm in ms) { int offset = mm.Index; Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string ss = MyGrid.Data.Substring(myIndex, myLength); if (ss != newvalue) { int ii = MyGrid.Data.Substring(0, mm.Index).LastIndexOf(@"\v"); int iil = MyGrid.Data.Substring(mm.Index + m.Value.Length).IndexOf(@"\v0"); string part1 = MyGrid.Data.Substring(0, ii); // length up to \v string part2 = MyGrid.Data.Substring(ii + 2, mm.Index - (ii + 2)); string part3 = ss; string part4 = MyGrid.Data.Substring(mm.Index + m.Value.Length, iil); string part5 = MyGrid.Data.Substring(mm.Index + (m.Value.Length + iil + 3)); MyGrid.Data = part1 + part2 + part3 + part4 + part5; } break; // Text has been processed } lastIndex = mm.Index + mm.Length; } return; } public string ConvertTransitionToText(TransitionInfo tran, string value) { string retval = null; string newvalue = value; string findLink = @""; MatchCollection ms = Regex.Matches(Text, findLink); //string lookFor = string.Format(@"", rousg.ROUsageID); //string lookFor = string.Format(@"^$", rousg.ROUsageID); string lookFor; if (tran == null) { // B2018-002 - Invalid Transitions - Added code to support range transitions int loc1 = Text.IndexOf("#Link:Transition:", 0); if (loc1 > 0) loc1 += ("#Link:Transition:").Length; else loc1 = Text.IndexOf("#Link:TransitionRange:", 0) + ("#Link:TransitionRange:").Length; ; int loc2 = Text.IndexOf(" ", loc1); string trantype = Text.Substring(loc1, loc2 - loc1); loc1 = loc2 + 1; loc2 = Text.IndexOf(" ", loc1); string tranid = Text.Substring(loc1, loc2 - loc1); lookFor = string.Format(@"^", trantype, tranid); } else lookFor = string.Format(@"^", tran.TranType, tran.TransitionID); int lastIndex = 0; string newText = Text; foreach (Match mm in ms) { int offset = mm.Index; Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { string prefix = GetMyPrefix(mm.Index, lastIndex); string suffix = GetMySuffix(mm.Index + mm.Length); int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = newText.Substring(myIndex, myLength); retval = gg; gg = gg.Replace("{", @"\{").Replace("}", @"\}"); string part1 = newText.Substring(0, mm.Index); string part2 = gg; string part3 = newText.Substring(mm.Index + mm.Length); //modify part1 based on prefix if (prefix == @"\v ") part1 = part1.Substring(0, part1.Length - 3); else part1 = part1.Substring(0, part1.Length - 3) + " "; //modify part3 based on suffix if (suffix == @"\v0 ") part3 = part3.Substring(4); else part3 = suffix.Replace(@"\v0", "") + part3.Substring(suffix.Length); if (gg.Contains(@"\u8209?")) { Match mmm = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (mmm == null) newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } if (gg.Contains(@"\u9586?")) // process backslash symbol { Match mmm = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (mmm == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } Text = part1 + part2 + part3; break; // Text has been processed } lastIndex = mm.Index + mm.Length; } //Console.WriteLine("Text: {0} NewText: {1}", Text, newText); return retval; } public string ConvertTransitionToText(int tranID, int tranType, string value) { string retval = null; string newvalue = value; string findLink = @""; MatchCollection ms = Regex.Matches(Text, findLink); string lookFor = string.Format(@"^", tranType, tranID); int lastIndex = 0; string newText = Text; foreach (Match mm in ms) { int offset = mm.Index; Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { string prefix = GetMyPrefix(mm.Index, lastIndex); string suffix = GetMySuffix(mm.Index + mm.Length); int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = newText.Substring(myIndex, myLength); retval = gg; gg = gg.Replace("{", @"\{").Replace("}", @"\}"); string part1 = newText.Substring(0, mm.Index); string part2 = gg; string part3 = newText.Substring(mm.Index + mm.Length); //modify part1 based on prefix if (prefix == @"\v ") part1 = part1.Substring(0, part1.Length - 3); else part1 = part1.Substring(0, part1.Length - 3) + " "; //modify part3 based on suffix if (suffix == @"\v0 ") part3 = part3.Substring(4); else part3 = suffix.Replace(@"\v0", "") + part3.Substring(suffix.Length); if (gg.Contains(@"\u8209?")) { Match mmm = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (mmm == null) newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } if (gg.Contains(@"\u9586?")) { Match mmm = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (mmm == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } Text = part1 + part2 + part3; break; // Text has been processed } lastIndex = mm.Index + mm.Length; } //Console.WriteLine("Text: {0} NewText: {1}", Text, newText); return retval; } private string GetMySuffix(int start) { string txt = Text.Substring(start); int firstSlashVeeZero = txt.IndexOf(@"\v0"); if (firstSlashVeeZero == 0 && txt.Length > 3 && txt[3] == ' ') //"\v0 " return Text.Substring(start, 4); return Text.Substring(start, firstSlashVeeZero + 3); //everything upto \v0" } private string GetMyPrefix(int start, int lastIndex) { // B2020-061: Remove font size rtf command before looking for prefix string tText = Text; if (tText.Contains(@"\fs")) { tText = Regex.Replace(tText, @"\\v\\fs[0-9]+ ", "\\v "); start = tText.IndexOf(""; MatchCollection ms = Regex.Matches(Text, findLink); //string lookFor = string.Format(@"", rousg.ROUsageID); //string lookFor = string.Format(@"^$", rousg.ROUsageID); string strROUID = (rousg != null) ? rousg.ROUsageID.ToString() : roidFrmImportStep; string lookFor = string.Format(@"^$", strROUID); int lastIndex = 0; string newText = Text; foreach (Match mm in ms) { int offset = mm.Index; Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { string prefix = GetMyPrefix(mm.Index, lastIndex); string suffix = GetMySuffix(mm.Index + mm.Length); int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = newText.Substring(myIndex, myLength); retval = gg; gg = gg.Replace("{", @"\{").Replace("}", @"\}"); string part1 = newText.Substring(0, mm.Index); string part2 = gg; string part3 = newText.Substring(mm.Index + mm.Length); //modify part1 based on prefix if (prefix == @"\v ") part1 = part1.Substring(0, part1.Length - 3); else part1 = part1.Substring(0, part1.Length - 3) + " "; //modify part3 based on suffix if (suffix == @"\v0 ") part3 = part3.Substring(4); else part3 = suffix.Replace(@"\v0", "") + part3.Substring(suffix.Length); if (gg.Contains(@"\u8209?")) { Match mmm = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (mmm == null) newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } if (gg.Contains(@"\u9586?")) { Match mmm = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (mmm == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } //System.Text.RegularExpressions.Group g2 = m.Groups[2]; //if (g2.Value.StartsWith(@"\u8209?")) //{ // string gg = g2.Value + " " + g.Value; // retval = gg; // part2 = retval; //} //else ////else if (g.ToString() != newvalue) //{ // retval = g.Value; // part2 = retval; //} Text = part1 + part2 + part3; break; // Text has been processed } lastIndex = mm.Index + mm.Length; } //Console.WriteLine("Text: {0} NewText: {1}", Text, newText); // see if there is a grid to update too. if (_MyGrid != null) //(rousg.MyContent.MyGrid != null) { if (rotype == (int)E_ROValueType.Table) // if change in rotable data... { if (origROFstInfo != null) { List retlist = origROFstInfo.OnROTableUpdate(this, new ROFstInfoROTableUpdateEventArgs(newvalue, MyGrid.Data)); if (MyGrid.Data != retlist[1]) { MyGrid.Data = retlist[1]; retval = Text; if (Text != retlist[0]) Text = retlist[0]; } } } else { // if it's an ro within a table, need to process into an flex grid to save the grid data: string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v '?\\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>", rousg.ROUsageID); string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", strROUID); MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); int nmsg = msg.Count; for (int i = nmsg - 1; i >= 0; i--) { Match mmg = msg[i]; Match mg = Regex.Match(mmg.Value, lookForXml);// Regex.Match(MyGrid.Data, lookForXml); if (mg != null && mg.Groups.Count > 1) { int myIndex = mg.Groups[4].Index + mmg.Index; int myLength = mg.Groups[4].Length; if (mg.Groups[3].Value != " ") { myIndex = mg.Groups[3].Index + mmg.Index; myLength += mg.Groups[3].Length; } string gg = MyGrid.Data.Substring(myIndex, myLength); if (value == "?") newvalue = gg; // B2017-060 the text part of the RO link if (newvalue.Contains(@"\u8209?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u9586?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } if (value == "?" || gg != newvalue) { MyGrid.Data = Content.ConvertGridROsToText(MyGrid.Data, mmg, mg, newvalue); // B2017-060 convert the RO in the grid (table) to text } } } } } return retval == null ? "" : retval; } // B2017-060 logic pulled from dlgExportImport to covert a RO in a table (grid) to text public static string ConvertGridROsToText(string data, Match mmg, Match mg, string ss) { int ii = data.Substring(0, mmg.Index).LastIndexOf(@"\v"); int iil = data.Substring(mmg.Index + mg.Value.Length).IndexOf(@"\v0"); string part1 = data.Substring(0, ii); // length up to \v string part2 = data.Substring(ii + 2, mmg.Index - (ii + 2)); string part3 = ss; string part4 = data.Substring(mmg.Index + mg.Value.Length, iil); string part5 = data.Substring(mmg.Index + (mg.Value.Length + iil + 3)); data = part1 + part2 + part3 + part4 + part5; return data; } public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo, bool saveAnnotation) { return FixContentText(rousg, value, rotype, origROFstInfo, null, "", saveAnnotation); } public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo) { string filenameonly = null; //B2020-127 don't try to parse out a file name from "?" (happens with the RO figure no longer exists) // - this allows it to drop through and put an annotation on the step if (Text != null && Text.Length > 0 && value != "?") { if (ContentItems[0].MyItem.MyItemInfo.IsFigure) filenameonly = value.Substring(0, value.IndexOf("\n")); } return FixContentText(rousg, value, rotype, origROFstInfo, filenameonly, "", false); } // B2017-060 added roidFrmImportStep to pass in a ROID to use when rousg is null (import procedure uses this) public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo, string fileNameOnly, string roidFrmImportStep) { return FixContentText(rousg, value, rotype, origROFstInfo, fileNameOnly, roidFrmImportStep, false); } public string FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo, string fileNameOnly, string roidFrmImportStep, bool saveAnnotation) { string retval = null; if (value == "?") { retval = this.ConvertROToText(rousg, value, rotype, origROFstInfo, roidFrmImportStep); using (Item myitem = this.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(retval)), null); } if (rousg != null) RoUsage.Delete(rousg.ROUsageID); return retval; } string newvalue = value; // B2023-108: Added check for null reference if (newvalue != null) newvalue = newvalue.Replace("{", @"\{").Replace("}", @"\}"); string findLink = @""; MatchCollection ms = Regex.Matches(Text, findLink); //string lookFor = string.Format(@"", rousg.ROUsageID); string lookFor = string.Format(@"^$", rousg.ROUsageID); foreach (Match mm in ms) { Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = Text.Substring(myIndex, myLength); if (((fileNameOnly == null) && (MakeConsistentFormat(gg) != MakeConsistentFormat(newvalue))) || ((fileNameOnly != null) && !(gg.Replace(@"\u8209?", "-").StartsWith(fileNameOnly) && newvalue.Replace(@"\u8209?", "-").StartsWith(fileNameOnly)))) { retval = gg; Text = Text.Substring(0, myIndex) + newvalue + Text.Substring(myIndex + myLength); if (!saveAnnotation) { using (Item myitem = this.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("Verification Required"), "", string.Format("Referenced Object (Change in RO Values: Old value = {0}, New value = {1}) Changed", FixValue(gg), FixValue(newvalue)), null); } } break; // Text has been processed } } } // see if there is a grid to update too. if (rousg.MyContent.MyGrid != null) { if (rotype == (int)E_ROValueType.Table) // if change in rotable data... { if (origROFstInfo != null) { List retlist = origROFstInfo.OnROTableUpdate(this, new ROFstInfoROTableUpdateEventArgs(newvalue, MyGrid.Data)); if (MyGrid.Data != retlist[1]) { MyGrid.Data = retlist[1]; retval = Text; if (Text != retlist[0]) Text = retlist[0]; } } } else { // if it's an ro within a table, need to process into an flex grid to save the grid data: string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v '?\\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>", rousg.ROUsageID); string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", rousg.ROUsageID); MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); foreach (Match mmg in msg) { Match mg = Regex.Match(mmg.Value, lookForXml);// Regex.Match(MyGrid.Data, lookForXml); if (mg != null && mg.Groups.Count > 1) { int myIndex = mg.Groups[4].Index + mmg.Index; int myLength = mg.Groups[4].Length; if (mg.Groups[3].Value != " ") { myIndex = mg.Groups[3].Index + mmg.Index; myLength += mg.Groups[3].Length; } string gg = MyGrid.Data.Substring(myIndex, myLength); //CSM B2024-003 Updating RO Values inside a text Grid, adding a karat // and/or dash into the RO value changes to question marks in the UI, if (newvalue.Contains(@"\u8209?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u8209?", "-"); else if (m.Groups[1].Value == "") newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } int indx_to_addfont = -1; if (newvalue.Contains(@"\u916?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u916?", "^"); else if (m.Groups[1].Value == "" && !ContentItems[0].MyItem.MyItemInfo.MyDocVersion.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta) newvalue = newvalue.Replace(@"\u916?", "^"); else if (m.Groups[1].Value == "") { //B2024-003, B2023-113, B2024-093 - Updating RO Values inside a text Grid, // adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. // This is to handle if ConvertCaretToDelta is true // since delta is not part of the standard ascii // may need to add a font to handle it. newvalue = newvalue.Replace(@"\u916?", @"\f9\u916?\f0 "); indx_to_addfont = GetLocationToInsertFontInGrid(myIndex); } else newvalue = newvalue.Replace(@"\u916?", m.Groups[1].Value + @"\u916?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u8593?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u8593?", "^"); else if (m.Groups[1].Value == "") newvalue = newvalue.Replace(@"\u8593?", "^"); else newvalue = newvalue.Replace(@"\u8593?", m.Groups[1].Value + @"\u8593?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u9586?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else if (m.Groups[1].Value == "") newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } // B2022-134: crash when updating an RO that contains '<' or '>' when RO is used in a table cell. These // are xml special characters, the grid is stored as xml, so these characters need translated so that // storing them as xml in the database won't crash. They get translated back when used in Proms. if (newvalue.Contains("<")) newvalue = newvalue.Replace("<", "<"); if (newvalue.Contains(">")) newvalue = newvalue.Replace(">", ">"); if (gg != newvalue) { retval = gg; //B2024-003, B2023-113, B2024-093 - Updating RO Values inside a text Grid, // adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. // This is to handle if ConvertCaretToDelta is true // since delta is not part of the standard ascii // may need to add a font to handle it. string begin_str = MyGrid.Data.Substring(0, myIndex); if (indx_to_addfont > -1) begin_str = begin_str.Insert(indx_to_addfont, @"{\f9\fnil\fcharset0 FreeMono;}"); MyGrid.Data = begin_str + newvalue + MyGrid.Data.Substring(myIndex + myLength); MyGrid.Save(); break; } } } } } return retval; } //B2024-003, B2023-113, B2024-093 - Updating RO Values inside a text Grid, // adding a caret and/or dash into the RO value and then updating RO values changed to question marks in the UI. // This is to handle if ConvertCaretToDelta is true // since delta is not part of the standard ascii // may need to add a font to handle it. // startIndex = Index in the Grid at which the text we want to replace is starting //basic Grid data partitioning using the variables in this sub is as follows: // // [indexOfPrefix] [indx] // | | // [text before last occurrence of prefix] {prefix} [rest of fonts] [text after fonts] private int GetLocationToInsertFontInGrid(int startIndex) { //searches backwards from the srtIndex for the last previous occurrence of the prefix string prefix = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{"; int indexOfPrefix = MyGrid.Data.LastIndexOf(prefix, startIndex); //find the end of the font section //by passing in the Grid data //with the following removed: // - Everything before the last occurrence of the prefix // - the prefix itself removed int indx = GetIndexOfCloseBracket(MyGrid.Data.Substring(indexOfPrefix + prefix.Length, startIndex - indexOfPrefix - prefix.Length)); if (indx > -1) { indx += indexOfPrefix; indx += prefix.Length; } //indx will contain last spot inside the font section return indx; } //B2024-003, B2023-113, B2024-093 - Updating RO Values inside a text Grid, // this function will find the corresponding occurrence of a closing bracket : // usage is you pass in some text after an opening bracket, and it will tell you what the index is for it closing private int GetIndexOfCloseBracket(string text) { int indx = 0; Stack stk = new System.Collections.Generic.Stack(); foreach (char c in text) { if (c == '{') stk.Push('{'); else if (c == '}' && stk.Count == 0) return indx; else if (c == '}') stk.Pop(); indx++; } return -1; } public static string MakeConsistentFormat(string gg) { // replace degree, bullet dash, hardspace return ROFSTLookup.ConvertFortranFormatToScienctificNotation(gg).Replace("`", @"\'B0").Replace(@"\'b0", @"\'B0").Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " ").Replace(@"\'a0", " ").Replace(@"\'A0", " "); } private string FixValue(string str) { return str.Replace(@"\u8209?", "-").Replace(@"\u160?", " "); //dash and hard space } //C2022-028 (only used from Amin Tools) check the RO link text - compare with RO Usage information, annotate RO links that are bad public bool CheckROLinkTextandUsage(ref int BadROLinksCount, ref int CheckROLinksCount, ref int FixedROLinksCount) { /*** needed if we fix RO link text bool bFixedROLinks = false; bool bFixedTableDataText = false; ***/ if (this.Text.Contains("#Link:ReferencedObject:")) { if (this.ContentRoUsageCount == 0) // Procedure text has one or more links but no RO Usage records { CheckROLinksCount++; _MyLog.ErrorFormat(string.Format("No RO usage records for RO link(s) - ContentID = {0}", this.ContentID)); using (Item myItem = this.ContentItems[0].MyItem) // so that myitem does not stay in cache { myItem.DisposeOfContent = false; // don't dispose of the contents may be needed if more than one RO needs processed Annotation.MakeAnnotation(myItem, AnnotationType.GetByNameOrCreate("Bad RO link"), "", "Incomplete RO Link Information for all RO References in this text - Relink RO References", null); } } else { // We have RO link text and RO Usages - so verify link information matches RO Usage record information string findLink = @""; MatchCollection ms = Regex.Matches(Text, findLink); // finds all the links (both RO and Transitions) string lookFor = "#Link:ReferencedObject:"; string fixedContentText = Text; if (ms.Count > 0) { int roCnt = 0; string sAnnotationText = ""; foreach (Match mm in ms) { int offset = mm.Index; Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); // Is this a RO link? if (m != null && m.Length > 0) { string linkText = mm.Value; // the link text for the Referenced Object CheckROLinksCount++; roCnt++; // the RO instance in the text that we are checking // parse out usageid from link int rousgidx = m.Index + m.Length; int rousagid_len = mm.Value.IndexOf(" ", rousgidx) - rousgidx; string sROusageID = mm.Value.Substring(rousgidx, rousagid_len); // ROUsageID from link text (as a string) int roidIdx = rousgidx + rousagid_len + 1; int roid_Len = mm.Value.IndexOf(" ", roidIdx) - roidIdx; string sROid = mm.Value.Substring(roidIdx, roid_Len); // the ROID from the link text (as a string) // initialize to zero for cases where the ROUsage text is to force a no match below // when a link has either of these, then the process of inserting that RO link did not complete for some reason int iRousage = 0; if (!sROusageID.StartsWith("<")) // don't try to convert if link has for the ROUsageID value iRousage = Convert.ToInt32(sROusageID); //ROUsageID as interger // Both GoodROUsageID and GoodROUID must match in ROUsage record for link to be good bool GoodROUsageID = false; bool GoodROID = false; // Check each ContentRoUsages and look for a matching ROUsageID and ROID if (iRousage > 0 && this.ContentRoUsageCount > 0) { int lastROUsageID = -1; string lastROID = ""; RoUsageInfo badRoUsageInfo = null; foreach (RoUsageInfo rui in this.ContentItems[0].MyItem.MyItemInfo.MyContent.ContentRoUsages) { GoodROID = rui.ROID.Equals(sROid); //does this usage record have a matching ROID with the link text? GoodROUsageID = rui.ROUsageID.Equals(iRousage); //does the usage record have a matching ROUsageID with the link text? if (GoodROID && GoodROUsageID) { //myROUsages.RemoveAt(myROUsageCnt - 1); break; // jump out loop - valid RO Usage record found } if (GoodROID && !GoodROUsageID) { lastROUsageID = rui.ROUsageID; lastROID = rui.ROID; } else if (!GoodROID && GoodROUsageID) badRoUsageInfo = rui; } if (!GoodROID) // the ROID in the ROUsage record does not match the RO Link text - add annotation { BadROLinksCount++; // Add detail information to the error log _MyLog.ErrorFormat(string.Format("Invalid ROID - ContentID = {0} Link - {1}", this.ContentID, mm.Value)); sAnnotationText += string.Format("Bad RO Instance {0} - RO Needs Relinked - RO Text different than RO Data\n", roCnt); } else if (!GoodROUsageID) // Link does not have a valid ROUsage record for that RO link - add annotation { BadROLinksCount++; /********* //** below is logic to replace the ROUsageID in the linked text with one (for this contentID) that has the same ROID //** Commented out for now as this was test code for now - don't want to give to customers until we are comfortable //if (lastROUsageID != -1) //{ // // set the ROUsageID in the link text to last good ROUsageID found in ROUsage table // linkText = linkText.Replace(string.Format("#Link:ReferencedObject:{0} ", sROusageID), string.Format("#Link:ReferencedObject:{0} ", lastROUsageID)); // fixedContentText = fixedContentText.Replace(string.Format("#Link:ReferencedObject:{0} ", sROusageID), string.Format("#Link:ReferencedObject:{0} ", lastROUsageID)); // bFixedROLinks = true; // set to true so we know to update content text // _MyLog.InfoFormat(string.Format("Fixed Invalid RO Link - ContentID = {0} badLink - {1} goodLink - {2}",this.ContentID, mm.Value, linkText)); // FixedROLinksCount++; // using (Item myItem = this.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 // //Annotation.MakeAnnotation(myItem, AnnotationType.GetByNameOrCreate("Bad RO link"), "", string.Format("Invalid RO Usage ID for RO Instance {0}",roCnt), null); // Annotation.MakeAnnotation(myItem, AnnotationType.GetByNameOrCreate("Fixed Bad RO link"), "", string.Format("Fixed RO Instance {0} - Verify RO Value", roCnt), null); // } //} *********/ //else //{ // Add detail information to the error log _MyLog.ErrorFormat(string.Format("Invalid ROUsageID - ContentID = {0} Link - {1}", this.ContentID, mm.Value)); sAnnotationText += string.Format("RO Instance {0} Needs Relinked - Value Not Able To Update\n", roCnt); //} } } } } if (roCnt < this.ContentRoUsageCount) { BadROLinksCount++; // there are more RO Usage records then there links in the step _MyLog.WarnFormat(string.Format("Possible missing RO links, more RO Usage records than Links - ContentID = {0}", this.ContentID)); sAnnotationText += "Possible missing RO links.\n"; } // if any bad RO links were found, put the information in an Annotation if (sAnnotationText.Length > 0) { char[] newLine = { '\n' }; sAnnotationText = sAnnotationText.TrimEnd(newLine); using (Item myItem = this.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 //Annotation.MakeAnnotation(myItem, AnnotationType.GetByNameOrCreate("Bad RO link"), "", string.Format("Invalid RO Usage ID for RO Instance {0}",roCnt), null); Annotation.MakeAnnotation(myItem, AnnotationType.GetByNameOrCreate("Bad RO link"), "", sAnnotationText, null); } } /*** COMMENTED OUT BECAUSE WE NOT MAKING CHANGES TO THE DATA - FOR NOW //if (bFixedROLinks) //{ // // save content text // Text = fixedContentText; //} *****/ /******* // if we fix RO links in the RTF then see if there is a grid to update too. // WE DON'T NEED TO ADD ANNOTATIONS AS THAT IS DONE ABOVE (FOR THE RTF OF THE TABLE - BELOW IS THE XML OF THE TABLE // *** bFixedROLinks WILL REMAIN FALSE FOR NOW AS WE ARE NOT CHANGING LINK TEXT - THIS WILL PREVENT THE CHECKING OF THE XML TABLE if (bFixedROLinks && MyGrid != null && MyGrid.Data.Length > 0) { string fixedTableDataText = MyGrid.Data; // **** NEED LOGIC TO CHECK RO TABLES **** //if (rotype == (int)E_ROValueType.Table) // if change in rotable data... //{ // if (origROFstInfo != null) // { // List retlist = origROFstInfo.OnROTableUpdate(this, new ROFstInfoROTableUpdateEventArgs(newvalue, MyGrid.Data)); // if (MyGrid.Data != retlist[1]) // { // MyGrid.Data = retlist[1]; // retval = Text; // if (Text != retlist[0]) // Text = retlist[0]; // } // } //} //else { // if it's an ro within a table, need to process into an flex grid to save the grid data: string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", rousg.ROUsageID); string lookForXml = "#Link:ReferencedObject:"; MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); foreach (Match mmg in msg) { Match mg = Regex.Match(mmg.Value, lookForXml);// look for Referenced Object link in linked text if (mg != null && mg.Groups.Count > 1) { string tblLinkText = mmg.Value; // the link text in the table XML int rousgidx = mg.Index + mg.Length; int rousagid_len = mmg.Value.IndexOf(" ", rousgidx) - rousgidx; string sROusageID = mmg.Value.Substring(rousgidx, rousagid_len); // ROUsageID from link text int roidIdx = rousgidx + rousagid_len + 1; int roid_Len = mmg.Value.IndexOf(" ", roidIdx) - roidIdx; string sROid = mmg.Value.Substring(roidIdx, roid_Len); // initialize to zero for cases where the ROUsage is to force a no match below // -when a link has either of these, then the process of inserting that RO link did not complete for some reason int iRousage = 0; if (!sROusageID.StartsWith("<")) // don't try to convert if link has for the ROUsageID value iRousage = Convert.ToInt32(sROusageID); //ROUsageID as interger // see if there is a ContentID and ROUsage record match // Both GoodROUsageID and GoodROUID must match in ROUsage record for link to be good bool GoodROUsageID = false; bool GoodROID = false; // Check each ContentRoUsages and look for a matching ROUsageID and ROID if (iRousage > 0 && this.ContentRoUsageCount > 0) { int lastROUsageID = -1; string lastROID = ""; RoUsageInfo badRoUsageInfo = null; foreach (RoUsageInfo rui in this.ContentItems[0].MyItem.MyItemInfo.MyContent.ContentRoUsages) { GoodROID = rui.ROID.Equals(sROid); //does this usage record have a matching ROID with the link text? GoodROUsageID = rui.ROUsageID.Equals(iRousage); //does the usage record have a matching ROUsageID with the link text? if (GoodROID && GoodROUsageID) break; // jump out loop - valid RO Usage record found if (GoodROID && !GoodROUsageID) { lastROUsageID = rui.ROUsageID; lastROID = rui.ROID; } else if (!GoodROID && GoodROUsageID) badRoUsageInfo = rui; } if (!GoodROUsageID && GoodROID && lastROUsageID != -1) // Link does not have a valid ROUsage record for that RO link - add annotation { // set the ROUsageID in the link text to last good ROUsageID found in ROUsage table tblLinkText = tblLinkText.Replace(string.Format("#Link:ReferencedObject:{0} ", sROusageID), string.Format("#Link:ReferencedObject:{0} ", lastROUsageID)); fixedTableDataText = fixedTableDataText.Replace(string.Format("#Link:ReferencedObject:{0} ", sROusageID), string.Format("#Link:ReferencedObject:{0} ", lastROUsageID)); bFixedTableDataText = true; // set to true so we know to update content text } if (bFixedTableDataText) // if we changed the table XML, then save it { this.MyGrid.Data = fixedTableDataText; } } } } } ******* End modify table ****/ } } } /*** needed if we fix RO links return (bFixedROLinks || bFixedTableDataText); ***/ return false; } } public delegate void StaticContentInfoEvent(object sender, StaticContentInfoEventArgs args); public class StaticContentInfoEventArgs { string _OldValue; public string OldValue { get { return _OldValue; } set { _OldValue = value; } } string _NewValue; public string NewValue { get { return _NewValue; } set { _NewValue = value; } } string _Type; public string Type { get { return _Type; } set { _Type = value; } } public StaticContentInfoEventArgs(string oldValue, string newValue, string type) { _OldValue = oldValue; _NewValue = newValue; _Type = type; } } public partial class ContentInfo { public static string FormatByteArray(byte[] myArray) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < myArray.Length; i++) { sb.Append(string.Format("{0:x2}", myArray[i])); } return sb.ToString(); } public string LastChangedString { get { return ContentInfo.FormatByteArray(_LastChanged); } } public Int64 LastChangedInt64 { get { return Convert.ToInt64(LastChangedString, 16); } } public static bool IsInCache(int contentID) { return _CacheByPrimaryKey.ContainsKey(contentID.ToString()); } public static event StaticContentInfoEvent StaticContentInfoChange; // B2018-002 - Invalid Transitions - Changed to Public public static void OnStaticContentInfoChange(object sender, StaticContentInfoEventArgs args) { if (StaticContentInfoChange != null) StaticContentInfoChange(sender, args); } public string MyContentMessage = string.Empty; public string MyGridMessage = string.Empty; public bool InList(params int[] IDs) { foreach (int id in IDs) { if (id == ContentID) return true; } return false; } public void FixTransitionText(TransitionInfo tran, TransitionLookup tranLookup, ItemInfo ii) { FixTransitionText(tran, tranLookup, ii, ""); } public void FixTransitionText(TransitionInfo tran, ItemInfo ii) { FixTransitionText(tran, ii, ""); } public void FixTransitionText(TransitionInfo tran, ItemInfo ii, string forceConvertToText) { FixTransitionText(tran, null, ii, forceConvertToText); } public void FixTransitionText(TransitionInfo tran, TransitionLookup tranLookup, ItemInfo ii, string forceConvertToText) { string newvalue; MyContentMessage = string.Empty; if (tranLookup == null) newvalue = tran.ResolvePathTo(); else newvalue = tran.ResolvePathTo(tranLookup); if (forceConvertToText != string.Empty) newvalue = "?"; string findLink = @""; // B2019-084: There were 2 '", tran.TranType, tran.TransitionID); foreach (Match mm in ms) { Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = Text.Substring(myIndex, myLength); MyContentMessage = string.Format("ContentExt.ContentInfo:Content:{0}, {1}, {2}", this.ContentID, tran.TransitionID, gg); newvalue = newvalue.Replace("{", @"\{").Replace("}", @"\}"); if ((gg.Replace(@"\u8209?", "-").Replace(@"\u9586?", @"\\")) != (newvalue.Replace("\\u8209?", "-").Replace(@"\u9586?", @"\\")) || newvalue == "?") // B2017-165 added check of newvalue { _Text = Text.Substring(0, myIndex) + newvalue + Text.Substring(myIndex + myLength); if (newvalue == "?") { gg = ItemInfo.ConvertToDisplayText(gg); if (gg == "?" && forceConvertToText == "") // B2017-165 existing transition is a question mark (left over from 16-bit data) forceConvertToText = "Reason for Change: Transition Step does not Exist"; newvalue = forceConvertToText; OnStaticContentInfoChange(ii, new StaticContentInfoEventArgs(gg, newvalue, "TX")); break; } if (newvalue.StartsWith(gg) && (newvalue.ToUpper().Contains("BMP") || newvalue.ToUpper().Contains("GIF") || newvalue.ToUpper().Contains("TIF"))) { break; // Text has been processed } else { gg = ItemInfo.ConvertToDisplayText(gg); newvalue = ItemInfo.ConvertToDisplayText(newvalue); OnStaticContentInfoChange(ii, new StaticContentInfoEventArgs(gg, newvalue, "TX")); break; // Text has been processed } } } } // see if there is a grid to update too. if (tran.MyContent.MyGrid != null) { //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* ([^#]*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:Transition[^:]*?:{0} {1}( [0-9]*){{1,2}}\[END>", tran.TranType, tran.TransitionID); //Match mg = Regex.Match(MyGrid.Data, lookForXml); //if (mg != null && mg.Groups.Count > 1) //{ // System.Text.RegularExpressions.Group g = mg.Groups[3]; // //if (g.ToString() != transText) // // MyGrid.Data = MyGrid.Data.Substring(0, g.Index) + transText + MyGrid.Data.Substring(g.Index + g.Length); //} MyGridMessage = string.Empty; string findLinkXml = @"<START\].*?\[END>"; //string lookForXml = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v '?\\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>", rousg.ROUsageID); string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:Transition[^:]*?:{0} {1}( [0-9]*){{1,2}}\[END>", tran.TranType, tran.TransitionID); MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); foreach (Match mmg in msg) { Match mg = Regex.Match(mmg.Value, lookForXml);// Regex.Match(MyGrid.Data, lookForXml); if (mg != null && mg.Groups.Count > 1) { int myIndex = mg.Groups[4].Index + mmg.Index; int myLength = mg.Groups[4].Length; if (mg.Groups[3].Value != " ") { myIndex = mg.Groups[3].Index + mmg.Index; myLength += mg.Groups[3].Length; } string gg = MyGrid.Data.Substring(myIndex, myLength); if (newvalue.Contains(@"\u8209?")) { // B2022-058: Printing of '-' in transition in table prints as '?' instead of '-'. Wasn't using correct string to // look for font character (was using newvalue, not gg) Match m = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u9586?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u9586?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m == null) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } MyGridMessage = string.Format("ContentExt.ContentInfo:Grid:{0}, {1}, {2}", this.ContentID, tran.TransitionID, gg); if (gg != newvalue) { MyGrid.SetData(MyGrid.Data.Substring(0, myIndex) + newvalue + MyGrid.Data.Substring(myIndex + myLength)); } } } } } public void FixContentText(RoUsageInfo rousg, string value, int rotype, ROFstInfo origROFstInfo, ItemInfo ii) { string fileNameOnly = null; //B2020-127 don't try to parse out a file name from "?" (happens with the RO figure no longer exists) // - this allows it to drop through and put an annotation on the step if (ii.IsFigure && Text != null && Text.Length > 0 && value != "?") { fileNameOnly = value.Substring(0, value.IndexOf("\n")).Replace(@"\u8209?", "-"); // check only the file name of the RO figure } string newvalue = value; newvalue = newvalue.Replace("{", @"\{").Replace("}", @"\}"); newvalue = newvalue.Replace(@"\up2 \u8209?", @"\up2\u8209?");// B2017-167 Remove spurious space in RO Value between two RTF Commands string findLink = @""; MatchCollection ms = Regex.Matches(Text, findLink); string lookFor = string.Format(@"^$", rousg.ROUsageID); foreach (Match mm in ms) { int offset = mm.Index; Match m = Regex.Match(mm.Value, lookFor, RegexOptions.Singleline); if (m != null && m.Groups.Count > 1) { int myIndex = m.Groups[4].Index + mm.Index; int myLength = m.Groups[4].Length; if (m.Groups[3].Value != " ") { myIndex = m.Groups[3].Index + mm.Index; myLength += m.Groups[3].Length; } string gg = Text.Substring(myIndex, myLength); string gg1 = Content.MakeConsistentFormat(gg).Replace("\\up2 -", "\\up2-").Replace("\\up2 \\u8209?", "\\up2\\u8209?"); string newvalue1 = Content.MakeConsistentFormat(newvalue).Replace("\\up2 -", "\\up2-").Replace("\\up2 \\u8209?", "\\up2\\u8209?"); if (((fileNameOnly == null) && (gg1 !=newvalue1)) || ((fileNameOnly != null) && !(gg.Replace(@"\u8209?", "-").StartsWith(fileNameOnly) && newvalue.Replace(@"\u8209?", "-").StartsWith(fileNameOnly)))) { _Text = Text.Substring(0, myIndex) + newvalue + _Text.Substring(myIndex + myLength); if (newvalue == "?") { gg = ItemInfo.ConvertToDisplayText(gg); newvalue = "Deleted RO"; OnStaticContentInfoChange(ii, new StaticContentInfoEventArgs(gg, newvalue, "RO")); break; } if (newvalue.StartsWith(gg) && (newvalue.ToUpper().Contains("BMP") || newvalue.ToUpper().Contains("GIF") || newvalue.ToUpper().Contains("TIF"))) { break; // Text has been processed } else { gg = ItemInfo.ConvertToDisplayText(gg); newvalue = ItemInfo.ConvertToDisplayText(newvalue); //CSM B2024-094 - Carats (as Deltas) print as question marks in tables when unit is used in RO Definition Value //If there is a grid, need to keep these as the \u code //Otherwise they will not use the correct font and end up as question marks if (MyGrid != null) { gg = gg.Replace($"{(char)916}", @"\u916?"); newvalue = newvalue.Replace($"{(char)916}", @"\u916?"); } // Debug - jsj 5-19-2017 - left in for initial check-in //string xx_gg = gg_org.Replace(@"\'b0", @"\'B0").Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " "); //string xx_nv = newval_org.Replace(@"\'b0", @"\'B0").Replace(@"\u8209?", "-").Replace(@"\u160?", " ").Replace("\xA0", " "); //Console.WriteLine(xx_gg.CompareTo(xx_nv)); OnStaticContentInfoChange(ii, new StaticContentInfoEventArgs(gg, newvalue, "RO")); break; // Text has been processed } } } } // see if there is a grid to update too. if (MyGrid != null) { if (rotype == (int)E_ROValueType.Table) // if change in rotable data... { List retlist = origROFstInfo.OnROTableUpdate(this.Get(), new ROFstInfoROTableUpdateEventArgs(newvalue, MyGrid.Data)); if (retlist != null && Text != retlist[0]) _Text = retlist[0]; //B2022-075 added null reference check } else { // if it's an ro within a table, need to process into an flex grid to save the grid data: string findLinkXml = @"<START\].*?\[END>"; string lookForXml = string.Format(@"^<START\](\\[^v \\]+)*\\v0(\\[^v '?{{}}\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}} \\]+)*\\v(\\[^v \\]+)* #Link:ReferencedObject:{0} .*?\[END>$", rousg.ROUsageID); MatchCollection msg = Regex.Matches(MyGrid.Data, findLinkXml); foreach (Match mmg in msg) { //int offset = 0; // crashed in substring line below if using mmg.Index; Set to 0 and it worked - KBR. Match mg = Regex.Match(mmg.Value, lookForXml); if (mg != null && mg.Groups.Count > 1) { int myIndex = mg.Groups[4].Index; int myLength = mg.Groups[4].Length; if (mg.Groups[3].Value != " ") { myIndex = mg.Groups[3].Index; myLength += mg.Groups[3].Length; } string gg = MyGrid.Data.Substring(myIndex + mmg.Index, myLength); if (newvalue.Contains(@"\u8209?")) { Match m = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m.Groups.Count < 3) newvalue = newvalue.Replace(@"\u8209?", "-"); else newvalue = newvalue.Replace(@"\u8209?", m.Groups[1].Value + @"\u8209?" + m.Groups[3].Value); } //B2024-003, B2023-113, B2024-093 - Updating RO Values inside a text Grid, // This will handle if there is a delta and the column/row of the grid is removed //then restored from history if (newvalue.Contains(@"\u916?")) { Match m = Regex.Match(gg, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m.Groups.Count < 3 && !ContentItems[0].MyDocVersion.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta) newvalue = newvalue.Replace(@"\u916?", "^"); else if (m.Groups.Count < 3) newvalue = newvalue.Replace(@"\u916?", $"{(char)916}"); else newvalue = newvalue.Replace(@"\u916?", m.Groups[1].Value + @"\u916?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u8593?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m.Groups.Count < 3) newvalue = newvalue.Replace(@"\u8593?", "^"); else newvalue = newvalue.Replace(@"\u8593?", m.Groups[1].Value + @"\u8593?" + m.Groups[3].Value); } if (newvalue.Contains(@"\u9586?")) { Match m = Regex.Match(newvalue, @"(\\f[0-9]+)(\\u[0-9]{1,4}\?)(\\f[0-9]+ ?)"); if (m.Groups.Count < 3) newvalue = newvalue.Replace(@"\u9586?", @"\\"); else newvalue = newvalue.Replace(@"\u9586?", m.Groups[1].Value + @"\u9586?" + m.Groups[3].Value); } // B2022-064: Translate '<' to '<', '<' is xml token, so xml grid string was incorrect for print. // Note that the '>' symbol was also translated. This method does NOT save the string to database, // it is used for setting grid data xml string before printing. This method resolves symbols // (above - not bug fix) and untit specific ROs (this bug fix): if (newvalue.Contains("<")) newvalue = newvalue.Replace("<", "<"); if (newvalue.Contains(">")) newvalue = newvalue.Replace(">", ">"); if (gg != newvalue) { string prefix1 = MyGrid.Data.Substring(0, mmg.Index); string prefix2 = mmg.Value.Substring(0, myIndex); string suffix1 = MyGrid.Data.Substring(mmg.Index + mmg.Length); string suffix2 = mmg.Value.Substring(myIndex + myLength); MyGrid.SetData(prefix1 + prefix2 + newvalue + suffix2 + suffix1); break; } } } } } if (_Text == string.Empty) _Text = "?"; } // C2021-018 used to update the content record when displaying Alarm Pont Table information in the step Editor (BNPP alarms) public void UpdateAlarmTableInfoView(string updateText) { _Text = updateText; } public void LoadNonCachedGrid() { _MyGrid = GridInfo.GetNonCached(ContentID); //Console.WriteLine("LoadNonCachedGrid {0},{1},{2}",ContentID,_MyGrid==null,_MyContentInfoUnique); } public PartInfoList LocalContentParts { get { return _ContentParts; } } public void AddPart(SafeDataReader dr, ItemInfo itemInfo) { if (_ContentParts == null) _ContentParts = new PartInfoList(dr, itemInfo); else _ContentParts.AddPartInfo(dr, itemInfo); } public override string ToString() { return string.Format("{0} {1}", Number, Text); } public void ShowChange() { OnChange(); } internal ContentInfo(SafeDataReader dr, bool ForItem) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ContentInfo.Constructor", GetHashCode()); try { ReadDataItemList(dr); _CacheList.Add(this); } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ContentInfo.Constructor", ex); throw new DbCslaException("ContentInfo.Constructor", ex); } } private void ReadDataItemList(SafeDataReader dr) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ContentInfo.ReadDataItemList", GetHashCode()); try { _ContentID = dr.GetInt32("ContentID"); _Number = dr.GetString("Number"); _Text = dr.GetString("Text"); _Type = (int?)dr.GetValue("Type"); _FormatID = (int?)dr.GetValue("FormatID"); _Config = dr.GetString("Config"); _DTS = dr.GetDateTime("cDTS"); _UserID = dr.GetString("cUserID"); _ContentDetailCount = dr.GetInt32("DetailCount"); _ContentEntryCount = dr.GetInt32("EntryCount"); _ContentGridCount = dr.GetInt32("GridCount"); _ContentImageCount = dr.GetInt32("ImageCount"); _ContentItemCount = dr.GetInt32("ItemCount"); _ContentPartCount = dr.GetInt32("cPartCount"); _ContentRoUsageCount = dr.GetInt32("RoUsageCount"); _ContentTransitionCount = dr.GetInt32("TransitionCount"); _ContentZContentCount = dr.GetInt32("ZContentCount"); } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ContentInfo.ReadData", ex); _ErrorMessage = ex.Message; throw new DbCslaException("ContentInfo.ReadData", ex); } } } public partial class ContentInfoList { public static ContentInfoList GetList(int? itemID) { try { ContentInfoList tmp = DataPortal.Fetch(new ContentListCriteria(itemID)); ContentInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } [Serializable()] private class ContentListCriteria { public ContentListCriteria(int? itemID) { _ItemID = itemID; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } } private void DataPortal_Fetch(ContentListCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ListContentsByItemID"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("ContentInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ContentInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } public static ContentInfoList GetChangedList(byte[] lastChanged) { try { ContentInfoList tmp = DataPortal.Fetch(new ChangeListCriteria(lastChanged)); // ContentInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.GetChangedList", ex); } } [Serializable()] private class ChangeListCriteria { private byte[] _LastChanged; public byte[] LastChanged { get { return _LastChanged; } set { _LastChanged = value; } } public ChangeListCriteria(byte[] lastChanged) { _LastChanged = lastChanged; } } private void DataPortal_Fetch(ChangeListCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ListContentsAfterLastChanged"; cm.Parameters.AddWithValue("@LastChanged", criteria.LastChanged); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("ContentInfoList.DataPortal_Fetch", ex); throw new DbCslaException("ContentInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } #region ClearCBOverride // B2015-039 fix: // the following code clears the change bar override attribute from the step config, using the // sql stored procedure 'ClearCBOverrideForProcedure'. The stored procedure returns // a list of content records whose config was updated - so that this list can be used // to refresh config data (caching) and refresh content (caching & User Interface) [Serializable()] private class ClearCBOverrideCriteria { public ClearCBOverrideCriteria(int? itemID) { _ItemID = itemID; } private int? _ItemID; public int? ItemID { get { return _ItemID; } set { _ItemID = value; } } } private void DataPortal_Fetch(ClearCBOverrideCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "ClearCBOverrideForProcedure"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { while (dr.Read()) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } } catch (Exception ex) { Database.LogException("ClearCBOverrideCriteria.DataPortal_Fetch", ex); throw new DbCslaException("ClearCBOverrideCriteria.DataPortal_Fetch", ex); } } public static ContentInfoList GetClearedCBOverrides(int itemID) { try { ContentInfoList tmp = DataPortal.Fetch(new ClearCBOverrideCriteria(itemID)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.GetClearedCBOverrides", ex); } } #endregion #region UCF Fix FormatId After Import private class FixFormatIDAfterImportCriteria { private string _DocVersionList; public string DocVersionList { get { return _DocVersionList; } set { _DocVersionList = value; } } private int _OldFormatID; public int OldFormatID { get { return _OldFormatID; } set { _OldFormatID = value; } } private int _NewFormatID; public int NewFormatID { get { return _NewFormatID; } set { _NewFormatID = value; } } public FixFormatIDAfterImportCriteria(string dvlst, int oldfid, int newfid) { _DocVersionList = dvlst; _OldFormatID = oldfid; _NewFormatID = newfid; } } private void DataPortal_Fetch(FixFormatIDAfterImportCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_UpdateVersionFormatForUCF"; cm.Parameters.AddWithValue("@VersionList", criteria.DocVersionList); cm.Parameters.AddWithValue("@OldFormatID", criteria.OldFormatID); cm.Parameters.AddWithValue("@NewFormatID", criteria.NewFormatID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("FixFormatIDAfterImport.DataPortal_Fetch", ex); throw new DbCslaException("FixFormatIDAfterImport.DataPortal_Fetch", ex); } } public static ContentInfoList FixFormatIDAfterImport(string dvlst, int oldfid, int newfid) { try { ContentInfoList tmp = DataPortal.Fetch(new FixFormatIDAfterImportCriteria(dvlst, oldfid, newfid)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.FixFormatIDAfterImport", ex); } } #endregion #region UCF Clear Overwridden Formats private class ClearOverrideFormatsByFolderCriteria { public ClearOverrideFormatsByFolderCriteria(int folderID, int? formatID, int? newformatID) { _FormatID = formatID; _FolderID = folderID; _NewFormatID = newformatID; } private int? _FormatID; public int? FormatID { get { return _FormatID; } set { _FormatID = value; } } private int? _NewFormatID; public int? NewFormatID { get { return _NewFormatID; } set { _NewFormatID = value; } } private int _FolderID; public int FolderID { get { return _FolderID; } set { _FolderID = value; } } } private void DataPortal_Fetch(ClearOverrideFormatsByFolderCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ClearOverrideFormatsByFolder"; cm.Parameters.AddWithValue("@FolderID", criteria.FolderID); if (criteria.FormatID == null) cm.Parameters.AddWithValue("@FormatID", DBNull.Value); else cm.Parameters.AddWithValue("@FormatID", criteria.FormatID); if (criteria.NewFormatID == null) cm.Parameters.AddWithValue("@NewFormatID", DBNull.Value); else cm.Parameters.AddWithValue("@NewFormatID", criteria.NewFormatID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("ClearOverrideFormatsByFolderCriteria.DataPortal_Fetch", ex); throw new DbCslaException("ClearOverrideFormatsByFolderCriteria.DataPortal_Fetch", ex); } } public static ContentInfoList ClearOverrideFormatsByFolder(int folderID, int? formatID, int? newformatID) { try { ContentInfoList tmp = DataPortal.Fetch(new ClearOverrideFormatsByFolderCriteria(folderID, formatID, newformatID)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.ClearOverrideFormatsByFolder", ex); } } private class ClearOverrideFormatsByDocVersionCriteria { public ClearOverrideFormatsByDocVersionCriteria(string dvlist, int? formatID, int? newformatID) { _FormatID = formatID; _DVList = dvlist; _NewFormatID = newformatID; } private int? _FormatID; public int? FormatID { get { return _FormatID; } set { _FormatID = value; } } private int? _NewFormatID; public int? NewFormatID { get { return _NewFormatID; } set { _NewFormatID = value; } } private string _DVList; public string DVList { get { return _DVList; } set { _DVList = value; } } } private void DataPortal_Fetch(ClearOverrideFormatsByDocVersionCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ClearOverrideFormatsByDocVersion"; cm.Parameters.AddWithValue("@DocVersionList", criteria.DVList); if (criteria.FormatID == null) cm.Parameters.AddWithValue("@FormatID", DBNull.Value); else cm.Parameters.AddWithValue("@FormatID", criteria.FormatID); if (criteria.NewFormatID == null) cm.Parameters.AddWithValue("@NewFormatID", DBNull.Value); else cm.Parameters.AddWithValue("@NewFormatID", criteria.NewFormatID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("ClearOverrideFormatsByDocVersion.DataPortal_Fetch", ex); throw new DbCslaException("ClearOverrideFormatsByDocVersion.DataPortal_Fetch", ex); } } public static ContentInfoList ClearOverrideFormatsByDocVersion(string dvlist, int? formatID, int? newformatID) { try { ContentInfoList tmp = DataPortal.Fetch(new ClearOverrideFormatsByDocVersionCriteria(dvlist, formatID, newformatID)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.ClearOverrideFormatsByDocVersion", ex); } } private class ClearOverrideFormatsByItemCriteria { public ClearOverrideFormatsByItemCriteria(int itemID, int? formatID, int? newformatID) { _FormatID = formatID; _NewFormatID = newformatID; _ItemID = itemID; } private int? _FormatID; public int? FormatID { get { return _FormatID; } set { _FormatID = value; } } private int? _NewFormatID; public int? NewFormatID { get { return _NewFormatID; } set { _NewFormatID = value; } } private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } } private void DataPortal_Fetch(ClearOverrideFormatsByItemCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_ClearOverrideFormatsByItem"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); if (criteria.FormatID == null) cm.Parameters.AddWithValue("@FormatID", DBNull.Value); else cm.Parameters.AddWithValue("@FormatID", criteria.FormatID); if (criteria.NewFormatID == null) cm.Parameters.AddWithValue("@NewFormatID", DBNull.Value); else cm.Parameters.AddWithValue("@NewFormatID", criteria.NewFormatID); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("ClearOverrideFormatsByItem.DataPortal_Fetch", ex); throw new DbCslaException("ClearOverrideFormatsByItem.DataPortal_Fetch", ex); } } public static ContentInfoList ClearOverrideFormatsByItem(int itemID, int? formatID, int? newformatID) { try { ContentInfoList tmp = DataPortal.Fetch(new ClearOverrideFormatsByItemCriteria(itemID, formatID, newformatID)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.ClearOverrideFormatsByItem", ex); } } #endregion #region Enhanced #region Enhanced_UnlinkItems [Serializable()] private class EnhancedUnlinkCriteria { public EnhancedUnlinkCriteria(int? enhancedID, int? enhType, bool onlyCur) { _EnhancedID = enhancedID; _EnhType = enhType; _OnlyCur = onlyCur; } private int? _EnhancedID; public int? EnhancedID { get { return _EnhancedID; } set { _EnhancedID = value; } } private int? _EnhType; public int? EnhType { get { return _EnhType; } set { _EnhType = value; } } private bool _OnlyCur; public bool OnlyCur { get { return _OnlyCur; } set { _OnlyCur = value; } } } private void DataPortal_Fetch(EnhancedUnlinkCriteria criteria) { // B2022-049: Copy/paste of enhanced procedure and bad links between source and enhanced. To fix this problem, // a sql script was added 'vesp_PurgeProcLinkedItemsAndChildren' that only removes link information within the // input procedure, i.e. does not remove them from linked procedure. if (criteria.OnlyCur) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_PurgeProcLinkedItemsAndChildren"; cm.Parameters.AddWithValue("@EnhanceID", criteria.EnhancedID); // note query had 'EnhanceID', not 'EnhancedID' cm.Parameters.AddWithValue("@EnhType", criteria.EnhType); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("EnhancedUnlinkCriteria.DataPortal_Fetch", ex); throw new DbCslaException("EnhancedUnlinkCriteria.DataPortal_Fetch", ex); } return; } try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_PurgeEnhancedItemsAndChildren"; cm.Parameters.AddWithValue("@EnhanceID", criteria.EnhancedID); // note query had 'EnhanceID', not 'EnhancedID' cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("EnhancedUnlinkCriteria.DataPortal_Fetch", ex); throw new DbCslaException("EnhancedUnlinkCriteria.DataPortal_Fetch", ex); } } public static ContentInfoList DoEnhancedUnlink(int enhancedID, int enhType, bool onlyCur) { try { ContentInfoList tmp = DataPortal.Fetch(new EnhancedUnlinkCriteria(enhancedID, enhType, onlyCur)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.DoEnhancedUnlink", ex); } } #endregion Enhanced_UnlinkItems #region Enhanced_UnlinkDocVersionAndItems [Serializable()] private class EnhancedDocVersionUnlinkCriteria { public EnhancedDocVersionUnlinkCriteria(int? enhancedDocVersionID) { _EnhancedDocVersionID = enhancedDocVersionID; } private int? _EnhancedDocVersionID; public int? EnhancedDocVersionID { get { return _EnhancedDocVersionID; } set { _EnhancedDocVersionID = value; } } } private void DataPortal_Fetch(EnhancedDocVersionUnlinkCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_PurgeEnhancedDocVersionsAndChildren"; cm.Parameters.AddWithValue("@EnhanceID", criteria.EnhancedDocVersionID); // note query has 'EnhanceID' cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("EnhancedDocVersionUnlinkCriteria.DataPortal_Fetch", ex); throw new DbCslaException("EnhancedDocVersionUnlinkCriteria.DataPortal_Fetch", ex); } } public static ContentInfoList DoEnhancedDocVersionUnlink(int enhancedDocVersionID) { try { ContentInfoList tmp = DataPortal.Fetch(new EnhancedDocVersionUnlinkCriteria(enhancedDocVersionID)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.DoEnhancedDocVersionUnlink", ex); } } #endregion Enhanced_UnlinkDocVersionAndItems #region Enhanced_Convert16To32 ////// [Serializable()] private class GetEnhanced16To32ContentsCriteria { public GetEnhanced16To32ContentsCriteria(int? srcProcID, int? enhancedProcID, int enhType) { _SrcProcID = srcProcID; _EnhancedProcID = enhancedProcID; _EnhType = enhType; } private int? _SrcProcID; public int? SrcProcID { get { return _SrcProcID; } set { _SrcProcID = value; } } private int? _EnhancedProcID; public int? EnhancedProcID { get { return _EnhancedProcID; } set { _EnhancedProcID = value; } } private int? _EnhType; public int? EnhType { get { return _EnhType; } set { _EnhType = value; } } } private void DataPortal_Fetch(GetEnhanced16To32ContentsCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_Get16BitEnhancedContents"; cm.Parameters.AddWithValue("@SourceID", criteria.SrcProcID); cm.Parameters.AddWithValue("@EnhanceID", criteria.EnhancedProcID); cm.Parameters.AddWithValue("@EnhType", criteria.EnhType); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("GetEnhanced16To32ContentsCriteria.DataPortal_Fetch", ex); } } public static ContentInfoList Get16BitEnhancedContents(int srcProcID, int enhProcID, int enhType) { // query returns a list of items that were found to have compatible 16bit data to set link to enhanced // from the input source. Caller can check if there are non-procedure items, then procedures can be // linked using 16bit data in the config field try { ContentInfoList tmp = DataPortal.Fetch(new GetEnhanced16To32ContentsCriteria(srcProcID, enhProcID, enhType)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.Get16BitEnhancedContents", ex); } } ////// [Serializable()] private class ConvertEnhanced16To32ContentsCriteria { public ConvertEnhanced16To32ContentsCriteria(int? srcProcID, int? enhancedProcID, int enhType) { _SrcProcID = srcProcID; _EnhancedProcID = enhancedProcID; _EnhType = enhType; } private int? _SrcProcID; public int? SrcProcID { get { return _SrcProcID; } set { _SrcProcID = value; } } private int? _EnhancedProcID; public int? EnhancedProcID { get { return _EnhancedProcID; } set { _EnhancedProcID = value; } } private int? _EnhType; public int? EnhType { get { return _EnhType; } set { _EnhType = value; } } } private void DataPortal_Fetch(ConvertEnhanced16To32ContentsCriteria criteria) { try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_Convert16to32EnhancedContents"; cm.Parameters.AddWithValue("@SourceID", criteria.SrcProcID); cm.Parameters.AddWithValue("@EnhanceID", criteria.EnhancedProcID); cm.Parameters.AddWithValue("@EnhType", criteria.EnhType); cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { ContentInfo contentInfo = new ContentInfo(dr); this.Add(contentInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("ConvertEnhanced16To32ContentsCriteria.DataPortal_Fetch", ex); } } public static ContentInfoList Convert16To32EnhancedContents(int srcProcID, int enhProcID, int enhType) { // query links the 2 procedures (source and enhanced) setting the Enhanced type to 'enhType' try { ContentInfoList tmp = DataPortal.Fetch(new ConvertEnhanced16To32ContentsCriteria(srcProcID, enhProcID, enhType)); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on ContentInfoList.Convert16To32EnhancedContents", ex); } } #endregion Enhanced_Convert16To32 #endregion Enhanced } }