1748 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1748 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Text;
 | |
| using System.Windows.Forms;
 | |
| using System.Text.RegularExpressions;
 | |
| using System.Drawing;
 | |
| using VEPROMS.CSLA.Library;
 | |
| 
 | |
| namespace Volian.Controls.Library
 | |
| {
 | |
| 	public class DisplayText
 | |
| 	{
 | |
| 		private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 | |
| 		#region Properties
 | |
| 		private E_FieldToEdit _FieldToEdit;
 | |
| 		public E_FieldToEdit FieldToEdit
 | |
| 		{
 | |
| 			get { return _FieldToEdit; }
 | |
| 			set { _FieldToEdit = value; }
 | |
| 		}
 | |
| 		private ItemInfo _MyItemInfo;
 | |
| 		private string InfoText
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				switch (FieldToEdit)
 | |
| 				{
 | |
| 					case E_FieldToEdit.StepText:
 | |
| 					case E_FieldToEdit.Text:
 | |
| 						return _MyItemInfo.MyContent.Text;
 | |
| 						break;
 | |
| 					case E_FieldToEdit.Number:
 | |
| 						return _MyItemInfo.MyContent.Number;
 | |
| 						break;
 | |
| 				}
 | |
| 				return string.Empty;
 | |
| 			}
 | |
| 		}
 | |
| 		private Item _MyItem;
 | |
| 		private string EditText
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				switch (FieldToEdit)
 | |
| 				{
 | |
| 					case E_FieldToEdit.StepText:
 | |
| 					case E_FieldToEdit.Text:
 | |
| 						return _MyItem.MyContent.Text;
 | |
| 						break;
 | |
| 					case E_FieldToEdit.Number:
 | |
| 						return _MyItem.MyContent.Number;
 | |
| 						break;
 | |
| 				}
 | |
| 				return string.Empty;
 | |
| 			}
 | |
| 			set
 | |
| 			{
 | |
| 				switch (FieldToEdit)
 | |
| 				{
 | |
| 					case E_FieldToEdit.StepText:
 | |
| 					case E_FieldToEdit.Text:
 | |
| 						_MyItem.MyContent.Text = value;
 | |
| 						_MyItem.MyContent.UserID = Volian.Base.Library.VlnSettings.UserID;
 | |
| 						_MyItem.MyContent.DTS = DateTime.Now;
 | |
| 						break;
 | |
| 					case E_FieldToEdit.Number:
 | |
| 						_MyItem.MyContent.Number = value;
 | |
| 						_MyItem.MyContent.UserID = Volian.Base.Library.VlnSettings.UserID;
 | |
| 						_MyItem.MyContent.DTS = DateTime.Now;
 | |
| 						break;
 | |
| 					default:
 | |
| 						break;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		// list of 'pieces of text' for this item.  Pieces include symbols, ros, 
 | |
| 		// transitions & plain text.
 | |
| 		private List<displayTextElement> _DisplayTextElementList;
 | |
| 		public List<displayTextElement> DisplayTextElementList
 | |
| 		{
 | |
| 			get { return _DisplayTextElementList; }
 | |
| 			set { _DisplayTextElementList = value; }
 | |
| 		}
 | |
| 		// dictionary for the font table for this item.  Note that this may
 | |
| 		// go away (it is not really used).
 | |
| 		private Dictionary<int, string> _dicRtfFontTable;
 | |
| 		public Dictionary<int, string> dicRtfFontTable
 | |
| 		{
 | |
| 			get { return _dicRtfFontTable; }
 | |
| 			set { _dicRtfFontTable = value; }
 | |
| 		}
 | |
| 		private VE_Font _textFont;		// Font from format for this item
 | |
| 		public VE_Font TextFont
 | |
| 		{
 | |
| 		  get { return _textFont; }
 | |
| 		  set { _textFont = value; }
 | |
| 		}
 | |
| 		private bool PrintingSmartTemplate = false;
 | |
| 		public string StartText;
 | |
| 		public string OriginalText;		// compare for save to see if change for links.
 | |
| 		private FormatInfo _MyFormat;
 | |
| 		#endregion
 | |
| 		#region Constructors
 | |
| 		/// <summary>
 | |
| 		///     DisplayText constructor:
 | |
| 		///			Creates a DisplayText object that converts the database text into rtf text
 | |
| 		///			Arguments are:
 | |
| 		///				ItemInfo itemInfo - the item whose text will be resolved
 | |
| 		///				E_EditPrintMode ep_mode - edit or print.
 | |
| 		///				E_ViewMode vw_mode - view or edit.
 | |
| 		///				bool noEdit - flags whether to edit or not (used to set data in
 | |
| 		///						rtb as resolved replacewords for non-active rtb.
 | |
| 		///				E_FieldToEdit fieldToEdit - identifies the field to edit (number or text)
 | |
| 		///				bool colorLinks - whether to add color to links
 | |
| 		/// </summary>
 | |
| 		public DisplayText(ItemInfo itemInfo, E_EditPrintMode epMode, E_ViewMode vwMode, bool noEdit,E_FieldToEdit fieldToEdit, bool colorLinks, string prefix, string suffix)
 | |
| 		{
 | |
| 			_FieldToEdit = fieldToEdit;
 | |
| 			_MyItemInfo = itemInfo;
 | |
| 			OriginalText = InfoText;
 | |
| 			TextFont = itemInfo.GetItemFont();//GetItemFont();
 | |
| 			// if in print mode, and this is the HLS of a smart template (checklist formats), add a space before and
 | |
| 			// after the HLS text - this allows for the vertical bar characters to be added.
 | |
| 			if (itemInfo.IsStep && itemInfo.FormatStepData.UseSmartTemplate && epMode == E_EditPrintMode.Print) Console.WriteLine("here");
 | |
| 			string addSpace = (itemInfo.IsStep && itemInfo.FormatStepData.UseSmartTemplate && epMode == E_EditPrintMode.Print) ? "   " : "";
 | |
| 			string text = prefix + addSpace + InfoText + addSpace + suffix;
 | |
| 			_MyFormat = itemInfo.ActiveFormat;
 | |
| 
 | |
| 			bool tableShouldBeOutlined = (epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View || noEdit) &&
 | |
| 				(_FieldToEdit == E_FieldToEdit.StepText || _FieldToEdit == E_FieldToEdit.Text) &&
 | |
| 				(!itemInfo.IsSection && !itemInfo.IsProcedure) && (itemInfo.IsTable || itemInfo.IsFigure);
 | |
| 			bool wordsShouldBeReplaced = epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View || noEdit;
 | |
| 			if (_MyFormat == null)
 | |
| 				Console.WriteLine(this._MyItemInfo.MyItemInfoUnique);
 | |
| 			bool numbersShouldBeFormated = (!_MyFormat.PlantFormat.FormatData.SectData.StepSectionData.FortranFormatNumbers && (epMode == E_EditPrintMode.Print || vwMode == E_ViewMode.View || noEdit));
 | |
| 			int typ = ((int)itemInfo.MyContent.Type) % 10000;
 | |
| 			bool tableHasBorder = tableShouldBeOutlined ? itemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[typ].Type.IndexOf(@"Borderless") < 0 : false;
 | |
| 			bool ROsShouldBeAdjusted = wordsShouldBeReplaced; // same logical value
 | |
| 			if (epMode == E_EditPrintMode.Print && _MyItemInfo.IsStep)
 | |
| 			{
 | |
| 				if (_MyItemInfo.FormatStepData.UseSmartTemplate)
 | |
| 				{
 | |
| 					// Add 2 spaces before and 1 after if there is prefix so that wrapping in RTB accounts for vertical 
 | |
| 					// lines (the 2 spaces after the first "\par " command and 1 space before 2nd "\par").  Tried other
 | |
| 					// combinations that did not work.
 | |
| 					if (_MyItemInfo.FormatStepData.Prefix != null && _MyItemInfo.FormatStepData.Prefix != "")
 | |
| 						text = !_MyItemInfo.FormatStepData.Font.FontIsProportional() ? ReplaceLinesWithUnicode(_MyItemInfo.FormatStepData.Prefix) + @"\par " + text + @"\par " :
 | |
| 							@"\par " + text + @"\par ";
 | |
| 					if (_MyItemInfo.FormatStepData.Suffix != null && _MyItemInfo.FormatStepData.Suffix != "")
 | |
| 						text = text + (!_MyItemInfo.FormatStepData.Font.FontIsProportional() ? ReplaceLinesWithUnicode(_MyItemInfo.FormatStepData.Suffix) :
 | |
| 							@"\par\par\par ");
 | |
| 				}
 | |
| 			}
 | |
| 			text = CreateRtf(colorLinks, text, tableShouldBeOutlined, wordsShouldBeReplaced, numbersShouldBeFormated, tableHasBorder, ROsShouldBeAdjusted);
 | |
| 			
 | |
| 			StartText = text;
 | |
| 		}
 | |
| 		private string ReplaceLinesWithUnicode(string text)
 | |
| 		{
 | |
| 			text = text.Replace("\x2500", @"\u9472?");  // Horizontal
 | |
| 			text = text.Replace("\x2502", @"\u9474?");	// Vertical
 | |
| 			text = text.Replace("\x2514", @"\u9492?");	// Bottom Left Corner
 | |
| 			text = text.Replace("\x2518", @"\u9496?");	// Bottom Right Corner
 | |
| 			text = text.Replace("\x2534", @"\u9524?");	// Bottom Tee
 | |
| 			text = text.Replace("\x250c", @"\u9484?");	// Upper Left Corner
 | |
| 			text = text.Replace("\x251c", @"\u9500?");	// Left Tee
 | |
| 			text = text.Replace("\x2510", @"\u9488?");  // Upper Right Corner
 | |
| 			text = text.Replace("\x252c", @"\u9516?");  // Top Tee
 | |
| 			text = text.Replace("\x2524", @"\u9508?");  // Right Tee
 | |
| 			text = text.Replace("\x253c", @"\u9532?");	// Plus
 | |
| 			return text;
 | |
| 		}
 | |
| 
 | |
| 		public DisplayText(string text, VE_Font vFont, bool colorLinks)
 | |
| 		{
 | |
| 			TextFont = vFont;
 | |
| 			StartText = CreateRtf(colorLinks, text, false, false, false, false, false);
 | |
| 		}
 | |
| 		public DisplayText(ItemInfo itemInfo, string text, bool colorLinks)
 | |
| 		{
 | |
| 			_FieldToEdit = E_FieldToEdit.Text;
 | |
| 			_MyItemInfo = itemInfo;
 | |
| 			OriginalText = text;
 | |
| 			TextFont = itemInfo.GetItemFont();
 | |
| 			_MyFormat = itemInfo.ActiveFormat;
 | |
| 
 | |
| 			bool wordsShouldBeReplaced = true;
 | |
| 			bool numbersShouldBeFormated = !_MyFormat.PlantFormat.FormatData.SectData.StepSectionData.FortranFormatNumbers;
 | |
| 			int typ = ((int)itemInfo.MyContent.Type) % 10000;
 | |
| 			bool ROsShouldBeAdjusted = wordsShouldBeReplaced; // same logical value
 | |
| 
 | |
| 			text = CreateRtf(colorLinks, text, false, wordsShouldBeReplaced, numbersShouldBeFormated, false, ROsShouldBeAdjusted);
 | |
| 			StartText = text;
 | |
| 		}
 | |
| 		private string CreateRtf(bool colorLinks, string text, bool tableShouldBeOutlined, bool wordsShouldBeReplaced, bool numbersShouldBeFormated, bool tableHasBorder, bool ROsShouldBeAdjusted)
 | |
| 		{
 | |
| 			// Adjust RO display
 | |
| 			if (ROsShouldBeAdjusted)
 | |
| 			{
 | |
| 				try // Added try/catch because an unresolved RO Link was causing a failure.
 | |
| 				{
 | |
| 					text = DoROAdjustments(text);
 | |
| 				}
 | |
| 				catch (Exception ex)
 | |
| 				{
 | |
| 					if (_MyItemInfo != null)
 | |
| 					{
 | |
| 						_MyLog.ErrorFormat("<<< ERROR >>> Error doing DoROAdjustments\r\n==>'RO Adjustments Error',{0},'{1}','{2}','{3}'"
 | |
| 							, _MyItemInfo.ItemID, _MyItemInfo.MyDocVersion.MyFolder.Name, _MyItemInfo.ShortPath, ex.Message);
 | |
| 					}
 | |
| 					else
 | |
| 						_MyLog.Error("DisplayText.CreateRTF Error doing DoROAdjustments", ex);
 | |
| 
 | |
| 				}
 | |
| 			}
 | |
| 			// if in print mode, view mode, or non-active richtextbox do replace words.  Only if in 
 | |
| 			// actual edit mode are replace words left as is.
 | |
| 			if (wordsShouldBeReplaced) 
 | |
| 				text = DoReplaceWords2(text);
 | |
| 			if (_MyItemInfo != null)
 | |
| 			{
 | |
| 				text = DoSearchAndReplace(text, "<U-ID>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_ID);
 | |
| 				text = text.Replace(@"<S\u8209?ID>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_ProcedureSetID);
 | |
| 				text = text.Replace("<U>", _MyItemInfo.MyDocVersion.DocVersionConfig.Unit_Number);
 | |
| 			}
 | |
| 			// Adjust RO display
 | |
| 			if (ROsShouldBeAdjusted)
 | |
| 				text = DoTransitionAdjustments(text, _MyItemInfo.ActiveFormat.PlantFormat.FormatData.TransData.BoldTransition);
 | |
| 			// add colors around links:
 | |
| 			if (colorLinks)
 | |
| 				text = DoColorLinks(text);
 | |
| 				//Console.WriteLine(text);
 | |
| 			// adjust formatting of exponents
 | |
| 			if (numbersShouldBeFormated) 
 | |
| 				text = DoFortranFormat(text);
 | |
| 			// determine whether the table/figure should be outlined:
 | |
| 			if (tableShouldBeOutlined)
 | |
| 			{
 | |
| 				OutlineRTFTable myTable = new OutlineRTFTable(text, tableHasBorder);
 | |
| 				// if a table has internal line draw characters, we may have to do part of 'OutlineTable'
 | |
| 				// to convert dashes and vertical bars to line draw characters.
 | |
| 				if (tableHasBorder) myTable.OutlineTable();
 | |
| 				text = myTable.Lines.ToString();
 | |
| 			}
 | |
| 
 | |
| 			// if we're working with a grid it won't go thru here.
 | |
| 			if (!text.StartsWith(@"{\rtf"))
 | |
| 			{
 | |
| 				// as a precaution, convert any \~ to \u160?. This is for Hard spaces. see the commentary in the
 | |
| 				// save portion of this code for an explanation.
 | |
| 				text = text.Replace(@"\~", @"\u160?");
 | |
| 				text = text.Replace("\r\n", @"\par ");
 | |
| 				//if (text.IndexOf(@"\line") > -1)
 | |
| 				//    MessageBox.Show("Found rtf line");
 | |
| 				text = text.Replace(@"\line", @"\par");
 | |
| 
 | |
| 				// Now put symbol (for fixed fonts) or unicode font (proportional) around symbols
 | |
| 				// These fonts are VESymbFix & Arial Unicode MS respectively, and the font table
 | |
| 				// is actually defined in the StepRTB code.
 | |
| 				int indxsym = NextUnicode(text, 0);//text.IndexOf(@"\u");
 | |
| 				while (indxsym != -1)
 | |
| 				{
 | |
| 					int incrindx = 3;
 | |
| 					if (text[indxsym + 2] != 'l')
 | |
| 					{
 | |
| 						text = text.Insert(indxsym, @"\f1 ");
 | |
| 						int indxendsym = text.IndexOfAny(@"\ ?".ToCharArray(), indxsym + 5);
 | |
| 						if (indxendsym == -1)  // must be end of line:
 | |
| 							text = text.Insert(text.Length - 1, @"\f0 ");
 | |
| 						else
 | |
| 						{
 | |
| 							if (text[indxendsym] == '?') indxendsym++;
 | |
| 							text = text.Insert(indxendsym, @"\f0 ");   // TODO: do I need a space??
 | |
| 						}
 | |
| 						incrindx = 5;
 | |
| 					}
 | |
| 					indxsym = NextUnicode(text, indxsym + incrindx);//text.IndexOf(@"\u", indxsym + incrindx);
 | |
| 				}
 | |
| 			}
 | |
| 			return text;
 | |
| 		}
 | |
| 
 | |
| 		private string DoSearchAndReplace(string text, string find, string replace)
 | |
| 		{
 | |
| 			return text.Replace(find, replace);
 | |
| 		}
 | |
| 		private static string DoColorLinks(string text)
 | |
| 		{
 | |
| 			string origtext = text;
 | |
| 			text = Regex.Replace(text, @"(<START\](\\[^v \\]+)*\\v0)((?= |\\))", @"$1\cf1");
 | |
| 			//text = Regex.Replace(text, @"<START]\b0\v0 ", @"<START]\b0\v0\cf1 ");
 | |
| 			int indxcf = text.IndexOf(@"\v0\cf1");
 | |
| 			int indxend = 0; 
 | |
| 			try
 | |
| 			{
 | |
| 				while (indxcf != -1)
 | |
| 				{
 | |
| 					indxcf += 4;
 | |
| 					indxend = text.IndexOf(@"\v", indxcf);
 | |
| 					if (indxend > -1)
 | |
| 					{
 | |
| 						text = text.Insert(indxend, @"\cf0");
 | |
| 						indxcf = text.IndexOf(@"\v0\cf1", indxend);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						indxcf = -1;
 | |
| 						_MyLog.WarnFormat("DisplayText.DoColorLinks Failed\r\norgitext:'{0}'\r\ntext'{1}'", origtext, text);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			catch (Exception ex)
 | |
| 			{
 | |
| 				_MyLog.WarnFormat("DisplayText.DoColorLinks Failed\r\norgitext:'{0}'\r\ntext'{1}'", origtext, text);
 | |
| 			}
 | |
| 			return text;
 | |
| 		}
 | |
| 		private int NextUnicode(string text, int offset)
 | |
| 		{
 | |
| 			// Skip Hard Spaces
 | |
| 			Match m = Regex.Match(text.Substring(offset), @"\\u[0-9a-fA-F]");
 | |
| 			while(m.Success && text.Substring(offset+m.Index).StartsWith(@"\u160"))
 | |
| 			{
 | |
| 				offset += m.Index + 5;
 | |
| 				m = Regex.Match(text.Substring(offset), @"\\u[0-9a-fA-F]");
 | |
| 			}
 | |
| 			if (m.Success)
 | |
| 				return m.Index + offset;
 | |
| 			return -1;
 | |
| 		}
 | |
| 		private string DoROAdjustments(string text)
 | |
| 		{
 | |
| 			Regex regRefObj = new Regex(@"\#Link\:ReferencedObject:([0-9]*) ([0-9a-zA-Z]*) ([0-9]*)", RegexOptions.Singleline);
 | |
| 			string strippedText = StaticStripRtfCommands(text);
 | |
| 			// (\\[^v \\]+)*    -->  look for any rtf commands  (first part of lookFor)
 | |
| 			// \\v0    --> end of comment
 | |
| 			// (\\[^v \\]+)*	-->  more rtf commands ended by a space
 | |
| 			// (.*?)		--> smallest anything to that matches this based on what's next
 | |
| 			// (\\[^v' \\]+)*   --> look for rtf commands but exclude \' before the \v
 | |
| 			// \\v(\\[^v \\]+)* --> look for rtf commands after the \v
 | |
| 			// if it turns out that if ro's have any embedded unicode characters this needs expanded, such as /u8209? (hard hyphen)
 | |
| 			string lookFor = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(ReferencedObject|Transition[^:]*?):.*?\[END>");
 | |
| 			MatchCollection matches = Regex.Matches(text, lookFor);
 | |
| 			for (int i = matches.Count - 1; i >= 0; i--)
 | |
| 			{
 | |
| 				Match m = matches[i];
 | |
| 				if (m != null && m.Groups.Count > 6 && m.Groups[6].ToString() == "ReferencedObject")
 | |
| 				{
 | |
| 					System.Text.RegularExpressions.Group g = m.Groups[3];
 | |
| 					string beforeRO = StaticStripRtfCommands(text.Substring(0, g.Index));
 | |
| 					string afterRO = StaticStripRtfCommands(text.Substring(g.Index + g.Length));
 | |
| 					string newvalue = DoROFormatFlags(g.ToString(), beforeRO, afterRO);
 | |
| 					newvalue = DoROReplaceWords(_MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList, newvalue, _MyItemInfo.IsHigh);
 | |
| 					Match myMatch = regRefObj.Match(m.ToString());
 | |
| 					int dbid = System.Convert.ToInt32(myMatch.Groups[2].Value.Substring(0, 4), 16);
 | |
| 					int rodbid = int.Parse(myMatch.Groups[3].Value);
 | |
| 					ROFstInfo myROFst = _MyItemInfo.MyDocVersion.GetROFst(rodbid);
 | |
| 					if (myROFst.IsSetpointDB(dbid))	newvalue = ReplaceSpaceWithHardspace(newvalue);
 | |
| 					if (g.ToString() != newvalue)
 | |
| 						text = text.Substring(0, g.Index) + newvalue + text.Substring(g.Index + g.Length);
 | |
| 				}
 | |
| 			}
 | |
| 			return text;
 | |
| 		}
 | |
| 		private string DoROReplaceWords(ReplaceStrList replaceStrList, string newvalue, bool isHigh)
 | |
| 		{
 | |
| 			foreach (ReplaceStr rs in replaceStrList)
 | |
| 			{
 | |
| 				if (((rs.Flag & E_ReplaceFlags.Setpoint) > 0) || (isHigh && (rs.Flag & E_ReplaceFlags.HLSSetpnt) > 0))
 | |
| 				{
 | |
| 					newvalue = newvalue.Replace(rs.ReplaceWord, rs.ReplaceWith);
 | |
| 				}
 | |
| 			}
 | |
| 			return newvalue;
 | |
| 		}
 | |
| 		// Replace spaces with hardspaces, but DO NOT replace the end of an Rtf Command with a hardspace
 | |
| 		private string ReplaceSpaceWithHardspace(string newvalue)
 | |
| 		{
 | |
| 			string oldvalue = newvalue;
 | |
| 			int spindx = newvalue.IndexOf(" ");
 | |
| 			int lstindx = -1;
 | |
| 			while (spindx >= 0)
 | |
| 			{
 | |
| 				if (!EndsRtfCommand(newvalue, spindx, lstindx))
 | |
| 				{
 | |
| 					newvalue = newvalue.Remove(spindx, 1);
 | |
| 					newvalue = newvalue.Insert(spindx, @"\u160?");
 | |
| 				}
 | |
| 				lstindx = spindx;
 | |
| 				spindx = (spindx + 1 >= newvalue.Length)?spindx = -1: newvalue.IndexOf(" ", spindx+1);
 | |
| 			}
 | |
| 			return newvalue;
 | |
| 		}
 | |
| 
 | |
| 		private bool EndsRtfCommand(string str, int spindx, int previndx)
 | |
| 		{
 | |
| 			// get text from last space to current, or from beginning of string to current:
 | |
| 			int start = previndx < 0 ? 0 : previndx+1;
 | |
| 			string substring = str.Substring(start, spindx-start);
 | |
| 			if (substring.Contains(@"\"))
 | |
| 			{
 | |
| 				// is space ending an rtf command.
 | |
| 				int startCmd = substring.LastIndexOf(@"\");
 | |
| 				string Cmd = substring.Substring(startCmd);
 | |
| 				char tst = Cmd[1];
 | |
| 				// consider rtf commands up/dn/b/ul/i
 | |
| 				if (tst == 'u' || tst == 'd' || tst == 'b' || tst == 'u' || tst == 'i') return true;
 | |
| 			}
 | |
| 			return false;
 | |
| 		}
 | |
| 		private string DoTransitionAdjustments(string text, bool boldTran)
 | |
| 		{
 | |
| 			string strippedText = StaticStripRtfCommands(text);
 | |
| 			string lookFor = string.Format(@"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v \\u]+)*\\v(\\[^v \\]+)* #Link:(ReferencedObject|Transition[^:]*?):[0-9]* ([0-9]*).*?\[END>");
 | |
| 			MatchCollection matches = Regex.Matches(text, lookFor);
 | |
| 			if (matches.Count == 0) return text;
 | |
| 			string retstr = text;
 | |
| 			for (int i = matches.Count - 1; i >= 0; i--)
 | |
| 			{
 | |
| 				Match m = matches[i];
 | |
| 				// if this transition text already has a hard space, don't add another.
 | |
| 				if (m.Groups[3].Value.Contains("\xA0")) continue;
 | |
| 				// if the transition text does not start with a digit, don't add the hardspace.
 | |
| 				//if (!Char.IsDigit(m.Groups[3].Value[0])) continue;
 | |
| 				if (m != null && m.Groups.Count > 7 && m.Groups[6].ToString().StartsWith("Transition"))
 | |
| 				{
 | |
| 					if (m.Groups[7].Value != "") // && StepTransition(int.Parse(m.Groups[7].Value)))
 | |
| 					{
 | |
| 						System.Text.RegularExpressions.Group g = m.Groups[3];
 | |
| 						string beforeTran = retstr.Substring(0, g.Index);
 | |
| 						string afterTran = retstr.Substring(g.Index + g.Length);
 | |
| 
 | |
| 						// if replacing text in the 'beforeTran' string, then do it here,
 | |
| 						// i.e. there is a format flag 'BeforeTrans' that bolds text before the transition
 | |
| 						// (in wst formats).
 | |
| 						beforeTran = DoBeforeTransFlagSupport(beforeTran, _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.ReplaceStrList);
 | |
| 						string newvalue = g.ToString();
 | |
| 						// if this is a 'step transition' type, i.e. includes a step number, in addition to other replacements,
 | |
| 						// we want to change a space to a hardspace.
 | |
| 						if (StepTransition(int.Parse(m.Groups[7].Value)))
 | |
| 						{
 | |
| 							int indexLastSpace = newvalue.LastIndexOf(' ');
 | |
| 							if (indexLastSpace >= 0)
 | |
| 								// Use a "\x1" as a token to replace later.  Insert the unicode char, whose length is
 | |
| 								// more than 1 character was throwing of the regexp Matches index, so that the resulting
 | |
| 								// string may have been incorrect.
 | |
| 								retstr = beforeTran + (boldTran ? @"\b " : null) + newvalue.Substring(0, indexLastSpace) + "\x1" + newvalue.Substring(indexLastSpace + 1) + (boldTran ? @"\b0" : null) + afterTran;
 | |
| 							else
 | |
| 								if (beforeTran.EndsWith(" "))
 | |
| 									retstr = ReplaceLastSpaceWithHardSpace(beforeTran) + (boldTran ? @"\b " : null) + newvalue + (boldTran ? @"\b0" : null) + afterTran;
 | |
| 								else
 | |
| 									Console.Write("");// Don't know where to put the Hard Space
 | |
| 						}
 | |
| 						else if (boldTran)
 | |
| 						{
 | |
| 							retstr = beforeTran +  @"\b " + newvalue +  @"\b0" + afterTran;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return retstr.Replace("\x1", @"\u160?");
 | |
| 		}
 | |
| 
 | |
| 		private string DoBeforeTransFlagSupport(string beforeTran, ReplaceStrList replaceStrList)
 | |
| 		{
 | |
| 			foreach (ReplaceStr repstr in replaceStrList)
 | |
| 			{
 | |
| 				if ((repstr.Flag & E_ReplaceFlags.BeforeTrans) > 0)
 | |
| 				{
 | |
| 					// the beforeTran string ends with the string that starts the transition comment, i.e.
 | |
| 					// '\\v <START] \\v0 '. The replace word string needs to be before this:
 | |
| 					int indx = beforeTran.LastIndexOf(@"\v <START]\v0");
 | |
| 					if (indx > -1)
 | |
| 					{
 | |
| 						string findit = beforeTran.Substring(0, beforeTran.LastIndexOf(@"\v <START]\v0"));
 | |
| 						if (findit != null && findit.Trim().ToUpper().EndsWith(repstr.ReplaceWord.ToUpper()))
 | |
| 						{
 | |
| 							int rindx = findit.Trim().ToUpper().IndexOf(repstr.ReplaceWord.ToUpper());
 | |
| 							// don't replace string because case of words may be match replace with string.
 | |
| 							beforeTran = findit.Substring(0, rindx) + @"\b " + findit.Substring(rindx) + @"\b0" + beforeTran.Substring(indx);
 | |
| 							return beforeTran;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return beforeTran;
 | |
| 		}
 | |
| 		private string ReplaceLastSpaceWithHardSpace(string str)
 | |
| 		{
 | |
| 			int ind =str.LastIndexOf("<START]");
 | |
| 			ind = str.LastIndexOf(@"\", ind);
 | |
| 			while (ind > 0 && str[ind - 1] != ' ')
 | |
| 			{
 | |
| 				if (ind > 5 && str.Substring(0, ind).EndsWith(@"\u160?") || str.Substring(0, ind).ToLower().EndsWith(@"\'a0"))
 | |
| 					return str;//Already has a Hard Space
 | |
| 				ind = str.LastIndexOf(@"\", ind - 1);
 | |
| 			}
 | |
| 			// If the previous character is a comma or a space then don't add a Hard Space 
 | |
| 			if (ind > 1 && (str[ind - 2] == ',' || str[ind - 2] == ' ')) return str;
 | |
| 			if (ind <= 0) return str;
 | |
| 
 | |
| 			// replace with a 'token' "\x1" instead of a hardspace unicode char.  When using a hardspace unicode
 | |
| 			// char the string length/contents was thrown off so that the calling method's processing was off
 | |
| 			// in terms of regexp matches in string.
 | |
| 			return str.Substring(0, ind - 1) + "\x1" + str.Substring(ind);
 | |
| 		}
 | |
| 		private bool StepTransition(int TransId)
 | |
| 		{
 | |
| 			if (_MyItemInfo == null) return false;
 | |
| 			_MyItemInfo.MyContent.RefreshContentTransitions();
 | |
| 			foreach (TransitionInfo trans in _MyItemInfo.MyContent.ContentTransitions)
 | |
| 				if (trans.TransitionID == TransId)
 | |
| 					return trans.MyItemToID.IsStep;
 | |
| 			return false;
 | |
| 		}
 | |
| 		private string DoFortranFormat(string text)
 | |
| 		{
 | |
| 			if (text.IndexOf(@".E") < 0) return text;
 | |
| 			// Look for text as n.Ey, where n can be null or a number, and y can be 
 | |
| 			// positive or negative.  This translates into nx10x10y where y is 
 | |
| 			// superscripted.  For example, .E3 -> x103 where 3 is superscripted
 | |
| 			// and 10.E5 -> 10x10-5 where 5 is superscripted
 | |
| 			string pat = @"(\d*).E([+-]*\d+)";
 | |
| 			string retstr = text;
 | |
| 			// for each one that needs translated:
 | |
| 			foreach (Match m in Regex.Matches(text, pat))
 | |
| 			{
 | |
| 				string fnum = m.Groups[1].Value;
 | |
| 				string supnum = m.Groups[2].Value;
 | |
| 				string newstr = string.Format(@"{0}x10\up2 {1}\up0 ", fnum, supnum);
 | |
| 				retstr = retstr.Replace(m.Value, newstr);
 | |
| 			}
 | |
| 			return retstr;
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#region SaveData
 | |
| 		public bool Save(RichTextBox rtb)
 | |
| 		{
 | |
| 			//int savSelStart = rtb.SelectionStart;
 | |
| 			try
 | |
| 			{
 | |
| 				//FormatInfo formatInfo = _MyItemInfo.ActiveFormat;
 | |
| 				using (_MyItem = _MyItemInfo.Get())
 | |
| 				{
 | |
| 					// The following was added to support transitions to un-numbered steps
 | |
| 					if (_MyItemInfo.NewTransToUnNumberedItem && rtb.Text.Contains("<NewID>"))
 | |
| 					{
 | |
| 						ItemAnnotation ia = _MyItem.ItemAnnotations.Add(AnnotationType.GetByName("Verification Required"));
 | |
| 						ia.SearchText = "Transition to Un-Numbered Step";
 | |
| 						_MyItemInfo.NewTransToUnNumberedItem = false;
 | |
| 					}
 | |
| 					// check for different text, i.e. text from this itm doesn't match
 | |
| 					// original text, a change occurred in database, but not from this user.
 | |
| 					if (OriginalText != EditText)
 | |
| 					{
 | |
| 						Console.WriteLine("Save Failed because text changed outside of this edit session.");
 | |
| 						return false;
 | |
| 					}
 | |
| 					string modtext = RtfToDbText(rtb.Rtf).Replace("<BackSlash>", "\\\\");
 | |
| 
 | |
| 					// if there are links, we'll need to do extra processing to see if
 | |
| 					// there were additions, deletions or modifications.
 | |
| 					bool haslinks = ((modtext.IndexOf(@"<START]") > -1) || (OriginalText != null && OriginalText != "" && OriginalText.IndexOf(@"<START]") > -1));
 | |
| 					if (haslinks)
 | |
| 					{
 | |
| 						// Get all links in original list
 | |
| 						RtfToDisplayTextElements(OriginalText);
 | |
| 						List<displayLinkElement> origList = GetLinkList(DisplayTextElementList);
 | |
| 						// now get new text into displaytext elements for comparison for links:
 | |
| 						RtfToDisplayTextElements(modtext);
 | |
| 						// Compare ro/transition lists and delete or add any to the item for any ros/transitions that have been
 | |
| 						// added/deleted or modified.
 | |
| 						ProcessRoTranChanges(_MyItem, origList);
 | |
| 						EditText = DteToString();
 | |
| 						// if new transitions/ros, we need to 'fix' the string in the embedded link to contain the
 | |
| 						// transition or usage record.
 | |
| 						Dictionary<int, ContentTransition> ctReplacements = BuildCtReplacements(_MyItem.MyContent.ContentTransitions);
 | |
| 						Dictionary<int, ContentRoUsage> roUsgReplacements = BuildRoUsgReplacements(_MyItem.MyContent.ContentRoUsages);
 | |
| 						_MyItem.DTS = DateTime.Now;
 | |
| 						_MyItem.UserID = Volian.Base.Library.VlnSettings.UserID;
 | |
| 						// Do the Save once rather than multiple times
 | |
| 						_MyItem.Save();
 | |
| 						if (ctReplacements.Count > 0)
 | |
| 						{
 | |
| 							EditText = FixCtReplacements(EditText, ctReplacements);
 | |
| 							// Replace Transition Text
 | |
| 							foreach (ContentTransition ct in ctReplacements.Values)
 | |
| 								using (TransitionInfo tran = TransitionInfo.Get(ct.TransitionID))
 | |
| 									_MyItem.MyContent.FixTransitionText(tran);
 | |
| 							_MyItem.Save();
 | |
| 						}
 | |
| 						if (roUsgReplacements.Count > 0)
 | |
| 						{
 | |
| 							EditText = FixRoUsgReplacements(EditText, roUsgReplacements);
 | |
| 							_MyItem.Save();
 | |
| 						}
 | |
| 						modtext = EditText;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						EditText = modtext;
 | |
| 						foreach (Csla.Validation.BrokenRule br in _MyItem.MyContent.BrokenRulesCollection)
 | |
| 						{
 | |
| 							Console.WriteLine("{0} - {1}", br.Property, br.Description);
 | |
| 						}
 | |
| 						// Don't update the DTS or User for Text Changes
 | |
| 						//_MyItem.DTS = DateTime.Now;
 | |
| 						//_MyItem.UserID = Volian.Base.Library.VlnSettings.UserID;
 | |
| 						_MyItem.Save();
 | |
| 					}
 | |
| 					_MyItem = null;
 | |
| 					OriginalText = modtext;
 | |
| 				}
 | |
| 			}
 | |
| 			catch (Exception ex)
 | |
| 			{
 | |
| 				Console.WriteLine("DisplayText Save Failed with error: {0} - {1}\r\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
 | |
| 				return false;
 | |
| 			}
 | |
| 			//rtb.SelectionStart = savSelStart;
 | |
| 			return true;
 | |
| 		}
 | |
| 		private string DteToString()
 | |
| 		{
 | |
| 			StringBuilder sret = new StringBuilder();
 | |
| 			foreach (displayTextElement vte in DisplayTextElementList)
 | |
| 			{
 | |
| 				if (vte.Type == E_TextElementType.Text || vte.Type == E_TextElementType.Symbol)
 | |
| 					sret.Append(vte.Text);
 | |
| 				else
 | |
| 				{
 | |
| 					displayLinkElement dle = vte as displayLinkElement;
 | |
| 					if (vte != null) sret.Append(dle.TextAndLink);
 | |
| 				}
 | |
| 			}
 | |
| 			string modtext = sret.ToString();
 | |
| 			return modtext;
 | |
| 		}
 | |
| 		private string FixRoUsgReplacements(string p, Dictionary<int, ContentRoUsage> roUsgReplacements)
 | |
| 		{
 | |
| 			foreach (int oldid in roUsgReplacements.Keys)
 | |
| 			{
 | |
| 				p = p.Replace(string.Format("<CROUSGID={0}>", oldid), roUsgReplacements[oldid].ROUsageID.ToString());
 | |
| 			}
 | |
| 			return p;
 | |
| 		}
 | |
| 		private Dictionary<int, ContentRoUsage> BuildRoUsgReplacements(ContentRoUsages contentRoUsages)
 | |
| 		{
 | |
| 			Dictionary<int, ContentRoUsage> retval = new Dictionary<int, ContentRoUsage>();
 | |
| 			foreach (ContentRoUsage rou in contentRoUsages)
 | |
| 			{
 | |
| 				if (rou.ROUsageID < 0) retval.Add(rou.ROUsageID, rou);
 | |
| 			}
 | |
| 			return retval;
 | |
| 		}
 | |
| 		private string FixCtReplacements(string p, Dictionary<int, ContentTransition> ctReplacements)
 | |
| 		{
 | |
| 			foreach (int oldid in ctReplacements.Keys)
 | |
| 			{
 | |
| 				p = p.Replace(string.Format("<CTID={0}>",oldid),ctReplacements[oldid].TransitionID.ToString()); 
 | |
| 			}
 | |
| 			return p;
 | |
| 		}
 | |
| 		private Dictionary<int, ContentTransition> BuildCtReplacements(ContentTransitions contentTransitions)
 | |
| 		{
 | |
| 			Dictionary<int, ContentTransition> retval = new Dictionary<int, ContentTransition>();
 | |
| 			foreach (ContentTransition ct in contentTransitions)
 | |
| 			{
 | |
| 				if (ct.TransitionID < 0) retval.Add(ct.TransitionID, ct);
 | |
| 			}
 | |
| 			return retval;
 | |
| 		}
 | |
| 		private void ProcessRoTranChanges(Item itm, List<displayLinkElement> origList)
 | |
| 		{
 | |
| 			// go through list.  Note that only linked items are in the origList.
 | |
| 			//	1)	delete any that are in origList but not in the DisplayTextElementList
 | |
| 			//		(that represents the current text & links)
 | |
| 			//	2)	add any that are only in DisplayTextElementList
 | |
| 			//	3)	delete/add for modify?
 | |
| 
 | |
| 			// delete first - if in original, but not in current list, delete the one
 | |
| 			// in the original list.
 | |
| 			foreach (displayLinkElement odte in origList)
 | |
| 			{
 | |
| 				bool found = false;
 | |
| 				foreach (displayTextElement dte in DisplayTextElementList)
 | |
| 				{
 | |
| 					if (dte.Type == odte.Type)
 | |
| 					{
 | |
| 						displayLinkElement l_dte = (displayLinkElement)dte;
 | |
| 						if (odte.Link == l_dte.Link)
 | |
| 						{
 | |
| 							found = true;
 | |
| 							break;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				// remove the link element from the item.
 | |
| 				if (!found)
 | |
| 				{
 | |
| 					// Get record id for ro or trans and then find the associated ro or transition
 | |
| 					// in the item's list. remove it.
 | |
| 					int recid = -1;
 | |
| 					if (odte.Type != E_TextElementType.ReferencedObject)
 | |
| 					{
 | |
| 						int sp = odte.Link.IndexOf(" ") + 1;   // get past tran type
 | |
| 						string srecid = odte.Link.Substring(sp, odte.Link.IndexOf(" ", sp) - sp);
 | |
| 						recid = System.Convert.ToInt32(srecid);
 | |
| 						foreach (ContentTransition ct in itm.MyContent.ContentTransitions)
 | |
| 						{
 | |
| 							if (ct.TransitionID == recid)
 | |
| 							{
 | |
| 								itm.MyContent.ContentTransitions.Remove(ct);
 | |
| 								break;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						int sp = odte.Link.IndexOf(" "); 
 | |
| 						//rousageid starts after "ReferencedObject:", i.e. index in link of 17
 | |
| 						string srecid = odte.Link.Substring(17, sp-17);
 | |
| 						recid = System.Convert.ToInt32(srecid);
 | |
| 						foreach (ContentRoUsage cr in itm.MyContent.ContentRoUsages)
 | |
| 						{
 | |
| 							if (cr.ROUsageID == recid)
 | |
| 							{
 | |
| 								itm.MyContent.ContentRoUsages.Remove(cr);
 | |
| 								break;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			// now do insert, i.e. in new list, but not in old.
 | |
| 			foreach (displayTextElement dte in DisplayTextElementList)
 | |
| 			{
 | |
| 				bool found = false;
 | |
| 				if (dte.Type == E_TextElementType.ReferencedObject || dte.Type == E_TextElementType.Transition || dte.Type == E_TextElementType.TransitionRange)
 | |
| 				{
 | |
| 					foreach (displayLinkElement odte in origList)
 | |
| 					{
 | |
| 						if (dte.Type == odte.Type)
 | |
| 						{
 | |
| 							// if the link is the same, it exists, so no action is required.
 | |
| 							displayLinkElement l_dte = (displayLinkElement)dte;
 | |
| 							if (odte.Link == l_dte.Link)
 | |
| 							{
 | |
| 								found = true;
 | |
| 								break;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 					// Insert the link (ro or transition) to the item
 | |
| 					if (!found)
 | |
| 					{
 | |
| 						if (dte.Type == E_TextElementType.ReferencedObject)  // do ro
 | |
| 						{
 | |
| 							displayLinkElement l_dte = (displayLinkElement)dte;
 | |
| 							Match m = Regex.Match(l_dte.Link, "([A-Za-z]*):(.*)");
 | |
| 							string linkstr = m.Groups[2].Value;
 | |
| 							string[] roparts = linkstr.Split(" ".ToCharArray());
 | |
| 							ContentRoUsage rousg = null;
 | |
| 							using (RODb rodb = RODb.GetJustRoDb(Convert.ToInt32(roparts[2])))
 | |
| 							{
 | |
| 								rousg = itm.MyContent.ContentRoUsages.Add(roparts[1], rodb);
 | |
| 							}
 | |
| 							l_dte.Link = l_dte.Link.Replace("<NewID>", string.Format("<CROUSGID={0}>", rousg.ROUsageID));
 | |
| 							l_dte.TextAndLink = l_dte.TextAndLink.Replace("<NewID>", string.Format("<CROUSGID={0}>", rousg.ROUsageID));
 | |
| 							break; 
 | |
| 						}
 | |
| 						else if (dte.Type == E_TextElementType.TransitionRange || dte.Type == E_TextElementType.Transition)
 | |
| 						{
 | |
| 							displayLinkElement l_dte = (displayLinkElement)dte;
 | |
| 							Match m = Regex.Match(l_dte.Link, "([A-Za-z]*):(.*)");
 | |
| 							string linkstr = m.Groups[2].Value;
 | |
| 							string[] tparts = linkstr.Split(" ".ToCharArray());
 | |
| 							int type = System.Convert.ToInt32(tparts[0]);
 | |
| 							int tr1 = System.Convert.ToInt32(tparts[2]);		// tparts[2] is token for tranid
 | |
| 							int tr2 = tr1;
 | |
| 							if(tparts.Length > 3)
 | |
| 								tr2 = System.Convert.ToInt32(tparts[3]);		// tparts[3] is token for rangeid
 | |
| 							bool dispose1 = false;
 | |
| 							Item itm1 = null;
 | |
| 							bool dispose2 = false;
 | |
| 							Item itm2 = null;
 | |
| 							if (itm.ItemID == tr1)
 | |
| 								itm1 = itm;  // a transition that points to itself should not dispose
 | |
| 							else
 | |
| 							{
 | |
| 								dispose1 = true;
 | |
| 								itm1 = Item.Get(tr1);
 | |
| 							}
 | |
| 							if (itm.ItemID == tr2)
 | |
| 								itm2 = itm;  // a transition that points to itself should not dispose
 | |
| 							else if (tr1 == tr2)
 | |
| 								itm2 = itm1; // if both destinations are the same only dispose the first one
 | |
| 							else
 | |
| 							{
 | |
| 								dispose2 = true;
 | |
| 								itm2 = Item.Get(tr2);
 | |
| 							}
 | |
| 							ContentTransition ct = itm.MyContent.ContentTransitions.Add(itm1, itm2);
 | |
| 							//Console.WriteLine("CT {0},{1},{2},{3}", ct.TransitionID, itm.ItemID, itm.MyContent.MyContentUnique, itm.MyContent.ContentTransitions.Count);
 | |
| 							ct.TranType = type;
 | |
| 							if (dte.Type == E_TextElementType.Transition)
 | |
| 								ct.IsRange = 0;
 | |
| 							else if (tr1 != tr2)
 | |
| 								ct.IsRange = 1;
 | |
| 							else
 | |
| 								ct.IsRange = 2;
 | |
| 							l_dte.Link = l_dte.Link.Replace("<NewID>", string.Format("<CTID={0}>", ct.TransitionID));
 | |
| 							l_dte.TextAndLink = l_dte.TextAndLink.Replace("<NewID>", string.Format("<CTID={0}>", ct.TransitionID));
 | |
| 							if (dispose2) itm2.Dispose();
 | |
| 							if (dispose1) itm1.Dispose();
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		private List<displayLinkElement> GetLinkList(List<displayTextElement> locDisplayTextElementList)
 | |
| 		{
 | |
| 			List<displayLinkElement> retList = new List<displayLinkElement>();
 | |
| 			foreach (displayTextElement vte in locDisplayTextElementList)
 | |
| 			{
 | |
| 				if (vte.Type == E_TextElementType.ReferencedObject || vte.Type == E_TextElementType.TransitionRange || vte.Type == E_TextElementType.Transition)
 | |
| 				{
 | |
| 					displayLinkElement tmp = (displayLinkElement)vte;
 | |
| 					displayLinkElement copy_vte = new displayLinkElement();
 | |
| 					copy_vte.Type = tmp.Type;
 | |
| 					copy_vte.Link = tmp.Link;
 | |
| 					copy_vte.Text = tmp.Text;
 | |
| 					retList.Add(copy_vte);
 | |
| 				}
 | |
| 			}
 | |
| 			return retList;
 | |
| 		}
 | |
| 		private void RtfToDisplayTextElements(string text)
 | |
| 		{
 | |
| 			// get original text into displaytext elements for comparison for links:
 | |
| 			if (DisplayTextElementList == null)
 | |
| 				DisplayTextElementList = new List<displayTextElement>();
 | |
| 			else
 | |
| 				DisplayTextElementList.Clear();
 | |
| 
 | |
| 			if (text == null || text == "") return;
 | |
| 
 | |
| 			string noExtraRtfStr = text;
 | |
| 			
 | |
| 			int startIndex = 0;
 | |
| 			int index = -1;
 | |
| 			noExtraRtfStr = noExtraRtfStr.Replace(@"><", @">\v0 \v <");
 | |
| 			while ((index = FindTokenChar(noExtraRtfStr, startIndex)) > -1)
 | |
| 			{
 | |
| 				// Do any 'plain' text that preceeds the token.
 | |
| 				if (index > startIndex) DoTextElement(noExtraRtfStr, startIndex, index);
 | |
| 
 | |
| 				if (noExtraRtfStr[index + 1] == 'v')
 | |
| 					index = DoLink(noExtraRtfStr, index);
 | |
| 				else
 | |
| 					index = DoSymbol(noExtraRtfStr, startIndex, index);
 | |
| 				startIndex = index; // +1;
 | |
| 				if (startIndex >= noExtraRtfStr.Length) break;
 | |
| 			}
 | |
| 			// Add any remaining text.
 | |
| 			if (startIndex < noExtraRtfStr.Length) DoTextElement(noExtraRtfStr, startIndex, index);
 | |
| 		}
 | |
| 		private string RtfToDbText(string text)
 | |
| 		{
 | |
| 			// For hardspaces, the windows richtextbox does some 'quirky' things:
 | |
| 			// A unicode representation of \u160? is sent INTO the rtb.  Coming out, 
 | |
| 			// that \u160? was translated to a \~ (by the underlying windows rtb).
 | |
| 			// Note that if the \~ is sent to the rtb, it is treated as a regular space,
 | |
| 			// i.e. no longer a hardspace, and actually is converted to a regular space.
 | |
| 			// SO, on the way out, convert any \~ to \u160?
 | |
| 			string noExtraRtfStr = text.Replace(@"\~", @"\u160?");
 | |
| 			noExtraRtfStr = noExtraRtfStr.Replace(@"\'a0", @"\u160?");
 | |
| 
 | |
| 			// Check for two links in a row & if found, add separating rtf comment 
 | |
| 			// commands (these get removed in the richtextbox:
 | |
| 			// RHM 20100303 Not sure why this is here.  The RichTextBox will always remove it.
 | |
| 			//noExtraRtfStr = noExtraRtfStr.Replace(@"[END><START]", @"[END>\v0 \v <START]");
 | |
| 
 | |
| 			// GetFontTable returns a non-negative number font number in the
 | |
| 			// font table for the unicode font, if it is used (otherwise -1)
 | |
| 			//int unicodeFont = GetFontTable(rtb.Rtf);
 | |
| 
 | |
| 			// strip off all rtf commands...
 | |
| 			noExtraRtfStr = StripRtfCommands(noExtraRtfStr);
 | |
| 
 | |
| 			// the indent character was translated in the richtextbox, change it back:
 | |
| 			if (noExtraRtfStr.IndexOf(@"\'05") > -1) noExtraRtfStr = noExtraRtfStr.Replace(@"\'05", "\x05");
 | |
| 
 | |
| 			return noExtraRtfStr;
 | |
| 		}
 | |
| 		public static string StaticReplaceRTFClause(Match m)
 | |
| 		{
 | |
| 			try
 | |
| 			{
 | |
| 				string token = m.Groups[1].Value;
 | |
| 				switch (token[1])
 | |
| 				{
 | |
| 					case '\\':
 | |
| 						return token;
 | |
| 					case 'u':
 | |
| 						if (Regex.IsMatch(token, @"^\\u[0-9]+$"))
 | |
| 							return token; // Special Charcaters
 | |
| 						if (Regex.IsMatch(token, @"^\\ulnone ?$"))
 | |
| 							return token;
 | |
| 						if (Regex.IsMatch(token, @"^\\ul.*$"))
 | |
| 							return token; // Underline
 | |
| 						if (Regex.IsMatch(token, @"^\\up[0-9] ?$"))
 | |
| 							return token; // shift up (superscript)
 | |
| 						break;
 | |
| 					case 'd':
 | |
| 						if (Regex.IsMatch(token, @"^\\dn[0-9] ?$"))
 | |
| 							return token; // shift down (subscript)
 | |
| 						break;
 | |
| 					case '\'': // Special Character
 | |
| 						return token;
 | |
| 					case 'b': // Bold
 | |
| 						return token;
 | |
| 					case 'i': // Italics
 | |
| 						return token;
 | |
| 					case '{': // look for escape for curly braces:
 | |
| 						return token;
 | |
| 					case '}':
 | |
| 						return token;
 | |
| 					case 'v': // save link hidden info
 | |
| 						if (Regex.IsMatch(token, @"^\\v0? ?$")) return token;	// comment part of link
 | |
| 						// end comment may end in space or may end in '\' if another rtf command,
 | |
| 						// or may end at end of string.  First check for space, keep it in string
 | |
| 						// if it is there.
 | |
| 						//if (Regex.IsMatch(token, @"\\v0 "))
 | |
| 						//    return token;
 | |
| 						//if (Regex.IsMatch(token, @"\\v0"))
 | |
| 						//    return token;
 | |
| 						break;
 | |
| 					case 'l':
 | |
| 						if (Regex.IsMatch(token, @"^\\line ?$")) return token;
 | |
| 						break;
 | |
| 					case 'p':
 | |
| 						if (Regex.IsMatch(token, @"^\\par ?$")) return "\r\n";
 | |
| 						//if (token == @"\protect")
 | |
| 						//    return token;
 | |
| 						//if (token == @"\protect0")
 | |
| 						//    return token;
 | |
| 						//if (token.Length >= 6 && token.Substring(0, 6) == "\\par\r\n") return token.Replace("\r\n", " ");
 | |
| 						break;
 | |
| 					//case 'f':   // handle fonts separately because they may or may not have a space after them
 | |
| 					//    if (token[2] >= '0' && token[2] <= '9') return token;
 | |
| 					//    break;
 | |
| 				}
 | |
| 			}
 | |
| 			catch (Exception ex)
 | |
| 			{
 | |
| 				Console.WriteLine("StaticReplaceRTFClause {0} - {1}", ex.GetType().Name, ex.Message);
 | |
| 			}
 | |
| 			return "";//Strip All
 | |
| 		}
 | |
| 		public string StripRtfCommands(string rtf)
 | |
| 		{
 | |
| 			// replace \{ & \} with (![ & (!] respectively and then redo at end.  The curly braces
 | |
| 			// are rtf so were getting removed and/or not handled correctly.
 | |
| 			string retval = rtf.Replace(@"\{", @"(![");
 | |
| 			retval = retval.Replace(@"\}", @"(!]");
 | |
| 
 | |
| 			// remove carriage return/newlines after \par commands (these are introduced by rtb
 | |
| 			// for hard returns, goes into rtb as \par and comes out as \par\r\n):
 | |
| 			retval = Regex.Replace(retval, @"\\par\r\n(?!\\)", "\\par ");
 | |
| 			retval = Regex.Replace(retval, @"[\r\n]", "", RegexOptions.Singleline); // Strip Carriage Returns and Newlines
 | |
| 			retval = Regex.Replace(retval, @"^\{(.*)\}$", "$1", RegexOptions.Singleline); // Strip Opening and Closing Braces
 | |
| 			retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
 | |
| 			retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
 | |
| 			retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+)(?=\\)", "$1 ");  // add space after token if followed by token
 | |
| 			retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+ )", new MatchEvaluator(StaticReplaceRTFClause));  // take backslash xyz and evaluates them
 | |
| 			retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+) (?=\\)", "$1");  // remove space between tokens
 | |
| 			retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+) (?=\r\n)", "$1");  // remove space before /r/n
 | |
| 			// remove \r\n at end of string if the string has 2 or more characters
 | |
| 			if (retval.EndsWith("\r\n")) retval = retval.Remove(retval.Length - 2, 2);
 | |
| 			if (retval.Length == 0) return "";
 | |
| 			if (retval.EndsWith(@"\v")) retval = retval.Remove(retval.Length - 2, 2);
 | |
| 			retval = _MyItemInfo.RemoveRtfStyles(retval); // RemoveRtfStyles(retval);
 | |
| 			retval = retval.Replace(@"(![", @"\{");
 | |
| 			retval = retval.Replace(@"(!]", @"\}");
 | |
| 			retval = retval.TrimEnd(' ');
 | |
| 			return retval;
 | |
| 		}
 | |
| 		// This is used in the DataLoader
 | |
| 		public static string StaticStripRtfCommands(string rtf)
 | |
| 		{
 | |
| 			// replace \{ & \} with (![ & (!] respectively and then redo at end.  The curly braces
 | |
| 			// are rtf so were getting removed and/or not handled correctly.
 | |
| 			string retval = rtf.Replace(@"\{", @"(![");
 | |
| 			retval = retval.Replace(@"\}", @"(!]");
 | |
| 
 | |
| 			// For hardspaces, the windows richtextbox does some 'quirky' things:
 | |
| 			// A unicode representation of \u160? is sent INTO the rtb.  Coming out, 
 | |
| 			// that \u160? was translated to a \~ (by the underlying windows rtb).
 | |
| 			// Note that if the \~ is sent to the rtb, it is treated as a regular space,
 | |
| 			// i.e. no longer a hardspace, and actually is converted to a regular space.
 | |
| 			// SO, on the way out, convert any \~ to \u160?
 | |
| 			retval = retval.Replace(@"\~", @"\u160?");
 | |
| 
 | |
| 			// remove carriage return/newlines after \par commands (these are introduced by rtb
 | |
| 			// for hard returns, goes into rtb as \par and comes out as \par\r\n):
 | |
| 			retval = Regex.Replace(retval, @"\\par\r\n(?!\\)", "\\par ");
 | |
| 			//retval = Regex.Replace(retval, @"\\par\r\n(?=\\)", "\\par");
 | |
| 
 | |
| 			retval = Regex.Replace(retval, @"[\r\n]", "", RegexOptions.Singleline); // Strip Carriage Returns and Newlines
 | |
| 			retval = Regex.Replace(retval, @"^\{(.*)\}$", "$1", RegexOptions.Singleline); // Strip Opening and Closing Braces
 | |
| 			retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
 | |
| 			retval = Regex.Replace(retval, @"\{[^{]*?\}", "", RegexOptions.Singleline); // Strip Clauses - remove anything from curly braces
 | |
| 			//retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+)\\f[0-9] ", "$1 ");	// remove font command - if next to another command, keep other command and space
 | |
| 			// OLD:  The following two lines are replaced by the more generic replace above.
 | |
| 			//retval = Regex.Replace(retval, @"\\v\\f[0-9] ", "\\v ");	// remove font command - if next to Comment keep space
 | |
| 			//retval = Regex.Replace(retval, @"\\line\\f[0-9] ", "\\line ");	// remove font command - if next to Line keep space
 | |
| 			//retval = Regex.Replace(retval, @"\\f[0-9] ", "");	// remove font command with ending space
 | |
| 			//retval = Regex.Replace(retval, @"\\f[0-9]", "");	// remove font command without ending space
 | |
| 			//retval = Regex.Replace(retval, @"\\par ", "\r\n");
 | |
| 			retval = Regex.Replace(retval, @"(\\[^' \\?\r\n\t]+)(?=\\)", "$1 ");  // add space after token if followed by token
 | |
| 			//retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+)(\\)", "$1 $2");  // take backslash xyz and evaluates them
 | |
| 			retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+ )", new MatchEvaluator(StaticReplaceRTFClause));  // take backslash xyz and evaluates them
 | |
| 			retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+) (?=\\)", "$1");  // remove space between tokens
 | |
| 			retval = Regex.Replace(retval, @"(\\[^ \\?\r\n\t]+) (?=\r\n)", "$1");  // remove space before /r/n
 | |
| 			// remove a space if there is one as the first character or the last character
 | |
| 			//if (retval[0] == ' ') retval = retval.Remove(0, 1);
 | |
| 			//retval = retval.TrimEnd(' ');
 | |
| 			// remove \r\n at end of string if the string has 2 or more characters
 | |
| 			if (retval.Length > 1 && retval.Substring(retval.Length - 2, 2) == "\r\n") retval = retval.Remove(retval.Length - 2, 2);
 | |
| 			// remove \par at end of string if the string has 4 or more characters
 | |
| 			//if (retval.Length > 3 && retval.Substring(retval.Length - 4, 4) == @"\par") retval = retval.Remove(retval.Length - 4, 4);
 | |
| 			// remove a space following \r\n
 | |
| 			//retval = Regex.Replace(retval, "\r\n ", "\r\n");
 | |
| 			////if there are still spaces following \r\n, then probable in a table - we need to put the space back
 | |
| 			//retval = Regex.Replace(retval, "\r\n ", "\r\n  ");
 | |
| 
 | |
| 			if (retval.Length == 0) return "";
 | |
| 			if (retval.Length > 1 && retval.Substring(retval.Length - 2, 2) == @"\v") retval = retval.Remove(retval.Length - 2, 2);
 | |
| 			//retval = RemoveRtfStyles(retval);
 | |
| 			//if (itmInfo != null)
 | |
| 			//    retval = StaticRemoveRtfStyles(retval, itmInfo);
 | |
| 
 | |
| 			retval = retval.Replace(@"(![", @"\{");
 | |
| 			retval = retval.Replace(@"(!]", @"\}");
 | |
| 			retval = retval.TrimEnd(' ');
 | |
| 
 | |
| 			// the indent character was translated in the richtextbox, change it back:
 | |
| 			if (retval.IndexOf(@"\'05") > -1) retval = retval.Replace(@"\'05", "\x05");
 | |
| 			return retval;
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#region StyleData
 | |
| 		//private VE_Font GetItemFont()
 | |
| 		//{
 | |
| 		//    VE_Font font = null;
 | |
| 		//    FormatInfo format = _MyItemInfo.ActiveFormat;
 | |
| 		//    int type = (int)_MyItemInfo.MyContent.Type;
 | |
| 		//    switch (type/10000)
 | |
| 		//    {
 | |
| 		//        case 0:	// procedure
 | |
| 		//            font = format.PlantFormat.FormatData.Font;
 | |
| 		//            break;
 | |
| 		//        case 1: // section
 | |
| 		//            font = format.PlantFormat.FormatData.SectData.SectionHeader.Font;
 | |
| 		//            break;
 | |
| 		//        case 2: // step types
 | |
| 		//            int typindx = type - 20000;  // what to do for other types rather than steps
 | |
| 		//            font = format.PlantFormat.FormatData.StepDataList[typindx].Font;
 | |
| 		//            break;
 | |
| 		//    }
 | |
| 		//    TextFont = font;
 | |
| 		//    return font;
 | |
| 		//}
 | |
| 		#endregion
 | |
| 		#region DoListElements
 | |
| 		private int FindTokenChar(string txt, int startIndex)
 | |
| 		{
 | |
| 			// 'tokens' are for symbols and links (ro & transitions).  symbols are represented by \u<num>
 | |
| 			// and links are represented by \v <START]\v0 'link text'\v #'link info'[END>\v0
 | |
| 			bool done = false;
 | |
| 			while (!done)
 | |
| 			{
 | |
| 				int indx = txt.IndexOf('\\', startIndex);
 | |
| 				if (indx < 0) return indx;
 | |
| 				// see if symbol (but not underline) or another rtf command: has a 'u' 
 | |
| 				// followed by a non-underline or single quote, and if so, return it.  
 | |
| 				if (((txt[indx + 1] == 'u' && txt[indx + 2] != 'l' && txt[indx + 2] !='p')) || (txt[indx + 1] == '\'')) return indx;
 | |
| 				// see if link
 | |
| 				if (txt[indx + 1] == 'v') return indx;  //TODO - should have <START here too!
 | |
| 				// Otherwise, get next index, must have been a slash or other rtf command.
 | |
| 				startIndex = indx + 1;
 | |
| 			}
 | |
| 			return -1;
 | |
| 		}
 | |
| 		private int DoTextElement(string text, int startIndex, int index)
 | |
| 		{
 | |
| 			displayTextElement vte = new displayTextElement();
 | |
| 			vte.Type = E_TextElementType.Text;
 | |
| 			int len = (index == -1) ? text.Length - startIndex : index - startIndex;
 | |
| 			vte.Text = text.Substring(startIndex, len);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			return index+1;
 | |
| 		}
 | |
| 		private int DoLink(string text, int startIndex)
 | |
| 		{
 | |
| 			int retval = -1;
 | |
| 			int fnd = text.IndexOf("#Link:", startIndex);
 | |
| 			if (text.Substring(fnd + 6, 3) == "Ref")
 | |
| 				retval = DoRO(text, startIndex);
 | |
| 			else
 | |
| 				retval = DoTran(text, startIndex);
 | |
| 			return retval;
 | |
| 		}
 | |
| 		private int DoRO(string text, int index)
 | |
| 		{
 | |
| 			displayLinkElement vte = new displayLinkElement();
 | |
| 			vte.Type = E_TextElementType.ReferencedObject;
 | |
| 			return DoLinkElements(text, index, vte);
 | |
| 		}
 | |
| 		private string FixTransition(string link, string text)
 | |
| 		{
 | |
| 			if (link.IndexOf("<NewID>") != -1) return text;
 | |
| 			int transitionID = Convert.ToInt32(link.Split(" ".ToCharArray())[1]);
 | |
| 			// Find the transition
 | |
| 			if (_MyItemInfo.MyContent.ContentTransitionCount <= 0)
 | |
| 			{
 | |
| 				// TODO:  RHM 20100310
 | |
| 				_MyItemInfo.MyContent.RefreshContentTransitions();
 | |
| 				if (_MyItemInfo.MyContent.ContentTransitionCount <= 0) 
 | |
| 					return "*Resolved Transition Text*";
 | |
| 			}
 | |
| 			foreach (TransitionInfo ti in _MyItemInfo.MyContent.ContentTransitions)
 | |
| 			{
 | |
| 				if (ti.TransitionID == transitionID)
 | |
| 				{
 | |
| 					string path = ti.ResolvePathTo(_MyFormat, _MyItemInfo, ti.TranType, ti.MyItemToID, ti.MyItemRangeID);
 | |
| 					return path;
 | |
| 				}
 | |
| 			}
 | |
| 			return text;
 | |
| 		}
 | |
| 		private int DoTran(string text,int index)
 | |
| 		{
 | |
| 			displayLinkElement vte = new displayLinkElement();
 | |
| 			
 | |
| 			// determine if Range by checking for "R" after Transition (otherwise ":")
 | |
| 			int linkindx = text.IndexOf(@"#Link", index);
 | |
| 			vte.Type =  (text[linkindx+16]=='R')?E_TextElementType.TransitionRange:E_TextElementType.Transition;
 | |
| 			return  DoLinkElements(text, index, vte);
 | |
| 		}
 | |
| 
 | |
| 		//private int GetLastLower(string stepText)
 | |
| 		//{
 | |
| 		//     // TO DO: need to check AlwaysUpperCase format setting - this was not yet converted as of 17Jun2010
 | |
| 		//     //     if (AlwaysUpperCase[steptype]) return (stepText.Length-1);
 | |
| 
 | |
| 		//    int idx = stepText.Length - 1;
 | |
| 		//    while (idx >= 0 && !(char.IsLower(stepText[idx]) && stepText[idx] != 's')) idx--;
 | |
| 		//    if (idx < 0) idx = stepText.Length - 1; // entire string is uppercased set return value to end of string
 | |
| 		//    return idx;
 | |
| 		//}
 | |
| 
 | |
| 		//private bool IsSpaceOrHardSpace(char ch)
 | |
| 		//{
 | |
| 		//    string spaces = @" \u160?";
 | |
| 		//    return (spaces.IndexOf(ch) >= 0);
 | |
| 		//}
 | |
| 		private string DoROFormatFlags(string roText, string beforeRO, string afterRO)
 | |
| 		{
 | |
| 			string rtnstr = roText;
 | |
| 			// The RO text is being changed to match it's context.  Since it is changed in reverse order, the text before the RO
 | |
| 			// should ignore other RO text.
 | |
| 			beforeRO = Regex.Replace(beforeRO, @"(\\[^v \\]+)*\\v0[^v\\]*\\v(\\[^v \\]+)* #Link:Refer", ""); // Remove any RO Values.
 | |
| 			beforeRO = Regex.Replace(beforeRO, @"(\\[^v \\]+)*\\v(\\[^v \\]+)* .*?\\v0(\\[^v \\]+)*( |$)", ""); // Remove Comments
 | |
| 			afterRO = Regex.Replace(afterRO, @"(\\[^v \\]+)*\\v(\\[^v \\]+)* .*?\\v0(\\[^v \\]+)*( |$)", ""); // Remove Comments
 | |
| 
 | |
| 			// Underline all ROs, values and Units
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UnderlineRo)
 | |
| 			{
 | |
| 				// TO DO: Need to check if step text is already underlined
 | |
| 				rtnstr = @"\ul " + rtnstr + @"\ulnone ";
 | |
| 			}
 | |
| 
 | |
| 			// UpcaseAllRoUnits - Uppercases ALL ROs units everywhere.
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpcaseAllRoUnits)
 | |
| 				return UpperCaseUnits(rtnstr);
 | |
| 
 | |
| 			//Forces the units for a RO to be uppercased for high level steps
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapHighRo &&_MyItemInfo.IsHigh)
 | |
| 				return UpperCaseUnits(rtnstr);
 | |
| 
 | |
| 			// Caps ROs anywhere if no lower case text follows 
 | |
| 			// and an upper case letter immediately precedes the RO.
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapRoIfLastLower && !Regex.IsMatch(afterRO,"[a-z]") && char.IsUpper(LastAlpha(beforeRO)))
 | |
| 			{
 | |
| 				//int indx = startLinkText - 1;
 | |
| 				//int indx2 = endLinkText + 1;
 | |
| 				//while (indx > 0 && !IsSpaceOrHardSpace(stepText[indx])) indx--; // find character before RO
 | |
| 				//while (indx2 <= stepText.Length && !IsSpaceOrHardSpace(stepText[indx2])) indx2++; // find character after RO
 | |
| 				
 | |
| 				//if (indx >= 0 && char.IsUpper(stepText[indx]) && indx2 > GetLastLower(stepText))
 | |
| 				//    doUpCase = true;
 | |
| 				return UpperCaseUnits(rtnstr);
 | |
| 			}
 | |
| 
 | |
| 			// If a RO follows a "- " then it will be uppercased
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpRoAftrDash && Regex.IsMatch(beforeRO, @".*\\u8209\?( |\\u160\?)$"))
 | |
| 			{
 | |
| 				//int indx = startLinkText - 1;
 | |
| 				//while (indx > 0 && !IsSpaceOrHardSpace(stepText[indx])) indx--; // find character before RO
 | |
| 				//string prefix = indx >= 7?stepText.Substring(indx-7,8):"";
 | |
| 				//doUpCase = (prefix == @"\u8209? "); // Dash character before RO
 | |
| 				return UpperCaseUnits(rtnstr);
 | |
| 			}
 | |
| 
 | |
| 			// Uppercase the RO Unit if the previous letter is uppercase
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.UpRoIfPrevUpper && char.IsUpper(LastAlpha(beforeRO)))
 | |
| 			{
 | |
| 				//doUpCase = (char.IsUpper(stepText[startLinkText - 1]));
 | |
| 				return UpperCaseUnits(rtnstr);
 | |
| 
 | |
| 			}
 | |
| 
 | |
| 			//CapFirstLetterInHighRO - Cap only the first letters of the units in a high level RO
 | |
| 			// note: used in FLP (Turkey Point) format
 | |
| 			if (_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.CapFirstLetterInHighRO && _MyItemInfo.IsHigh)
 | |
| 			{
 | |
| 				int idx = 0;
 | |
| 				string tstr = "";
 | |
| 				while (idx < rtnstr.Length && !char.IsLetter(rtnstr[idx])) tstr += rtnstr[idx++].ToString();
 | |
| 				if (idx < rtnstr.Length)
 | |
| 				{
 | |
| 					tstr += char.ToUpper(rtnstr[idx]).ToString();
 | |
| 					if (idx + 1 < rtnstr.Length)
 | |
| 						tstr += rtnstr.Substring(idx + 1);
 | |
| 				}
 | |
| 				rtnstr = tstr;
 | |
| 			}
 | |
| 
 | |
| 			//In a sequence of RO values, the unit appears with every value 
 | |
| 			//(e.g., "25 gpm and 30 gpm" vs. "25 and 30 gpm")
 | |
| 			//if (!_MyItemInfo.ActiveFormat.PlantFormat.FormatData.ROData.AllUnits)
 | |
| 			//{
 | |
| 			//    int idx = rtnstr.LastIndexOf(' ');
 | |
| 			//    if (idx > 0)
 | |
| 			//    {
 | |
| 			//        StringBuilder sb = new StringBuilder();
 | |
| 			//        string lastunit = rtnstr.Substring(idx); // RO unit including preceeding space
 | |
| 			//        int idx2 = rtnstr.IndexOf(lastunit);
 | |
| 			//        int si = 0;
 | |
| 			//        while (idx2 < idx)
 | |
| 			//        {
 | |
| 			//            sb.Append(rtnstr.Substring(si, idx2 - si));
 | |
| 			//            si = idx2 + lastunit.Length;
 | |
| 			//            idx2 = rtnstr.IndexOf(lastunit, si);
 | |
| 			//        }
 | |
| 			//        sb.Append(rtnstr.Substring(si));
 | |
| 			//        rtnstr = sb.ToString();
 | |
| 			//    }
 | |
| 			//}
 | |
| 
 | |
| 			return rtnstr;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Uppercase alphabetical strings excluding any RTF token
 | |
| 		/// </summary>
 | |
| 		/// <param name="match"></param>
 | |
| 		/// <returns></returns>
 | |
| 		private string MatchEvaluatorUppercaseROUnits(Match match)
 | |
| 		{
 | |
| 			if (match.Value[0] == '\\') // If the previous character is a backslash then this is an RTF token
 | |
| 				return match.Value;
 | |
| 			return match.Value.ToUpper();
 | |
| 		}
 | |
| 		Regex _RegExUppercaseROUnits = new Regex("(^|[^a-zA-Z])[a-zA-Z]+");
 | |
| 		private string UpperCaseUnits(string rtnstr)
 | |
| 		{
 | |
| 			// Uppercase Units
 | |
| 			rtnstr = _RegExUppercaseROUnits.Replace(rtnstr, new MatchEvaluator(MatchEvaluatorUppercaseROUnits));
 | |
| 			// After converting the value to uppercase, change X10 to x10 to handle Fortran Formatted numbers
 | |
| 			return rtnstr.Replace("X10", "x10");
 | |
| 		}
 | |
| 
 | |
| 		// Find the last Alphabetical character
 | |
| 		private char LastAlpha(string beforeRO)
 | |
| 		{
 | |
| 			Match m = Regex.Match(beforeRO, ".*([a-zA-Z])[^a-zA-Z]*");
 | |
| 			if (m.Success) return m.Groups[1].ToString()[0];
 | |
| 			return '\0';
 | |
| 		}
 | |
| 
 | |
| 		private int DoLinkElements(string text, int index, displayLinkElement vte)
 | |
| 		{
 | |
| 			// Find the 'end comment' for this <START], can't count characters
 | |
| 			// because there may be formatting characters such as \b or \ul before
 | |
| 			// the \v0
 | |
| 			int linkIndx = text.IndexOf(@"#Link", index);
 | |
| 			int endStartTknIndx = text.IndexOf(@"\v0 ", index);
 | |
| 			if (endStartTknIndx == -1)
 | |
| 				endStartTknIndx = text.IndexOf(@"\v0", index);
 | |
| 			int endTextIndx = text.IndexOf(@"\v ", endStartTknIndx);  // find end of text
 | |
| 			if (endTextIndx == -1)
 | |
| 				endTextIndx = text.IndexOf(@"\v", endStartTknIndx);
 | |
| 			int endTextIndx2 = text.IndexOf(@"\v\up0 ", endStartTknIndx);  // find end of text
 | |
| 			if(endTextIndx2 > 0 && (endTextIndx < 0 || endTextIndx > endTextIndx2))
 | |
| 				endTextIndx = endTextIndx2; 
 | |
| 			vte.Text = text.Substring(endStartTknIndx + 4, endTextIndx - endStartTknIndx - 4); // 4 for \v0
 | |
| 
 | |
| 			// Now get the link part.  It can be terminated by a '\v0' or an [END>
 | |
| 			int endLinkIndxV = text.IndexOf(@"\v0 ", linkIndx);
 | |
| 			if (endLinkIndxV == -1) endLinkIndxV = text.IndexOf(@"\v0", linkIndx);  // at end of string
 | |
| 			int endLinkIndxE = text.IndexOf(@"[END>", linkIndx);
 | |
| 			int endLinkIndx = (endLinkIndxV < endLinkIndxE) ? endLinkIndxV : endLinkIndxE;
 | |
| 			vte.Link = text.Substring(linkIndx + 6, endLinkIndx - linkIndx - 6);  // 6 for #Link:
 | |
| 
 | |
| 			string tmptxt = null;
 | |
| 			if (vte.Type != E_TextElementType.ReferencedObject)
 | |
| 			{
 | |
| 				tmptxt = FixTransition(vte.Link, vte.Text);
 | |
| 				vte.Text = tmptxt;
 | |
| 			}
 | |
| 			//else
 | |
| 			//{
 | |
| 			//    tmptxt = DoROFormatFlags(vte.Text, text, index, endLinkIndx);
 | |
| 			//    vte.Text = tmptxt;
 | |
| 			//}
 | |
| 			
 | |
| 			// Now get the entire text & link. Account for various ending possibilities:
 | |
| 			// ends with '\v0\'; ends with '\v0 '; ends with '\v0' (end of string);
 | |
| 			// ends with '[END>' if two in a row - will have <START]
 | |
| 			int endToken = (endLinkIndx == endLinkIndxE)?endLinkIndx+3:text.IndexOf(@"[END>", endLinkIndx + 3); // get past end of link
 | |
| 			int endComment = text.IndexOf(@"\v0", endToken);
 | |
| 
 | |
| 			int rettoken = 0;
 | |
| 			int retlen = 4;
 | |
| 			if (endComment + 3 == text.Length) retlen = 3;
 | |
| 			else if (text[endComment + 3] == '\\') retlen = 3;
 | |
| 			vte.TextAndLink = text.Substring(index, endComment - index + retlen);
 | |
| 			rettoken = endComment + retlen;
 | |
| 			if (vte.Type != E_TextElementType.ReferencedObject)
 | |
| 			{
 | |
| 				if (vte.TextAndLink.Contains("(Resolved Transition Text)"))
 | |
| 					vte.TextAndLink = vte.TextAndLink.Replace("(Resolved Transition Text)", tmptxt);
 | |
| 				else
 | |
| 					if (vte.Text != tmptxt)
 | |
| 						vte.Text = tmptxt;
 | |
| 			}
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			return rettoken;
 | |
| 		}
 | |
| 		private int DoSymbol(string text, int startIndex, int index)
 | |
| 		{
 | |
| 			displayTextElement vte = new displayTextElement();
 | |
| 			vte.Type = E_TextElementType.Symbol;
 | |
| 			// symbols are the unicode/rtf command. A symbol can be represented by \'xy or 
 | |
| 			// in the text from the database \uxyz?. If the \'xy is used the length of the 
 | |
| 			// symbol number will always be two, otherwise find the index of the '?' to 
 | |
| 			// find the end.  
 | |
| 			int endindx = -1;
 | |
| 			if (text[index + 1] == '\'') endindx = index + 3;
 | |
| 			else endindx = text.IndexOf("?", index);
 | |
| 			vte.Text = text.Substring(index, endindx - index + 1);
 | |
| 			DisplayTextElementList.Add(vte);
 | |
| 			return endindx+1; 
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#region ReplaceWords
 | |
| 		#region commented out
 | |
| 		//private string DoReplaceWords(string Text)
 | |
| 		//{
 | |
| 		//    ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList;
 | |
| 		//    foreach (ReplaceStr rs in rsl)
 | |
| 		//    {
 | |
| 		//        if (_MyItemInfo.MyContent.Type < 20000) return Text;   // for now only replace in steps.
 | |
| 		//        bool replaceit = false;
 | |
| 
 | |
| 		//        if (_MyItemInfo.ItemID == 2557) Console.WriteLine("here");
 | |
| 		//        // note that the order of this check is important.  Check in this order...
 | |
| 		//        // background here
 | |
| 		//        if (_MyItemInfo.IsHigh && (rs.Flag & E_ReplaceFlags.High)>0) replaceit = true;
 | |
| 		//        else if ((_MyItemInfo.IsTable || _MyItemInfo.IsFigure) && (rs.Flag & E_ReplaceFlags.Table) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsInRNO && (rs.Flag & E_ReplaceFlags.RNO) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsCaution && (rs.Flag & E_ReplaceFlags.Caution) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsNote && (rs.Flag & E_ReplaceFlags.Note) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsStepPart && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 		//        //else if (_MyItemInfo.IsInFirstLevelSubStep && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsAccPages & (rs.Flag & E_ReplaceFlags.Attach) > 0) replaceit = true;
 | |
| 
 | |
| 		//        if (replaceit)
 | |
| 		//        {
 | |
| 		//            // CASEINSENS: Do ReplaceWords for all words that match, regardless of case, and replace 
 | |
| 		//            // with the ReplaceWith string as is
 | |
| 		//            if ((rs.Flag & E_ReplaceFlags.CaseInsens) > 0)
 | |
| 		//            {
 | |
| 		//                //string res = "";
 | |
| 		//                //string fortest = Text.ToUpper();
 | |
| 		//                ////string pat = @"(?<=\W|^)" + rs.ReplaceWord.ToUpper() + @"(?=\W|$)";
 | |
| 		//                //// jsj 07Jun2010 HardSpaces defeat replaceword logic
 | |
| 		//                //string pat = @"(?<=\W|^)(?<![\\u160?])" + rs.ReplaceWord.ToUpper() + @"(?=[^\\u160?]|$)";
 | |
| 		//                //int cpindx = 0;
 | |
| 		//                //foreach (Match m in Regex.Matches(fortest, pat))
 | |
| 		//                //{
 | |
| 		//                //    res += Text.Substring(cpindx, m.Index - cpindx);
 | |
| 		//                //    cpindx += (m.Index - cpindx);
 | |
| 		//                //    res += rs.ReplaceWith;
 | |
| 		//                //    cpindx += rs.ReplaceWord.Length;
 | |
| 		//                //}
 | |
| 		//                //if (cpindx < Text.Length) res += Text.Substring(cpindx, Text.Length - cpindx);
 | |
| 		//                //Text = res;
 | |
| 
 | |
| 		//                // If there are Regex Control Characters '\[]()' prefix them with backslash
 | |
| 		//                string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0");
 | |
| 		//                //string pat = @"(?<=\W|^)" + replaceWord + @"(?=\W|$)";
 | |
| 		//                // jsj 07Jun2010 HardSpaces defeat replaceword logic
 | |
| 		//                //string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?=[^\\u160?]|\W|$)";
 | |
| 		//                string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?![\\u160?])(?=\W|$)";
 | |
| 		//                try
 | |
| 		//                {
 | |
| 		//                    Text = ReplaceWord(Text, pat, rs.ReplaceWith, RegexOptions.IgnoreCase);
 | |
| 		//                    //Text = Regex.Replace(Text, pat, rs.ReplaceWith, RegexOptions.IgnoreCase);
 | |
| 		//                }
 | |
| 		//                catch (Exception ex)
 | |
| 		//                {
 | |
| 		//                    Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, replaceWord, ex.GetType().Name, ex.Message);
 | |
| 		//                }
 | |
| 						
 | |
| 		//            }
 | |
| 		//            // CASEINSENSALL: Do ReplaceWords for all words that match the ReplaceWord, regardless of case
 | |
| 		//            else if ((rs.Flag & E_ReplaceFlags.CaseInsensAll) > 0)
 | |
| 		//            {
 | |
| 		//                // only in Maine Yankee - we don't need to do this one.
 | |
| 		//            }
 | |
| 		//            // CASEINSENSFIRST:	Do ReplaceWords for all words that exactly match the ReplaceWord,  
 | |
| 		//            // except the case where the first character may be different
 | |
| 		//            else if ((rs.Flag & E_ReplaceFlags.CaseInsensFirst) > 0)
 | |
| 		//            {
 | |
| 		//                // only used in V.C. Summer  - we don't need to do this either.
 | |
| 		//            }
 | |
| 		//            else
 | |
| 		//            {
 | |
| 		//                // If there are Regex Control Characters '\[]()' prefix them with backslash
 | |
| 		//                string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0");
 | |
| 		//                //string pat = @"(?<=\W|^)" + replaceWord + @"(?=\W|$)";
 | |
| 		//                // jsj 07Jun2010 HardSpaces defeat replaceword logic
 | |
| 		//                //string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?=[^\\u160?]|\W|$)";
 | |
| 		//                string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?![\\u160?])(?=\W|$)";
 | |
| 		//                try
 | |
| 		//                {
 | |
| 		//                    Text = ReplaceWord(Text, pat, rs.ReplaceWith, RegexOptions.None);
 | |
| 		//                    //Text = Regex.Replace(Text, pat, rs.ReplaceWith);
 | |
| 		//                }
 | |
| 		//                catch (Exception ex)
 | |
| 		//                {
 | |
| 		//                    Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, replaceWord, ex.GetType().Name, ex.Message);
 | |
| 		//                }
 | |
| 		//            }
 | |
| 						
 | |
| 		//        }
 | |
| 		//    }
 | |
| 		//    //Console.WriteLine("--- Before '{0}'", Text);
 | |
| 		//    Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
 | |
| 		//    //Console.WriteLine("--- After '{0}'", Text);
 | |
| 		//    return Text;
 | |
| 		//}
 | |
| 		//private string DoReplaceWords1(string Text)
 | |
| 		//{
 | |
| 		//    if (_MyItemInfo.MyContent.Type < 20000) return Text;   // for now only replace in steps.
 | |
| 		//    ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList;
 | |
| 		//    // Loop through text looking for words to be replaced
 | |
| 		//    foreach (ReplaceStr rs in rsl)
 | |
| 		//    {
 | |
| 		//        bool replaceit = false;
 | |
| 
 | |
| 		//        // note that the order of this check is important.  Check in this order...
 | |
| 		//        // background here
 | |
| 		//        if (_MyItemInfo.IsHigh && (rs.Flag & E_ReplaceFlags.High) > 0) replaceit = true;
 | |
| 		//        else if ((_MyItemInfo.IsTable || _MyItemInfo.IsFigure) && (rs.Flag & E_ReplaceFlags.Table) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsInRNO && (rs.Flag & E_ReplaceFlags.RNO) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsCaution && (rs.Flag & E_ReplaceFlags.Caution) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsNote && (rs.Flag & E_ReplaceFlags.Note) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsStepPart && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 		//        //else if (_MyItemInfo.IsInFirstLevelSubStep && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 		//        else if (_MyItemInfo.IsAccPages & (rs.Flag & E_ReplaceFlags.Attach) > 0) replaceit = true;
 | |
| 
 | |
| 		//        if (replaceit)
 | |
| 		//        {
 | |
| 		//            // CASEINSENS: Do ReplaceWords for all words that match, regardless of case, and replace with the ReplaceWith string as is
 | |
| 		//            RegexOptions myOptions = (rs.Flag & E_ReplaceFlags.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase : RegexOptions.None;
 | |
| 		//            string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0");
 | |
| 		//            string pat = @"(?<=\W|^)(?<![\\u160?])" + replaceWord + @"(?![\\u160?])(?=\W|$)";
 | |
| 		//            try
 | |
| 		//            {
 | |
| 		//                Text = ReplaceWord(Text, pat, rs.ReplaceWith, myOptions);
 | |
| 		//            }
 | |
| 		//            catch (Exception ex)
 | |
| 		//            {
 | |
| 		//                Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, replaceWord, ex.GetType().Name, ex.Message);
 | |
| 		//            }
 | |
| 
 | |
| 		//        }
 | |
| 		//    }
 | |
| 		//    Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
 | |
| 		//    return Text;
 | |
| 		//}
 | |
| #endregion
 | |
| 		private Dictionary<ReplaceStr, Regex> dicReplaceRegex = new Dictionary<ReplaceStr, Regex>();
 | |
| 		private string DoReplaceWords2(string Text)
 | |
| 		{
 | |
| 			if (_MyItemInfo.MyContent.Type < 20000) return Text;   // for now only replace in steps.
 | |
| 			FoundMatches myMatches = new FoundMatches(Text);
 | |
| 			// Exclude Link Text from Replace Word process
 | |
| 			myMatches.AddLink(regFindLink, _MyFormat.PlantFormat.FormatData.SectData.ReplaceWordsInROs, _MyItemInfo.MyProcedure.MyDocVersion); 
 | |
| 			ReplaceStrList rsl = _MyFormat.PlantFormat.FormatData.SectData.ReplaceStrList;
 | |
| 			
 | |
| 			// The only way to get an 'empty' list is to have one 'dummy' replacestr, i.e. that has ReplaceWord as an empty string.  If the 
 | |
| 			// ReplaceStrData xml node is empty, it does the inheritance and gets the 'base' format's list.
 | |
| 			if (rsl.Count==1 && (rsl[0].ReplaceWord == null  || rsl[0].ReplaceWord == "")) return Text;
 | |
| 			// Loop through text looking for words to be replaced
 | |
| 			foreach (ReplaceStr rs in rsl)
 | |
| 			{
 | |
| 				bool replaceit = false;
 | |
| 				// note that the order of this check is important.  Check in this order...
 | |
| 				// background here
 | |
| 				if (_MyItemInfo.IsHigh && (rs.Flag & E_ReplaceFlags.High) > 0) replaceit = true;
 | |
| 				else if ((_MyItemInfo.IsTable || _MyItemInfo.IsFigure) && (rs.Flag & E_ReplaceFlags.Table) > 0) replaceit = true;
 | |
| 				else if (_MyItemInfo.IsInRNO && (rs.Flag & E_ReplaceFlags.RNO) > 0) replaceit = true;
 | |
| 				else if (_MyItemInfo.IsCaution && (rs.Flag & E_ReplaceFlags.Caution) > 0) replaceit = true;
 | |
| 				else if (_MyItemInfo.IsNote && (rs.Flag & E_ReplaceFlags.Note) > 0) replaceit = true;
 | |
| 				else if (_MyItemInfo.IsStepPart && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 				//else if (_MyItemInfo.IsInFirstLevelSubStep && (rs.Flag & E_ReplaceFlags.Substep) > 0) replaceit = true;
 | |
| 				else if (_MyItemInfo.IsAccPages & (rs.Flag & E_ReplaceFlags.Attach) > 0) replaceit = true;
 | |
| 				
 | |
| 				if (replaceit)
 | |
| 				{
 | |
| 					if (!dicReplaceRegex.ContainsKey(rs))
 | |
| 					{
 | |
| 						// CASEINSENS: Do ReplaceWords for all words that match, regardless of case, and replace with the ReplaceWith string as is
 | |
| 						//RegexOptions myOptions = (rs.Flag & E_ReplaceFlags.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase & RegexOptions.Singleline : RegexOptions.None & RegexOptions.Singleline;
 | |
| 						RegexOptions myOptions = (rs.Flag & E_ReplaceFlags.CaseInsens) == E_ReplaceFlags.CaseInsens ? RegexOptions.IgnoreCase: RegexOptions.None;
 | |
| 						string replaceWord = Regex.Replace(rs.ReplaceWord, @"[[\]\\()]", @"\$0");
 | |
| 						// if first or last character in replaceword is a non-word character, for example, ',', ')', or '.',
 | |
| 						// don't use the \W, i.e. don't bother to look for a non-word character.
 | |
| 						string wordMatchBeg = Regex.IsMatch(replaceWord.Substring(0, 1), @"\W") ? "" : @"(?<=\W|^)";
 | |
| 						string wordMatchEnd = Regex.IsMatch(replaceWord.Substring(replaceWord.Length - 1, 1), @"\W") ? "" : @"(?=\W|$)";
 | |
| 						string pat = wordMatchBeg + @"(?<!\\u160\?)" + replaceWord + @"(?!\\u160\?)" + wordMatchEnd;
 | |
| 						dicReplaceRegex.Add(rs, new Regex(pat, myOptions));
 | |
| 					}
 | |
| 					try
 | |
| 					{
 | |
| 						myMatches.Add(dicReplaceRegex[rs], rs);
 | |
| 					}
 | |
| 					catch (Exception ex)
 | |
| 					{
 | |
| 						Console.WriteLine("{0},'{1}',{2},'{3}'", _MyItemInfo.ActiveFormat.Name, rs.ReplaceWord, ex.GetType().Name, ex.Message);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			Text = myMatches.ReplaceMatches();
 | |
| 			Text = Text.Replace(@"\xA0", @"\u160?"); //replace hard space
 | |
| 			return Text;
 | |
| 		}
 | |
| 		#region notused
 | |
| 		static Regex regFindLink = new Regex(@"\<START\].*?\[END\>", RegexOptions.Singleline);
 | |
| 		private string ReplaceWord(string text, string replace, string with, RegexOptions regexOptions)
 | |
| 		{
 | |
| 			MatchCollection myMatches = Regex.Matches(text, replace, regexOptions);
 | |
| 			MatchCollection myLinks = regFindLink.Matches(text);
 | |
| 			for (int i = myMatches.Count - 1; i >= 0; i--)
 | |
| 			{
 | |
| 				Match myMatch = myMatches[i];
 | |
| 				if (!PartOfLinkText(myMatch, myLinks))
 | |
| 					text = text.Substring(0, myMatch.Index) + with + text.Substring(myMatch.Index + myMatch.Length);
 | |
| 			}
 | |
| 			return text;
 | |
| 		}
 | |
| 		
 | |
| 		private bool PartOfLinkText(Match myMatch, MatchCollection myLinks)
 | |
| 		{
 | |
| 			foreach (Match myLink in myLinks)
 | |
| 				if (myMatch.Index > myLink.Index && myMatch.Index < (myLink.Index + myLink.Length))
 | |
| 					return true;
 | |
| 			return false;
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#endregion
 | |
| 	}
 | |
| 	#region displayTextElementClass
 | |
| 	public enum E_TextElementType : uint
 | |
| 	{
 | |
| 		Text = 0,
 | |
| 		Transition = 1,
 | |
| 		TransitionRange = 2,
 | |
| 		ReferencedObject = 3,
 | |
| 		Symbol = 4
 | |
| 	};
 | |
| 	public class displayTextElement
 | |
| 	{
 | |
| 		private E_TextElementType _Type;
 | |
| 		public E_TextElementType Type
 | |
| 		{
 | |
| 			get { return _Type; }
 | |
| 			set { _Type = value; }
 | |
| 		}
 | |
| 		protected string _Text;
 | |
| 		virtual public string Text
 | |
| 		{
 | |
| 			get { return _Text; }
 | |
| 			set { _Text = value; }
 | |
| 		}
 | |
| 	}
 | |
| 	public class displayLinkElement : displayTextElement
 | |
| 	{
 | |
| 		private string _Link;
 | |
| 		public string Link
 | |
| 		{
 | |
| 			get { return _Link; }
 | |
| 			set { _Link = value; }
 | |
| 		}
 | |
| 		private string _TextAndLink;
 | |
| 		public string TextAndLink
 | |
| 		{
 | |
| 			get { return _TextAndLink; }
 | |
| 			set { _TextAndLink = value; }
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Text - this should parse the text and return the results
 | |
| 		/// </summary>
 | |
| 		override public string Text
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_TextAndLink != null)
 | |
| 				{
 | |
| 					Match m = Regex.Match(_TextAndLink, @"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>");
 | |
| 					return m.Groups[3].ToString();
 | |
| 				}
 | |
| 				return _Text;
 | |
| 			}
 | |
| 			set
 | |
| 			{
 | |
| 				if (_TextAndLink != null)
 | |
| 				{
 | |
| 					Match m = Regex.Match(_TextAndLink, @"<START\](\\[^v \\]+)*\\v0(\\[^v \\]+)* (.*?)(\\[^v'? \\]+)*\\v(\\[^v \\]+)* #Link:(.*?)\[END>");
 | |
| 					System.Text.RegularExpressions.Group g = m.Groups[3];
 | |
| 					_TextAndLink = _TextAndLink.Substring(0, g.Index) + value + _TextAndLink.Substring(g.Index + g.Length);
 | |
| 				}
 | |
| 				_Text = value;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	#endregion
 | |
| 	public class FoundMatches : SortedList<int, FoundMatch>
 | |
| 	{
 | |
| 		private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 | |
| 		private string _Text;
 | |
| 		public FoundMatches(string text)
 | |
| 			: base()
 | |
| 		{
 | |
| 			_Text = text;
 | |
| 		}
 | |
| 		public void Add(Regex myRegEx, ReplaceStr myWord)
 | |
| 		{
 | |
| 			MatchCollection myMatches = myRegEx.Matches(_Text);
 | |
| 			foreach (Match myMatch in myMatches)
 | |
| 				Add(myMatch, myWord);
 | |
| 		}
 | |
| 		public void AddLink(Regex myRegEx, bool replaceWordsInROs, DocVersionInfo myDocVersion)
 | |
| 		{
 | |
| 			MatchCollection myMatches = myRegEx.Matches(_Text);
 | |
| 			foreach (Match myMatch in myMatches)
 | |
| 			{
 | |
| 				if (!replaceWordsInROs || IsTransition(myMatch.Value) || IsSetpointRO(myMatch.Value, myDocVersion))
 | |
| 					Add(myMatch, null);// Exclude from Replace Words
 | |
| 			}
 | |
| 		}
 | |
| 		private bool IsTransition(string link)
 | |
| 		{
 | |
| 			return link.Contains("#Link:Transition");
 | |
| 		}
 | |
| 		private static Regex regRefObj = new Regex(@"\#Link\:ReferencedObject:([0-9]*) ([0-9a-zA-Z]*) ([0-9]*)", RegexOptions.Singleline);
 | |
| 		private static bool IsSetpointRO(string link, DocVersionInfo myDocVersion)
 | |
| 		{
 | |
| 			Match myMatch = regRefObj.Match(link);
 | |
| 			if (myMatch.Success)
 | |
| 			{
 | |
| 				int dbid = System.Convert.ToInt32(myMatch.Groups[2].Value.Substring(0, 4), 16); 
 | |
| 				int rodbid = int.Parse(myMatch.Groups[3].Value);
 | |
| 				ROFstInfo myROFst = myDocVersion.GetROFst(rodbid);
 | |
| 				return myROFst.IsSetpointDB(dbid);
 | |
| 			}
 | |
| 			return false;
 | |
| 		}
 | |
| 		public void Add(Match myMatch, ReplaceStr myWord)
 | |
| 		{
 | |
| 			// If one already exists for this location, then don't add another.
 | |
| 			if (ContainsKey(myMatch.Index)) return;
 | |
| 			// Start by Adding it.
 | |
| 			base.Add(myMatch.Index, new FoundMatch(myMatch, myWord));
 | |
| 			// Now see what I can do with it.
 | |
| 			int index = this.IndexOfKey(myMatch.Index);
 | |
| 			if (index > 0) // If this match is contained within the previous match remove it
 | |
| 			{
 | |
| 				FoundMatch previousMatch = Values[index - 1];
 | |
| 				if (previousMatch.MyMatch.Index + previousMatch.MyMatch.Length > myMatch.Index)
 | |
| 					Remove(myMatch.Index);
 | |
| 			} // If the next match is contained within this match, remove the next match
 | |
| 			while (index < Count - 1 && Values[index + 1].MyMatch.Index < (myMatch.Index + myMatch.Length))
 | |
| 				Remove(Values[index + 1].MyMatch.Index);
 | |
| 		}
 | |
| 		public string ReplaceMatches()
 | |
| 		{
 | |
| 			int offset = 0;
 | |
| 			string text = _Text;
 | |
| 			foreach (FoundMatch foundMatch in Values)
 | |
| 			{
 | |
| 				if (foundMatch.MyWord != null)
 | |
| 				{
 | |
| 					text = text.Substring(0, offset + foundMatch.MyMatch.Index) + foundMatch.MyWord.ReplaceWith + text.Substring(offset + foundMatch.MyMatch.Index + foundMatch.MyMatch.Length);
 | |
| 					offset += foundMatch.MyWord.ReplaceWith.Length - foundMatch.MyMatch.Length;
 | |
| 				}
 | |
| 			}
 | |
| 			return text;
 | |
| 		}
 | |
| 	}
 | |
| 	public class FoundMatch
 | |
| 	{
 | |
| 		private Match _MyMatch;
 | |
| 		public Match MyMatch
 | |
| 		{
 | |
| 			get { return _MyMatch; }
 | |
| 			set { _MyMatch = value; }
 | |
| 		}
 | |
| 		private ReplaceStr _MyWord;
 | |
| 		public ReplaceStr MyWord
 | |
| 		{
 | |
| 			get { return _MyWord; }
 | |
| 			set { _MyWord = value; }
 | |
| 		}
 | |
| 		public FoundMatch(Match myMatch, ReplaceStr myWord)
 | |
| 		{
 | |
| 			_MyMatch = myMatch;
 | |
| 			_MyWord = myWord;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| }
 |