
Add logic to exclude high level steps from those items included in the Replace Words list for substeps. Removed event handlers for DSOFramer. It appears that these no longer work for MSWord 2013. New Watermark Logic
1772 lines
73 KiB
C#
1772 lines
73 KiB
C#
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
|
|
{
|
|
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
#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 = Volian.Base.Library.VlnSettings.UserID;
|
|
_MyItem.MyContent.DTS = DateTime.Now;
|
|
break;
|
|
case E_FieldToEdit.Number:
|
|
_MyItem.MyContent.Number = value;
|
|
_MyItem.MyContent.UserID = Volian.Base.Library.VlnSettings.UserID;
|
|
_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<displayTextElement> _DisplayTextElementList;
|
|
public List<displayTextElement> 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<int, string> _dicRtfFontTable;
|
|
public Dictionary<int, string> 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; }
|
|
}
|
|
private bool PrintingSmartTemplate = false;
|
|
public string StartText;
|
|
public string OriginalText; // compare for save to see if change for links.
|
|
private FormatInfo _MyFormat;
|
|
#endregion
|
|
#region Constructors
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
public DisplayText(ItemInfo itemInfo, E_EditPrintMode epMode, E_ViewMode vwMode, bool noEdit,E_FieldToEdit fieldToEdit, bool colorLinks, string prefix, string suffix)
|
|
{
|
|
_FieldToEdit = fieldToEdit;
|
|
_MyItemInfo = itemInfo;
|
|
OriginalText = InfoText;
|
|
TextFont = itemInfo.GetItemFont();//GetItemFont();
|
|
// if in print mode, and this is the HLS of a smart template (checklist formats), add a space before and
|
|
// after the HLS text - this allows for the vertical bar characters to be added.
|
|
if (itemInfo.IsStep && itemInfo.FormatStepData.UseSmartTemplate && epMode == E_EditPrintMode.Print) Console.WriteLine("here");
|
|
string addSpace = (itemInfo.IsStep && itemInfo.FormatStepData.UseSmartTemplate && epMode == E_EditPrintMode.Print) ? " " : "";
|
|
string text = prefix + addSpace + InfoText + addSpace + suffix;
|
|
_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;
|
|
if (_MyFormat == null)
|
|
Console.WriteLine(this._MyItemInfo.MyItemInfoUnique);
|
|
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;
|
|
bool ROsShouldBeAdjusted = wordsShouldBeReplaced; // same logical value
|
|
if (epMode == E_EditPrintMode.Print && _MyItemInfo.IsStep)
|
|
{
|
|
if (_MyItemInfo.FormatStepData.UseSmartTemplate)
|
|
{
|
|
// Add 2 spaces before and 1 after if there is prefix so that wrapping in RTB accounts for vertical
|
|
// lines (the 2 spaces after the first "\par " command and 1 space before 2nd "\par"). Tried other
|
|
// combinations that did not work.
|
|
if (_MyItemInfo.FormatStepData.Prefix != null && _MyItemInfo.FormatStepData.Prefix != "")
|
|
text = !_MyItemInfo.FormatStepData.Font.FontIsProportional() ? ReplaceLinesWithUnicode(_MyItemInfo.FormatStepData.Prefix) + @"\par " + text + @"\par " :
|
|
@"\par " + text + @"\par ";
|
|
if (_MyItemInfo.FormatStepData.Suffix != null && _MyItemInfo.FormatStepData.Suffix != "")
|
|
text = text + (!_MyItemInfo.FormatStepData.Font.FontIsProportional() ? ReplaceLinesWithUnicode(_MyItemInfo.FormatStepData.Suffix) :
|
|
@"\par\par\par ");
|
|
}
|
|
}
|
|
text = CreateRtf(colorLinks, text, tableShouldBeOutlined, wordsShouldBeReplaced, numbersShouldBeFormated, tableHasBorder, ROsShouldBeAdjusted);
|
|
|
|
StartText = text;
|
|
}
|
|
private string ReplaceLinesWithUnicode(string text)
|
|
{
|
|
text = text.Replace("\x2500", @"\u9472?"); // Horizontal
|
|
text = text.Replace("\x2502", @"\u9474?"); // Vertical
|
|
text = text.Replace("\x2514", @"\u9492?"); // Bottom Left Corner
|
|
text = text.Replace("\x2518", @"\u9496?"); // Bottom Right Corner
|
|
text = text.Replace("\x2534", @"\u9524?"); // Bottom Tee
|
|
text = text.Replace("\x250c", @"\u9484?"); // Upper Left Corner
|
|
text = text.Replace("\x251c", @"\u9500?"); // Left Tee
|
|
text = text.Replace("\x2510", @"\u9488?"); // Upper Right Corner
|
|
text = text.Replace("\x252c", @"\u9516?"); // Top Tee
|
|
text = text.Replace("\x2524", @"\u9508?"); // Right Tee
|
|
text = text.Replace("\x253c", @"\u9532?"); // Plus
|
|
return text;
|
|
}
|
|
|
|
public DisplayText(string text, VE_Font vFont, bool colorLinks)
|
|
{
|
|
TextFont = vFont;
|
|
StartText = CreateRtf(colorLinks, text, false, false, false, false, false);
|
|
}
|
|
public DisplayText(ItemInfo itemInfo, string text, bool colorLinks)
|
|
{
|
|
_FieldToEdit = E_FieldToEdit.Text;
|
|
_MyItemInfo = itemInfo;
|
|
OriginalText = text;
|
|
TextFont = itemInfo.GetItemFont();
|
|
_MyFormat = itemInfo.ActiveFormat;
|
|
|
|
bool wordsShouldBeReplaced = true;
|
|
bool numbersShouldBeFormated = !_MyFormat.PlantFormat.FormatData.SectData.StepSectionData.FortranFormatNumbers;
|
|
int typ = ((int)itemInfo.MyContent.Type) % 10000;
|
|
bool ROsShouldBeAdjusted = wordsShouldBeReplaced; // same logical value
|
|
|
|
text = CreateRtf(colorLinks, text, false, wordsShouldBeReplaced, numbersShouldBeFormated, false, ROsShouldBeAdjusted);
|
|
StartText = text;
|
|
}
|
|
private string CreateRtf(bool colorLinks, string text, bool tableShouldBeOutlined, bool wordsShouldBeReplaced, bool numbersShouldBeFormated, bool tableHasBorder, bool ROsShouldBeAdjusted)
|
|
{
|
|
// Adjust RO display
|
|
if (ROsShouldBeAdjusted)
|
|
{
|
|
try // Added try/catch because an unresolved RO Link was causing a failure.
|
|
{
|
|
text = DoROAdjustments(text);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (_MyItemInfo != null)
|
|
{
|
|
_MyLog.ErrorFormat("<<< ERROR >>> Error doing DoROAdjustments\r\n==>'RO Adjustments Error',{0},'{1}','{2}','{3}'"
|
|
, _MyItemInfo.ItemID, _MyItemInfo.MyDocVersion.MyFolder.Name, _MyItemInfo.ShortPath, ex.Message);
|
|
}
|
|
else
|
|
_MyLog.Error("DisplayText.CreateRTF Error doing DoROAdjustments", ex);
|
|
|
|
}
|
|
}
|
|
// if in print mode, view mode, or non-active richtextbox do replace words. Only if in
|
|
// actual edit mode are replace words left as is.
|
|
// But don't do ReplaceWords if the TurnOffReplaceWords format flag is set
|
|
if (wordsShouldBeReplaced && !_MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.TurnOffReplaceWords)
|
|
text = DoReplaceWords2(text);
|
|
if (_MyItemInfo != null)
|
|
{
|
|
text = DoSearchAndReplace(text, "<U-ID>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_ID);
|
|
text = text.Replace(@"<S\u8209?ID>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_ProcedureSetID);
|
|
text = text.Replace("<U>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_Number);
|
|
}
|
|
// Adjust RO display
|
|
if (ROsShouldBeAdjusted)
|
|
text = DoTransitionAdjustments(text, _MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.BoldTransition || (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.BoldTransitionExceptHLS && !_MyItemInfo.IsHigh));
|
|
// add colors around links:
|
|
if (colorLinks)
|
|
text = DoColorLinks(text);
|
|
//Console.WriteLine(text);
|
|
// adjust formatting of exponents
|
|
if (numbersShouldBeFormated)
|
|
text = DoFortranFormat(text);
|
|
// determine whether the table/figure should be outlined:
|
|
if (tableShouldBeOutlined)
|
|
{
|
|
OutlineRTFTable myTable = new OutlineRTFTable(text, tableHasBorder);
|
|
// if a table has internal line draw characters, we may have to do part of 'OutlineTable'
|
|
// to convert dashes and vertical bars to line draw characters.
|
|
if (tableHasBorder) myTable.OutlineTable();
|
|
text = myTable.Lines.ToString();
|
|
}
|
|
|
|
// if we're working with a grid it won't go thru here.
|
|
if (!text.StartsWith(@"{\rtf"))
|
|
{
|
|
// as a precaution, convert any \~ to \u160?. This is for Hard spaces. see the commentary in the
|
|
// save portion of this code for an explanation.
|
|
text = text.Replace(@"\~", @"\u160?");
|
|
text = text.Replace("\r\n", @"\par ");
|
|
//if (text.IndexOf(@"\line") > -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 = NextUnicode(text, 0);//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 = NextUnicode(text, indxsym + incrindx);//text.IndexOf(@"\u", indxsym + incrindx);
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private string DoSearchAndReplace(string text, string find, string replace)
|
|
{
|
|
return text.Replace(find, replace);
|
|
}
|
|
private static string DoColorLinks(string text)
|
|
{
|
|
string origtext = text;
|
|
text = Regex.Replace(text, @"(<START\](\\[^v \\]+)*\\v0)((?= |\\))", @"$1\cf1");
|
|
//text = Regex.Replace(text, @"<START]\b0\v0 ", @"<START]\b0\v0\cf1 ");
|
|
int indxcf = text.IndexOf(@"\v0\cf1");
|
|
int indxend = 0;
|
|
try
|
|
{
|
|
while (indxcf != -1)
|
|
{
|
|
indxcf += 4;
|
|
indxend = text.IndexOf(@"\v", indxcf);
|
|
if (indxend > -1)
|
|
{
|
|
text = text.Insert(indxend, @"\cf0");
|
|
indxcf = text.IndexOf(@"\v0\cf1", indxend);
|
|
}
|
|
else
|
|
{
|
|
indxcf = -1;
|
|
_MyLog.WarnFormat("DisplayText.DoColorLinks Failed\r\norgitext:'{0}'\r\ntext'{1}'", origtext, text);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_MyLog.WarnFormat("DisplayText.DoColorLinks Failed\r\norgitext:'{0}'\r\ntext'{1}'", origtext, text);
|
|
}
|
|
return text;
|
|
}
|
|
private int NextUnicode(string text, int offset)
|
|
{
|
|
// Skip Hard Spaces
|
|
Match m = Regex.Match(text.Substring(offset), @"\\u[0-9a-fA-F]");
|
|
while(m.Success && text.Substring(offset+m.Index).StartsWith(@"\u160"))
|
|
{
|
|
offset += m.Index + 5;
|
|
m = Regex.Match(text.Substring(offset), @"\\u[0-9a-fA-F]");
|
|
}
|
|
if (m.Success)
|
|
return m.Index + offset;
|
|
return -1;
|
|
}
|
|
private string DoROAdjustments(string text)
|
|
{
|
|
Regex regRefObj = new Regex(@"\#Link\:ReferencedObject:([0-9]*) ([0-9a-zA-Z]*) ([0-9]*)", RegexOptions.Singleline);
|
|
string strippedText = StaticStripRtfCommands(text);
|
|
// (\\[^v \\]+)* --> look for any rtf commands (first part of lookFor)
|
|
// \\v0 --> end of comment
|
|
// (\\[^v \\]+)* --> more rtf commands ended by a space
|
|
// (.*?) --> smallest anything to that matches this based on what's next
|
|
// (\\[^v' \\]+)* --> look for rtf commands but exclude \' before the \v
|
|
// \\v(\\[^v \\]+)* --> look for rtf commands after the \v
|
|
// if it turns out that if ro's have any embedded unicode characters this needs expanded, such as /u8209? (hard hyphen)
|
|
string lookFor = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(ReferencedObject|Transition[^:]*?):.*?\[END>");
|
|
MatchCollection matches = Regex.Matches(text, lookFor);
|
|
for (int i = matches.Count - 1; i >= 0; i--)
|
|
{
|
|
Match m = matches[i];
|
|
if (m != null && m.Groups.Count > 6 && m.Groups[6].ToString() == "ReferencedObject")
|
|
{
|
|
System.Text.RegularExpressions.Group g = m.Groups[3];
|
|
string beforeRO = StaticStripRtfCommands(text.Substring(0, g.Index));
|
|
string afterRO = StaticStripRtfCommands(text.Substring(g.Index + g.Length));
|
|
string newvalue = DoROFormatFlags(g.ToString(), beforeRO, afterRO);
|
|
newvalue = DoROReplaceWords(_MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList, newvalue, _MyItemInfo.IsHigh);
|
|
Match myMatch = regRefObj.Match(m.ToString());
|
|
int dbid = System.Convert.ToInt32(myMatch.Groups[2].Value.Substring(0, 4), 16);
|
|
int rodbid = int.Parse(myMatch.Groups[3].Value);
|
|
ROFstInfo myROFst = _MyItemInfo.MyDocVersion.GetROFst(rodbid);
|
|
if (myROFst.IsSetpointDB(dbid)) newvalue = ReplaceSpaceWithHardspace(newvalue);
|
|
if (g.ToString() != newvalue)
|
|
text = text.Substring(0, g.Index) + newvalue + text.Substring(g.Index + g.Length);
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
private string DoROReplaceWords(ReplaceStrList replaceStrList, string newvalue, bool isHigh)
|
|
{
|
|
foreach (ReplaceStr rs in replaceStrList)
|
|
{
|
|
if (((rs.Flag & E_ReplaceFlags.Setpoint) > 0) || (isHigh && (rs.Flag & E_ReplaceFlags.HLSSetpnt) > 0))
|
|
{
|
|
newvalue = newvalue.Replace(rs.ReplaceWord, rs.ReplaceWith);
|
|
}
|
|
}
|
|
return newvalue;
|
|
}
|
|
// Replace spaces with hardspaces, but DO NOT replace the end of an Rtf Command with a hardspace
|
|
private string ReplaceSpaceWithHardspace(string newvalue)
|
|
{
|
|
string oldvalue = newvalue;
|
|
int spindx = newvalue.IndexOf(" ");
|
|
int lstindx = -1;
|
|
while (spindx >= 0)
|
|
{
|
|
if (!EndsRtfCommand(newvalue, spindx, lstindx))
|
|
{
|
|
newvalue = newvalue.Remove(spindx, 1);
|
|
newvalue = newvalue.Insert(spindx, @"\u160?");
|
|
}
|
|
lstindx = spindx;
|
|
spindx = (spindx + 1 >= newvalue.Length)?spindx = -1: newvalue.IndexOf(" ", spindx+1);
|
|
}
|
|
return newvalue;
|
|
}
|
|
|
|
private bool EndsRtfCommand(string str, int spindx, int previndx)
|
|
{
|
|
// get text from last space to current, or from beginning of string to current:
|
|
int start = previndx < 0 ? 0 : previndx+1;
|
|
string substring = str.Substring(start, spindx-start);
|
|
if (substring.Contains(@"\"))
|
|
{
|
|
// is space ending an rtf command.
|
|
int startCmd = substring.LastIndexOf(@"\");
|
|
string Cmd = substring.Substring(startCmd);
|
|
char tst = Cmd[1];
|
|
// consider rtf commands up/dn/b/ul/i
|
|
if (tst == 'u' || tst == 'd' || tst == 'b' || tst == 'u' || tst == 'i') return true;
|
|
}
|
|
return false;
|
|
}
|
|
private string DoTransitionAdjustments(string text, bool boldTran)
|
|
{
|
|
string strippedText = StaticStripRtfCommands(text);
|
|
string lookFor = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v \\u]+)*\\v(\\[^v \\]+)* #Link:(ReferencedObject|Transition[^:]*?):[0-9]* ([0-9]*).*?\[END>");
|
|
MatchCollection matches = Regex.Matches(text, lookFor);
|
|
if (matches.Count == 0) return text;
|
|
string retstr = text;
|
|
for (int i = matches.Count - 1; i >= 0; i--)
|
|
{
|
|
Match m = matches[i];
|
|
// if this transition text already has a hard space, don't add another.
|
|
if (m.Groups[3].Value.Contains("\xA0")) continue;
|
|
// if the transition text does not start with a digit, don't add the hardspace.
|
|
//if (!Char.IsDigit(m.Groups[3].Value[0])) continue;
|
|
if (m != null && m.Groups.Count > 7 && m.Groups[6].ToString().StartsWith("Transition"))
|
|
{
|
|
if (m.Groups[7].Value != "") // && StepTransition(int.Parse(m.Groups[7].Value)))
|
|
{
|
|
System.Text.RegularExpressions.Group g = m.Groups[3];
|
|
string beforeTran = retstr.Substring(0, g.Index);
|
|
string afterTran = retstr.Substring(g.Index + g.Length);
|
|
|
|
// if replacing text in the 'beforeTran' string, then do it here,
|
|
// i.e. there is a format flag 'BeforeTrans' that bolds text before the transition
|
|
// (in wst formats).
|
|
beforeTran = DoBeforeTransFlagSupport(beforeTran, _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.ReplaceStrList);
|
|
string newvalue = g.ToString();
|
|
// if this is a 'step transition' type, i.e. includes a step number, in addition to other replacements,
|
|
// we want to change a space to a hardspace.
|
|
if (StepTransition(int.Parse(m.Groups[7].Value)))
|
|
{
|
|
int indexLastSpace = newvalue.LastIndexOf(' ');
|
|
if (indexLastSpace >= 0)
|
|
// Use a "\x1" as a token to replace later. Insert the unicode char, whose length is
|
|
// more than 1 character was throwing of the regexp Matches index, so that the resulting
|
|
// string may have been incorrect.
|
|
retstr = beforeTran + (boldTran ? @"\b " : null) + newvalue.Substring(0, indexLastSpace) + "\x1" + newvalue.Substring(indexLastSpace + 1) + (boldTran ? @"\b0" : null) + afterTran;
|
|
else
|
|
if (beforeTran.EndsWith(" "))
|
|
retstr = ReplaceLastSpaceWithHardSpace(beforeTran) + (boldTran ? @"\b " : null) + newvalue + (boldTran ? @"\b0" : null) + afterTran;
|
|
else
|
|
Console.Write("");// Don't know where to put the Hard Space
|
|
}
|
|
else if (boldTran)
|
|
{
|
|
retstr = beforeTran + @"\b " + newvalue + @"\b0" + afterTran;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return retstr.Replace("\x1", @"\u160?");
|
|
}
|
|
|
|
private string DoBeforeTransFlagSupport(string beforeTran, ReplaceStrList replaceStrList)
|
|
{
|
|
foreach (ReplaceStr repstr in replaceStrList)
|
|
{
|
|
if ((repstr.Flag & E_ReplaceFlags.BeforeTrans) > 0)
|
|
{
|
|
// the beforeTran string ends with the string that starts the transition comment, i.e.
|
|
// '\\v <START] \\v0 '. The replace word string needs to be before this:
|
|
int indx = beforeTran.LastIndexOf(@"\v <START]\v0");
|
|
if (indx > -1)
|
|
{
|
|
string findit = beforeTran.Substring(0, beforeTran.LastIndexOf(@"\v <START]\v0"));
|
|
if (findit != null && findit.Trim().ToUpper().EndsWith(repstr.ReplaceWord.ToUpper()))
|
|
{
|
|
// int rindx = findit.Trim().ToUpper().IndexOf(repstr.ReplaceWord.ToUpper());
|
|
int rindx = findit.Trim().ToUpper().LastIndexOf(repstr.ReplaceWord.ToUpper());
|
|
// don't replace string because case of words may be match replace with string.
|
|
beforeTran = findit.Substring(0, rindx) + @"\b " + findit.Substring(rindx) + @"\b0" + beforeTran.Substring(indx);
|
|
return beforeTran;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return beforeTran;
|
|
}
|
|
private string ReplaceLastSpaceWithHardSpace(string str)
|
|
{
|
|
int ind =str.LastIndexOf("<START]");
|
|
ind = str.LastIndexOf(@"\", ind);
|
|
while (ind > 0 && str[ind - 1] != ' ')
|
|
{
|
|
if (ind > 5 && str.Substring(0, ind).EndsWith(@"\u160?") || str.Substring(0, ind).ToLower().EndsWith(@"\'a0"))
|
|
return str;//Already has a Hard Space
|
|
ind = str.LastIndexOf(@"\", ind - 1);
|
|
}
|
|
// If the previous character is a comma or a space then don't add a Hard Space
|
|
if (ind > 1 && (str[ind - 2] == ',' || str[ind - 2] == ' ')) return str;
|
|
if (ind <= 0) return str;
|
|
|
|
// replace with a 'token' "\x1" instead of a hardspace unicode char. When using a hardspace unicode
|
|
// char the string length/contents was thrown off so that the calling method's processing was off
|
|
// in terms of regexp matches in string.
|
|
return str.Substring(0, ind - 1) + "\x1" + str.Substring(ind);
|
|
}
|
|
private bool StepTransition(int TransId)
|
|
{
|
|
if (_MyItemInfo == null) return false;
|
|
_MyItemInfo.MyContent.RefreshContentTransitions();
|
|
foreach (TransitionInfo trans in _MyItemInfo.MyContent.ContentTransitions)
|
|
if (trans.TransitionID == TransId)
|
|
return trans.MyItemToID.IsStep;
|
|
return false;
|
|
}
|
|
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\up2 {1}\up0 ", fnum, supnum);
|
|
retstr = retstr.Replace(m.Value, newstr);
|
|
}
|
|
return retstr;
|
|
}
|
|
#endregion
|
|
#region SaveData
|
|
public bool Save(RichTextBox rtb)
|
|
{
|
|
//int savSelStart = rtb.SelectionStart;
|
|
try
|
|
{
|
|
//FormatInfo formatInfo = _MyItemInfo.ActiveFormat;
|
|
using (_MyItem = _MyItemInfo.Get())
|
|
{
|
|
// The following was added to support transitions to un-numbered steps
|
|
if (_MyItemInfo.NewTransToUnNumberedItem && rtb.Text.Contains("<NewID>"))
|
|
{
|
|
ItemAnnotation ia = _MyItem.ItemAnnotations.Add(AnnotationType.GetByName("Verification Required"));
|
|
ia.SearchText = "Transition to Un-Numbered Step";
|
|
_MyItemInfo.NewTransToUnNumberedItem = false;
|
|
}
|
|
// 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).Replace("<BackSlash>", "\\\\");
|
|
|
|
// if there are links, we'll need to do extra processing to see if
|
|
// there were additions, deletions or modifications.
|
|
bool haslinks = ((modtext.IndexOf(@"<START]") > -1) || (OriginalText != null && OriginalText != "" && OriginalText.IndexOf(@"<START]") > -1));
|
|
if (haslinks)
|
|
{
|
|
// Get all links in original list
|
|
RtfToDisplayTextElements(OriginalText);
|
|
List<displayLinkElement> origList = GetLinkList(DisplayTextElementList);
|
|
// now get new text into displaytext elements for comparison for links:
|
|
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<int, ContentTransition> ctReplacements = BuildCtReplacements(_MyItem.MyContent.ContentTransitions);
|
|
Dictionary<int, ContentRoUsage> roUsgReplacements = BuildRoUsgReplacements(_MyItem.MyContent.ContentRoUsages);
|
|
_MyItem.DTS = DateTime.Now;
|
|
_MyItem.UserID = Volian.Base.Library.VlnSettings.UserID;
|
|
// Do the Save once rather than multiple times
|
|
_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);
|
|
}
|
|
// Don't update the DTS or User for Text Changes
|
|
//_MyItem.DTS = DateTime.Now;
|
|
//_MyItem.UserID = Volian.Base.Library.VlnSettings.UserID;
|
|
_MyItem.Save();
|
|
}
|
|
_MyItem = null;
|
|
OriginalText = modtext;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("DisplayText Save Failed with error: {0} - {1}\r\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
|
|
return false;
|
|
}
|
|
//rtb.SelectionStart = savSelStart;
|
|
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<int, ContentRoUsage> roUsgReplacements)
|
|
{
|
|
foreach (int oldid in roUsgReplacements.Keys)
|
|
{
|
|
p = p.Replace(string.Format("<CROUSGID={0}>", oldid), roUsgReplacements[oldid].ROUsageID.ToString());
|
|
}
|
|
return p;
|
|
}
|
|
private Dictionary<int, ContentRoUsage> BuildRoUsgReplacements(ContentRoUsages contentRoUsages)
|
|
{
|
|
Dictionary<int, ContentRoUsage> retval = new Dictionary<int, ContentRoUsage>();
|
|
foreach (ContentRoUsage rou in contentRoUsages)
|
|
{
|
|
if (rou.ROUsageID < 0) retval.Add(rou.ROUsageID, rou);
|
|
}
|
|
return retval;
|
|
}
|
|
private string FixCtReplacements(string p, Dictionary<int, ContentTransition> ctReplacements)
|
|
{
|
|
foreach (int oldid in ctReplacements.Keys)
|
|
{
|
|
p = p.Replace(string.Format("<CTID={0}>",oldid),ctReplacements[oldid].TransitionID.ToString());
|
|
}
|
|
return p;
|
|
}
|
|
private Dictionary<int, ContentTransition> BuildCtReplacements(ContentTransitions contentTransitions)
|
|
{
|
|
Dictionary<int, ContentTransition> retval = new Dictionary<int, ContentTransition>();
|
|
foreach (ContentTransition ct in contentTransitions)
|
|
{
|
|
if (ct.TransitionID < 0) retval.Add(ct.TransitionID, ct);
|
|
}
|
|
return retval;
|
|
}
|
|
private void ProcessRoTranChanges(Item itm, List<displayLinkElement> 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("<NewID>", string.Format("<CROUSGID={0}>", rousg.ROUsageID));
|
|
l_dte.TextAndLink = l_dte.TextAndLink.Replace("<NewID>", string.Format("<CROUSGID={0}>", 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[2] is token for tranid
|
|
int tr2 = tr1;
|
|
if(tparts.Length > 3)
|
|
tr2 = System.Convert.ToInt32(tparts[3]); // tparts[3] is token for rangeid
|
|
bool dispose1 = false;
|
|
Item itm1 = null;
|
|
bool dispose2 = false;
|
|
Item itm2 = null;
|
|
if (itm.ItemID == tr1)
|
|
itm1 = itm; // a transition that points to itself should not dispose
|
|
else
|
|
{
|
|
dispose1 = true;
|
|
itm1 = Item.Get(tr1);
|
|
}
|
|
if (itm.ItemID == tr2)
|
|
itm2 = itm; // a transition that points to itself should not dispose
|
|
else if (tr1 == tr2)
|
|
itm2 = itm1; // if both destinations are the same only dispose the first one
|
|
else
|
|
{
|
|
dispose2 = true;
|
|
itm2 = Item.Get(tr2);
|
|
}
|
|
ContentTransition ct = itm.MyContent.ContentTransitions.Add(itm1, itm2);
|
|
//Console.WriteLine("CT {0},{1},{2},{3}", ct.TransitionID, itm.ItemID, itm.MyContent.MyContentUnique, itm.MyContent.ContentTransitions.Count);
|
|
ct.TranType = type;
|
|
if (dte.Type == E_TextElementType.Transition)
|
|
ct.IsRange = 0;
|
|
else if (tr1 != tr2)
|
|
ct.IsRange = 1;
|
|
else
|
|
ct.IsRange = 2;
|
|
l_dte.Link = l_dte.Link.Replace("<NewID>", string.Format("<CTID={0}>", ct.TransitionID));
|
|
l_dte.TextAndLink = l_dte.TextAndLink.Replace("<NewID>", string.Format("<CTID={0}>", ct.TransitionID));
|
|
if (dispose2) itm2.Dispose();
|
|
if (dispose1) itm1.Dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private List<displayLinkElement> GetLinkList(List<displayTextElement> locDisplayTextElementList)
|
|
{
|
|
List<displayLinkElement> retList = new List<displayLinkElement>();
|
|
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<displayTextElement>();
|
|
else
|
|
DisplayTextElementList.Clear();
|
|
|
|
if (text == null || text == "") return;
|
|
|
|
string noExtraRtfStr = text;
|
|
|
|
int startIndex = 0;
|
|
int index = -1;
|
|
noExtraRtfStr = noExtraRtfStr.Replace(@"><", @">\v0 \v <");
|
|
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?");
|
|
noExtraRtfStr = noExtraRtfStr.Replace(@"\'a0", @"\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><START]", @"[END>\v0 \v <START]");
|
|
|
|
// GetFontTable returns a non-negative number font number in the
|
|
// font table for the unicode font, if it is used (otherwise -1)
|
|
//int unicodeFont = GetFontTable(rtb.Rtf);
|
|
|
|
// strip off all rtf commands...
|
|
noExtraRtfStr = StripRtfCommands(noExtraRtfStr);
|
|
|
|
// the indent character was translated in the richtextbox, change it back:
|
|
if (noExtraRtfStr.IndexOf(@"\'05") > -1) noExtraRtfStr = noExtraRtfStr.Replace(@"\'05", "\x05");
|
|
|
|
return noExtraRtfStr;
|
|
}
|
|
public static string StaticReplaceRTFClause(Match m)
|
|
{
|
|
try
|
|
{
|
|
string token = m.Groups[1].Value;
|
|
switch (token[1])
|
|
{
|
|
case '\\':
|
|
return token;
|
|
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
|
|
if (Regex.IsMatch(token, @"^\\up[0-9] ?$"))
|
|
return token; // shift up (superscript)
|
|
break;
|
|
case 'd':
|
|
if (Regex.IsMatch(token, @"^\\dn[0-9] ?$"))
|
|
return token; // shift down (subscript)
|
|
break;
|
|
case '\'': // Special Character
|
|
return token;
|
|
case 'b': // Bold
|
|
return token;
|
|
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("StaticReplaceRTFClause {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 ");
|
|
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.EndsWith("\r\n")) retval = retval.Remove(retval.Length - 2, 2);
|
|
if (retval.Length == 0) return "";
|
|
if (retval.EndsWith(@"\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;
|
|
}
|
|
// This is used in the DataLoader
|
|
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<num>
|
|
// and links are represented by \v <START]\v0 'link text'\v #'link info'[END>\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 + 2] !='p')) || (txt[indx + 1] == '\'')) return indx;
|
|
// see if link
|
|
if (txt[indx + 1] == 'v') return indx; //TODO - should have <START here too!
|
|
// 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("<NewID>") != -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 GetLastLower(string stepText)
|
|
//{
|
|
// // TO DO: need to check AlwaysUpperCase format setting - this was not yet converted as of 17Jun2010
|
|
// // if (AlwaysUpperCase[steptype]) return (stepText.Length-1);
|
|
|
|
// int idx = stepText.Length - 1;
|
|
// while (idx >= 0 && !(char.IsLower(stepText[idx]) && stepText[idx] != 's')) idx--;
|
|
// if (idx < 0) idx = stepText.Length - 1; // entire string is uppercased set return value to end of string
|
|
// return idx;
|
|
//}
|
|
|
|
//private bool IsSpaceOrHardSpace(char ch)
|
|
//{
|
|
// string spaces = @" \u160?";
|
|
// return (spaces.IndexOf(ch) >= 0);
|
|
//}
|
|
private string DoROFormatFlags(string roText, string beforeRO, string afterRO)
|
|
{
|
|
string rtnstr = roText;
|
|
// The RO text is being changed to match it's context. Since it is changed in reverse order, the text before the RO
|
|
// should ignore other RO text.
|
|
beforeRO = Regex.Replace(beforeRO, @"(\\[^v \\]+)*\\v0[^v\\]*\\v(\\[^v \\]+)* #Link:Refer", ""); // Remove any RO Values.
|
|
beforeRO = Regex.Replace(beforeRO, @"(\\[^v \\]+)*\\v(\\[^v \\]+)* .*?\\v0(\\[^v \\]+)*( |$)", ""); // Remove Comments
|
|
afterRO = Regex.Replace(afterRO, @"(\\[^v \\]+)*\\v(\\[^v \\]+)* .*?\\v0(\\[^v \\]+)*( |$)", ""); // Remove Comments
|
|
|
|
// Underline all ROs, values and Units
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UnderlineRo)
|
|
{
|
|
// TO DO: Need to check if step text is already underlined
|
|
rtnstr = @"\ul " + rtnstr + @"\ulnone ";
|
|
}
|
|
|
|
// UpcaseAllRoUnits - Uppercases ALL ROs units everywhere.
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpcaseAllRoUnits)
|
|
return UpperCaseUnits(rtnstr);
|
|
|
|
//Forces the units for a RO to be uppercased for high level steps
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapHighRo &&_MyItemInfo.IsHigh)
|
|
return UpperCaseUnits(rtnstr);
|
|
|
|
// Caps ROs anywhere if no lower case text follows
|
|
// and an upper case letter immediately precedes the RO.
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapRoIfLastLower && !Regex.IsMatch(afterRO,"[a-z]") && char.IsUpper(LastAlpha(beforeRO)))
|
|
{
|
|
//int indx = startLinkText - 1;
|
|
//int indx2 = endLinkText + 1;
|
|
//while (indx > 0 && !IsSpaceOrHardSpace(stepText[indx])) indx--; // find character before RO
|
|
//while (indx2 <= stepText.Length && !IsSpaceOrHardSpace(stepText[indx2])) indx2++; // find character after RO
|
|
|
|
//if (indx >= 0 && char.IsUpper(stepText[indx]) && indx2 > GetLastLower(stepText))
|
|
// doUpCase = true;
|
|
return UpperCaseUnits(rtnstr);
|
|
}
|
|
|
|
// If a RO follows a "- " then it will be uppercased
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpRoAftrDash && Regex.IsMatch(beforeRO, @".*\\u8209\?( |\\u160\?)$"))
|
|
{
|
|
//int indx = startLinkText - 1;
|
|
//while (indx > 0 && !IsSpaceOrHardSpace(stepText[indx])) indx--; // find character before RO
|
|
//string prefix = indx >= 7?stepText.Substring(indx-7,8):"";
|
|
//doUpCase = (prefix == @"\u8209? "); // Dash character before RO
|
|
return UpperCaseUnits(rtnstr);
|
|
}
|
|
|
|
// Uppercase the RO Unit if the previous letter is uppercase
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpRoIfPrevUpper && char.IsUpper(LastAlpha(beforeRO)))
|
|
{
|
|
//doUpCase = (char.IsUpper(stepText[startLinkText - 1]));
|
|
return UpperCaseUnits(rtnstr);
|
|
|
|
}
|
|
|
|
//CapFirstLetterInHighRO - Cap only the first letters of the units in a high level RO
|
|
// note: used in FLP (Turkey Point) format
|
|
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapFirstLetterInHighRO && _MyItemInfo.IsHigh)
|
|
{
|
|
int idx = 0;
|
|
string tstr = "";
|
|
while (idx < rtnstr.Length && !char.IsLetter(rtnstr[idx])) tstr += rtnstr[idx++].ToString();
|
|
if (idx < rtnstr.Length)
|
|
{
|
|
tstr += char.ToUpper(rtnstr[idx]).ToString();
|
|
if (idx + 1 < rtnstr.Length)
|
|
tstr += rtnstr.Substring(idx + 1);
|
|
}
|
|
rtnstr = tstr;
|
|
}
|
|
|
|
//In a sequence of RO values, the unit appears with every value
|
|
//(e.g., "25 gpm and 30 gpm" vs. "25 and 30 gpm")
|
|
//if (!_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.AllUnits)
|
|
//{
|
|
// int idx = rtnstr.LastIndexOf(' ');
|
|
// if (idx > 0)
|
|
// {
|
|
// StringBuilder sb = new StringBuilder();
|
|
// string lastunit = rtnstr.Substring(idx); // RO unit including preceeding space
|
|
// int idx2 = rtnstr.IndexOf(lastunit);
|
|
// int si = 0;
|
|
// while (idx2 < idx)
|
|
// {
|
|
// sb.Append(rtnstr.Substring(si, idx2 - si));
|
|
// si = idx2 + lastunit.Length;
|
|
// idx2 = rtnstr.IndexOf(lastunit, si);
|
|
// }
|
|
// sb.Append(rtnstr.Substring(si));
|
|
// rtnstr = sb.ToString();
|
|
// }
|
|
//}
|
|
|
|
return rtnstr;
|
|
}
|
|
/// <summary>
|
|
/// Uppercase alphabetical strings excluding any RTF token
|
|
/// </summary>
|
|
/// <param name="match"></param>
|
|
/// <returns></returns>
|
|
private string MatchEvaluatorUppercaseROUnits(Match match)
|
|
{
|
|
if (match.Value[0] == '\\') // If the previous character is a backslash then this is an RTF token
|
|
return match.Value;
|
|
return match.Value.ToUpper();
|
|
}
|
|
Regex _RegExUppercaseROUnits = new Regex("(^|[^a-zA-Z])[a-zA-Z]+");
|
|
private string UpperCaseUnits(string rtnstr)
|
|
{
|
|
// Uppercase Units
|
|
rtnstr = _RegExUppercaseROUnits.Replace(rtnstr, new MatchEvaluator(MatchEvaluatorUppercaseROUnits));
|
|
// After converting the value to uppercase, change X10 to x10 to handle Fortran Formatted numbers
|
|
return rtnstr.Replace("X10", "x10");
|
|
}
|
|
|
|
// Find the last Alphabetical character
|
|
private char LastAlpha(string beforeRO)
|
|
{
|
|
Match m = Regex.Match(beforeRO, ".*([a-zA-Z])[^a-zA-Z]*");
|
|
if (m.Success) return m.Groups[1].ToString()[0];
|
|
return '\0';
|
|
}
|
|
|
|
private int DoLinkElements(string text, int index, displayLinkElement vte)
|
|
{
|
|
// Find the 'end comment' for this <START], can't count characters
|
|
// because there may be formatting characters such as \b or \ul before
|
|
// the \v0
|
|
int linkIndx = text.IndexOf(@"#Link", index);
|
|
int endStartTknIndx = text.IndexOf(@"\v0 ", index);
|
|
if (endStartTknIndx == -1)
|
|
endStartTknIndx = text.IndexOf(@"\v0", index);
|
|
int endTextIndx = text.IndexOf(@"\v ", endStartTknIndx); // find end of text
|
|
if (endTextIndx == -1)
|
|
endTextIndx = text.IndexOf(@"\v", endStartTknIndx);
|
|
int endTextIndx2 = text.IndexOf(@"\v\up0 ", endStartTknIndx); // find end of text
|
|
if(endTextIndx2 > 0 && (endTextIndx < 0 || endTextIndx > endTextIndx2))
|
|
endTextIndx = endTextIndx2;
|
|
vte.Text = text.Substring(endStartTknIndx + 4, endTextIndx - endStartTknIndx - 4); // 4 for \v0
|
|
|
|
// Now get the link part. It can be terminated by a '\v0' or an [END>
|
|
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;
|
|
}
|
|
//else
|
|
//{
|
|
// tmptxt = DoROFormatFlags(vte.Text, text, index, endLinkIndx);
|
|
// 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 <START]
|
|
int endToken = (endLinkIndx == endLinkIndxE)?endLinkIndx+3:text.IndexOf(@"[END>", 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
|
|
#region commented out
|
|
//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;
|
|
|
|
// if (_MyItemInfo.ItemID == 2557) Console.WriteLine("here");
|
|
// // 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.IsStepPart && (rs.Flag & E_ReplaceFlags.Substep) > 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|^)(?<![\\u160?])" + rs.ReplaceWord.ToUpper() + @"(?=[^\\u160?]|$)";
|
|
// //int cpindx = 0;
|
|
// //foreach (Match m in Regex.Matches(fortest, pat))
|
|
// //{
|
|
// // res += Text.Substring(cpindx, m.Index - cpindx);
|
|
// // cpindx += (m.Index - cpindx);
|
|
// // res += rs.ReplaceWith;
|
|
// // cpindx += rs.ReplaceWord.Length;
|
|
// //}
|
|
// //if (cpindx < Text.Length) res += Text.Substring(cpindx, Text.Length - cpindx);
|
|
// //Text = res;
|
|
|
|
// // 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|^)(?<![\\u160?])" + replaceWord + @"(?=[^\\u160?]|\W|$)";
|
|
// string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?![\\u160?])(?=\W|$)";
|
|
// try
|
|
// {
|
|
// Text = ReplaceWord(Text, pat, rs.ReplaceWith, RegexOptions.IgnoreCase);
|
|
// //Text = Regex.Replace(Text, pat, rs.ReplaceWith, RegexOptions.IgnoreCase);
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, replaceWord, ex.GetType().Name, ex.Message);
|
|
// }
|
|
|
|
// }
|
|
// // CASEINSENSALL: Do ReplaceWords for all words that match the ReplaceWord, regardless of case
|
|
// else if ((rs.Flag & E_ReplaceFlags.CaseInsensAll) > 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|^)(?<![\\u160?])" + replaceWord + @"(?=[^\\u160?]|\W|$)";
|
|
// string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?![\\u160?])(?=\W|$)";
|
|
// try
|
|
// {
|
|
// Text = ReplaceWord(Text, pat, rs.ReplaceWith, RegexOptions.None);
|
|
// //Text = Regex.Replace(Text, pat, rs.ReplaceWith);
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, replaceWord, ex.GetType().Name, ex.Message);
|
|
// }
|
|
// }
|
|
|
|
// }
|
|
// }
|
|
// //Console.WriteLine("--- Before '{0}'", Text);
|
|
// Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
|
|
// //Console.WriteLine("--- After '{0}'", Text);
|
|
// return Text;
|
|
//}
|
|
//private string DoReplaceWords1(string Text)
|
|
//{
|
|
// if (_MyItemInfo.MyContent.Type < 20000) return Text; // for now only replace in steps.
|
|
// ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList;
|
|
// // Loop through text looking for words to be replaced
|
|
// foreach (ReplaceStr rs in rsl)
|
|
// {
|
|
// 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.IsStepPart && (rs.Flag & E_ReplaceFlags.Substep) > 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
|
|
// RegexOptions myOptions = (rs.Flag & E_ReplaceFlags.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase : RegexOptions.None;
|
|
// string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0");
|
|
// string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?![\\u160?])(?=\W|$)";
|
|
// try
|
|
// {
|
|
// Text = ReplaceWord(Text, pat, rs.ReplaceWith, myOptions);
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, replaceWord, ex.GetType().Name, ex.Message);
|
|
// }
|
|
|
|
// }
|
|
// }
|
|
// Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
|
|
// return Text;
|
|
//}
|
|
#endregion
|
|
private Dictionary<ReplaceStr, Regex> dicReplaceRegex = new Dictionary<ReplaceStr, Regex>();
|
|
private string DoReplaceWords2(string Text)
|
|
{
|
|
if (_MyItemInfo.MyContent.Type < 20000) return Text; // for now only replace in steps.
|
|
FoundMatches myMatches = new FoundMatches(Text);
|
|
// Exclude Link Text from Replace Word process
|
|
myMatches.AddLink(regFindLink, _MyFormat.PlantFormat.FormatData.SectData.ReplaceWordsInROs, _MyItemInfo.MyProcedure.MyDocVersion);
|
|
ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList;
|
|
|
|
// The only way to get an 'empty' list is to have one 'dummy' replacestr, i.e. that has ReplaceWord as an empty string. If the
|
|
// ReplaceStrData xml node is empty, it does the inheritance and gets the 'base' format's list.
|
|
if (rsl.Count==1 && (rsl[0].ReplaceWord == null || rsl[0].ReplaceWord == "")) return Text;
|
|
// Loop through text looking for words to be replaced
|
|
foreach (ReplaceStr rs in rsl)
|
|
{
|
|
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.IsStepPart && !_MyItemInfo.IsHigh && (rs.Flag & E_ReplaceFlags.Substep) > 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)
|
|
{
|
|
if (!dicReplaceRegex.ContainsKey(rs))
|
|
{
|
|
// CASEINSENS: Do ReplaceWords for all words that match, regardless of case, and replace with the ReplaceWith string as is
|
|
//RegexOptions myOptions = (rs.Flag & E_ReplaceFlags.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase & RegexOptions.Singleline : RegexOptions.None & RegexOptions.Singleline;
|
|
RegexOptions myOptions = (rs.Flag & E_ReplaceFlags.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase: RegexOptions.None;
|
|
string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0");
|
|
// if first or last character in replaceword is a non-word character, for example, ',', ')', or '.',
|
|
// don't use the \W, i.e. don't bother to look for a non-word character.
|
|
string wordMatchBeg = Regex.IsMatch(replaceWord.Substring(0, 1), @"\W") ? "" : @"(?<=\W|^)";
|
|
string wordMatchEnd = Regex.IsMatch(replaceWord.Substring(replaceWord.Length - 1, 1), @"\W") ? "" : @"(?=\W|$)";
|
|
string pat = wordMatchBeg + @"(?<!\\u160\?|\\u8209\?)" + replaceWord + @"(?!\\u160\?|\\u8209\?)" + wordMatchEnd;
|
|
dicReplaceRegex.Add(rs, new Regex(pat, myOptions));
|
|
}
|
|
try
|
|
{
|
|
myMatches.Add(dicReplaceRegex[rs], rs);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, rs.ReplaceWord, ex.GetType().Name, ex.Message);
|
|
}
|
|
}
|
|
}
|
|
Text = myMatches.ReplaceMatches();
|
|
Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
|
|
return Text;
|
|
}
|
|
#region notused
|
|
static Regex regFindLink = new Regex(@"\<START\].*?\[END\>", RegexOptions.Singleline);
|
|
private string ReplaceWord(string text, string replace, string with, RegexOptions regexOptions)
|
|
{
|
|
MatchCollection myMatches = Regex.Matches(text, replace, regexOptions);
|
|
MatchCollection myLinks = regFindLink.Matches(text);
|
|
for (int i = myMatches.Count - 1; i >= 0; i--)
|
|
{
|
|
Match myMatch = myMatches[i];
|
|
if (!PartOfLinkText(myMatch, myLinks))
|
|
text = text.Substring(0, myMatch.Index) + with + text.Substring(myMatch.Index + myMatch.Length);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private bool PartOfLinkText(Match myMatch, MatchCollection myLinks)
|
|
{
|
|
foreach (Match myLink in myLinks)
|
|
if (myMatch.Index > myLink.Index && myMatch.Index < (myLink.Index + myLink.Length))
|
|
return true;
|
|
return false;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|
|
#region displayTextElementClass
|
|
public enum E_TextElementType : uint
|
|
{
|
|
Text = 0,
|
|
Transition = 1,
|
|
TransitionRange = 2,
|
|
ReferencedObject = 3,
|
|
Symbol = 4
|
|
};
|
|
public class displayTextElement
|
|
{
|
|
private E_TextElementType _Type;
|
|
public E_TextElementType Type
|
|
{
|
|
get { return _Type; }
|
|
set { _Type = value; }
|
|
}
|
|
protected string _Text;
|
|
virtual public string Text
|
|
{
|
|
get { return _Text; }
|
|
set { _Text = value; }
|
|
}
|
|
}
|
|
public class displayLinkElement : displayTextElement
|
|
{
|
|
private string _Link;
|
|
public string Link
|
|
{
|
|
get { return _Link; }
|
|
set { _Link = value; }
|
|
}
|
|
private string _TextAndLink;
|
|
public string TextAndLink
|
|
{
|
|
get { return _TextAndLink; }
|
|
set { _TextAndLink = value; }
|
|
}
|
|
/// <summary>
|
|
/// Text - this should parse the text and return the results
|
|
/// </summary>
|
|
override public string Text
|
|
{
|
|
get
|
|
{
|
|
if (_TextAndLink != null)
|
|
{
|
|
Match m = Regex.Match(_TextAndLink, @"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>");
|
|
return m.Groups[3].ToString();
|
|
}
|
|
return _Text;
|
|
}
|
|
set
|
|
{
|
|
if (_TextAndLink != null)
|
|
{
|
|
Match m = Regex.Match(_TextAndLink, @"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>");
|
|
System.Text.RegularExpressions.Group g = m.Groups[3];
|
|
_TextAndLink = _TextAndLink.Substring(0, g.Index) + value + _TextAndLink.Substring(g.Index + g.Length);
|
|
}
|
|
_Text = value;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
public class FoundMatches : SortedList<int, FoundMatch>
|
|
{
|
|
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
private string _Text;
|
|
public FoundMatches(string text)
|
|
: base()
|
|
{
|
|
_Text = text;
|
|
}
|
|
public void Add(Regex myRegEx, ReplaceStr myWord)
|
|
{
|
|
MatchCollection myMatches = myRegEx.Matches(_Text);
|
|
foreach (Match myMatch in myMatches)
|
|
Add(myMatch, myWord);
|
|
}
|
|
public void AddLink(Regex myRegEx, bool replaceWordsInROs, DocVersionInfo myDocVersion)
|
|
{
|
|
MatchCollection myMatches = myRegEx.Matches(_Text);
|
|
foreach (Match myMatch in myMatches)
|
|
{
|
|
if (!replaceWordsInROs || IsTransition(myMatch.Value) || IsSetpointRO(myMatch.Value, myDocVersion))
|
|
Add(myMatch, null);// Exclude from Replace Words
|
|
}
|
|
}
|
|
private bool IsTransition(string link)
|
|
{
|
|
return link.Contains("#Link:Transition");
|
|
}
|
|
private static Regex regRefObj = new Regex(@"\#Link\:ReferencedObject:([0-9]*) ([0-9a-zA-Z]*) ([0-9]*)", RegexOptions.Singleline);
|
|
private static bool IsSetpointRO(string link, DocVersionInfo myDocVersion)
|
|
{
|
|
Match myMatch = regRefObj.Match(link);
|
|
if (myMatch.Success)
|
|
{
|
|
int dbid = System.Convert.ToInt32(myMatch.Groups[2].Value.Substring(0, 4), 16);
|
|
int rodbid = int.Parse(myMatch.Groups[3].Value);
|
|
ROFstInfo myROFst = myDocVersion.GetROFst(rodbid);
|
|
return myROFst.IsSetpointDB(dbid);
|
|
}
|
|
return false;
|
|
}
|
|
public void Add(Match myMatch, ReplaceStr myWord)
|
|
{
|
|
// If one already exists for this location, then don't add another.
|
|
if (ContainsKey(myMatch.Index)) return;
|
|
// Start by Adding it.
|
|
base.Add(myMatch.Index, new FoundMatch(myMatch, myWord));
|
|
// Now see what I can do with it.
|
|
int index = this.IndexOfKey(myMatch.Index);
|
|
if (index > 0) // If this match is contained within the previous match remove it
|
|
{
|
|
FoundMatch previousMatch = Values[index - 1];
|
|
if (previousMatch.MyMatch.Index + previousMatch.MyMatch.Length > myMatch.Index)
|
|
Remove(myMatch.Index);
|
|
} // If the next match is contained within this match, remove the next match
|
|
while (index < Count - 1 && Values[index + 1].MyMatch.Index < (myMatch.Index + myMatch.Length))
|
|
Remove(Values[index + 1].MyMatch.Index);
|
|
}
|
|
public string ReplaceMatches()
|
|
{
|
|
int offset = 0;
|
|
string text = _Text;
|
|
foreach (FoundMatch foundMatch in Values)
|
|
{
|
|
if (foundMatch.MyWord != null)
|
|
{
|
|
if (VerifyNoHardSpace(text, foundMatch, offset))
|
|
{
|
|
if(offset != 0 || foundMatch.MyMatch.Index != 0 || !foundMatch.MyWord.ReplaceWith.StartsWith("{\\par}"))
|
|
{
|
|
text = text.Substring(0, offset + foundMatch.MyMatch.Index) + foundMatch.MyWord.ReplaceWith + text.Substring(offset + foundMatch.MyMatch.Index + foundMatch.MyMatch.Length);
|
|
offset += foundMatch.MyWord.ReplaceWith.Length - foundMatch.MyMatch.Length;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private bool VerifyNoHardSpace(string text, FoundMatch foundMatch, int offset)
|
|
{
|
|
string begin = text.Substring(0, offset + foundMatch.MyMatch.Index);
|
|
string end = text.Substring(offset + foundMatch.MyMatch.Index + foundMatch.MyMatch.Length);
|
|
if (text.StartsWith(@"{\rtf"))
|
|
{
|
|
// make sure that it is not preceded by \u160? \'a0 or \~
|
|
if(Regex.IsMatch(begin,@"(\\(u160\?|'a0|~)(\\f[0-9]* ?)*(\\fs[0-9]* ?)*)$"))
|
|
return false;
|
|
// make sure that it is not followed by \u160? \'a0 or \~
|
|
if(Regex.IsMatch(end,@"^((\\f[0-9]* ?)*(\\fs[0-9]* ?)*\\(u160\?|'a0|~))"))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
public class FoundMatch
|
|
{
|
|
private Match _MyMatch;
|
|
public Match MyMatch
|
|
{
|
|
get { return _MyMatch; }
|
|
set { _MyMatch = value; }
|
|
}
|
|
private ReplaceStr _MyWord;
|
|
public ReplaceStr MyWord
|
|
{
|
|
get { return _MyWord; }
|
|
set { _MyWord = value; }
|
|
}
|
|
public FoundMatch(Match myMatch, ReplaceStr myWord)
|
|
{
|
|
_MyMatch = myMatch;
|
|
_MyWord = myWord;
|
|
}
|
|
}
|
|
|
|
}
|