2959 lines
130 KiB
C#
2959 lines
130 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using System.Windows.Forms;
|
||
using System.Text.RegularExpressions;
|
||
using System.Drawing;
|
||
using Volian.Base.Library;
|
||
using JR.Utils.GUI.Forms;
|
||
|
||
// This was moved from volian.controls.library
|
||
namespace VEPROMS.CSLA.Library
|
||
{
|
||
public enum E_FieldToEdit { StepText, Text, Number, PSI };
|
||
public class DisplayText
|
||
{
|
||
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||
#region Properties
|
||
public static int RemoveTrailingBlankID = -1;
|
||
private bool _setDTS = true; // Added for when data is cleaned so that DTS/UserID are not reset (for B2016-037 fix)
|
||
public bool SetDTS
|
||
{
|
||
get { return _setDTS; }
|
||
set { _setDTS = value; }
|
||
}
|
||
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;
|
||
if (SetDTS)
|
||
{
|
||
_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.
|
||
public bool AddedDefaultTextFromFmt = false;
|
||
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, bool RemoveTrailingHardReturnAndManualPageBreaks)
|
||
{
|
||
int profileDepth = ProfileTimer.Push(">>>> DisplayText");
|
||
_FieldToEdit = fieldToEdit;
|
||
_MyItemInfo = itemInfo;
|
||
OriginalText = epMode == E_EditPrintMode.Print && RemoveTrailingHardReturnAndManualPageBreaks ?
|
||
Regex.Replace(InfoText, "(\\\\line|\r|\n|\\\\u160\\?| )+$", "") : InfoText;
|
||
// C2021-010: Remove trailing returns/spaces & manual page breaks & allow save. Use RemoveTrailingBlankID to
|
||
// return the itemid if this item's text was changed because print is occurring with removal of trailing
|
||
// hardreturns.
|
||
RemoveTrailingBlankID = -1;
|
||
if (!itemInfo.IsTable && RemoveTrailingHardReturnAndManualPageBreaks && InfoText != OriginalText)
|
||
{
|
||
// No 'true' change occurred if trailing space was after an rtf command
|
||
if (!OriginalText.EndsWith(@"\b0") && !OriginalText.EndsWith(@"\i0") && !OriginalText.EndsWith(@"\ulnone") &&
|
||
!OriginalText.EndsWith(@"\up0") && !OriginalText.EndsWith(@"\dn0"))
|
||
{
|
||
RemoveTrailingBlankID = itemInfo.ItemID;
|
||
if (OriginalText == "") OriginalText = " "; // B2021-028: don't make step empty, print with a space
|
||
}
|
||
else
|
||
OriginalText = InfoText;
|
||
}
|
||
//OriginalText = InfoText;
|
||
//if (OriginalText != InfoText) Console.WriteLine("ItemId = {0}, {1}", itemInfo.ItemID, OriginalText.Length-InfoText.Length);
|
||
if (OriginalText.Contains("Prerequisite") && epMode == E_EditPrintMode.Print)
|
||
OriginalText = Regex.Replace(OriginalText, @"\\{Prerequisite Step: .*?\\}", "");
|
||
TextFont = itemInfo.GetItemFont();//GetItemFont();
|
||
// if in print mode, and this is the HLS of a smart template (checklist formats) see if the hls
|
||
// splits across 2 lines.
|
||
if (itemInfo.IsStep && itemInfo.FormatStepData.UseSmartTemplate && epMode == E_EditPrintMode.Print)
|
||
{
|
||
int hlslen = (int)(itemInfo.FormatStepData.StepPrintData.HLSLength ?? 66);
|
||
List<string> titleLines = Volian.Base.Library.RtfTools.SplitText(OriginalText, hlslen);
|
||
if (titleLines.Count > 1)
|
||
{
|
||
string tmporig = titleLines[0];
|
||
for (int ix = 1; ix < titleLines.Count; ix++)
|
||
tmporig = tmporig + @"\par " + titleLines[ix];
|
||
OriginalText = tmporig;
|
||
}
|
||
}
|
||
string text = prefix + OriginalText + suffix;
|
||
_MyFormat = itemInfo.ActiveFormat;
|
||
|
||
bool tableShouldBeOutlined = false; //(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
|
||
bool underlineAfterDashSpace = (itemInfo.FormatStepData == null) ? false : itemInfo.FormatStepData.UnderlineAfterDashSpace;
|
||
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 ");
|
||
}
|
||
}
|
||
// B2018-041 this logic was moved to fix this bug, but it is needed to keep Braidwood print of Procedure ROs to remain consistent with how it was
|
||
// before the fix. Replace Hard Hyphens with normal hyphen so the PDF search for hyphens will work properly
|
||
// B2019-171: added a format flag, DoSpaceDashBeforeROResolve, so that this fix for B2018-041 would not affect Braidwood/Byron, RO's that were defined
|
||
// as Procedures should not have the text uppercased.
|
||
if (itemInfo.ActiveFormat.PlantFormat.FormatData.ROData.DoSpaceDashBeforeROResolve)
|
||
{
|
||
if (text.Contains(@"\u8209?") && epMode == E_EditPrintMode.Print)
|
||
{
|
||
// Handle RTF Tokens followed immediately by a hard hyphen
|
||
text = Regex.Replace(text, @"(?<=\\[^\\?' \r\n\t]+)\\u8209\?", " -");
|
||
text = text.Replace(@"\u8209?", "-");
|
||
}
|
||
}
|
||
// Replace backslash symbol with normal backslash so the PDF search for backslashes will work properly
|
||
if (text.Contains(@"\u9586?") && epMode == E_EditPrintMode.Print)
|
||
{
|
||
// Handle RTF Tokens followed immediately by a backslash
|
||
text =Regex.Replace(text, @"(?<=\\[^\\?' \r\n\t]+)\\u9586\?", @" \\");
|
||
text = text.Replace(@"\u9586?", @"\\");
|
||
}
|
||
_MyStaticItemInfo = _MyItemInfo;
|
||
// F2019-069: Add format variable to allow format to specify Default Text for a step. Implemented for Barakah's 'Hold Point'
|
||
// B2021-074 Needed a null reference check for FormatStepData
|
||
if (_MyItemInfo.MyContent.Text == "" && _MyItemInfo.FormatStepData != null && _MyItemInfo.FormatStepData.DefaultText != null && _MyItemInfo.FormatStepData.DefaultText != "")
|
||
{
|
||
text= _MyItemInfo.FormatStepData.DefaultText;
|
||
AddedDefaultTextFromFmt = true;
|
||
}
|
||
text = CreateRtf(colorLinks, text, tableShouldBeOutlined, wordsShouldBeReplaced, numbersShouldBeFormated, tableHasBorder, ROsShouldBeAdjusted, underlineAfterDashSpace, epMode);
|
||
_MyStaticItemInfo = null;
|
||
StartText = text;
|
||
ProfileTimer.Pop(profileDepth);
|
||
}
|
||
|
||
public void CleanUpNewIDs()
|
||
{
|
||
Save(InfoText);
|
||
}
|
||
private static ItemInfo _MyStaticItemInfo = null; // Used to report errors
|
||
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, false, E_EditPrintMode.Edit);
|
||
}
|
||
// F2021-053: BNPP Alarm - need ability to have super/sub scripts in the text of Alarm Tables (ROs). Added a
|
||
// constructor that allows for passing in a flag to set whether replace words should be done on page list. If doing
|
||
// on page list, the object has a section not a step associated with it.
|
||
private bool _DoReplWordInPageList = false;
|
||
public DisplayText(ItemInfo itemInfo, string text, bool colorLinks, bool dorepl)
|
||
{
|
||
_DoReplWordInPageList = dorepl;
|
||
_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
|
||
bool underlineAfterDashSpace = (itemInfo.FormatStepData == null) ? false : itemInfo.FormatStepData.UnderlineAfterDashSpace;
|
||
|
||
text = CreateRtf(colorLinks, text, false, wordsShouldBeReplaced, numbersShouldBeFormated, false, ROsShouldBeAdjusted, underlineAfterDashSpace, E_EditPrintMode.Edit);
|
||
StartText = text;
|
||
}
|
||
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
|
||
bool underlineAfterDashSpace = (itemInfo.FormatStepData == null) ? false : itemInfo.FormatStepData.UnderlineAfterDashSpace;
|
||
|
||
text = CreateRtf(colorLinks, text, false, wordsShouldBeReplaced, numbersShouldBeFormated, false, ROsShouldBeAdjusted, underlineAfterDashSpace, E_EditPrintMode.Edit);
|
||
StartText = text;
|
||
// Shearon Harris Tables are Bold
|
||
if (itemInfo.IsTable && (TextFont.Style & E_Style.Bold) == E_Style.Bold)
|
||
{
|
||
// Strip out Bold OFF commands
|
||
text = text.Replace(@"\b0 "," ");
|
||
text = text.Replace(@"\b0", "");
|
||
// Insert a Bold ON command at the beginning of the printable text.
|
||
StartText = Regex.Replace(text, @"(\\viewkind.*?)(?= |\\u[0-9]+?|\\'[0-9A-F])", @"$1\b");
|
||
}
|
||
}
|
||
private bool InLinkedText(string text, int idx)
|
||
{
|
||
MatchCollection mc = Regex.Matches(text, @"<START\].*?\[END>", RegexOptions.Singleline);
|
||
if (mc.Count == 0) return false;
|
||
foreach (Match m in mc)
|
||
if (m.Index < idx && m.Index + m.Length > idx) return true;
|
||
return (false);
|
||
}
|
||
private string CreateRtf(bool colorLinks, string text, bool tableShouldBeOutlined, bool wordsShouldBeReplaced, bool numbersShouldBeFormated, bool tableHasBorder, bool ROsShouldBeAdjusted, bool underlineAfterDashSpace, E_EditPrintMode epMode)
|
||
{
|
||
int profileDepth = ProfileTimer.Push(">>>> CreateRtf");
|
||
// F2019-065: Upper case if step format has flag
|
||
if (_MyItemInfo != null && wordsShouldBeReplaced && _MyItemInfo.IsStep && _MyItemInfo.FormatStepData.UpperCase)
|
||
text = UpCaseStep(text);
|
||
// 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);
|
||
|
||
}
|
||
}
|
||
// B2018-041 moved this logic here from DisplayText() so the it does not defeat the Upcase RO's after Dash logic
|
||
// Replace Hard Hyphens with normal hyphen so the PDF search for hyphens will work properly
|
||
// B2019-171: added a format flag, DoSpaceDashBeforeROResolve, so that this fix for B2018-041 would not affect Braidwood/Byron, RO's that were defined
|
||
// as Procedures should not have the text uppercased.
|
||
if (_MyItemInfo == null || !_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.DoSpaceDashBeforeROResolve)
|
||
{
|
||
if (text.Contains(@"\u8209?") && epMode == E_EditPrintMode.Print)
|
||
{
|
||
// Handle RTF Tokens followed immediately by a hard hyphen
|
||
text = Regex.Replace(text, @"(?<=\\[^\\?' \r\n\t]+)\\u8209\?", " -");
|
||
text = text.Replace(@"\u8209?", "-");
|
||
}
|
||
}
|
||
// 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)
|
||
{
|
||
int profileDepth1 = ProfileTimer.Push(">>>> DoReplaceWords2");
|
||
|
||
text = DoReplaceWords2(text);
|
||
ProfileTimer.Pop(profileDepth1);
|
||
}
|
||
if (_MyItemInfo != null && ROsShouldBeAdjusted) // B2017-019 - added check for ROsShouldBeAdjusted so that these token are not "cooked" on property pages
|
||
{
|
||
// B2022-035: resolve unit specific designators - moved code to ResolveUnitSpecific so other objects can use it.
|
||
text = ResolveUnitSpecific(_MyItemInfo.MyDocVersion, text);
|
||
text = text.Replace(@"<S\u8209?ID>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_ProcedureSetID);
|
||
}
|
||
// Adjust RO display
|
||
if (ROsShouldBeAdjusted)
|
||
{
|
||
bool fontIsBold = _MyItemInfo.IsStep && (_MyItemInfo.FormatStepData.Font.Style & E_Style.Bold) != E_Style.Bold;
|
||
text = DoTransitionAdjustments(text, _MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.BoldTransition ||
|
||
(_MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.BoldTransitionExceptHLS && !_MyItemInfo.IsHigh) ||
|
||
// B2017-269 Don't bold transition if font for step is bold
|
||
(_MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.BoldTransitionExceptBoldHLS && (!_MyItemInfo.IsHigh || fontIsBold)));
|
||
}
|
||
// 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?");
|
||
// convert \'99 to \u8482? this is for the trade mark symbol. For some reason RTF is automatically
|
||
// converting the unicode \u8482? to \'99, but once this is done, PROMS StepRTB (edit windows) do not show it
|
||
//text = text.Replace(@"\'99", @"\u8482?");
|
||
text = RtfTools.RTFConvertedSymbolsToUnicode(text);
|
||
text = text.Replace("\r\n", @"\line "); // replace a \r\n with a \line instead of a \par
|
||
// B2015-134 Hanging Indent with Hard Returns was not being saved
|
||
//text = text.Replace(@"\line", @"\pard\line");
|
||
//text = text.Replace(@"\pard\pard\line", @"\pard\line");
|
||
//if (text.IndexOf(@"\line") > -1)
|
||
// MessageBox.Show("Found rtf line");
|
||
//text = text.Replace(@"\line", @"\par"); // we don't want to replace the \line part of bug fix B2015-140
|
||
|
||
// 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);
|
||
}
|
||
}
|
||
if (underlineAfterDashSpace)
|
||
{
|
||
// Bug fix: B2015-110 - currently used in Byron and Braidwood formats
|
||
// for the screen we need to look for the unicode dash
|
||
// for printing we need to look for the keyboard dash character
|
||
MatchCollection mc = Regex.Matches(text,((epMode == E_EditPrintMode.Edit)? @"\\u8209\?\\f[0-9]+ " : "- "));
|
||
if (mc.Count > 0)
|
||
{
|
||
Match m = mc[0];
|
||
if (!InLinkedText(text, m.Index))
|
||
{
|
||
string str1 = text.Substring(0, m.Index + m.Length);
|
||
string str2 = text.Substring(m.Index + m.Length);
|
||
string str3 = "";
|
||
int iTerm = FindUnderlineTerminator(str2);
|
||
if (iTerm >= 0)
|
||
{
|
||
str3 = str2.Substring(iTerm);
|
||
str2 = str2.Substring(0, iTerm);
|
||
}
|
||
str2 = str2.Replace(@"\ulnone ", "");
|
||
str2 = str2.Replace(@"\ulnone", "");
|
||
str2 = str2.Replace(@"\ul ", "");
|
||
str2 = str2.Replace(@"\ul", "");
|
||
text = str1 + @"\ul " + str2 + @"\ulnone " + str3;
|
||
}
|
||
}
|
||
}
|
||
text = FixDiffUnitROReplaceWords(text);
|
||
ProfileTimer.Pop(profileDepth);
|
||
return text;
|
||
}
|
||
// B2022-035: resolve unit specific designators - moved code to here so that other objects can use it
|
||
// B2024-025 added <ID> to the replace list
|
||
public static string ResolveUnitSpecific(DocVersionInfo mydocversion, string text)
|
||
{
|
||
if (mydocversion == null) return text;
|
||
text = Regex.Replace(text, @"\<U\>", mydocversion.DocVersionConfig.Unit_Number, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<ID\>", mydocversion.DocVersionConfig.Unit_ID, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)ID)\>", mydocversion.DocVersionConfig.Unit_ID, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)NAME)\>", mydocversion.DocVersionConfig.Unit_Name, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)TEXT)\>", mydocversion.DocVersionConfig.Unit_Text, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)NUMBER)\>", mydocversion.DocVersionConfig.Unit_Number, RegexOptions.IgnoreCase);
|
||
//B2021-148 removed space character after OTHER
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHERID)\>", mydocversion.DocVersionConfig.Other_Unit_ID, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHERNAME)\>", mydocversion.DocVersionConfig.Other_Unit_Name, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHERTEXT)\>", mydocversion.DocVersionConfig.Other_Unit_Text, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHERNUMBER)\>", mydocversion.DocVersionConfig.Other_Unit_Number, RegexOptions.IgnoreCase);
|
||
//B2022-023 also check for other followed by a space
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHER ID)\>", mydocversion.DocVersionConfig.Other_Unit_ID, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHER NAME)\>", mydocversion.DocVersionConfig.Other_Unit_Name, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHER TEXT)\>", mydocversion.DocVersionConfig.Other_Unit_Text, RegexOptions.IgnoreCase);
|
||
text = Regex.Replace(text, @"\<(U(-|\\u8209\?)OTHER NUMBER)\>", mydocversion.DocVersionConfig.Other_Unit_Number, RegexOptions.IgnoreCase);
|
||
|
||
return text;
|
||
}
|
||
|
||
// F2019-065: Upper case if step format has flag
|
||
private string UpCaseStep(string text)
|
||
{
|
||
// upper case all text except in links/symbols
|
||
RtfToDisplayTextElements(text);
|
||
StringBuilder sret = new StringBuilder();
|
||
foreach (displayTextElement vte in DisplayTextElementList)
|
||
{
|
||
if (vte.Type == E_TextElementType.Text)
|
||
sret.Append(vte.Text.ToUpper());
|
||
else if (vte.Type == E_TextElementType.Symbol)
|
||
sret.Append(vte.Text);
|
||
else
|
||
{
|
||
displayLinkElement dle = vte as displayLinkElement;
|
||
sret.Append(dle.TextAndLink);
|
||
}
|
||
}
|
||
string mdtxt = sret.ToString();
|
||
return mdtxt;
|
||
}
|
||
private string FixDiffUnitROReplaceWords(string text)
|
||
{
|
||
if (_MyFormat == null) return text;
|
||
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
|
||
List<ReplaceStr> partialReplaceList = new List<ReplaceStr>();
|
||
foreach (ReplaceStr rs in rsl)
|
||
{
|
||
if (rs.ReplaceWord.Contains("{RO}"))
|
||
{
|
||
//if (_MyItemInfo.InList(34770,34771,34782,34882,34886,34916,34891,35121,36361))
|
||
// Console.WriteLine("FixDiffUnitROReplaceWords jcb");
|
||
string oldvalue = text;
|
||
string replaceWord = rs.ReplaceWord;
|
||
string replaceWord2 = Regex.Replace( replaceWord,@"(\{RO\})([0-9,]+)(\{RO\})",@"\\v <START]\\v0 ($2)\\v");
|
||
string replaceWith = rs.ReplaceWith.Replace(@"\xA0",@"\'A0") + @"\v";
|
||
if (!rs.ReplaceWith.Contains(@"\b0") || _MyItemInfo.FormatStepData == null || (_MyItemInfo.FormatStepData.Font.Style & E_Style.Bold) == 0)
|
||
{
|
||
text = ReplaceOppositeUnitRO(text, replaceWord2, replaceWith);
|
||
if(replaceWord2.StartsWith("UNIT ") && text.Contains(@"UNIT\u160?"))
|
||
text = ReplaceOppositeUnitRO(text, replaceWord2.Replace("UNIT ",@"UNIT\\u160?"), replaceWith);
|
||
}
|
||
}
|
||
}
|
||
return text;
|
||
}
|
||
|
||
private string ReplaceOppositeUnitRO(string text, string replaceWord2, string replaceWith)
|
||
{
|
||
Match m = Regex.Match(text, replaceWord2, RegexOptions.IgnoreCase);
|
||
int offset = 0;
|
||
while (m.Success)
|
||
{
|
||
int len = m.Length;
|
||
if (FoundMatches.DiffUnit(m.Groups[1].Value, _MyItemInfo, ""))
|
||
{
|
||
text = text.Substring(0, offset + m.Index) + replaceWith + text.Substring(offset + m.Index + m.Length);
|
||
len = replaceWith.Length;
|
||
//text = text.Replace(replaceWord2, rs.ReplaceWith.Replace(@"\xA0",@"\'A0") + @"\v");
|
||
}
|
||
offset += m.Index + len;
|
||
m = Regex.Match(text.Substring(offset), replaceWord2, RegexOptions.IgnoreCase);
|
||
}
|
||
return text;
|
||
}
|
||
private Match FirstMatch(string text, string replaceWord2)
|
||
{
|
||
//if(text.Contains(replaceWord2.Replace("(","").Replace(")","").Replace(@"\\",@"\")))
|
||
// Console.WriteLine("here");
|
||
MatchCollection matches = Regex.Matches(text, replaceWord2, RegexOptions.IgnoreCase);
|
||
if (matches.Count > 0)
|
||
{
|
||
Match mm = Regex.Match(text, replaceWord2, RegexOptions.IgnoreCase);
|
||
return matches[0];
|
||
}
|
||
return null;
|
||
}
|
||
private int FindUnderlineTerminator(string text)
|
||
{
|
||
int idx = -1;
|
||
UnderlineTerminateList utl = _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.UnderlineTerminateList;
|
||
foreach (UnderlineTerminate ut in utl)
|
||
{
|
||
MatchCollection mc = Regex.Matches(text, "(?<!Link|ReferencedObject|Transition|TransitionRange)" + ut.Text);
|
||
if (mc.Count > 0)
|
||
{
|
||
Match m = mc[mc.Count - 1];
|
||
if (idx < 0 || idx > m.Index)
|
||
idx = m.Index;
|
||
}
|
||
}
|
||
return idx;
|
||
}
|
||
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)
|
||
{
|
||
// B2018-088 - Added code to look for CROUSGID
|
||
Regex regRefObj = new Regex(@"\#Link\:ReferencedObject:([0-9]*|<NewID>|<CROUSGID=-?[0-9]+>) ([0-9a-zA-Z]*) ([0-9]*)", RegexOptions.Singleline);
|
||
string strippedText = StaticStripRtfCommands(text, _MyItemInfo!=null?_MyItemInfo.IsTable:false);
|
||
// (\\[^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 '?{{}}~\\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v '?{{}}~\\]+)*\\v(\\[^v \\]+)* #Link:(ReferencedObject|Transition[^:]*?):.*?\[END>");
|
||
MatchCollection matches = Regex.Matches(text, lookFor);
|
||
string prevValue = null;
|
||
for (int i = matches.Count - 1; i >= 0; i--)
|
||
{
|
||
Match m = matches[i];
|
||
if (m != null && m.Groups.Count > 7 && m.Groups[7].ToString() == "ReferencedObject")
|
||
{
|
||
// if previous processed (next ro) was found, then see if it has an 'and' between it and the previous
|
||
//if (prevValue != null)
|
||
//{
|
||
// int endIndx = m.Index + m.Length;
|
||
// string tr = text.Substring(endIndx).Replace(@"\v0","").TrimStart();
|
||
// if (!tr.ToUpper().StartsWith("AND")) prevValue = null;
|
||
//}
|
||
int myIndex = m.Groups[4].Index;
|
||
int myLength = m.Groups[4].Length;
|
||
if (m.Groups[3].Value != " ")
|
||
{
|
||
myIndex = m.Groups[3].Index;
|
||
myLength += m.Groups[3].Length;
|
||
}
|
||
string gg = text.Substring(myIndex, myLength).TrimEnd(" ".ToCharArray());// RHM 20180608 - Found an issue where the value contained a trailing space
|
||
//System.Text.RegularExpressions.Group g = m.Groups[3];
|
||
string beforeRO = StaticStripRtfCommands(text.Substring(0, myIndex), _MyItemInfo != null ? _MyItemInfo.IsTable : false);
|
||
string afterRO = StaticStripRtfCommands(text.Substring(myIndex + myLength), _MyItemInfo != null ? _MyItemInfo.IsTable : false);
|
||
Match myMatch = regRefObj.Match(m.ToString());
|
||
// B-2018-088 Made Error Log output more useful
|
||
if (m.ToString().ToUpper().Contains("<NEWID>") || m.ToString().ToUpper().Contains("<CROUSGID="))
|
||
_MyLog.WarnFormat("\r\n==> Unprocessed RO in [{0}] {1} with a value of {2} \r\n" +
|
||
" in {3}\r\n" +
|
||
" ACTION REQUIRED: Step should be relinked (Deleted, Retyped and Linked)",
|
||
_MyItemInfo.ItemID, _MyItemInfo.ShortPath,gg.Replace("\\u8209?","-"),
|
||
_MyItemInfo.SearchDVPath.Replace("\a","/"));
|
||
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);
|
||
bool isSetpoint=myROFst.IsSetpointDB(dbid, _MyItemInfo.MyDocVersion);
|
||
string newvalue1 = DoROFormatFlags(gg, beforeRO, afterRO, isSetpoint);
|
||
string newvalue = RemoveMultipleUnits(prevValue, newvalue1);
|
||
if (!_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.AllUnits) prevValue = newvalue1;
|
||
newvalue = DoROReplaceWords(_MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList, newvalue, _MyItemInfo.IsHigh);
|
||
if (isSetpoint) newvalue = ReplaceSpaceWithHardspace(newvalue);
|
||
// B2017-147: backquotes should be translated to degrees for edit/print:
|
||
newvalue = newvalue.Replace("`", @"\'b0");
|
||
// B2023-037: Handle <=, >=, +-, -> and <- symbols. If the format has flags to convert these RO symbols, it
|
||
bool arrows1 = _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseDashGreaterLessThenForArrowsInROValue;
|
||
bool arrows2 = _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertGTELTEPMinROValue;
|
||
// is done here so that output (print & edit/view) has symbol, not 2 characters.
|
||
if (!_MyItemInfo.IsTable && (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseDashGreaterLessThenForArrowsInROValue ||
|
||
_MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertGTELTEPMinROValue))
|
||
newvalue = ROFSTLookup.ROConvertSymbols(newvalue, arrows1, arrows2);
|
||
|
||
if (gg != newvalue)
|
||
text = text.Substring(0, myIndex) + newvalue + text.Substring(myIndex + myLength);
|
||
}
|
||
}
|
||
return text;
|
||
}
|
||
private string DoROReplaceWords(ReplaceStrList replaceStrList, string oldvalue, bool isHigh)
|
||
{
|
||
int profileDepth = ProfileTimer.Push(">>>> DoROReplaceWords");
|
||
string newvalue = oldvalue;
|
||
foreach (ReplaceStr rs in replaceStrList)
|
||
{
|
||
if (((rs.Flag & E_ReplaceFlags.Setpoint) > 0) || (isHigh && (rs.Flag & E_ReplaceFlags.HLSSetpnt) > 0))
|
||
{
|
||
try
|
||
{
|
||
// Use regular expression to assure that the ReplaceWord is not part of another word
|
||
// For VEPROMS_CAL E-0 Step 23 (Reset SI) the word "after" was being changed to "aFTer"
|
||
newvalue = Regex.Replace(newvalue, @"(?<=\W|^)" + rs.ReplaceWord + @"(?=\W|$)", rs.ReplaceWith);
|
||
//newvalue = newvalue.Replace(rs.ReplaceWord, rs.ReplaceWith);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_MyLog.Warn("Problem with regular expression", ex);
|
||
}
|
||
}
|
||
}
|
||
//if (oldvalue != newvalue)
|
||
// Console.WriteLine("\"{0}\"\r\n\"{1}\"",oldvalue,newvalue);
|
||
ProfileTimer.Pop(profileDepth);
|
||
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))
|
||
{
|
||
if (!SpaceBetweenLetters(newvalue, spindx)) // only replace a space with a hard space if the character before or after is a number B2016-144
|
||
{
|
||
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 SpaceBetweenLetters(string newvalue, int spindx)
|
||
{
|
||
if (spindx > 0 && spindx < newvalue.Length)
|
||
{
|
||
char cb = newvalue[spindx - 1];
|
||
char ca = newvalue[spindx + 1];
|
||
if (char.IsLetter(cb) && char.IsLetter(ca))
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
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
|
||
// B2018-067 Added more specific comparison to eliminate \u8209? from consideration
|
||
// B2018-128 Added check for font specification (tst =='f') so we don't get a hard space after the font command (happend inserting RO in tables) - Farely SAMGs
|
||
if (Cmd.StartsWith("\\up") || tst == 'd' || tst == 'b' || Cmd.StartsWith("\\ul") || tst == 'i' || tst =='f') return true;
|
||
}
|
||
return false;
|
||
}
|
||
private string DoTransitionAdjustments(string text, bool boldTran)
|
||
{
|
||
int profileDepth = ProfileTimer.Push(">>>> DoTransitionAdjustments");
|
||
bool undtran = _MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.Underline;
|
||
string strippedText = StaticStripRtfCommands(text, _MyItemInfo != null ? _MyItemInfo.IsTable : false);
|
||
string lookFor = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v'?{{}}~ \\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{{}}~ \\]+)*\\v(\\[^v \\]+)* #Link:(ReferencedObject|Transition[^:]*?):[0-9]* ([0-9]*).*?\[END>");
|
||
MatchCollection matches = Regex.Matches(text, lookFor);
|
||
if (matches.Count == 0)
|
||
{
|
||
ProfileTimer.Pop(profileDepth);
|
||
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[4].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 > 8 && m.Groups[7].ToString().StartsWith("Transition"))
|
||
{
|
||
if (m.Groups[8].Value != "") // && StepTransition(int.Parse(m.Groups[7].Value)))
|
||
{
|
||
int myIndex = m.Groups[4].Index;
|
||
int myLength = m.Groups[4].Length;
|
||
if (m.Groups[3].Value != " ")
|
||
{
|
||
myIndex = m.Groups[3].Index;
|
||
myLength += m.Groups[3].Length;
|
||
}
|
||
string newvalue = text.Substring(myIndex, myLength);
|
||
if (boldTran) newvalue = newvalue.Replace(@"\b0", "").Replace(@"\B0", "");
|
||
//System.Text.RegularExpressions.Group g = m.Groups[3];
|
||
string beforeTran = retstr.Substring(0, myIndex);
|
||
string afterTran = retstr.Substring(myIndex + myLength);
|
||
|
||
// 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[8].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) + (undtran ? @"\ul " : null) + newvalue.Substring(0, indexLastSpace) + "\x1" + newvalue.Substring(indexLastSpace + 1) + (undtran ? @"\ulnone " : null) + (boldTran ? @"\b0" : null) + afterTran;
|
||
else
|
||
if (beforeTran.EndsWith(" "))
|
||
retstr = ReplaceLastSpaceWithHardSpace(beforeTran) + (boldTran ? @"\b " : null) + (undtran ? @"\ul " : null) + newvalue + (undtran? @"\ulnone ":null) + (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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
ProfileTimer.Pop(profileDepth);
|
||
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
|
||
// B2017-168 Fixed Regular Expression to cover more examples
|
||
// +1.25E6 1.25E6 -1.25E6 +2.E6 2.E6 -2.E6 +1.E6 1.E6 -1.E6 .E2
|
||
string pat = @"(\d*\.\d*)E(([-+]|\\u8209\?)?\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;
|
||
if (fnum == "1.0" || fnum == "1." || fnum == ".")
|
||
newstr = string.Format(@"10\up2 {0}\up0 ", supnum);
|
||
else
|
||
newstr = string.Format(@"{0}x10\up2 {1}\up0 ", fnum, supnum);
|
||
retstr = retstr.Replace(m.Value, newstr);
|
||
}
|
||
return retstr;
|
||
}
|
||
#endregion
|
||
#region SaveData
|
||
/// <summary>
|
||
/// B2017-121 Regular Express for all RTF tokens for Hyphens
|
||
/// </summary>
|
||
private static Regex regHyphen = new Regex(@"(?<!\\)(\\u8208\?|\\u8210\?|\\u8211\?|\\u8212\?|\\u8213\?|\\_|\\endash|\\emdash)");
|
||
public bool Save(RichTextBox rtb)
|
||
{
|
||
// B2017-121 Replace all types of hyphens with non-breaking hyphens
|
||
string rtbString = regHyphen.Replace( RtfToDbText(rtb.Rtf).Replace("<BackSlash>", "\\\\"),@"\u8209?");
|
||
// B2017-196: Now replace plain '-' with unicode. Note that the hanging indent rtf command had 'fi-' in it, so couldn't do it in regex above:
|
||
int indx = rtbString.IndexOf('-');
|
||
while (indx > -1)
|
||
{
|
||
// B2017-265 - Make sure that the location is at least 2 if checking the previous three charracters.
|
||
// This occurs when pasting from MSWord
|
||
if (indx < 2 || rtbString[indx - 1] != 'i' || rtbString[indx - 2] != 'f' || rtbString[indx - 3] != '\\')
|
||
{
|
||
rtbString = rtbString.Remove(indx, 1);
|
||
rtbString = rtbString.Insert(indx, @"\u8209?");
|
||
}
|
||
if (indx + 1 > rtbString.Length) indx = -1;
|
||
else indx = rtbString.IndexOf('-', indx + 1);
|
||
}
|
||
return Save(rtbString);
|
||
}
|
||
public bool Save(string modtext)
|
||
{
|
||
//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 && modtext.Contains("<NewID>")) //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)
|
||
{
|
||
// B2019-084: Procedure number change not updated in pasted transition when copied text was a transition also - there were 2 '<START]'s, so replace w/ 1:
|
||
if (modtext.Contains("<START]<START]")) modtext = modtext.Replace("<START]<START]", "<START]");
|
||
// 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))
|
||
{ // C2016-023 Convert Transition to Text is the transtion is to a different procedure set
|
||
// and the destination proedure number matches a procedure number in the current set
|
||
bool forceConvertToText = false;
|
||
if (tran.MyContent.ContentItems[0].MyDocVersion.VersionID != tran.MyItemToID.MyDocVersion.VersionID &&
|
||
(tran.MyContent.ContentItems[0].ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[tran.TranType].TransMenu.Contains("Proc") ||
|
||
tran.MyContent.ContentItems[0].ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[tran.TranType].TransMenu.Contains("other proc")))
|
||
{
|
||
// B2022-148: cannot insert outside transition in a background document that references a related EOP <20> transition is converted to text
|
||
bool dvsLinked = DocVersionInfo.Linked(tran.MyItemToID.MyDocVersion, tran.MyContent.ContentItems[0].MyDocVersion);
|
||
if (!dvsLinked)
|
||
{
|
||
string destProcNumber = tran.MyItemToID.MyProcedure.DisplayNumber;
|
||
foreach (ProcedureInfo prci in tran.MyContent.ContentItems[0].MyDocVersion.Procedures)
|
||
{
|
||
if (prci.DisplayNumber == destProcNumber)
|
||
{
|
||
forceConvertToText = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
_MyItem.MyContent.FixTransitionText(tran,forceConvertToText);
|
||
}
|
||
_MyItem.Save();
|
||
// B2020-155: Entering transitions, move off and move back on converts them to text. After save, refresh cache
|
||
_MyItemInfo.MyContent.RefreshContentTransitions();
|
||
}
|
||
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;
|
||
}
|
||
if (!_MyItemInfo.IsStep)
|
||
{
|
||
_MyItemInfo.UpdateTransitionText();
|
||
_MyItemInfo.UpdateROText();
|
||
}
|
||
}
|
||
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);
|
||
|
||
//CSM B2024-078 - when a bad transition link / does not contain a number, simply return the text as-is
|
||
if (int.TryParse(srecid, out recid))
|
||
{
|
||
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.
|
||
bool processedRO = false;
|
||
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)
|
||
{
|
||
// (B2016-037): The following line was added so that if a 'NewID' is found in the data it gets resolved
|
||
// even if the links in original vs modified text are same (they both have 'NewID', i.e. an incompletely inserted transition - bad data)
|
||
if (!odte.Link.Contains("<NewID>")) 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));
|
||
processedRO = true;
|
||
//break; // this break was causing only the first new ro's 'NewID' to get resolved. (found during fix of B2016-037)
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// B2017-204 if we processed a RO we need to refresh the usage count for the content
|
||
if (processedRO)
|
||
itm.MyItemInfo.MyContent.RefreshContentRoUsages();
|
||
}
|
||
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?");
|
||
// convert \'99 to \u8482? this is for the trade mark symbol. For some reason RTF is automatically
|
||
// converting the unicode \u8482? to \'99, but once this is done, PROMS StepRTB (edit windows) do not show it
|
||
//noExtraRtfStr = noExtraRtfStr.Replace(@"\'99", @"\u8482?");
|
||
|
||
string noExtraRtfStr = RtfTools.RTFConvertedSymbolsToUnicode(text);
|
||
// 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 '_': // B2020-100 New Non-Breaking Hyphen
|
||
return token.Trim();
|
||
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 (token == "\\viewkind4 ") break;
|
||
if (Regex.IsMatch(token, @"^\\v0? ?$"))
|
||
return token; // comment part of link
|
||
// If possible show what procedure was being processed.
|
||
if(_MyStaticItemInfo == null)
|
||
_MyLog.WarnFormat("<<<ERROR>>>\r\n==> Token including Comment not processed '{0}'", token);
|
||
else
|
||
_MyLog.WarnFormat("<<<ERROR>>>\r\n==> Token including Comment not processed '{0}' in {1},[{2}]", token, _MyStaticItemInfo.ShortPath, _MyStaticItemInfo.ItemID);
|
||
break;
|
||
case 'l':
|
||
if (Regex.IsMatch(token, @"^\\line ?$")) return token;
|
||
if (Regex.IsMatch(token, @"^\\li[-0-9]+ ?$")) return token; // line indent
|
||
break;
|
||
case 'f':
|
||
if (Regex.IsMatch(token, @"^\\fi[-0-9]+ ?$")) return token; // first line indent
|
||
// C2020-001: only keep the font size rtf if in a table.
|
||
if (_fromTable && Regex.IsMatch(token, @"^\\fs[-0-9]+ ?$")) return token; // font size
|
||
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
|
||
}
|
||
private static Regex reg1 = new Regex(@"\\par\r\n(?!\\)");
|
||
private static Regex reg2 = new Regex(@"[\r\n]", RegexOptions.Singleline); // Strip Carriage Returns and Newlines
|
||
private static Regex reg3 = new Regex(@"^\{(.*)\}$", RegexOptions.Singleline); // Strip Opening and Closing Braces
|
||
private static Regex reg4 = new Regex(@"\{[^{]*?\}", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
|
||
private static Regex reg5 = new Regex(@"\{[^{]*?\}", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
|
||
private static Regex reg6 = new Regex(@"(\\[^' \\?\r\n\t]+)(?=\\)"); // add space after token if followed by token
|
||
private static Regex reg7 = new Regex(@"(\\[^' \\?\r\n\t]+ )"); // take backslash xyz and evaluates them
|
||
private static Regex reg8 = new Regex(@"(\\[^' \\?\r\n\t]+) (?=\\)"); // remove space between tokens
|
||
private static Regex reg9 = new Regex(@"(\\[^' \\?\r\n\t]+) (?=\r\n)"); // remove space before /r/n
|
||
|
||
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(@"\{", @"(!["); // B2020-113 don't have a space in the replacement string
|
||
retval = retval.Replace(@"\}", @"(!]"); // B2020-113 don't have a space in the replacement string
|
||
// 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 = reg1.Replace(retval, "\\par ");
|
||
retval = retval.Replace("\\v0\r\n", "\\v0 "); // Replace Carriage Return and Newline after comment
|
||
retval = reg2.Replace(retval, ""); // Strip Carriage Returns and Newlines
|
||
retval = reg3.Replace(retval, "$1"); // Strip Opening and Closing Braces
|
||
retval = reg4.Replace(retval, ""); // Strip Clauses - remove anything from curly braces
|
||
retval = reg5.Replace(retval, ""); // Strip Clauses - remove anything from curly braces
|
||
retval = retval.Replace(@"(![", @"\{"); // B2020-113 put user entered open curly braces back in
|
||
retval = retval.Replace(@"(!]", @"\}"); // B2020-113 put user entered close curly braces back in
|
||
retval = reg6.Replace(retval, "$1 "); // add space after token if followed by token
|
||
retval = reg7.Replace(retval, new MatchEvaluator(StaticReplaceRTFClause)); // take backslash xyz and evaluates them
|
||
retval = reg8.Replace(retval, "$1"); // remove space between tokens
|
||
retval = reg9.Replace(retval, "$1"); // remove space before /r/n
|
||
|
||
//retval = Regex.Replace(retval, @"\\par\r\n(?!\\)", "\\par ");
|
||
//retval = retval.Replace("\\v0\r\n", "\\v0 "); // Replace Carriage Return and Newline after comment
|
||
//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.TrimEnd(' ');
|
||
return retval;
|
||
}
|
||
|
||
private static Regex sreg1 = new Regex(@"\\par\r\n(?!\\)");
|
||
private static Regex sreg2 = new Regex(@"[\r\n]", RegexOptions.Singleline); // Strip Carriage Returns and Newlines
|
||
private static Regex sreg3 = new Regex(@"^\{(.*)\}$", RegexOptions.Singleline); // Strip Opening and Closing Braces
|
||
private static Regex sreg4 = new Regex(@"\{[^{]*?\}", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
|
||
private static Regex sreg5 = new Regex(@"\{[^{]*?\}", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
|
||
private static Regex sreg6 = new Regex(@"(\\[^' \\?\r\n\t]+)(?=\\)"); // add space after token if followed by token
|
||
private static Regex sreg7 = new Regex(@"(\\[^ \\?\r\n\t]+ )"); // take backslash xyz and evaluates them
|
||
private static Regex sreg8 = new Regex(@"(\\[^ \\?\r\n\t]+) (?=\\)"); // remove space between tokens
|
||
private static Regex sreg9 = new Regex(@"(\\[^ \\?\r\n\t]+) (?=\r\n)"); // remove space before /r/n
|
||
|
||
// This is used in the DataLoader
|
||
private static bool _fromTable = false; // C2020-001: Change Font Size in Tables - keep rtf '\fs##' for tables only
|
||
public static string StaticStripRtfCommands(string rtf, bool fromTable)
|
||
{
|
||
_fromTable = fromTable;
|
||
// 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?");
|
||
// convert \'99 to \u8482? this is for the trade mark symbol. For some reason RTF is automatically
|
||
// converting the unicode \u8482? to \'99, but once this is done, PROMS StepRTB (edit windows) do not show it
|
||
//retval = retval.Replace(@"\'99", @"\u8482?");
|
||
|
||
retval = RtfTools.RTFConvertedSymbolsToUnicode(retval);
|
||
|
||
// 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 = sreg1.Replace(retval, "\\par ");
|
||
|
||
|
||
retval = retval.Replace("\\v0\r\n", "\\v0 "); // Replace Carriage Return and Newline after comment
|
||
retval = sreg2.Replace(retval, ""); // Strip Carriage Returns and Newlines
|
||
retval = sreg3.Replace(retval, "$1"); // Strip Opening and Closing Braces
|
||
retval = sreg4.Replace(retval, ""); // Strip Clauses - remove anything from curly braces
|
||
retval = sreg5.Replace(retval, ""); // Strip Clauses - remove anything from curly braces
|
||
retval = sreg6.Replace(retval, "$1 "); // add space after token if followed by token
|
||
retval = sreg7.Replace(retval, new MatchEvaluator(StaticReplaceRTFClause)); // take backslash xyz and evaluates them
|
||
retval = sreg8.Replace(retval, "$1"); // remove space between tokens
|
||
retval = sreg9.Replace(retval, "$1"); // remove space before /r/n
|
||
|
||
//retval = Regex.Replace(retval, @"\\par\r\n(?!\\)", "\\par ");
|
||
////retval = Regex.Replace(retval, @"\\par\r\n(?=\\)", "\\par");
|
||
|
||
//retval = retval.Replace("\\v0\r\n", "\\v0 "); // Replace Carriage Return and Newline after comment
|
||
//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");
|
||
_fromTable = false;
|
||
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;
|
||
|
||
//CSM B2024-078 - when a bad transition link / does not contain a number, simply return the text as-is
|
||
int transitionID;
|
||
string[] splt_link = link.Split(' ');
|
||
if (splt_link.Length < 2 || !int.TryParse(splt_link[1], out transitionID))
|
||
{
|
||
return text;
|
||
}
|
||
|
||
// 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);
|
||
if (!path.Contains("(Page ~)"))return path; // B2020-089, don't change back to a Page ~ if page number already set.
|
||
}
|
||
}
|
||
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, bool isSetpoint)
|
||
{
|
||
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, @"\<START\].*?#Link:Refer.*?\[END\>", ""); // Remove any RO Values.
|
||
beforeRO = Regex.Replace(beforeRO, @"(\\[^v \\]+)*\\v(\\[^v \\]+)* .*?\\v0(\\[^v \\]+)*( |$)", ""); // Remove Comments
|
||
string allUnitAfterRo = afterRO;
|
||
afterRO = Regex.Replace(afterRO, @"(\\[^v \\]+)*\\v(\\[^v \\]+)* .*?\\v0(\\[^v \\]+)*( |$)", ""); // Remove Comments
|
||
|
||
// Underline all ROs, values and Units
|
||
if (isSetpoint && _MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UnderlineRo)
|
||
{
|
||
// TO DO: Need to check if step text is already underlined
|
||
if ((_MyItemInfo.FormatStepData.Font.Style & E_Style.Underline) == 0)
|
||
rtnstr = @"\ul " + rtnstr + @"\ulnone ";
|
||
}
|
||
|
||
// UpcaseAllRoUnits - Uppercases ALL ROs units everywhere.
|
||
if (isSetpoint && _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 (isSetpoint && _MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapSPIfLastLower &&
|
||
!Regex.IsMatch(afterRO, @".*(?<!\\)[a-z].*") && char.IsUpper(LastAlpha(beforeRO)))
|
||
{
|
||
return UpperCaseUnits(rtnstr);
|
||
}
|
||
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);
|
||
}
|
||
// For Wolf Creek, the "- " should be right before the link. This ro format flag was introduced
|
||
// for Wolf Creek only because a problem was found with some of their data that was incorrectly
|
||
// processed through the 'UpRoAftrDash' flag. That flag was more general, i.e. upper cased units
|
||
// if there was a dash and then a space or hard space anywhere before the RO text. The original
|
||
// 16bit flag was more specific. Other plants that were released had the UpRoAftrDash, but
|
||
// we didn't want to change their formats since they had gone through testing.
|
||
if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpRoImmAftrDashSpace && Regex.IsMatch(beforeRO, @".*\\u8209\?( )"))
|
||
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;
|
||
}
|
||
|
||
return rtnstr;
|
||
}
|
||
|
||
private string RemoveMultipleUnits(string prevValue, string rtnstr)
|
||
{
|
||
//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 && prevValue != null)
|
||
{
|
||
string units = null;
|
||
//Match m = Regex.Match(prevValue, "[^0-9]");
|
||
int ind = prevValue.LastIndexOfAny("0123456789".ToCharArray());
|
||
if (ind>=0)
|
||
{
|
||
string mynum = prevValue.Substring(0, ind+1);
|
||
// Handle Hex characters which are part of the Units such as the degree character
|
||
if (Regex.IsMatch(mynum, @".*\\'[A-Fa-f0-9]{2,2}$"))
|
||
ind -= 4;
|
||
units = prevValue.Substring(ind+1);
|
||
if (rtnstr.EndsWith(units) && units != "")// Don't do this if there are no units
|
||
{
|
||
rtnstr = rtnstr.Replace(units, "");
|
||
}
|
||
}
|
||
}
|
||
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 startAdj = 4;
|
||
int linkIndx = text.IndexOf(@"#Link", index);
|
||
int endStartTknIndx = text.IndexOf(@"\v0 ", index);
|
||
int endStartTknIndxNoSpace = text.IndexOf(@"\v0", index);
|
||
if (endStartTknIndx == -1 || endStartTknIndxNoSpace < endStartTknIndx)
|
||
{
|
||
endStartTknIndx = endStartTknIndxNoSpace;
|
||
startAdj = 3;
|
||
}
|
||
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 + startAdj, endTextIndx - endStartTknIndx - startAdj); // 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)
|
||
{
|
||
// B2023-014: Braidwood - don't fixtransition text if uppercase flag. FixTransition does not resolve
|
||
// unit numbers. When data is loaded for print, the transition text is refreshed - so this call is
|
||
// not necessary. But only made change for Braidwood so as not to impact other plants
|
||
if (_MyItemInfo.FormatStepData.UpperCase)
|
||
tmptxt = vte.Text;
|
||
else
|
||
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 static Dictionary<FormatConfig.ReplaceStr, Regex> dicReplaceRegex = new Dictionary<FormatConfig.ReplaceStr, Regex>();
|
||
private static bool? _ProcessReplaceWords;
|
||
public static bool ProcessReplaceWords
|
||
{
|
||
get
|
||
{
|
||
if (_ProcessReplaceWords == null)
|
||
{
|
||
string[] parameters = System.Environment.CommandLine.Split(" ".ToCharArray());
|
||
_ProcessReplaceWords = true;
|
||
foreach (string parameter in parameters)
|
||
{
|
||
if (parameter.ToUpper() == "/NRW")
|
||
_ProcessReplaceWords = false;
|
||
}
|
||
}
|
||
return (bool) _ProcessReplaceWords;
|
||
}
|
||
}
|
||
private string DoReplaceWords2(string Text)
|
||
{
|
||
if(!ProcessReplaceWords) return Text;
|
||
// F2021-053: BNPP Alarm - need ability to have super/sub scripts in the text of Alarm Tables (ROs).
|
||
// if doing replace words for Page List items, the current item is not a step, use _DoReplWordInPageList flags this
|
||
if (_MyItemInfo.MyContent.Type < 20000 && !_DoReplWordInPageList) return Text; // for now only replace in steps.
|
||
FormatConfig.ReplaceStrData rsl = _MyFormat.PlantFormat.UCFandOrigReplaceStrData;
|
||
if (rsl.Count == 1 && (rsl[0].ReplaceWord == null || rsl[0].ReplaceWord == "")) return Text;
|
||
|
||
// F2021-093: Handle partials first and then plain replace words. Need to do this so that the words don't get processed by plain replace
|
||
// words then not found when hitting the partials, for example cm2 (plain replaced to superscript 2) and then Kg/cm2 for partials is
|
||
// not found. Note that when this was done (11/2021) only BGE & BNPP had partials and BGE's were very limited.
|
||
Text = DoReplacePartials(Text, rsl);
|
||
|
||
VE_Font vf = _MyItemInfo.MyContent.Type >= 20000 ? _MyItemInfo.FormatStepData.Font : _MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font;
|
||
FoundMatches myMatches = new FoundMatches(Text,vf,_MyItemInfo);
|
||
// Exclude Link Text from Replace Word process
|
||
myMatches.AddLink(regFindLink, _MyFormat.PlantFormat.FormatData.SectData.ReplaceWordsInROs, _MyItemInfo.MyProcedure.MyDocVersion);
|
||
// Loop through text looking for words to be replaced
|
||
Dictionary<E_ReplaceFlags?, bool> shouldReplace = new Dictionary<E_ReplaceFlags?, bool>();
|
||
//int profileDepth = ProfileTimer.Push(">>>> DoReplaceWords2.ForLoop");
|
||
foreach (FormatConfig.ReplaceStr rs in rsl)
|
||
{
|
||
bool dopartial = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.Partials) == E_ReplaceFlags.Partials;
|
||
if (!dopartial) // F2021-093: Partials moved into their own method and done first
|
||
{
|
||
bool onlyDoList = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.BeforeList) == E_ReplaceFlags.BeforeList; // C2021-045
|
||
bool onlyIfFirstWord = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.FirstWord) == E_ReplaceFlags.FirstWord; // C2021-056
|
||
bool doInPagelist = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.PageList) == E_ReplaceFlags.PageList; // B2021-132
|
||
//B2021-132 only do replacewords in paglist if the replaceword pagelist flag is set
|
||
if (_DoReplWordInPageList && !doInPagelist) continue;
|
||
|
||
// note that the order of this check is important. Check in this order...
|
||
// background here
|
||
if (!shouldReplace.ContainsKey((E_ReplaceFlags)rs.Flag))
|
||
{
|
||
//int profileDepth2 = ProfileTimer.Push(">>>> Before ShouldReplaceIt");
|
||
shouldReplace.Add((E_ReplaceFlags)rs.Flag, ShouldReplaceIt((E_ReplaceFlags)rs.Flag));
|
||
//ProfileTimer.Pop(profileDepth2);
|
||
}
|
||
bool replaceit = shouldReplace[(E_ReplaceFlags)rs.Flag];
|
||
|
||
if (replaceit)
|
||
{
|
||
// C2021-045 if the BeforeList ReplaceWords flag is set, only do the replace word if the text ends with a colon
|
||
if (onlyDoList && !Text.EndsWith(":"))
|
||
replaceit = false; // text does not end with a colon so don't replace this word
|
||
// C2021-056 if FirstWord ReplaceWords flag is set, only do if the replace word is the first word in the text
|
||
if (onlyIfFirstWord && !Text.StartsWith(rs.ReplaceWord))
|
||
replaceit = false;
|
||
}
|
||
if (!replaceit && _DoReplWordInPageList) replaceit = true; // F2021-053: Do replace words in page list
|
||
if (replaceit)
|
||
{
|
||
if (!dicReplaceRegex.ContainsKey(rs))
|
||
{
|
||
RegexOptions myOptions = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase : RegexOptions.None;
|
||
//int profileDepth3 = ProfileTimer.Push(">>>> DoReplaceWords2.BuildMatch");
|
||
// 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;
|
||
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\?|\\b|\-)" + replaceWord + @"(?!\\u160\?|\\u8209\?|\-)" + wordMatchEnd;
|
||
// C2021-061: For Barakah don't do replace if word is surrounded by " or ', i.e. they are no longer delimiters
|
||
if (_MyItemInfo != null && _MyItemInfo.ActiveFormat != null && _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.NoReplaceQuoteParenWords)
|
||
pat = wordMatchBeg + @"(?<!\\u160\?|\\u8209\?|\\b|\-|""|'|\()" + replaceWord + @"(?!\\u160\?|\\u8209\?|\-|""|'|\))" + wordMatchEnd;
|
||
dicReplaceRegex.Add(rs, new Regex(pat, myOptions));
|
||
//ProfileTimer.Pop(profileDepth3);
|
||
}
|
||
try
|
||
{
|
||
//int profileDepth4 = ProfileTimer.Push(">>>> DoReplaceWords2.Partial");
|
||
myMatches.Add(dicReplaceRegex[rs], rs);
|
||
//ProfileTimer.Pop(profileDepth4);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, rs.ReplaceWord, ex.GetType().Name, ex.Message);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//ProfileTimer.Pop(profileDepth);
|
||
//int profileDepth5 = ProfileTimer.Push(">>>> DoReplaceWords2.ReplaceMatches");
|
||
Text = myMatches.ReplaceMatches();
|
||
//ProfileTimer.Pop(profileDepth5);
|
||
Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
|
||
return Text;
|
||
}
|
||
// F2021-093: separate out partial replace words so that they can all be done before normal replace words. Partials read in the 'repword', use
|
||
// it as-is as a dotnet regular expression to do replacement. Aside from the dotnet regular expression process, the rest of this
|
||
// code is similar to plain regular expressions, in terms of processing flags for which steps, etc.
|
||
private string DoReplacePartials(string Text, FormatConfig.ReplaceStrData rsl)
|
||
{
|
||
Dictionary<FormatConfig.ReplaceStr, Regex> partialReplaceList = new Dictionary<FormatConfig.ReplaceStr, Regex>();
|
||
Dictionary<E_ReplaceFlags?, bool> shouldReplace = new Dictionary<E_ReplaceFlags?, bool>();
|
||
foreach (FormatConfig.ReplaceStr rs in rsl)
|
||
{
|
||
bool dopartial = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.Partials) == E_ReplaceFlags.Partials;
|
||
if (dopartial)
|
||
{
|
||
bool onlyDoList = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.BeforeList) == E_ReplaceFlags.BeforeList; // C2021-045
|
||
bool onlyIfFirstWord = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.FirstWord) == E_ReplaceFlags.FirstWord; // C2021-056
|
||
bool doInPagelist = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.PageList) == E_ReplaceFlags.PageList; // B2021-132
|
||
//B2021-132 only do replacewords in paglist if the replaceword pagelist flag is set
|
||
if (_DoReplWordInPageList && !doInPagelist) continue;
|
||
|
||
// note that the order of this check is important. Check in this order...
|
||
if (!shouldReplace.ContainsKey((E_ReplaceFlags)rs.Flag))
|
||
{
|
||
shouldReplace.Add((E_ReplaceFlags)rs.Flag, ShouldReplaceIt((E_ReplaceFlags)rs.Flag));
|
||
}
|
||
bool replaceit = shouldReplace[(E_ReplaceFlags)rs.Flag];
|
||
|
||
if (replaceit)
|
||
{
|
||
// C2021-045 if the BeforeList ReplaceWords flag is set, only do the replace word if the text ends with a colon
|
||
if (onlyDoList && !Text.EndsWith(":"))
|
||
replaceit = false; // text does not end with a colon so don't replace this word
|
||
// C2021-056 if FirstWord ReplaceWords flag is set, only do if the replace word is the first word in the text
|
||
if (onlyIfFirstWord && !Text.StartsWith(rs.ReplaceWord))
|
||
replaceit = false;
|
||
}
|
||
if (!replaceit && _DoReplWordInPageList) replaceit = true; // F2021-053: Do replace words in page list
|
||
if (replaceit)
|
||
{
|
||
if (!dicReplaceRegex.ContainsKey(rs))
|
||
{
|
||
RegexOptions myOptions = (E_ReplaceFlags)(rs.Flag & FormatConfig.E_ReplaceFlagsUCF.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase : RegexOptions.None;
|
||
dicReplaceRegex.Add(rs, new Regex(rs.ReplaceWord, myOptions));
|
||
}
|
||
try
|
||
{
|
||
partialReplaceList.Add(rs, dicReplaceRegex[rs]);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, rs.ReplaceWord, ex.GetType().Name, ex.Message);
|
||
}
|
||
}
|
||
}
|
||
Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
|
||
try
|
||
{
|
||
foreach (FormatConfig.ReplaceStr prs in partialReplaceList.Keys)
|
||
Text = partialReplaceList[prs].Replace(Text, prs.ReplaceWith);
|
||
//if (partialReplaceList.Count>0) GC.Collect(); // microsoft had a memory leak in regular expression code - this REALLY slows it down though
|
||
}
|
||
catch (Exception ex) // Don't crash on a format issue.
|
||
{
|
||
_MyLog.WarnFormat("{0} - {1}", ex.GetType().Name, ex.Message);
|
||
}
|
||
}
|
||
return Text;
|
||
}
|
||
private bool ShouldReplaceIt(E_ReplaceFlags? myFlag)
|
||
{
|
||
bool replaceit= false;
|
||
if (_MyItemInfo.IsHigh && (myFlag & E_ReplaceFlags.High) > 0)
|
||
{
|
||
replaceit = true;
|
||
}
|
||
else if ((_MyItemInfo.IsTable || _MyItemInfo.IsFigure) && (myFlag & E_ReplaceFlags.Table) > 0)
|
||
{
|
||
replaceit = true;
|
||
}
|
||
else if (_MyItemInfo.IsInRNO && (myFlag & E_ReplaceFlags.RNO) > 0)
|
||
{
|
||
replaceit = true;
|
||
// B2019-073 if there is table, caution, or note in an RNO and ReplaceWords is turn off
|
||
// for those step types, set replaceit to false.
|
||
if (_MyItemInfo.IsTable)
|
||
replaceit = ((myFlag & E_ReplaceFlags.Table) > 0);
|
||
else if (_MyItemInfo.IsCaution)
|
||
replaceit = ((myFlag & E_ReplaceFlags.Caution) > 0);
|
||
else if (_MyItemInfo.IsNote)
|
||
replaceit = ((myFlag & E_ReplaceFlags.Note) > 0);
|
||
}
|
||
else if (_MyItemInfo.IsCaution && (myFlag & E_ReplaceFlags.Caution) > 0)
|
||
{
|
||
replaceit = true;
|
||
}
|
||
else if (_MyItemInfo.IsNote && (myFlag & E_ReplaceFlags.Note) > 0)
|
||
{
|
||
replaceit = true;
|
||
}
|
||
else if (_MyItemInfo.IsStepPart && !_MyItemInfo.IsHigh && (myFlag & E_ReplaceFlags.Substep) > 0)
|
||
{
|
||
replaceit = true;
|
||
}
|
||
//else if (_MyItemInfo.IsInFirstLevelSubStep && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
|
||
else if (_MyItemInfo.IsAccPages & (myFlag & E_ReplaceFlags.Attach) > 0)
|
||
{
|
||
replaceit = true;
|
||
}
|
||
return replaceit;
|
||
}
|
||
#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'?{}~ \\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{}~ \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>", RegexOptions.Singleline);
|
||
if(m.Groups[3].Value == " ")
|
||
return m.Groups[4].Value;
|
||
return m.Groups[3].Value + m.Groups[4].Value;
|
||
}
|
||
return _Text;
|
||
}
|
||
set
|
||
{
|
||
if (_TextAndLink != null)
|
||
{
|
||
Match m = Regex.Match(_TextAndLink, @"<START\](\\[^v \\]+)*\\v0(\\[^v'?{}~ \\]+)*( |\\u[0-9]{{1,4}}?|\\'[0-9a-fA-F]{{2}}|\\[{{}}~])(.*?)(\\[^v'?{}~ \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>", RegexOptions.Singleline);
|
||
int myIndex = m.Groups[4].Index;
|
||
int myLength = m.Groups[4].Length;
|
||
if (m.Groups[3].Value != " ")
|
||
{
|
||
myIndex = m.Groups[3].Index;
|
||
myLength += m.Groups[3].Length;
|
||
}
|
||
string gg = _TextAndLink.Substring(myIndex, myLength);
|
||
string newvalue = value.Replace("{", @"\{").Replace("}", @"\}");
|
||
_TextAndLink = _TextAndLink.Substring(0, myIndex) + newvalue + _TextAndLink.Substring(myIndex + myLength);
|
||
}
|
||
_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;
|
||
private VE_Font _Font;
|
||
private ItemInfo _MyItemInfo;
|
||
public FoundMatches(string text, VE_Font font, ItemInfo myItemInfo)
|
||
: base()
|
||
{
|
||
_Text = text;
|
||
_Font = font;
|
||
_MyItemInfo = myItemInfo;
|
||
}
|
||
public void Add(Regex myRegEx, FormatConfig.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 DidMsgBox = false;
|
||
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);
|
||
// B2016-267: Linking to enhanced background steps crashed if step had RO and if no RO path was set. Really problem
|
||
// is that ro path was not set - just so happened it was found during use of Linking to enhanced.
|
||
if (myROFst == null)
|
||
{
|
||
if (!DidMsgBox) // only put the message box out once.
|
||
{
|
||
DidMsgBox = true;
|
||
FlexibleMessageBox.Show(string.Format("{0} does not have Referenced Object Path set.", myDocVersion.MyFolder.Name), "No RO Path Set", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||
}
|
||
}
|
||
return myROFst==null?false:myROFst.IsSetpointDB(dbid, myDocVersion);
|
||
}
|
||
return false;
|
||
}
|
||
public void Add(Match myMatch, FormatConfig.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 bool StartsWith(string text, int index, params string[] examples)
|
||
{
|
||
foreach (string str in examples)
|
||
if (str.Length == index && str == text.Substring(0, str.Length)) return true;
|
||
return false;
|
||
}
|
||
public string ReplaceMatches()
|
||
{
|
||
int offset = 0;
|
||
string text = _Text;
|
||
foreach (FoundMatch foundMatch in Values)
|
||
{
|
||
if (foundMatch.MyWord != null)
|
||
{
|
||
// B2022-015 BNPPalr: Determine whether RO text should have Replace Words applied. InLinkAndNotInRoFlag checks
|
||
// for flag on replace word item & checks that it is within and RO link
|
||
bool InLinkAndNotInRoFlag = ((foundMatch.MyWord.Flag & FormatConfig.E_ReplaceFlagsUCF.NotInRO) != 0) ? VerifyWithinLink(text, foundMatch, offset) : false;
|
||
if (!InLinkAndNotInRoFlag && VerifyNoHardSpace(text, foundMatch, offset) && VerifyNoLink(text, foundMatch, offset))
|
||
{
|
||
//if(offset != 0 || foundMatch.MyMatch.Index != 0 || !foundMatch.MyWord.ReplaceWith.StartsWith(@"{\par}"))
|
||
//{
|
||
if (((foundMatch.MyWord.Flag & FormatConfig.E_ReplaceFlagsUCF.DiffUnit) == 0) || DiffUnit(foundMatch.MyWord.ReplaceWord, _MyItemInfo, "UNIT "))
|
||
{
|
||
string with = foundMatch.MyWord.ReplaceWith;
|
||
if (offset == 0 && with.StartsWith(@"{\par}"))
|
||
if (StartsWith(text, foundMatch.MyMatch.Index, "", @"\ul ", @"\b ", @"* ", @"* \ul ", @"* \b ", @"*", @"*\ul ", @"*\b "))
|
||
with = with.Replace(@"{\par}", "");
|
||
bool IsBold = ((_Font.Style & E_Style.Bold) == E_Style.Bold) ||
|
||
(_MyItemInfo.FormatStepData != null && _MyItemInfo.FormatStepData.BoldHighLevel && _MyItemInfo.IsRNOPart && _MyItemInfo.MyParent.IsHigh);
|
||
// B2019-034 If the word to be replaced in the procedure text was manually bolded, remove the bold on/off commands from the replacement word
|
||
if (!IsBold)
|
||
{
|
||
int repidxBoldOff = text.LastIndexOf(@"\b0", foundMatch.MyMatch.Index + offset);
|
||
int repidxBoldOn = text.LastIndexOf(@"\b", foundMatch.MyMatch.Index + offset);
|
||
if (repidxBoldOff > 0)
|
||
{
|
||
repidxBoldOn = text.Substring(repidxBoldOff + 3, foundMatch.MyMatch.Index + offset - (repidxBoldOff + 3)).LastIndexOf(@"\b");
|
||
if (repidxBoldOn >= 0)
|
||
repidxBoldOn += (repidxBoldOff + 3);
|
||
}
|
||
if (repidxBoldOn >= 0) IsBold = true;
|
||
}
|
||
// B2019-034 added more cases to look for and remove bold on/off from the ReplaceWith word
|
||
if (IsBold && (with.Contains(@"\b ") || with.Contains(@"\b\")))
|
||
{
|
||
with = with.Replace(@"\b ", "");
|
||
with = with.Replace(@"\b\", @"\");
|
||
with = with.Replace(@"\b0 ", "");
|
||
with = with.Replace(@"\b0\", @"\");
|
||
if (with.EndsWith(@"\b0"))
|
||
with = with.Replace(@"\b0", "");
|
||
// Removed the following two lines of code to fix B2019-164. This change was not needed for
|
||
// B2019-092, a format file changed fixed that problem:
|
||
//if (with.LastIndexOf(@"\") > with.LastIndexOf(" ")) // B2019-092 - make sure there is a space char to terminate remaining rft formatting command
|
||
// with = with + " ";
|
||
}
|
||
bool IsUnderline = (((_Font.Style & E_Style.Underline) == E_Style.Underline) && with.Contains(@"\ul "));
|
||
// handle where replace words replaces a string with 'underline on'string'underline off', for example Point Beach
|
||
// had replaced OR's turning underline off in the middle of a transition, "EOP-0 UNIT 1, REACTOR TRIP OR SAFETY INJECTION".
|
||
if (!IsUnderline)
|
||
{
|
||
int repidxulnone = text.LastIndexOf(@"\ulnone", foundMatch.MyMatch.Index + offset);
|
||
int repidxst = text.LastIndexOf(@"\ul", foundMatch.MyMatch.Index + offset);
|
||
if (repidxulnone > 0)
|
||
{
|
||
repidxst = text.Substring(repidxulnone + 7, foundMatch.MyMatch.Index + offset - (repidxulnone + 7)).LastIndexOf(@"\ul");
|
||
if (repidxst >= 0)
|
||
repidxst += (repidxulnone + 7);
|
||
}
|
||
if (repidxst >= 0) IsUnderline = true;
|
||
}
|
||
// B2019-034 added more cases to look for and remove underline on/off from the ReplaceWith word
|
||
if (IsUnderline)
|
||
{
|
||
with = with.Replace(@"\ul ", "");
|
||
with = with.Replace(@"\ul\", @"\");
|
||
with = with.Replace(@"\ulnone ", "");
|
||
with = with.Replace(@"\ulnone\", @"\");
|
||
if (with.EndsWith(@"\ulnone"))
|
||
with = with.Replace(@"\ulnone", "");
|
||
// Removed the following two lines of code to fix B2019-164. This change was not needed for
|
||
// B2019-092, a format file changed fixed that problem:
|
||
//if (with.LastIndexOf(@"\") > with.LastIndexOf(" ")) // B2019-092 - make sure there is a space char to terminate remaining rft formatting command
|
||
// with = with + " ";
|
||
}
|
||
string preceedingText = text.Substring(0, offset + foundMatch.MyMatch.Index);
|
||
int ndxBold = preceedingText.LastIndexOf(@"\b");
|
||
if (ndxBold > -1 && preceedingText.Length > (ndxBold + 2) && preceedingText[ndxBold + 2] != '0' && with.Contains(@"\b "))
|
||
{
|
||
with = with.Replace(@"\b ", "");
|
||
with = with.Replace(@"\b0 ", "");
|
||
}
|
||
int ndxULine = preceedingText.LastIndexOf(@"\ul");
|
||
if (ndxULine > -1 && preceedingText[ndxULine + 3] != 'n' && with.Contains(@"\ul "))
|
||
{
|
||
with = with.Replace(@"\ul ", "");
|
||
with = with.Replace(@"\ulnone ", "");
|
||
}
|
||
|
||
text = text.Substring(0, offset + foundMatch.MyMatch.Index) + with + text.Substring(offset + foundMatch.MyMatch.Index + foundMatch.MyMatch.Length);
|
||
//offset += foundMatch.MyWord.ReplaceWith.Length - foundMatch.MyMatch.Length;
|
||
offset += with.Length - foundMatch.MyMatch.Length;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return text;
|
||
}
|
||
// B2022-015 BNPPalr: Determine whether RO text should have Replace Words applied
|
||
// B2022-022 BNPP needed to add use of 'offset' to work with string. 'offset' is used in code to keep track
|
||
// of offset in text in case other replacements are made before the current, i.e. adjusts the index found in the Match.
|
||
private bool VerifyWithinLink(string text, FoundMatch foundMatch, int offset)
|
||
{
|
||
// Is Match within a link, i.e. between a start & end and has '#Link:R' (defined referenced object link) between them too
|
||
int sindx = text.LastIndexOf("<START]", offset + foundMatch.MyMatch.Index); // B2022-022 added offset
|
||
if (sindx > -1)
|
||
{
|
||
int eindx = text.IndexOf("[END>",sindx + 1);
|
||
bool isRo = eindx > sindx && text.Substring(sindx, eindx - sindx - 1).Contains("#Link:R");
|
||
if (isRo && foundMatch.MyMatch.Index + offset > sindx && foundMatch.MyMatch.Index + offset < eindx) return true; // B2022-022 added offset
|
||
}
|
||
return false;
|
||
}
|
||
|
||
private bool VerifyNoLink(string text, FoundMatch fndMatch, int offset)
|
||
{
|
||
if (text.Substring(offset + fndMatch.MyMatch.Index, fndMatch.MyMatch.Length) == "START")
|
||
if (fndMatch.MyMatch.Index > 0 && offset + fndMatch.MyMatch.Index + fndMatch.MyMatch.Length < text.Length &&
|
||
text.Substring(offset + fndMatch.MyMatch.Index - 1, fndMatch.MyMatch.Length + 2) == "<START]")
|
||
return false;
|
||
return true;
|
||
}
|
||
internal static bool DiffUnit(string unit,ItemInfo myItemInfo,string prefix)
|
||
{
|
||
if (unit.StartsWith(prefix))
|
||
return unit.Substring(prefix.Length) != myItemInfo.MyDocVersion.DocVersionConfig.Unit_Number;
|
||
return true;
|
||
}
|
||
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 \~
|
||
// bug fix B2015-197 - need to consider underline and bold commands between a hard space and a word
|
||
if (Regex.IsMatch(begin, @"(\\(u160\?|'a0|~)(\\ulnone ?|\\b0 ?|\\ul ?|\\b ?)*(\\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]* ?)*(\\ulnone ?|\\b0 ?|\\ul ?|\\b ?)*\\(u160\?|'a0|~))"))
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
if (Regex.IsMatch(begin, @"(\\(u160\?|'a0|~)(\\ulnone ?|\\b0 ?|\\ul ?|\\b ?)*)$"))
|
||
return false;
|
||
// make sure that it is not followed by \u160? \'a0 or \~
|
||
if (Regex.IsMatch(end, @"^(\\ulnone ?|\\b0 ?|\\ul ?|\\b ?)*\\(u160\?|'a0|~)"))
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
public class FoundMatch
|
||
{
|
||
private Match _MyMatch;
|
||
public Match MyMatch
|
||
{
|
||
get { return _MyMatch; }
|
||
set { _MyMatch = value; }
|
||
}
|
||
private FormatConfig.ReplaceStr _MyWord;
|
||
public FormatConfig.ReplaceStr MyWord
|
||
{
|
||
get { return _MyWord; }
|
||
set { _MyWord = value; }
|
||
}
|
||
public FoundMatch(Match myMatch, FormatConfig.ReplaceStr myWord)
|
||
{
|
||
_MyMatch = myMatch;
|
||
_MyWord = myWord;
|
||
}
|
||
}
|
||
public class TextForBaseline
|
||
{
|
||
// put the symbol description in the baseline metafile output
|
||
public static string MetaSymbolText(string str)
|
||
{
|
||
string rtnVal = str;
|
||
FormatData fmtdata = FormatInfo.PROMSBaseFormat.FormatData;
|
||
if (fmtdata != null && fmtdata.SymbolList != null)
|
||
{
|
||
SymbolList sl = fmtdata.SymbolList;
|
||
if (sl != null)
|
||
{
|
||
foreach (Symbol sym in sl)
|
||
rtnVal = rtnVal.Replace(((char)sym.Unicode).ToString(), string.Format("[{0}]", sym.Desc)); //C2018-017 output symbol description from fromat file
|
||
}
|
||
}
|
||
return rtnVal;
|
||
}
|
||
public static string FixText(string str) // C2018-004 create meta file for baseline compares
|
||
{
|
||
return FixText(str, false);
|
||
}
|
||
public static string FixText(string str, bool doingWordDoc) // C2018-004 create meta file for baseline compares
|
||
{
|
||
// put a description of know symbols and ascii commands inbetween square brackets
|
||
if (str == null) return null;
|
||
str = MetaSymbolText(str); // C2018-017 replace know symbol character with text description
|
||
StringBuilder sb = new StringBuilder();
|
||
foreach (char c in str)
|
||
{
|
||
if (c < '\x1F' || c > '\x7F')
|
||
{
|
||
int i = (int)c;
|
||
switch (i)
|
||
{
|
||
case '\u0005':
|
||
sb.Append("[HngInd]"); // Hanging Indent char (for 16-bit) also used in MS Word tables for cell borders
|
||
break;
|
||
case '\u000A':
|
||
sb.Append("[LF]"); // line feed
|
||
break;
|
||
case '\u00A0':
|
||
sb.Append("[HS]"); // hard space
|
||
break;
|
||
case '\u2011':
|
||
sb.Append("[NBDash]"); // non-breaking dash
|
||
break;
|
||
case '\u000D':
|
||
sb.Append("[CR]"); // carriage return
|
||
break;
|
||
case '\uF0C9':
|
||
sb.Append("[dbxULC]"); // upper left cornner double line box
|
||
break;
|
||
case '\uF0BB':
|
||
sb.Append("[dbxURC]"); //upper right cornner double line box
|
||
break;
|
||
case '\uF0C8':
|
||
sb.Append("[dbxLLC]"); // lower left cornner double line box
|
||
break;
|
||
case '\uF0BC':
|
||
sb.Append("[dbxLRC]"); // lower right cornner double line box
|
||
break;
|
||
case '\uF0CD':
|
||
sb.Append("[dbxHZ]"); // horz double line box
|
||
break;
|
||
case '\uF0BA':
|
||
sb.Append("[dbxVT]"); // vertial double line box
|
||
break;
|
||
case '\uF0CC':
|
||
sb.Append("[dbxLM]"); // Left Midddle double line box
|
||
break;
|
||
case '\uF0B9':
|
||
sb.Append("[dbxRM]"); // right Midddle double line box
|
||
break;
|
||
case '\uF0CB':
|
||
sb.Append("[dbxDM]"); // down Midddle double line box
|
||
break;
|
||
case '\uF0CA':
|
||
sb.Append("[dbxUM]"); // up Midddle double line box
|
||
break;
|
||
case '\uF0CE':
|
||
sb.Append("[dbxMI]"); // Midddle intersection double line box
|
||
break;
|
||
case '\uF0D7':
|
||
sb.Append("[bxMIVDL]"); // Midddle intersection Single line box Vertial double line
|
||
break;
|
||
case '\uF0D8':
|
||
sb.Append("[dbxMIVSL]"); // Midddle intersection double line box Vertial Single line
|
||
break;
|
||
case '\uF0D1':
|
||
sb.Append("[dbxSLD]"); //double line to single line down
|
||
break;
|
||
case '\uF0CF':
|
||
sb.Append("[dbxSLU]"); //double line to single line Up
|
||
break;
|
||
case '\uF0C7':
|
||
sb.Append("[dbxSL]"); //double line to single line left
|
||
break;
|
||
case '\uF0B6':
|
||
sb.Append("[dbxSR]"); //double line to single line right
|
||
break;
|
||
case '\uF0D2':
|
||
sb.Append("[bxDLD]"); //single line to double line down
|
||
break;
|
||
case '\uF0D0':
|
||
sb.Append("[bxDLU]"); //single line to double line up
|
||
break;
|
||
case '\uF0DA':
|
||
case '\u250C':
|
||
sb.Append("[bxULC]"); //upper left cornner single line box
|
||
break;
|
||
case '\uF0BF':
|
||
case '\u2510':
|
||
sb.Append("[bxURC]"); //upper right cornner single line box
|
||
break;
|
||
case '\uF0C0':
|
||
case '\u2514':
|
||
sb.Append("[bxLLC]"); //lower left cornner single line box
|
||
break;
|
||
case '\uF0D9':
|
||
case '\u2518':
|
||
sb.Append("[bxLRC]"); //lower right cornner single line box
|
||
break;
|
||
case '\uF0C4':
|
||
case '\u2500':
|
||
sb.Append("[bxHZ]"); // horz single line box
|
||
break;
|
||
case '\uF0B3':
|
||
sb.Append("[bxVT]"); // Vertial single line box
|
||
break;
|
||
case '\uF0C5':
|
||
case '\u253C':
|
||
sb.Append("[bxMI]"); // middle intersection single line box
|
||
break;
|
||
case '\uF0B4':
|
||
case '\u2524':
|
||
sb.Append("[bxMR]"); // middle right single line box
|
||
break;
|
||
case '\uF0C3':
|
||
case '\u251C':
|
||
sb.Append("[bxML]"); // middle left single line box
|
||
break;
|
||
case '\uF0B5':
|
||
sb.Append("[bxMDLL]"); // middle single line box double line left
|
||
break;
|
||
case '\uF0C2':
|
||
case '\u252C':
|
||
sb.Append("[bxMD]"); // middle down single line box
|
||
break;
|
||
case '\uF0C1':
|
||
case '\u2534':
|
||
sb.Append("[bxMU]"); // middle up single line box
|
||
break;
|
||
case '\uF0DC':
|
||
sb.Append("[thbxtop]"); // top thick line box
|
||
break;
|
||
case '\uF0DB':
|
||
sb.Append("[thbxSide]"); // Side thick line box
|
||
break;
|
||
case '\uF0DF':
|
||
sb.Append("[thbxBtm]"); // Bottom thick line box
|
||
break;
|
||
case '\uF0DD':
|
||
sb.Append("[thbxLfSide]"); // Left Side thick line box
|
||
break;
|
||
case '\uF0DE':
|
||
sb.Append("[thbxRtSide]"); // Right Side thick line box
|
||
break;
|
||
case '\uF020':
|
||
case '\u2002':
|
||
case '\u2003':
|
||
sb.Append("[{SP}]"); // unicode space
|
||
break;
|
||
case '\u2010':
|
||
case '\u2012':
|
||
case '\u2013':
|
||
case '\u2014':
|
||
case '\u001E':
|
||
case '\u25AA':
|
||
sb.Append("[{Dash}]"); // dash
|
||
break;
|
||
case '\u201C':
|
||
case '\u001C':
|
||
sb.Append("[{BgDblQt}]"); // begin double quote
|
||
break;
|
||
case '\u201D':
|
||
case '\u001D':
|
||
case '\u2033':
|
||
sb.Append("[{EnDblQt}]"); // end double quote
|
||
break;
|
||
case '\u2018':
|
||
sb.Append("[{fwdQuote}]"); // forward quote (single quote)
|
||
break;
|
||
case '\u2019':
|
||
case '\u2032':
|
||
sb.Append("[{bckQuote}]"); // back quote (single quote)
|
||
break;
|
||
case '\u2022':
|
||
//case '\uF06C':
|
||
sb.Append("[{bullet}]"); // bullet not in PROMS symbol list
|
||
break;
|
||
case '\u00B7':
|
||
//case '\uF06C':
|
||
sb.Append("[{SqrBullet}]"); // square bullet not in PROMS symbol list
|
||
break;
|
||
case '\uF0B7':
|
||
case '\uF0A3':
|
||
sb.Append("[{ChkBox}]"); // check box not in PROMS symbol list
|
||
break;
|
||
case '\u00B5':
|
||
sb.Append("[{Micro}]"); // micro not in PROMS symbol list
|
||
break;
|
||
case '\u00B3':
|
||
sb.Append("[{Cubed}]"); // cubed char (supper script 3) not in PROMS symbol list
|
||
break;
|
||
case '\u2206':
|
||
sb.Append("[{Delta}]"); // Delta not in PROMS symbol list
|
||
break;
|
||
case '\u00BE':
|
||
sb.Append("[{3/4}]"); // 3/4 char not in PROMS symbol list
|
||
break;
|
||
case '\u2070':
|
||
case '\u00BA':
|
||
case '\u030A':
|
||
case '\u02DA':
|
||
case '\uF0B0':
|
||
sb.Append("[{Degree}]"); // degree char not in PROMS symbol list
|
||
break;
|
||
case '\uF0A8':
|
||
sb.Append("[{Diamond}]"); // Diamond char not in PROMS symbol list
|
||
break;
|
||
case '\u0018':
|
||
sb.Append("[{UpArrow}]"); // Up Arrow char not in PROMS symbol list
|
||
break;
|
||
case '\u01C0':
|
||
sb.Append("[{VtBar}]"); // Vertical bar char not in PROMS symbol list
|
||
break;
|
||
case '\u2026':
|
||
sb.Append("[{...}]"); // 3 dots (etc) char not in PROMS symbol list
|
||
break;
|
||
case '\u02C3':
|
||
sb.Append("[{>}]"); // greater than char not in PROMS symbol list
|
||
break;
|
||
case '\u00D7':
|
||
sb.Append("[{x}]"); // times char not in PROMS symbol list
|
||
break;
|
||
case '\u2298':
|
||
sb.Append("[{CirWthVLn}]"); // Cirlce with VLine char not in PROMS symbol list
|
||
break;
|
||
default:
|
||
bool hanledWrdChar = false;
|
||
if (doingWordDoc) // These characters are valid only in Word documents
|
||
{
|
||
hanledWrdChar = true;
|
||
switch (i)
|
||
{
|
||
case '\u0001':
|
||
sb.Append("[WordImage]"); // embedded image in Word document
|
||
break;
|
||
case '\u0002':
|
||
sb.Append("[WordFtNtChar]"); // Foot Note in Word document
|
||
break;
|
||
case '\u0015':
|
||
sb.Append("[WordBltLstChar]"); // Bullet List in Word document
|
||
break;
|
||
case '\u000B':
|
||
sb.Append("[VT]"); // vertical tab (used to center text in Word tables)
|
||
break;
|
||
case '\u000C':
|
||
sb.Append("[PgBrk]"); // new page (form feed)
|
||
break;
|
||
case '\u0009':
|
||
sb.Append("[TAB]"); // tab
|
||
break;
|
||
case '\u0007':
|
||
sb.Append("[Bell]"); // bell but used in MS Word tables for cell borders
|
||
break;
|
||
default:
|
||
hanledWrdChar = false;
|
||
break;
|
||
}
|
||
}
|
||
if (!hanledWrdChar)
|
||
{
|
||
if (c > '\uF01F' && c < '\uF07F')
|
||
sb.Append(string.Format("[{{{0}}}]", Convert.ToChar(((int)c & '\xFF')))); // usually normal text but was using the Volian Line Draw font
|
||
else
|
||
sb.Append(string.Format("[[{0:X}]]", (int)c));
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
sb.Append(c);
|
||
}
|
||
return sb.ToString();
|
||
}
|
||
}
|
||
}
|