using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Text.RegularExpressions; using System.Drawing; using VEPROMS.CSLA.Library; namespace Volian.Controls.Library { public class DisplayText { #region Properties private E_FieldToEdit _FieldToEdit; public E_FieldToEdit FieldToEdit { get { return _FieldToEdit; } set { _FieldToEdit = value; } } private ItemInfo _MyItemInfo; private string InfoText { get { switch (FieldToEdit) { case E_FieldToEdit.StepText: case E_FieldToEdit.Text: return _MyItemInfo.MyContent.Text; break; case E_FieldToEdit.Number: return _MyItemInfo.MyContent.Number; break; } return string.Empty; } } private Item _MyItem; private string EditText { get { switch (FieldToEdit) { case E_FieldToEdit.StepText: case E_FieldToEdit.Text: return _MyItem.MyContent.Text; break; case E_FieldToEdit.Number: return _MyItem.MyContent.Number; break; } return string.Empty; } set { switch (FieldToEdit) { case E_FieldToEdit.StepText: case E_FieldToEdit.Text: _MyItem.MyContent.Text = value; _MyItem.MyContent.UserID = Environment.UserName; _MyItem.MyContent.DTS = DateTime.Now; break; case E_FieldToEdit.Number: _MyItem.MyContent.Number = value; _MyItem.MyContent.UserID = Environment.UserName; _MyItem.MyContent.DTS = DateTime.Now; break; default: break; } } } // list of 'pieces of text' for this item. Pieces include symbols, ros, // transitions & plain text. private List _DisplayTextElementList; public List DisplayTextElementList { get { return _DisplayTextElementList; } set { _DisplayTextElementList = value; } } // dictionary for the font table for this item. Note that this may // go away (it is not really used). private Dictionary _dicRtfFontTable; public Dictionary dicRtfFontTable { get { return _dicRtfFontTable; } set { _dicRtfFontTable = value; } } private VE_Font _textFont; // Font from format for this item public VE_Font TextFont { get { return _textFont; } set { _textFont = value; } } public string StartText; public string OriginalText; // compare for save to see if change for links. private FormatInfo _MyFormat; #endregion #region Constructors /// /// DisplayText constructor: /// Creates a DisplayText object that converts the database text into rtf text /// Arguments are: /// ItemInfo itemInfo - the item whose text will be resolved /// E_EditPrintMode ep_mode - edit or print. /// E_ViewMode vw_mode - view or edit. /// bool noEdit - flags whether to edit or not (used to set data in /// rtb as resolved replacewords for non-active rtb. /// E_FieldToEdit fieldToEdit - identifies the field to edit (number or text) /// bool colorLinks - whether to add color to links /// public DisplayText(ItemInfo itemInfo, E_EditPrintMode epMode, E_ViewMode vwMode, bool noEdit,E_FieldToEdit fieldToEdit, bool colorLinks) { _FieldToEdit = fieldToEdit; _MyItemInfo = itemInfo; OriginalText = InfoText; TextFont = itemInfo.GetItemFont();//GetItemFont(); string text = InfoText; _MyFormat = itemInfo.ActiveFormat; bool tableShouldBeOutlined = (epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View || noEdit) && (_FieldToEdit == E_FieldToEdit.StepText || _FieldToEdit == E_FieldToEdit.Text) && (!itemInfo.IsSection && !itemInfo.IsProcedure) && (itemInfo.IsTable || itemInfo.IsFigure); bool wordsShouldBeReplaced = epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View || noEdit; bool numbersShouldBeFormated = (!_MyFormat.PlantFormat.FormatData.SectData.StepSectionData.FortranFormatNumbers && (epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View || noEdit)); int typ = ((int)itemInfo.MyContent.Type) % 10000; bool tableHasBorder = tableShouldBeOutlined ? itemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[typ].Type.IndexOf(@"Borderless") < 0 : false; text = CreateRtf(colorLinks, text, tableShouldBeOutlined, wordsShouldBeReplaced, numbersShouldBeFormated, tableHasBorder); StartText = text; } public DisplayText(string text, VE_Font vFont, bool colorLinks) { TextFont = vFont; StartText = CreateRtf(colorLinks, text, false, false, false, false); } private string CreateRtf(bool colorLinks, string text, bool tableShouldBeOutlined, bool wordsShouldBeReplaced, bool numbersShouldBeFormated, bool tableHasBorder) { // add colors around links: if (colorLinks) { text = Regex.Replace(text, @"( -1) // MessageBox.Show("Found rtf line"); text = text.Replace(@"\line", @"\par"); // Now put symbol (for fixed fonts) or unicode font (proportional) around symbols // These fonts are VESymbFix & Arial Unicode MS respectively, and the font table // is actually defined in the StepRTB code. int indxsym = text.IndexOf(@"\u"); while (indxsym != -1) { int incrindx = 3; if (text[indxsym + 2] != 'l') { text = text.Insert(indxsym, @"\f1 "); int indxendsym = text.IndexOfAny(@"\ ?".ToCharArray(), indxsym + 5); if (indxendsym == -1) // must be end of line: text = text.Insert(text.Length - 1, @"\f0 "); else { if (text[indxendsym] == '?') indxendsym++; text = text.Insert(indxendsym, @"\f0 "); // TODO: do I need a space?? } incrindx = 5; } indxsym = text.IndexOf(@"\u", indxsym + incrindx); } return text; } private string DoFortranFormat(string text) { if (text.IndexOf(@".E") < 0) return text; // Look for text as n.Ey, where n can be null or a number, and y can be // positive or negative. This translates into nx10x10y where y is // superscripted. For example, .E3 -> x103 where 3 is superscripted // and 10.E5 -> 10x10-5 where 5 is superscripted string pat = @"(\d*).E([+-]*\d+)"; string retstr = text; // for each one that needs translated: foreach (Match m in Regex.Matches(text, pat)) { string fnum = m.Groups[1].Value; string supnum = m.Groups[2].Value; string newstr = string.Format(@"{0}x10\super {1}\nosupersub ", fnum, supnum); retstr = retstr.Replace(m.Value, newstr); } return retstr; } #endregion #region SaveData public bool Save(RichTextBox rtb) { try { //FormatInfo formatInfo = _MyItemInfo.ActiveFormat; using (_MyItem = _MyItemInfo.Get()) { // check for different text, i.e. text from this itm doesn't match // original text, a change occurred in database, but not from this user. if (OriginalText != EditText) { Console.WriteLine("Save Failed because text changed outside of this edit session."); return false; } string modtext = RtfToDbText(rtb.Rtf); // if there are links, we'll need to do extra processing to see if // there were additions, deletions or modifications. bool haslinks = ((modtext.IndexOf(@" -1) || (OriginalText != null && OriginalText != "" && OriginalText.IndexOf(@" -1)); if (haslinks) { // Get all links in original list RtfToDisplayTextElements(OriginalText); List origList = GetLinkList(DisplayTextElementList); // now get new text into displaytext elements for comparison for links: //RtfToDisplayTextElements(rtb.Rtf); RtfToDisplayTextElements(modtext); // Compare ro/transition lists and delete or add any to the item for any ros/transitions that have been // added/deleted or modified. ProcessRoTranChanges(_MyItem, origList); EditText = DteToString(); // if new transitions/ros, we need to 'fix' the string in the embedded link to contain the // transition or usage record. Dictionary ctReplacements = BuildCtReplacements(_MyItem.MyContent.ContentTransitions); Dictionary roUsgReplacements = BuildRoUsgReplacements(_MyItem.MyContent.ContentRoUsages); _MyItem.DTS = DateTime.Now; _MyItem.UserID = Environment.UserName; _MyItem.Save(); if (ctReplacements.Count > 0) { EditText = FixCtReplacements(EditText, ctReplacements); // Replace Transition Text foreach (ContentTransition ct in ctReplacements.Values) using (TransitionInfo tran = TransitionInfo.Get(ct.TransitionID)) _MyItem.MyContent.FixTransitionText(tran); _MyItem.Save(); } if (roUsgReplacements.Count > 0) { EditText = FixRoUsgReplacements(EditText, roUsgReplacements); _MyItem.Save(); } modtext = EditText; } else { EditText = modtext; foreach (Csla.Validation.BrokenRule br in _MyItem.MyContent.BrokenRulesCollection) { Console.WriteLine("{0} - {1}", br.Property, br.Description); } _MyItem.DTS = DateTime.Now; _MyItem.UserID = Environment.UserName; _MyItem.Save(); } _MyItem = null; OriginalText = modtext; } } catch (Exception ex) { Console.WriteLine("Save Failed with error: {0}", ex.Message); return false; } return true; } private string DteToString() { StringBuilder sret = new StringBuilder(); foreach (displayTextElement vte in DisplayTextElementList) { if (vte.Type == E_TextElementType.Text || vte.Type == E_TextElementType.Symbol) sret.Append(vte.Text); else { displayLinkElement dle = vte as displayLinkElement; if (vte != null) sret.Append(dle.TextAndLink); } } string modtext = sret.ToString(); return modtext; } private string FixRoUsgReplacements(string p, Dictionary roUsgReplacements) { foreach (int oldid in roUsgReplacements.Keys) { p = p.Replace(string.Format("", oldid), roUsgReplacements[oldid].ROUsageID.ToString()); } return p; } private Dictionary BuildRoUsgReplacements(ContentRoUsages contentRoUsages) { Dictionary retval = new Dictionary(); foreach (ContentRoUsage rou in contentRoUsages) { if (rou.ROUsageID < 0) retval.Add(rou.ROUsageID, rou); } return retval; } private string FixCtReplacements(string p, Dictionary ctReplacements) { foreach (int oldid in ctReplacements.Keys) { p = p.Replace(string.Format("",oldid),ctReplacements[oldid].TransitionID.ToString()); } return p; } private Dictionary BuildCtReplacements(ContentTransitions contentTransitions) { Dictionary retval = new Dictionary(); foreach (ContentTransition ct in contentTransitions) { if (ct.TransitionID < 0) retval.Add(ct.TransitionID, ct); } return retval; } private void ProcessRoTranChanges(Item itm, List origList) { // go through list. Note that only linked items are in the origList. // 1) delete any that are in origList but not in the DisplayTextElementList // (that represents the current text & links) // 2) add any that are only in DisplayTextElementList // 3) delete/add for modify? // delete first - if in original, but not in current list, delete the one // in the original list. foreach (displayLinkElement odte in origList) { bool found = false; foreach (displayTextElement dte in DisplayTextElementList) { if (dte.Type == odte.Type) { displayLinkElement l_dte = (displayLinkElement)dte; if (odte.Link == l_dte.Link) { found = true; break; } } } // remove the link element from the item. if (!found) { // Get record id for ro or trans and then find the associated ro or transition // in the item's list. remove it. int recid = -1; if (odte.Type != E_TextElementType.ReferencedObject) { int sp = odte.Link.IndexOf(" ") + 1; // get past tran type string srecid = odte.Link.Substring(sp, odte.Link.IndexOf(" ", sp) - sp); recid = System.Convert.ToInt32(srecid); foreach (ContentTransition ct in itm.MyContent.ContentTransitions) { if (ct.TransitionID == recid) { itm.MyContent.ContentTransitions.Remove(ct); break; } } } else { int sp = odte.Link.IndexOf(" "); //rousageid starts after "ReferencedObject:", i.e. index in link of 17 string srecid = odte.Link.Substring(17, sp-17); recid = System.Convert.ToInt32(srecid); foreach (ContentRoUsage cr in itm.MyContent.ContentRoUsages) { if (cr.ROUsageID == recid) { itm.MyContent.ContentRoUsages.Remove(cr); break; } } } } } // now do insert, i.e. in new list, but not in old. foreach (displayTextElement dte in DisplayTextElementList) { bool found = false; if (dte.Type == E_TextElementType.ReferencedObject || dte.Type == E_TextElementType.Transition || dte.Type == E_TextElementType.TransitionRange) { foreach (displayLinkElement odte in origList) { if (dte.Type == odte.Type) { // if the link is the same, it exists, so no action is required. displayLinkElement l_dte = (displayLinkElement)dte; if (odte.Link == l_dte.Link) { found = true; break; } } } // Insert the link (ro or transition) to the item if (!found) { if (dte.Type == E_TextElementType.ReferencedObject) // do ro { displayLinkElement l_dte = (displayLinkElement)dte; Match m = Regex.Match(l_dte.Link, "([A-Za-z]*):(.*)"); string linkstr = m.Groups[2].Value; string[] roparts = linkstr.Split(" ".ToCharArray()); ContentRoUsage rousg = null; using (RODb rodb = RODb.GetJustRoDb(Convert.ToInt32(roparts[2]))) { rousg = itm.MyContent.ContentRoUsages.Add(roparts[1], rodb); } l_dte.Link = l_dte.Link.Replace("", string.Format("", rousg.ROUsageID)); l_dte.TextAndLink = l_dte.TextAndLink.Replace("", string.Format("", rousg.ROUsageID)); break; } else if (dte.Type == E_TextElementType.TransitionRange || dte.Type == E_TextElementType.Transition) { displayLinkElement l_dte = (displayLinkElement)dte; Match m = Regex.Match(l_dte.Link, "([A-Za-z]*):(.*)"); string linkstr = m.Groups[2].Value; string[] tparts = linkstr.Split(" ".ToCharArray()); int type = System.Convert.ToInt32(tparts[0]); int tr1 = System.Convert.ToInt32(tparts[2]); // tparts[1] is token for tranid Item itm1 = Item.Get(tr1); Item itm2 = null; if (dte.Type == E_TextElementType.TransitionRange) { itm2 = Item.Get(System.Convert.ToInt32(tparts[3])); } else itm2 = itm1; ContentTransition ct = itm.MyContent.ContentTransitions.Add(itm1, itm2); ct.TranType = type; l_dte.Link = l_dte.Link.Replace("", string.Format("", ct.TransitionID)); l_dte.TextAndLink = l_dte.TextAndLink.Replace("", string.Format("", ct.TransitionID)); } } } } } private List GetLinkList(List locDisplayTextElementList) { List retList = new List(); foreach (displayTextElement vte in locDisplayTextElementList) { if (vte.Type == E_TextElementType.ReferencedObject || vte.Type == E_TextElementType.TransitionRange || vte.Type == E_TextElementType.Transition) { displayLinkElement tmp = (displayLinkElement)vte; displayLinkElement copy_vte = new displayLinkElement(); copy_vte.Type = tmp.Type; copy_vte.Link = tmp.Link; copy_vte.Text = tmp.Text; retList.Add(copy_vte); } } return retList; } private void RtfToDisplayTextElements(string text) { // get original text into displaytext elements for comparison for links: if (DisplayTextElementList == null) DisplayTextElementList = new List(); else DisplayTextElementList.Clear(); if (text == null || text == "") return; //string noExtraRtfStr = RtfToDbText(text); string noExtraRtfStr = text; int startIndex = 0; int index = -1; while ((index = FindTokenChar(noExtraRtfStr, startIndex)) > -1) { // Do any 'plain' text that preceeds the token. if (index > startIndex) DoTextElement(noExtraRtfStr, startIndex, index); if (noExtraRtfStr[index + 1] == 'v') index = DoLink(noExtraRtfStr, index); else index = DoSymbol(noExtraRtfStr, startIndex, index); startIndex = index; // +1; if (startIndex >= noExtraRtfStr.Length) break; } // Add any remaining text. if (startIndex < noExtraRtfStr.Length) DoTextElement(noExtraRtfStr, startIndex, index); } private string RtfToDbText(string text) { // For hardspaces, the windows richtextbox does some 'quirky' things: // A unicode representation of \u160? is sent INTO the rtb. Coming out, // that \u160? was translated to a \~ (by the underlying windows rtb). // Note that if the \~ is sent to the rtb, it is treated as a regular space, // i.e. no longer a hardspace, and actually is converted to a regular space. // SO, on the way out, convert any \~ to \u160? string noExtraRtfStr = text.Replace(@"\~", @"\u160?"); // Check for two links in a row & if found, add separating rtf comment // commands (these get removed in the richtextbox: // RHM 20100303 Not sure why this is here. The RichTextBox will always remove it. //noExtraRtfStr = noExtraRtfStr.Replace(@"[END>\v0 \v -1) noExtraRtfStr = noExtraRtfStr.Replace(@"\'05", "\x05"); return noExtraRtfStr; } //private string RemoveRtfStyles(string rtf) //{ // string retval = rtf; // // remove rtf commands for any styles that were added. Note that if // // the entire item has a style, and also contains 'pieces' of text with // // the same style, the underlying rtf box removes the embedded rtf commands, // // for example, if the entire step is bolded, and 'THEN' has bold on/off // // surrounding it, the rtf box removes the bold around the 'THEN' // // These remove the command with a following space or the command alone, // // either case may exist, because if there are rtf commands following the // // style command, there will be no space character following the style command. // if (((TextFont.Style & E_Style.Bold) > 0) || ((TextFont.Style & E_Style.MmBold) > 0)) // { // retval = RemoveToken(retval, @"\\b0"); // retval = RemoveToken(retval, @"\\b"); // } // if ((TextFont.Style & E_Style.Underline) > 0) // { // retval = RemoveToken(retval, @"\\ulnone"); // retval = RemoveToken(retval, @"\\ul"); // } // if ((TextFont.Style & E_Style.Italics) > 0) // { // retval = RemoveToken(retval, @"\\i0"); // retval = RemoveToken(retval, @"\\i"); // } // return retval; //} //private string RemoveToken(string str, string token) //{ // // if this token is preceeded by another token and followed by a space // // leave the preceeding token the ending space // string retval = Regex.Replace(str, @"(\\[^ \\?\r\n\t]*)" + token + " ", "$1 "); // if (retval != str) // Console.WriteLine("leave the preceeding token the ending space"); // // otherwise replace the token optionally followed by a space // retval = Regex.Replace(retval, token + " ?", ""); // return retval; //} //private static string StaticRemoveToken(string str, string token) //{ // // if this token is preceeded by another token and followed by a space // // leave the preceeding token the ending space // string retval = Regex.Replace(str, @"(\\[^ \\?\r\n\t]*)" + token + " ", "$1 "); // if (retval != str) // Console.WriteLine("leave the preceeding token the ending space"); // // otherwise replace the token optionally followed by a space // retval = Regex.Replace(retval, token + " ?", ""); // return retval; //} //public static string ReplaceRTFClause(Match m) //{ // switch (m.Value[1]) // { // case 'u': // if (Regex.IsMatch(m.Value, @"\\u[0-9]+")) // return m.Value; // Special Charcaters // if (Regex.IsMatch(m.Value, @"\\ulnone")) // return m.Value; // if (Regex.IsMatch(m.Value, @"\\ul.*")) // return m.Value; // Underline // break; // case '\'': // Special Character // return m.Value; // case 'b': // Bold // return m.Value; // case 's': // sub or super.... // if (m.Value == @"\sub") return m.Value; // if (m.Value == @"\super") return m.Value; // break; // case 'n': // nosubsuper... // if (m.Value == @"\nosupersub") return m.Value; // break; // case 'i': // Italics // return m.Value; // case '{': // look for escape for curly braces: // return m.Value; // case '}': // return m.Value; // case 'v': // save link hidden info // if (m.Value == @"\v") return m.Value; // comment part of link // // end comment may end in space or may end in '\' if another rtf command, // // or may end at end of string. First check for space, keep it in string // // if it is there. // if (Regex.IsMatch(m.Value, @"\\v0 ")) // return m.Value; // if (Regex.IsMatch(m.Value, @"\\v0")) // return m.Value; // break; // case 'l': // if (m.Value == @"\line") return m.Value; // break; // case 'p': // if (m.Value == @"\par") return "\r\n"; // //if (m.Value == @"\protect") // // return m.Value; // //if (m.Value == @"\protect0") // // return m.Value; // if (m.Value.Length>=6 && m.Value.Substring(0,6) == "\\par\r\n") return m.Value.Replace("\r\n", " "); // break; // case 'f': // handle fonts separately because they may or may not have a space after them // if (m.Value[2]>='0' && m.Value[2]<='9')return m.Value; // break; // } // return "";//Strip All //} public static string StaticReplaceRTFClause(Match m) { try { string token = m.Groups[1].Value; switch (token[1]) { case 'u': if (Regex.IsMatch(token, @"^\\u[0-9]+$")) return token; // Special Charcaters if (Regex.IsMatch(token, @"^\\ulnone ?$")) return token; if (Regex.IsMatch(token, @"^\\ul.*$")) return token; // Underline break; case '\'': // Special Character return token; case 'b': // Bold return token; case 's': // sub or super.... if (Regex.IsMatch(token, @"^\\sub ?$")) return token; if (Regex.IsMatch(token, @"^\\super ?$")) return token; break; case 'n': // nosubsuper... if (Regex.IsMatch(token, @"^\\nosupersub ?$")) return token; break; case 'i': // Italics return token; case '{': // look for escape for curly braces: return token; case '}': return token; case 'v': // save link hidden info if (Regex.IsMatch(token, @"^\\v0? ?$")) return token; // comment part of link // end comment may end in space or may end in '\' if another rtf command, // or may end at end of string. First check for space, keep it in string // if it is there. //if (Regex.IsMatch(token, @"\\v0 ")) // return token; //if (Regex.IsMatch(token, @"\\v0")) // return token; break; case 'l': if (Regex.IsMatch(token, @"^\\line ?$")) return token; break; case 'p': if (Regex.IsMatch(token, @"^\\par ?$")) return "\r\n"; //if (token == @"\protect") // return token; //if (token == @"\protect0") // return token; //if (token.Length >= 6 && token.Substring(0, 6) == "\\par\r\n") return token.Replace("\r\n", " "); break; //case 'f': // handle fonts separately because they may or may not have a space after them // if (token[2] >= '0' && token[2] <= '9') return token; // break; } } catch (Exception ex) { Console.WriteLine("{0}-{1}",ex.GetType().Name, ex.Message); } return "";//Strip All } public string StripRtfCommands(string rtf) { // replace \{ & \} with (![ & (!] respectively and then redo at end. The curly braces // are rtf so were getting removed and/or not handled correctly. string retval = rtf.Replace(@"\{", @"(!["); retval = retval.Replace(@"\}", @"(!]"); //// remove carriage return/newlines after \par commands (these are introduced by rtb //// for hard returns, goes into rtb as \par and comes out as \par\r\n): //retval = Regex.Replace(retval, @"\\par\r\n([^\\.*?])", "\\par $1"); //retval = Regex.Replace(retval, @"\\par\r\n([\\.*?])", "\\par$1"); // remove carriage return/newlines after \par commands (these are introduced by rtb // for hard returns, goes into rtb as \par and comes out as \par\r\n): retval = Regex.Replace(retval, @"\\par\r\n(?!\\)", "\\par "); //retval = Regex.Replace(retval, @"[\r\n]", "", RegexOptions.Singleline); // Strip Carriage Returns and Newlines //retval = Regex.Replace(retval, @"^\{(.*)\}$", "$1", RegexOptions.Singleline); // Strip Opening and Closing Braces //retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces //retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces //retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+)\\f[0-9] ", "$1 "); // remove font command - if next to another command, keep other command and space //// OLD: The following two lines are replaced by the more generic replace above. ////retval = Regex.Replace(retval, @"\\v\\f[0-9] ", "\\v "); // remove font command - if next to Comment keep space ////retval = Regex.Replace(retval, @"\\line\\f[0-9] ", "\\line "); // remove font command - if next to Line keep space //retval = Regex.Replace(retval, @"\\f[0-9] ", ""); // remove font command with ending space //retval = Regex.Replace(retval, @"\\f[0-9]", ""); // remove font command without ending space //retval = Regex.Replace(retval, @"\\par ", "\r\n"); //retval = Regex.Replace(retval, @"\\[^ \\?\r\n\t]+", new MatchEvaluator(ReplaceRTFClause)); // take backslash xyz and evaluates them //// remove a space if there is one as the first character or the last character //if (retval[0] == ' ') retval = retval.Remove(0, 1); //retval = retval.TrimEnd(' '); //// remove \r\n at end of string if the string has 2 or more characters //if (retval.Length > 1 && retval.Substring(retval.Length - 2, 2) == "\r\n") retval = retval.Remove(retval.Length - 2, 2); //// remove \par at end of string if the string has 4 or more characters //if (retval.Length > 3 && retval.Substring(retval.Length - 4, 4) == @"\par") retval = retval.Remove(retval.Length - 4, 4); //// remove a space following \r\n //retval = Regex.Replace(retval, "\r\n ", "\r\n"); ////if there are still spaces following \r\n, then probable in a table - we need to put the space back //retval = Regex.Replace(retval, "\r\n ", "\r\n "); retval = Regex.Replace(retval, @"[\r\n]", "", RegexOptions.Singleline); // Strip Carriage Returns and Newlines retval = Regex.Replace(retval, @"^\{(.*)\}$", "$1", RegexOptions.Singleline); // Strip Opening and Closing Braces retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+)(?=\\)", "$1 "); // add space after token if followed by token retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+ )", new MatchEvaluator(StaticReplaceRTFClause)); // take backslash xyz and evaluates them retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+) (?=\\)", "$1"); // remove space between tokens retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+) (?=\r\n)", "$1"); // remove space before /r/n // remove \r\n at end of string if the string has 2 or more characters if (retval.Length > 1 && retval.Substring(retval.Length - 2, 2) == "\r\n") retval = retval.Remove(retval.Length - 2, 2); if (retval.Length == 0) return ""; if (retval.Substring(retval.Length - 2, 2) == @"\v") retval = retval.Remove(retval.Length - 2, 2); retval = _MyItemInfo.RemoveRtfStyles(retval); // RemoveRtfStyles(retval); retval = retval.Replace(@"(![", @"\{"); retval = retval.Replace(@"(!]", @"\}"); retval = retval.TrimEnd(' '); return retval; } //public static string StaticStripRtfCommands(string rtf, ItemInfo itmInfo) public static string StaticStripRtfCommands(string rtf) { // replace \{ & \} with (![ & (!] respectively and then redo at end. The curly braces // are rtf so were getting removed and/or not handled correctly. string retval = rtf.Replace(@"\{", @"(!["); retval = retval.Replace(@"\}", @"(!]"); // For hardspaces, the windows richtextbox does some 'quirky' things: // A unicode representation of \u160? is sent INTO the rtb. Coming out, // that \u160? was translated to a \~ (by the underlying windows rtb). // Note that if the \~ is sent to the rtb, it is treated as a regular space, // i.e. no longer a hardspace, and actually is converted to a regular space. // SO, on the way out, convert any \~ to \u160? retval = retval.Replace(@"\~", @"\u160?"); // remove carriage return/newlines after \par commands (these are introduced by rtb // for hard returns, goes into rtb as \par and comes out as \par\r\n): retval = Regex.Replace(retval, @"\\par\r\n(?!\\)", "\\par "); //retval = Regex.Replace(retval, @"\\par\r\n(?=\\)", "\\par"); retval = Regex.Replace(retval, @"[\r\n]", "", RegexOptions.Singleline); // Strip Carriage Returns and Newlines retval = Regex.Replace(retval, @"^\{(.*)\}$", "$1", RegexOptions.Singleline); // Strip Opening and Closing Braces retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces //retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+)\\f[0-9] ", "$1 "); // remove font command - if next to another command, keep other command and space // OLD: The following two lines are replaced by the more generic replace above. //retval = Regex.Replace(retval, @"\\v\\f[0-9] ", "\\v "); // remove font command - if next to Comment keep space //retval = Regex.Replace(retval, @"\\line\\f[0-9] ", "\\line "); // remove font command - if next to Line keep space //retval = Regex.Replace(retval, @"\\f[0-9] ", ""); // remove font command with ending space //retval = Regex.Replace(retval, @"\\f[0-9]", ""); // remove font command without ending space //retval = Regex.Replace(retval, @"\\par ", "\r\n"); retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+)(?=\\)", "$1 "); // add space after token if followed by token //retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+)(\\)", "$1 $2"); // take backslash xyz and evaluates them retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+ )", new MatchEvaluator(StaticReplaceRTFClause)); // take backslash xyz and evaluates them retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+) (?=\\)", "$1"); // remove space between tokens retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+) (?=\r\n)", "$1"); // remove space before /r/n // remove a space if there is one as the first character or the last character //if (retval[0] == ' ') retval = retval.Remove(0, 1); //retval = retval.TrimEnd(' '); // remove \r\n at end of string if the string has 2 or more characters if (retval.Length > 1 && retval.Substring(retval.Length - 2, 2) == "\r\n") retval = retval.Remove(retval.Length - 2, 2); // remove \par at end of string if the string has 4 or more characters //if (retval.Length > 3 && retval.Substring(retval.Length - 4, 4) == @"\par") retval = retval.Remove(retval.Length - 4, 4); // remove a space following \r\n //retval = Regex.Replace(retval, "\r\n ", "\r\n"); ////if there are still spaces following \r\n, then probable in a table - we need to put the space back //retval = Regex.Replace(retval, "\r\n ", "\r\n "); if (retval.Length == 0) return ""; if (retval.Length > 1 && retval.Substring(retval.Length - 2, 2) == @"\v") retval = retval.Remove(retval.Length - 2, 2); //retval = RemoveRtfStyles(retval); //if (itmInfo != null) // retval = StaticRemoveRtfStyles(retval, itmInfo); retval = retval.Replace(@"(![", @"\{"); retval = retval.Replace(@"(!]", @"\}"); retval = retval.TrimEnd(' '); // the indent character was translated in the richtextbox, change it back: if (retval.IndexOf(@"\'05") > -1) retval = retval.Replace(@"\'05", "\x05"); return retval; } #endregion #region StyleData //private VE_Font GetItemFont() //{ // VE_Font font = null; // FormatInfo format = _MyItemInfo.ActiveFormat; // int type = (int)_MyItemInfo.MyContent.Type; // switch (type/10000) // { // case 0: // procedure // font = format.PlantFormat.FormatData.Font; // break; // case 1: // section // font = format.PlantFormat.FormatData.SectData.SectionHeader.Font; // break; // case 2: // step types // int typindx = type - 20000; // what to do for other types rather than steps // font = format.PlantFormat.FormatData.StepDataList[typindx].Font; // break; // } // TextFont = font; // return font; //} #endregion #region DoListElements private int FindTokenChar(string txt, int startIndex) { // 'tokens' are for symbols and links (ro & transitions). symbols are represented by \u // and links are represented by \v \v0 bool done = false; while (!done) { int indx = txt.IndexOf('\\', startIndex); if (indx < 0) return indx; // see if symbol (but not underline) or another rtf command: has a 'u' // followed by a non-underline or single quote, and if so, return it. if (((txt[indx + 1] == 'u' && txt[indx + 2] != 'l')) || (txt[indx + 1] == '\'')) return indx; // see if link if (txt[indx + 1] == 'v') return indx; // Otherwise, get next index, must have been a slash or other rtf command. startIndex = indx + 1; } return -1; } private int DoTextElement(string text, int startIndex, int index) { displayTextElement vte = new displayTextElement(); vte.Type = E_TextElementType.Text; int len = (index == -1) ? text.Length - startIndex : index - startIndex; vte.Text = text.Substring(startIndex, len); DisplayTextElementList.Add(vte); return index+1; } private int DoLink(string text, int startIndex) { int retval = -1; int fnd = text.IndexOf("#Link:", startIndex); if (text.Substring(fnd + 6, 3) == "Ref") retval = DoRO(text, startIndex); else retval = DoTran(text, startIndex); return retval; } private int DoRO(string text, int index) { displayLinkElement vte = new displayLinkElement(); vte.Type = E_TextElementType.ReferencedObject; return DoLinkElements(text, index, vte); } private string FixTransition(string link, string text) { if (link.IndexOf("") != -1) return text; int transitionID = Convert.ToInt32(link.Split(" ".ToCharArray())[1]); // Find the transition if (_MyItemInfo.MyContent.ContentTransitionCount <= 0) { // TODO: RHM 20100310 _MyItemInfo.MyContent.RefreshContentTransitions(); if (_MyItemInfo.MyContent.ContentTransitionCount <= 0) return "*Resolved Transition Text*"; } foreach (TransitionInfo ti in _MyItemInfo.MyContent.ContentTransitions) { if (ti.TransitionID == transitionID) { string path = ti.ResolvePathTo(_MyFormat, _MyItemInfo, ti.TranType, ti.MyItemToID, ti.MyItemRangeID); return path; } } return text; } private int DoTran(string text,int index) { displayLinkElement vte = new displayLinkElement(); // determine if Range by checking for "R" after Transition (otherwise ":") int linkindx = text.IndexOf(@"#Link", index); vte.Type = (text[linkindx+16]=='R')?E_TextElementType.TransitionRange:E_TextElementType.Transition; return DoLinkElements(text, index, vte); } private int DoLinkElements(string text, int index, displayLinkElement vte) { // Find the 'end comment' for the int endLinkIndxV = text.IndexOf(@"\v0 ", linkIndx); if (endLinkIndxV == -1) endLinkIndxV = text.IndexOf(@"\v0", linkIndx); // at end of string int endLinkIndxE = text.IndexOf(@"[END>", linkIndx); int endLinkIndx = (endLinkIndxV < endLinkIndxE) ? endLinkIndxV : endLinkIndxE; vte.Link = text.Substring(linkIndx + 6, endLinkIndx - linkIndx - 6); // 6 for #Link: string tmptxt = null; if (vte.Type != E_TextElementType.ReferencedObject) { tmptxt = FixTransition(vte.Link, vte.Text); vte.Text = tmptxt; } // Now get the entire text & link. Account for various ending possibilities: // ends with '\v0\'; ends with '\v0 '; ends with '\v0' (end of string); // ends with '[END>' if two in a row - will have ", endLinkIndx + 3); // get past end of link int endComment = text.IndexOf(@"\v0", endToken); int rettoken = 0; int retlen = 4; if (endComment + 3 == text.Length) retlen = 3; else if (text[endComment + 3] == '\\') retlen = 3; vte.TextAndLink = text.Substring(index, endComment - index + retlen); rettoken = endComment + retlen; if (vte.Type != E_TextElementType.ReferencedObject) { if (vte.TextAndLink.Contains("(Resolved Transition Text)")) vte.TextAndLink = vte.TextAndLink.Replace("(Resolved Transition Text)", tmptxt); else if (vte.Text != tmptxt) vte.Text = tmptxt; } DisplayTextElementList.Add(vte); return rettoken; } private int DoSymbol(string text, int startIndex, int index) { displayTextElement vte = new displayTextElement(); vte.Type = E_TextElementType.Symbol; // symbols are the unicode/rtf command. A symbol can be represented by \'xy or // in the text from the database \uxyz?. If the \'xy is used the length of the // symbol number will always be two, otherwise find the index of the '?' to // find the end. int endindx = -1; if (text[index + 1] == '\'') endindx = index + 3; else endindx = text.IndexOf("?", index); vte.Text = text.Substring(index, endindx - index + 1); DisplayTextElementList.Add(vte); return endindx+1; } #endregion #region ReplaceWords private string DoReplaceWords(string Text) { ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList; foreach (ReplaceStr rs in rsl) { if (_MyItemInfo.MyContent.Type < 20000) return Text; // for now only replace in steps. bool replaceit = false; // note that the order of this check is important. Check in this order... // background here if (_MyItemInfo.IsHigh && (rs.Flag & E_ReplaceFlags.High)>0) replaceit = true; else if ((_MyItemInfo.IsTable || _MyItemInfo.IsFigure) && (rs.Flag & E_ReplaceFlags.Table) > 0) replaceit = true; else if (_MyItemInfo.IsInRNO && (rs.Flag & E_ReplaceFlags.RNO) > 0) replaceit = true; else if (_MyItemInfo.IsCaution && (rs.Flag & E_ReplaceFlags.Caution) > 0) replaceit = true; else if (_MyItemInfo.IsNote && (rs.Flag & E_ReplaceFlags.Note) > 0) replaceit = true; else if (_MyItemInfo.IsInFirstLevelSubStep && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true; else if (_MyItemInfo.IsAccPages & (rs.Flag & E_ReplaceFlags.Attach) > 0) replaceit = true; if (replaceit) { // CASEINSENS: Do ReplaceWords for all words that match, regardless of case, and replace // with the ReplaceWith string as is if ((rs.Flag & E_ReplaceFlags.CaseInsens) > 0) { //string res = ""; //string fortest = Text.ToUpper(); ////string pat = @"(?<=\W|^)" + rs.ReplaceWord.ToUpper() + @"(?=\W|$)"; //// jsj 07Jun2010 HardSpaces defeat replaceword logic //string pat = @"(?<=\W|^)(? 0) { // only in Maine Yankee - we don't need to do this one. } // CASEINSENSFIRST: Do ReplaceWords for all words that exactly match the ReplaceWord, // except the case where the first character may be different else if ((rs.Flag & E_ReplaceFlags.CaseInsensFirst) > 0) { // only used in V.C. Summer - we don't need to do this either. } else { // If there are Regex Control Characters '\[]()' prefix them with backslash string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0"); //string pat = @"(?<=\W|^)" + replaceWord + @"(?=\W|$)"; // jsj 07Jun2010 HardSpaces defeat replaceword logic //string pat = @"(?<=\W|^)(? /// Text - this should parse the text and return the results /// override public string Text { get { if (_TextAndLink != null) { Match m = Regex.Match(_TextAndLink, @""); return m.Groups[1].ToString(); } return _Text; } set { if (_TextAndLink != null) { Match m = Regex.Match(_TextAndLink, @""); System.Text.RegularExpressions.Group g = m.Groups[1]; _TextAndLink = _TextAndLink.Substring(0, g.Index) + value + _TextAndLink.Substring(g.Index + g.Length); } _Text = value; } } } #endregion }