1996 lines
		
	
	
		
			83 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1996 lines
		
	
	
		
			83 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Text;
 | |
| using System.Drawing;
 | |
| using System.Text.RegularExpressions;
 | |
| using System.IO;
 | |
| using iTextSharp.text.pdf;
 | |
| using iTextSharp.text;
 | |
| using Itenso.Rtf;
 | |
| using Itenso.Rtf.Parser;
 | |
| using Itenso.Rtf.Interpreter;
 | |
| using Itenso.Rtf.Support;
 | |
| using Volian.Controls.Library;
 | |
| using VEPROMS.CSLA.Library;
 | |
| using Volian.Base.Library;
 | |
| 
 | |
| namespace Volian.Print.Library
 | |
| {
 | |
| 	public partial class vlnParagraphs : List<vlnParagraph>
 | |
| 	{
 | |
| 		private vlnParagraph _Parent;
 | |
| 		public vlnParagraph Parent
 | |
| 		{
 | |
| 			get { return _Parent; }
 | |
| 			set { _Parent = value; }
 | |
| 		}
 | |
| 		public vlnParagraphs(vlnParagraph parent)
 | |
| 		{
 | |
| 			_Parent = parent;
 | |
| 		}
 | |
| 		public float Add(PdfContentByte cb, ItemInfoList itemInfoList, float xoff, float yoff, float yoffRight, int rnoLevel, int maxRNO, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			int? bxIndex = null;
 | |
| 			vlnBox box = null;
 | |
| 			float yTop = yoff;
 | |
| 			foreach (ItemInfo childItemInfo in itemInfoList)
 | |
| 			{
 | |
| 				// if this is a caution/note and it has a caution/note substep, do it before this caution/note, so that
 | |
| 				// it comes above it.
 | |
| 				if (childItemInfo.Cautions != null && (childItemInfo.IsCaution || childItemInfo.IsNote))
 | |
| 					yoff = Add(cb, childItemInfo.Cautions, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo);
 | |
| 				if (childItemInfo.Notes != null && (childItemInfo.IsCaution || childItemInfo.IsNote))
 | |
| 					yoff = Add(cb, childItemInfo.Notes, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo);
 | |
| 				int? bxIndx = childItemInfo.FormatStepData==null?-1:childItemInfo.FormatStepData.StepLayoutData.STBoxindex;
 | |
| 				if (bxIndx != -1 && (bxIndex != bxIndx || childItemInfo.FormatStepData.BoxIt))
 | |
| 				{
 | |
| 					if (childItemInfo.FormatStepData.BoxIt)   // this is a boxed HLS
 | |
| 					{
 | |
| 						box = new vlnBox();
 | |
| 						box.MyBox = new Box();
 | |
| 						box.DefBox = vlnBox.BoxThin;
 | |
| 						StepSectionLayoutData ssld = formatInfo.MyStepSectionLayoutData;
 | |
| 						int colR = int.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[childItemInfo.ColumnMode]);
 | |
| 						int widS = vlnPrintObject.ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
 | |
| 						box.DefEnd = (float)(ssld.ColS + colR + widS + (60/4.8));
 | |
| 						box.YOffset = yoff - .75F * vlnPrintObject.SixLinesPerInch;
 | |
| 					}
 | |
| 					else if (bxIndex == null) // First boxed step
 | |
| 					{
 | |
| 						box = new vlnBox();
 | |
| 						box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
 | |
| 						if (box.MyBox != null)
 | |
| 						{
 | |
| 							box.YOffset = yoff;
 | |
| 							int ln = 1;	// a format flag determines whether there is a space before the note/caution.  
 | |
| 							if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
 | |
| 							yoff += ln * vlnPrintObject.SixLinesPerInch;
 | |
| 						}
 | |
| 					}
 | |
| 					else // Change Box Style
 | |
| 					{
 | |
| 						if (box != null) box.Height = yoff - box.YOffset;  // new height, with children
 | |
| 						box = new vlnBox();
 | |
| 						box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
 | |
| 						box.YOffset = yoff;
 | |
| 						int ln = 1;	// a format flag determines whether there is a space before the note/caution.
 | |
| 						if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
 | |
| 						yoff += ln * vlnPrintObject.SixLinesPerInch;
 | |
| 					}
 | |
| 					bxIndex = bxIndx;
 | |
| 				}
 | |
| 				if (childItemInfo is SectionInfo) formatInfo = (childItemInfo as SectionInfo).LocalFormat ?? formatInfo;
 | |
| 				if (rnoLevel < maxRNO && childItemInfo.RNOs != null) yoff = Math.Max(yoff, yoffRight);
 | |
| 				
 | |
| 				
 | |
| 				vlnParagraph para = new vlnParagraph(Parent, cb, childItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo);
 | |
| 				if (box != null && box.MyParent == null)
 | |
| 				{
 | |
| 					box.MyParent = para;
 | |
| 					para.PartsContainer.Add(box);
 | |
| 				}
 | |
| 				Add(para);
 | |
| 				// para.YBottomMost will have y for bottom of any substeps that are also enclosed in the box.
 | |
| 				if (childItemInfo.IsStep && childItemInfo.MyHLS.FormatStepData.UseSmartTemplate && para.ChildrenBelow.Count>0 && para.ChildrenBelow[0].YBottomMost > para.YBottomMost)
 | |
| 					yoff = para.ChildrenBelow[0].YBottomMost;
 | |
| 				else
 | |
| 				yoff = para.YBottomMost;
 | |
| 				if (childItemInfo.FormatStepData != null && childItemInfo.FormatStepData.BoxIt)
 | |
| 				{
 | |
| 					box.Height = yoff - box.YOffset - (1.1F * vlnPrintObject.SixLinesPerInch);
 | |
| 					box = null;   // if doing boxed steps, only do single sibling at a time.
 | |
| 				}
 | |
| 			}
 | |
| 			if (box != null && box.MyBox != null)
 | |
| 			{
 | |
| 				box.Height = yoff - box.YOffset;  // new height, with children
 | |
| 				yoff += 2 * vlnPrintObject.SixLinesPerInch;
 | |
| 			}
 | |
| 			return yoff;
 | |
| 		}
 | |
| 		public float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
 | |
| 		{
 | |
| 			foreach (vlnParagraph child in this)
 | |
| 			{
 | |
| 				yPageStart = child.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			}
 | |
| 			return yPageStart;
 | |
| 		}
 | |
| 	}
 | |
| 	public partial class vlnParagraph : vlnPrintObject
 | |
| 	{
 | |
| 		private vlnTable _MyGrid;
 | |
| 		public vlnTable MyGrid
 | |
| 		{
 | |
| 			get { return _MyGrid; }
 | |
| 			set { _MyGrid = value; }
 | |
| 		}
 | |
| 		public float SectYPageStart = 0;
 | |
| 		private bool _IsWordDocPara = false;
 | |
| 		public bool IsWordDocPara
 | |
| 		{
 | |
| 			get { return _IsWordDocPara; }
 | |
| 			set { _IsWordDocPara = value; }
 | |
| 		}
 | |
| 		public float ParagraphToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
 | |
| 		{
 | |
| 			if (Processed) return yPageStart;
 | |
| 			//float localYPageStart = yPageStart;
 | |
| 			Processed = true;
 | |
| 			if (_PartsAbove != null && _PartsAbove.Count > 0) yPageStart = PartsAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			if (MyItemInfo.IsHigh && MyItemInfo.MyDocStyle.SpecialStepsFoldout) yPageStart -= SixLinesPerInch;
 | |
| 			float yLocation = CalculateYOffset(yPageStart, yTopMargin);
 | |
| 			if (MyItemInfo.HasChangeBar && MyPageHelper.ChangeBarDefinition.MyChangeBarType != PrintChangeBar.Without) MyPageHelper.AddChangeBar(DoChangeBar(cb, MyItemInfo, MyPageHelper, XOffset, yLocation, MyPageHelper.MaxRNO, MyItemInfo.ActiveFormat), cbMess);
 | |
| 			float retval = yLocation;
 | |
| 
 | |
| 			if (MyItemInfo.IsFigure)
 | |
| 			{
 | |
| 				yLocation -= (SixLinesPerInch * MyPageHelper.YMultiplier);
 | |
| 				if (ImageText != null)
 | |
| 					retval = DrawFigure(cb, yBottomMargin, yLocation);
 | |
| 				else
 | |
| 					retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
 | |
| 
 | |
| 			}
 | |
| 			else if (!MyItemInfo.IsStepSection 
 | |
| 				|| (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles 
 | |
| 				&& !MyItemInfo.MyDocStyle.CancelSectTitle
 | |
| 				&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)) // Don't ouput the Step Section title
 | |
| 			{
 | |
| 				bool doprint = true;
 | |
| 				// if this is a section, then check the section config for printable header too.
 | |
| 				if (MyItemInfo.IsSection)
 | |
| 				{
 | |
| 					SectionConfig sch = MyItemInfo.MyConfig as SectionConfig;
 | |
| 					if (!(MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles 
 | |
| 							&& !MyItemInfo.MyDocStyle.CancelSectTitle
 | |
| 							&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout) 
 | |
| 						&& 
 | |
| 					((sch != null && sch.Section_PrintHdr != "Y") || !MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections)) doprint = false;
 | |
| 				}
 | |
| 				if (MyItemInfo.MyContent.MyGrid != null)
 | |
| 					retval = DrawGrid(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
 | |
| 				else
 | |
| 					if (doprint)retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
 | |
| 				if (MyItemInfo.IsHigh)
 | |
| 				{
 | |
| 					MyPageHelper.PageBookmarks.Add(MyItemInfo, MyItemInfo.MyTab.CleanText + " " + MyItemInfo.DisplayText,
 | |
| 						new PdfDestination(PdfDestination.FITBH, yLocation + YVeryTop - YTopMost + SixLinesPerInch));
 | |
| 				}
 | |
| 			}
 | |
| 			if (MyItemInfo.IsSection)
 | |
| 			{
 | |
| 				SectionConfig sc = MyItemInfo.MyConfig as SectionConfig;
 | |
| 				if (sc != null && sc.Section_TOC == "Y")
 | |
| 				{
 | |
| 					string tocKey = string.Format("TOC{0}", MyItemInfo.ItemID);
 | |
| 					if (MyPageHelper.MyTOCPageCounts.ContainsKey(tocKey))
 | |
| 					{
 | |
| 						PageCount pc = MyPageHelper.MyTOCPageCounts[tocKey];
 | |
| 						pc.Total = MyPageHelper.CurrentPageNumber;
 | |
| 						pc.DrawTemplates();
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			//Height = yLocation - retval;
 | |
| 			if (_PartsLeft != null && _PartsLeft.Count > 0) yPageStart = PartsLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			if (_PartsRight != null && _PartsRight.Count > 0) yPageStart = PartsRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			if (_PartsBelow != null && _PartsBelow.Count > 0) yPageStart = PartsBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			if (_PartsContainer != null && _PartsContainer.Count > 0) yPageStart = PartsContainer.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 
 | |
| 			//if (localYPageStart != yPageStart) DebugText.WriteLine("ParToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, localYPageStart, yPageStart);
 | |
| 			return yPageStart;
 | |
| 		}
 | |
| 
 | |
| 		private float DrawGrid(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
 | |
| 		{
 | |
| 			//DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.ShortPath, FormattedText);
 | |
| 			DebugText.WriteLine("{0},'{1}','{2}','<<END>>',{3}", MyItemInfo.ItemID, MyItemInfo.ShortPath,MyItemInfo.MyContent.Text,XOffset);
 | |
| 			float retval = Rtf2Pdf.GridAt(cb, MyGrid, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
 | |
| 			return retval;
 | |
| 		}
 | |
| 
 | |
| 		private float DrawText(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
 | |
| 		{
 | |
| 			DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, FormattedText);
 | |
| 			//Console.WriteLine("{0},{1},'{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, IParagraph.Content);
 | |
| 			float retval = yLocation;
 | |
| 			// Check if only one line, i.e.  "Height < (1.2F * IParagraph.Leading".  The Leading can be for six or seven lines per inch, so the 1.2 
 | |
| 			// multiplier accounts for both.
 | |
| 			if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData.CenterOneLineOnly && MyItemInfo.MyPrevious == null && MyItemInfo.NextItem == null && Height < (1.2F * IParagraph.Leading))
 | |
| 				IParagraph.Alignment = Element.ALIGN_CENTER;
 | |
| 			if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData.StepPrintData.Justify == "Center")
 | |
| 				IParagraph.Alignment = Element.ALIGN_CENTER;
 | |
| 			retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin);
 | |
| 			if (retval == 0)		// problem occurred - paragraph was not able to be printed on page
 | |
| 			{						// pagination logic needs to be fixed.
 | |
| 				ForcePagination(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation, ref retval);
 | |
| 			}
 | |
| 			return retval;
 | |
| 		}
 | |
| 		private static List<string> myAttributes =new List<string>();
 | |
| 		private static void AddAttribute(string attr)
 | |
| 	{
 | |
| 		if (myAttributes.Contains(attr))
 | |
| 			return;
 | |
| 		//Console.WriteLine("Attribute = \"{0}\"", attr);
 | |
| 		myAttributes.Add(attr);
 | |
| 	}
 | |
| 		private void CheckAttributes(System.Collections.Hashtable attributes)
 | |
| 		{
 | |
| 			foreach (string attr in attributes.Keys)
 | |
| 			{
 | |
| 				AddAttribute(attr);
 | |
| 			}
 | |
| 		}
 | |
| 		private string FormattedText
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				bool subscript = false;
 | |
| 				//if (_MyItemInfo.ItemID == 467)
 | |
| 				//  Console.Write("");
 | |
| 				StringBuilder sb = new StringBuilder();
 | |
| 				//if (IParagraph.Chunks.Count > 1)
 | |
| 				//  Console.WriteLine("{0} Chunks", IParagraph.Chunks.Count);
 | |
| 				foreach (Chunk chk in IParagraph.Chunks)
 | |
| 				{
 | |
| 					string prefix = "";
 | |
| 					string suffix = "";
 | |
| 					CheckAttributes(chk.Attributes);
 | |
| 					if (chk.Font.BaseFont != null && chk.Font.BaseFont.PostscriptFontName.ToUpper().Contains("BOLD"))
 | |
| 					{
 | |
| 					  prefix += "\xD5";
 | |
| 					  suffix = "\xD6" + suffix;
 | |
| 					}
 | |
| 					if (chk.Attributes.ContainsKey("SUBSUPSCRIPT"))
 | |
| 					{
 | |
| 						float sup = (float)(chk.Attributes["SUBSUPSCRIPT"]);
 | |
| 						if (sup > 0)
 | |
| 						{
 | |
| 							prefix += "\xA6";
 | |
| 							suffix = "\xD1" + suffix;
 | |
| 						}
 | |
| 						else if (sup < 0)
 | |
| 						{
 | |
| 							prefix += "\xD1";
 | |
| 							suffix = "\xA6" + suffix;
 | |
| 						}
 | |
| 						
 | |
| 					}
 | |
| 					if (chk.Attributes.ContainsKey("UNDERLINE"))
 | |
| 					{
 | |
| 						prefix += "\x16";
 | |
| 						suffix = "\x16" + suffix; ;
 | |
| 					}
 | |
| 					sb.Append(prefix + chk.Content + suffix);
 | |
| 				}
 | |
| 				string retval = sb.ToString();
 | |
| 				retval = retval.Replace("\xD1\xA6", "");// Remove Multiple Superscript commands in a row
 | |
| 				retval = retval.Replace("\xA6\xD1", "");// Remove Multiple Superscript commands in a row
 | |
| 				retval = retval.Replace("\xD6\xD5", "");
 | |
| 				retval = retval.Replace("\xD6\x16\xD5", "\x16");
 | |
| 				return retval;
 | |
| 			}
 | |
| 		}
 | |
| 		//private bool _TextDebug = false; //true; this will turn on a writeline with debug in DrawText()
 | |
| 		private float DrawFigure(PdfContentByte cb, float yBottomMargin, float yLocation)
 | |
| 		{
 | |
| 			float retval = yLocation;
 | |
| 			if (ImageText != null)
 | |
| 			{
 | |
| 				string[] vals = ImageText.Split("\n".ToCharArray());
 | |
| 				ProcedureInfo proc = MyItemInfo.MyProcedure;
 | |
| 				DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo;
 | |
| 				ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst;
 | |
| 				ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]);
 | |
| 				if (roImage != null)
 | |
| 				{
 | |
| 					iTextSharp.text.Image it_image = iTextSharp.text.Image.GetInstance(roImage.Content);
 | |
| 					retval = Rtf2Pdf.FigureAt(cb, it_image, XOffset + MyItemInfo.FormatStepData.Font.CharsToTwips, yLocation, Width * MyPageHelper.YMultiplier, Height * MyPageHelper.YMultiplier, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
 | |
| 				}
 | |
| 			}
 | |
| 			return retval;
 | |
| 		}
 | |
| 		private string DebugInfo
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				return string.Format("DebugID = {0}, ID={1} Type={2} TypeName='{3}' StepLevel={4} DBSequence={5}", DebugId, MyItemInfo.ItemID, MyItemInfo.FormatStepType, MyItemInfo.FormatStepData==null?"NoStepData":MyItemInfo.FormatStepData.Type, MyItemInfo.StepLevel, MyItemInfo.DBSequence);
 | |
| 			}
 | |
| 		}
 | |
| 		public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
 | |
| 		{
 | |
| 			if (IsWordDocPara)
 | |
| 			{
 | |
| 				PdfReader tmp = null;
 | |
| 				string tmpstr = null;
 | |
| 				SectionInfo si = SectionInfo.Get(MyItemInfo.ItemID);
 | |
| 				cb.PdfDocument.NewPage();
 | |
| 				MyPageHelper.MyPromsPrinter.CreateWordDocPdf(cb, si, ref tmp, ref tmpstr);
 | |
| 				Processed = true;
 | |
| 				return yPageStart;
 | |
| 			}
 | |
| 			float yLocalypagestart = yPageStart;
 | |
| 			// yPageStart is offset into roll; YTopMost is offset of topmost of this paragraph.
 | |
| 			float yLocation = yPageStart - YTopMost;
 | |
| 			DebugText.WriteLine("ToPdf1:{0},'{1}',{2},{3},{4},{5}", MyItemInfo.ItemID, MyItemInfo.ShortSearchPath, XOffset, yLocation, yPageStart, YTopMost);
 | |
| 			int paginate = Paginate(yLocation, yTopMargin, yBottomMargin);
 | |
| 			bool firstHighLevelStep = MyItemInfo.IsHigh && (MyItemInfo.MyPrevious == null);
 | |
| 			switch (paginate)
 | |
| 			{
 | |
| 				case 0: // No page break
 | |
| 					if (MyItemInfo.IsSection)
 | |
| 					{
 | |
| 						SectionInfo si = MyItemInfo as SectionInfo;
 | |
| 						MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
 | |
| 						DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
 | |
| 					}
 | |
| 					break;
 | |
| 				case 1: // Break on High Level Step
 | |
| 					OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
 | |
| 					cb.PdfDocument.NewPage();
 | |
| 					DebugText.WriteLine("Paginate1");
 | |
| 					if (MyItemInfo.IsSection)
 | |
| 					{
 | |
| 						SectionInfo si = MyItemInfo as SectionInfo;
 | |
| 						MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
 | |
| 					}
 | |
| 					// Only do foldout page if not done for section break, i.e. check the there's a previous step.
 | |
| 					if (MyItemInfo.MyPrevious != null && (MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
 | |
| 						PromsPrinter.DoFoldoutPage(cb, "HLS", MyPageHelper.TextLayer, MyPageHelper);
 | |
| 					
 | |
| 					yPageStart = yTopMargin + YTopMost;
 | |
| 					DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
 | |
| 					MyPageHelper.YMultiplier = 1;
 | |
| 					break;
 | |
| 				case 2: // Break within a Step
 | |
| 					OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
 | |
| 					DocStyle docstyle = MyItemInfo.MyDocStyle;
 | |
| 					string myMsg = docstyle.Continue.Bottom.Message;
 | |
| 					if (myMsg != null && myMsg != "")
 | |
| 					{
 | |
| 						if (myMsg.IndexOf(@"%d") > -1)
 | |
| 							myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanText.Trim());
 | |
| 						if (myMsg.IndexOf(@"%2d") > -1)
 | |
| 							myMsg = myMsg.Replace(@"%2d", MyItemInfo.MyHLS.MyTab.CleanText.Trim(" .".ToCharArray()).PadLeft(2));
 | |
| 						float msg_yLocation = 0;
 | |
| 						if (myMsg.Contains("{par}"))
 | |
| 						{
 | |
| 							myMsg = myMsg.Replace("{par}", "");
 | |
| 							msg_yLocation = -SixLinesPerInch;
 | |
| 						}
 | |
| 						switch (docstyle.Continue.Bottom.Location)
 | |
| 						{
 | |
| 							case E_ContBottomLoc.EndOfText:					// place continue string at end of text
 | |
| 							case E_ContBottomLoc.BtwnTextAndBottom:			// place continue string between end of text & bottom of page
 | |
| 								Console.WriteLine("Not done yet");
 | |
| 								break;
 | |
| 							case E_ContBottomLoc.BottomOfPage:				// place continue message at bottom of page
 | |
| 								//msg_yLocation = yBottomMargin + 2 * SixLinesPerInch + (float)docstyle.Layout.FooterLength;   // 2 lines above bottom margin
 | |
| 								msg_yLocation = msg_yLocation + yBottomMargin + (float)docstyle.Layout.FooterLength;
 | |
| 								break;
 | |
| 							default:
 | |
| 								Console.WriteLine("**** BOTTOM CONTINUE MESSAGE NOT CODED*****");
 | |
| 								break;
 | |
| 						}
 | |
| 						MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Bottom.Margin ?? 0, msg_yLocation, docstyle.Continue.Bottom.Font);// MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
 | |
| 					}
 | |
| 					cb.PdfDocument.NewPage();
 | |
| 					DebugText.WriteLine("Paginate2");
 | |
| 					if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
 | |
| 						PromsPrinter.DoFoldoutPage(cb, "Break within Step", MyPageHelper.TextLayer, MyPageHelper);	// temporary foldout
 | |
| 
 | |
| 					// If there is a box, adjust the yTopMost to include it.
 | |
| 					float yTopMost = YTopMost;
 | |
| 					//if (YVeryTop < yTopMost) Console.WriteLine("{0},{1},{2}", MyItemInfo.DBSequence, yTopMost, YVeryTop);
 | |
| 					yTopMost = Math.Min(yTopMost,YVeryTop);
 | |
| 					yPageStart = yTopMargin + yTopMost;// -2 * SixLinesPerInch;
 | |
| 					DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
 | |
| 					if (EmptyTopMostPart) yPageStart += SixLinesPerInch;
 | |
| 					myMsg = docstyle.Continue.Top.Message;
 | |
| 					if (myMsg != null && myMsg != "")
 | |
| 					{
 | |
| 						yPageStart -= 2 * SixLinesPerInch;// Allow two lines for top continue message
 | |
| 						if (myMsg.IndexOf(@"%d") > -1)
 | |
| 							myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanTextNoSymbols.Trim(" .".ToCharArray()));
 | |
| 						MyPageHelper.TopMessage = new vlnText(cb, this, myMsg, myMsg, docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Top.Margin ?? 0, yTopMargin + 0.1F, docstyle.Continue.Top.Font);// MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
 | |
| 					}
 | |
| 					MyPageHelper.YMultiplier = 1;
 | |
| 					break;
 | |
| 				case 3: // Break on High Level Step (SevenLinesPerInch)
 | |
| 					if (!firstHighLevelStep)
 | |
| 					{
 | |
| 						OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
 | |
| 						cb.PdfDocument.NewPage();	// HLS (7 lpi) breakif (MyItemInfo.IsSection)
 | |
| 						DebugText.WriteLine("Paginate3");
 | |
| 						if (MyItemInfo.IsSection)
 | |
| 						{
 | |
| 							SectionInfo si = MyItemInfo as SectionInfo;
 | |
| 							MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
 | |
| 						}
 | |
| 						if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
 | |
| 							PromsPrinter.DoFoldoutPage(cb, "HLS (7 lpi) break", MyPageHelper.TextLayer, MyPageHelper);
 | |
| 					}
 | |
| 					if (MyItemInfo.MyParent != null && MyItemInfo.MyParent.IsStepSection &&
 | |
| 						MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
 | |
| 						&& !MyItemInfo.MyDocStyle.CancelSectTitle
 | |
| 						&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
 | |
| 						yPageStart = yPageStart;		// if printing the section title, we already have the y location
 | |
| 					else
 | |
| 						yPageStart = yTopMargin + YTopMost;
 | |
| 					MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
 | |
| 					DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
 | |
| 					break;
 | |
| 			}
 | |
| 			yPageStart = ChildrenAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			yPageStart = ChildrenLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 
 | |
| 			// If this is a high level step, the format may have specified that the step should be printed with
 | |
| 			// extra space between it and the previous step.  The 16bit code uses the value of the extra space
 | |
| 			// from the high level step format regardless of what type of high level step it is.  Also, if there
 | |
| 			// is caution or note above it, this space is not added:
 | |
| 			yPageStart -= ((!MyItemInfo.IsHigh || ChildrenAbove == null) ? 0 : MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[2].StepLayoutData.STExtraSpace ?? 0);
 | |
| 			yPageStart = ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			yPageStart = ChildrenRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			yPageStart = ChildrenBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 
 | |
| 			if (MyItemInfo.IsHigh && MyItemInfo.NextItem == null)		// last hls, add the 'end' message, if there is one
 | |
| 			{
 | |
| 				DocStyle docstyle = MyItemInfo.MyDocStyle;
 | |
| 				string myMsg = (docstyle.End == null) ? null : docstyle.End.Message;
 | |
| 				if (myMsg != null)
 | |
| 				{
 | |
| 					// If the flag is 0 or 1, just put the end message out right below this vlnParagraph:
 | |
| 					float msg_yLocation = CalculateYLocation(yPageStart - YBottomMost, yTopMargin);
 | |
| 
 | |
| 					// use the 'flag' to position the message.
 | |
| 					if (docstyle.End.Flag > 2)		// >2 position at an absolute location defined by docstyle.End.Flag.
 | |
| 					{
 | |
| 						msg_yLocation = yTopMargin - (float)(docstyle.End.Flag * SixLinesPerInch);
 | |
| 					}
 | |
| 
 | |
| 					if (myMsg.Contains("{Section Number}")) myMsg = myMsg.Replace("{Section Number}", MyItemInfo.ActiveSection.DisplayNumber);
 | |
| 					
 | |
| 					// center the message.
 | |
| 					float wtpm = (float)docstyle.Layout.PageWidth - (float)docstyle.Layout.LeftMargin;
 | |
| 					float centerpos = XOffsetBox + (float)docstyle.Layout.LeftMargin + (wtpm - (myMsg.Length * MyItemInfo.FormatStepData.Font.CharsToTwips)) / 2;
 | |
| 					MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, centerpos, msg_yLocation, docstyle.End.Font);
 | |
| 				}
 | |
| 			}
 | |
| 			if (yLocalypagestart != yPageStart) DebugText.WriteLine("ToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, yLocalypagestart, yPageStart);
 | |
| 			return yPageStart;
 | |
| 		}
 | |
| 		private vlnParagraph TopMostChild
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (ChildrenAbove.Count>0) return ChildrenAbove[0].TopMostChild;
 | |
| 				return this;
 | |
| 			}
 | |
| 		}
 | |
| 		private bool EmptyTopMostPart
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (TopMostChild.PartsAbove.Count == 0) return false;
 | |
| 				foreach (vlnPrintObject po in TopMostChild.PartsAbove)
 | |
| 				{
 | |
| 					vlnHeader hd = po as vlnHeader;
 | |
| 					if (hd == null) return false;
 | |
| 					if (hd.Text != "") return false;
 | |
| 				}
 | |
| 				return true;
 | |
| 			}
 | |
| 		}
 | |
| 		private void OutputOtherPageSteps(PdfContentByte cb, float YTopMost, float yPageStart, float yTopMargin, float yBottomMargin)
 | |
| 		{
 | |
| 			// Find any items remaining in MyPageHelper.MyParagraphs that should be printed on this page.
 | |
| 			vlnParagraphs process = new vlnParagraphs(null);
 | |
| 			foreach (vlnParagraph vPara in MyPageHelper.MyParagraphs.Values)
 | |
| 			{
 | |
| 				//if (!vPara.Processed && ((vPara.YOffset + vPara.Height) < YTopMost))
 | |
| 				if (!vPara.Processed && ((vPara.YOffset) < YTopMost))
 | |
| 					process.Add(vPara);
 | |
| 			}
 | |
| 			foreach (vlnParagraph vPara in process)
 | |
| 			{
 | |
| 				vPara.ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
 | |
| 			}
 | |
| 		}
 | |
| 		private float _YVeryTop = -1;
 | |
| 		public float YVeryTop
 | |
| 		{
 | |
| 			get 
 | |
| 			{
 | |
| 				if (_YVeryTop == -1)
 | |
| 				{
 | |
| 					_YVeryTop = YTop;
 | |
| 					_YVeryTop = VeryTop(PartsAbove,_YVeryTop);
 | |
| 					_YVeryTop = VeryTop(PartsContainer,_YVeryTop);
 | |
| 				}
 | |
| 				return _YVeryTop; 
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		private float VeryTop(vlnPrintObjects parts, float yVeryTop)
 | |
| 		{
 | |
| 			if (parts != null)
 | |
| 				foreach (vlnPrintObject part in parts)
 | |
| 					if (part.YOffset < yVeryTop)
 | |
| 						yVeryTop = part.YOffset;
 | |
| 			return yVeryTop;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// This gets the height of the step with it's Caution's, Notes and potentially any First Substeps
 | |
| 		/// </summary>
 | |
| 		/// <returns></returns>
 | |
| 		private float GetFirstPieceSize()
 | |
| 		{
 | |
| 			vlnParagraph paraLast = GetFirstPieceLastPart();
 | |
| 			float retval = (paraLast.YBottom) - YTopMost;
 | |
| 			//Console.WriteLine(MyItemInfo.DBSequence);
 | |
| 			return retval;
 | |
| 		}
 | |
| 		public override float YBottom
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				float bottom = YOffset + Height;
 | |
| 				if (PartsBelow != null)
 | |
| 				{
 | |
| 					foreach (vlnPrintObject part in PartsBelow)
 | |
| 					{
 | |
| 						float partBottom = part.YBottom;
 | |
| 						bottom = Math.Max(partBottom, bottom);
 | |
| 					}
 | |
| 				}
 | |
| 				return bottom;
 | |
| 			}
 | |
| 		}
 | |
| 		public float YBottomText
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				return YOffset + Height;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnParagraph GetFirstPieceLastPart()
 | |
| 		{
 | |
| 			vlnParagraph para = this;
 | |
| 			if (!MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PaginateOnFirstSubstep && ChildrenBelow != null && ChildrenBelow.Count > 0)
 | |
| 			{
 | |
| 				para = ChildrenBelow[0].GetFirstPieceLastPart();
 | |
| 			}
 | |
| 			if (ChildrenRight != null && ChildrenRight.Count > 0)
 | |
| 			{
 | |
| 				foreach(vlnParagraph paraRight in ChildrenRight)
 | |
| 				{
 | |
| 					vlnParagraph paraRightLast = paraRight.GetFirstPieceLastPart();
 | |
| 					if (paraRightLast.YBottom > para.YBottom)
 | |
| 						para = paraRightLast;
 | |
| 				}
 | |
| 			}
 | |
| 			return para;
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Find items from previous page (yLocation less than yTop) and remove them from the list.  
 | |
| 		/// yTop is the new starting location on the next page for this step.
 | |
| 		/// </summary>
 | |
| 		/// <param name="myList"></param>
 | |
| 		/// <param name="yTop"></param>
 | |
| 		private void RemoveProcessedParagraphs(StepLevelList myList, float yTop)
 | |
| 		{
 | |
| 			// the two CleanUpLists are used to remove items from 
 | |
| 			// the original list because list items cannot be removed in a
 | |
| 			// 'foreach'.
 | |
| 			List<int> CleanupListStepLevel = new List<int>();
 | |
| 			foreach(int stepLevel in myList.Keys)
 | |
| 			{
 | |
| 				List<float> CleanupListYLocation = new List<float>();
 | |
| 				SortedList<float, float> AdjustYLocation = new SortedList<float,float>();
 | |
| 				foreach (float yLocation in myList[stepLevel].Keys)
 | |
| 				{
 | |
| 					if (-yLocation <= yTop)
 | |
| 						CleanupListYLocation.Add(yLocation);
 | |
| 					else
 | |
| 						AdjustYLocation.Add(-yLocation, yLocation);  // order in ascending order
 | |
| 				}
 | |
| 				foreach (float yLocation in CleanupListYLocation)
 | |
| 					myList[stepLevel].Remove(yLocation);
 | |
| 				foreach (float yLocation in AdjustYLocation.Keys)
 | |
| 				{
 | |
| 					vlnParagraph para = myList[stepLevel][-yLocation];
 | |
| 					myList[stepLevel].Remove(-yLocation);
 | |
| 					// shift yLocation by yTop to work with items whose locations
 | |
| 					// are defined from the top of the new page rather than 
 | |
| 					// from the beginning of the step.
 | |
| 					// Note that yLocation is negative to have items in descending
 | |
| 					// order so that adding yTop decrements their values.
 | |
| 					myList[stepLevel].Add(yTop-yLocation, para);
 | |
| 				}
 | |
| 				if (myList[stepLevel].Count == 0)
 | |
| 					CleanupListStepLevel.Add(stepLevel);
 | |
| 			}
 | |
| 			foreach (int stepLevel in CleanupListStepLevel)
 | |
| 				myList.Remove(stepLevel);
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		/// Builds a list of paragraphs by StepLevel and yLocation in descending order.
 | |
| 		/// </summary>
 | |
| 		/// <param name="yTopMost"></param>
 | |
| 		/// <param name="myList"></param>
 | |
| 		private void BuildLocationList(float yTopMost, ParagraphLocations myLocations)
 | |
| 		{
 | |
| 			foreach (vlnParagraph child in ChildrenAbove)
 | |
| 				child.BuildLocationList(yTopMost, myLocations);
 | |
| 			foreach (vlnParagraph child in ChildrenLeft)
 | |
| 				child.BuildLocationList(yTopMost, myLocations);
 | |
| 
 | |
| 			// Add a list entry consisting of StepLevel, yoffset from the beginning of this step, paragraph itself
 | |
| 			myLocations.Add(this, yTopMost);
 | |
| 
 | |
| 			foreach (vlnParagraph child in ChildrenRight)
 | |
| 				child.BuildLocationList(yTopMost, myLocations);
 | |
| 			foreach (vlnParagraph child in ChildrenBelow)
 | |
| 				child.BuildLocationList(yTopMost, myLocations);
 | |
| 		}
 | |
| 		private int COL_WID_ADJ = 6;	// adjusts for incorrect use of WidSTable when breaking a line (it breaks 6 chars too short)
 | |
| 		public vlnParagraph(vlnParagraph parent, PdfContentByte cb, ItemInfo itemInfo, float xoff, float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			float savCheckListBottomMost = 0;
 | |
| 			//int[] problemIDs = { 889 };
 | |
| 			//List<int> lProblemIDs = new List<int>(problemIDs);
 | |
| 			//if (lProblemIDs.Contains(itemInfo.ItemID))
 | |
| 			//  Console.WriteLine("Found Item {0}", itemInfo.ItemID);formatInfochecko
 | |
| 			MyParent = parent;
 | |
| 			// The following code determines the last paragraph for an RNO
 | |
| 			// MyTopRNO finds the Top paragraph for an RNO
 | |
| 			if (itemInfo.IsInRNO)
 | |
| 			{
 | |
| 				if (rnoLevel <= maxRNO && itemInfo.IsRNOPart) // Not top level RNO
 | |
| 					MyTopRNO = this;
 | |
| 				else
 | |
| 					MyTopRNO = MyParent.MyTopRNO;
 | |
| 				if(MyTopRNO != null) MyTopRNO.LastRNO = this;
 | |
| 			}
 | |
| 			MyContentByte = cb;
 | |
| 			MyPageHelper.MyParagraphs.Add(itemInfo.ItemID, this);
 | |
| 			MyItemInfo = itemInfo;
 | |
| 			XOffset = xoff;
 | |
| 			if (!MyItemInfo.IsStep && !MyItemInfo.IsStepSection)
 | |
| 			{
 | |
| 				IsWordDocPara = true;
 | |
| 				// special case - this is a 'Word Doc' paragraph. The Processed flag is used to know
 | |
| 				// that steps need put out on a page for the pagination logic, and since there are no steps 
 | |
| 				// we don't want to have to worry about putting this out for pagination logic.
 | |
| 				Processed = true;			
 | |
| 				return;
 | |
| 			}
 | |
| 			// Set any position adjustment (defined in the format on a per type basis)
 | |
| 			yoff += (MyItemInfo.FormatStepData == null) ? 0 : MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0;
 | |
| 			YTopMost = YOffset = yoff;
 | |
| 			vlnTab mytab = null;
 | |
| 			bool doSectTab = false;
 | |
| 			// if this substep has a caution or note as its parent, then there may have been a special indent done on the
 | |
| 			// substep... check the CautionOrNoteSubstepIndent value, this is the additional indent amount in number
 | |
| 			// of characters.
 | |
| 			if (itemInfo.MyParent.IsCaution || itemInfo.MyParent.IsNote)
 | |
| 				XOffset += 72 * (itemInfo.FormatStepData.CautionOrNoteSubstepIndent == null ? 0 : (float)itemInfo.FormatStepData.CautionOrNoteSubstepIndent / (float)itemInfo.FormatStepData.Font.CPI);
 | |
| 
 | |
| 			if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate &&
 | |
| 				itemInfo.FormatStepData.StepLayoutData.AlignWithParentTab 
 | |
| 				|| (itemInfo.Steps != null && itemInfo.Steps.Count > 0 && itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab))
 | |
| 				itemInfo.MyTab = null;
 | |
| 			if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && itemInfo.MyTab.Text != "")
 | |
| 			{
 | |
| 				float localXOffset = XOffset;
 | |
| 				bool doprint = true;
 | |
| 				if (itemInfo.IsSection)
 | |
| 				{
 | |
| 					SectionConfig sch = MyItemInfo.MyConfig as SectionConfig;
 | |
| 					if (!(MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
 | |
| 							&& !MyItemInfo.MyDocStyle.CancelSectTitle
 | |
| 							&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
 | |
| 						&&
 | |
| 					((sch != null && sch.Section_PrintHdr != "Y") || !MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections)) doprint = false;
 | |
| 				}
 | |
| 				if (doprint && itemInfo.IsSection && !itemInfo.MyDocStyle.CancelSectTitle && itemInfo.MyTab.Text.ToUpper() != "FOLDOUT")
 | |
| 				{
 | |
| 					doSectTab = true;
 | |
| 					if (itemInfo.IsStepSection && formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Just == "PSLeft")
 | |
| 					{
 | |
| 						float offset = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 						if (formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos != null)
 | |
| 						{
 | |
| 							// determine level of metasections.  This level will be used to calculate the
 | |
| 							// indent.     DO I NEED THIS HERE????
 | |
| 							int level = 0;
 | |
| 							ItemInfo iilvl = itemInfo;
 | |
| 							while (!iilvl.IsProcedure)
 | |
| 							{
 | |
| 								level++;
 | |
| 								iilvl = iilvl.MyParent;
 | |
| 							}
 | |
| 							level = level <= 2 ? 1 : level - 1;
 | |
| 							if (level == 1)
 | |
| 							offset += (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos;
 | |
| 							else
 | |
| 								offset += (level-1) * ((float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos-(float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos);
 | |
| 						}
 | |
| 						localXOffset = offset;
 | |
| 					}
 | |
| 				}
 | |
| 				if (!itemInfo.IsSection || doSectTab)
 | |
| 				{
 | |
| 					mytab = new vlnTab(cb, this, itemInfo.MyTab.Text, itemInfo.MyTab.CleanText, localXOffset, yoff, itemInfo.MyTab.MyFont, doSectTab, StepRTB.MySymbolFontName, itemInfo.MyTab.RemovedStyleUnderline);
 | |
| 					PartsLeft.Add(mytab);
 | |
| 					if (mytab.MyMacro != null) PartsLeft.Add(mytab.MyMacro);
 | |
| 				}
 | |
| 			}
 | |
| 			AdjustWidth(itemInfo, maxRNO, formatInfo, mytab);
 | |
| 			AdjustXOffsetForTab(itemInfo, maxRNO, formatInfo, mytab);
 | |
| 			if (itemInfo.Cautions != null && !(itemInfo.IsCaution || itemInfo.IsNote))
 | |
| 				yoff = ChildrenAbove.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
 | |
| 			if (itemInfo.Notes != null && !(itemInfo.IsCaution || itemInfo.IsNote))
 | |
| 				yoff = ChildrenAbove.Add(cb, itemInfo.Notes, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
 | |
| 			YTop = yoff;
 | |
| 			if (itemInfo.MyHeader != null && itemInfo.MyHeader.Text != null && !doSectTab)
 | |
| 				yoff += SetHeader(this, cb, itemInfo, formatInfo);
 | |
| 			YOffset = yoff;
 | |
| 			if (mytab != null && mytab.SeparateBullet)
 | |
| 			{
 | |
| 				string identB = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.IdentB;
 | |
| 				vlnText myBullet = new vlnText(cb, this, identB, identB, XOffset - 12, YOffset, MyItemInfo.FormatStepData.TabData.Bullet.Font);
 | |
| 				myBullet.Rtf = myBullet.Rtf.Replace("\u25CF", @"\f1\u9679?\f0 ");
 | |
| 				PartsLeft.Add(myBullet);
 | |
| 			}
 | |
| 			if (itemInfo.IsRNOPart)
 | |
| 			{
 | |
| 				// there may be other places that double space, but this supports it for RNOs (the DoubleRNOspace flag)
 | |
| 				if (rnoLevel > maxRNO && itemInfo.FormatStepData.DoubleSpace) yoff = YOffset = yoff + SixLinesPerInch;
 | |
| 			}
 | |
| 			AddMacros(itemInfo, mytab);
 | |
| 			if (mytab != null)
 | |
| 			{
 | |
| 				mytab.YOffset = yoff;
 | |
| 				if (mytab.MyMacro != null) mytab.MyMacro.YOffset = yoff;
 | |
| 			}
 | |
| 			float yForCheckoff = yoff; //0; - default checkoff row is same as FIRST line of text
 | |
| 			// if dropCheckoff is true, then the checkoff is place on the same of row as the LAST line of text
 | |
| 			bool dropCheckoff = itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.DropCheckOff;
 | |
| 			if (itemInfo.MyContent.MyGrid != null)
 | |
| 			{
 | |
| 				VlnFlexGrid myFlexGrid = new VlnFlexGrid(1,1);
 | |
| 				myFlexGrid.LoadGrid(itemInfo);
 | |
| 				MyGrid = new vlnTable(myFlexGrid, cb);
 | |
| 				Height = MyGrid.Height;
 | |
| 				Width = MyGrid.Width;
 | |
| 				//yForCheckoff = yoff + Height - SixLinesPerInch;
 | |
| 				if (dropCheckoff)
 | |
| 					yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text
 | |
| 				yoff += (Height + (2 * SixLinesPerInch));
 | |
| 				CalculateXOffset(itemInfo, maxRNO, formatInfo);
 | |
| 			}
 | |
| 			else if (itemInfo.IsFigure)		// if a figure we've got to determine the size:
 | |
| 			{
 | |
| 				string erMsg = null;
 | |
| 				if (itemInfo.MyContent.Text != null)
 | |
| 				{
 | |
| 					ProcedureInfo proc = itemInfo.MyProcedure;
 | |
| //					DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo;
 | |
| 					DocVersionInfo dvi = proc.MyDocVersion;
 | |
| 					ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst;
 | |
| 					rofst.docVer = dvi;
 | |
| 					ROFSTLookup lookup = rofst.ROFSTLookup;
 | |
| 					string linkInfoText = itemInfo.MyContent.Text.Replace(@"\v ", "");
 | |
| 					if (linkInfoText.Contains("?"))
 | |
| 						erMsg = "RO was not found during data migration.";
 | |
| 					else
 | |
| 					{
 | |
| 					Match m = Regex.Match(linkInfoText, @"(.*)[#]Link:([A-Za-z]*):(.*)");
 | |
| 					string[] subs = m.Groups[3].Value.Split(" ".ToCharArray());
 | |
| 					string roid = subs[1];
 | |
| 					string val = lookup.GetRoValue(subs[1]);
 | |
| 					if (val == null) val = lookup.GetRoValue(subs[1].Substring(0, 12));
 | |
| 					if (val != null)
 | |
| 					{
 | |
| 						string[] vals = val.Split("\n".ToCharArray());
 | |
| 						Width = Int32.Parse(vals[3], System.Globalization.NumberStyles.AllowHexSpecifier) * MyItemInfo.FormatStepData.Font.CharsToTwips;
 | |
| 						int lines = Int32.Parse(vals[2], System.Globalization.NumberStyles.AllowHexSpecifier);
 | |
| 						Height = lines * SixLinesPerInch;
 | |
| 						//yForCheckoff = yoff + Height - SixLinesPerInch;
 | |
| 						if (dropCheckoff)
 | |
| 							yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text
 | |
| 						yoff += (Height + (2 * SixLinesPerInch));
 | |
| 
 | |
| 						try
 | |
| 						{
 | |
| 							ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]);
 | |
| 							if (roImage != null)
 | |
| 								ImageText = val;
 | |
| 							else
 | |
| 								erMsg = string.Format("Image {0} does not exist.", vals[0]);
 | |
| 						}
 | |
| 
 | |
| 						catch (Exception ex)
 | |
| 						{
 | |
| 							erMsg = string.Format("Image {0} does not exist, error = {1}.", vals[0], ex.Message);
 | |
| 						}
 | |
| 					}
 | |
| 					}
 | |
| 					if (erMsg != null) Rtf = GetRtf(erMsg, itemInfo.ActiveFormat.PlantFormat.FormatData.Font);
 | |
| 					CalculateXOffset(itemInfo, maxRNO, formatInfo);
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				Rtf = GetRtf(itemInfo);
 | |
| 				// Need the following with some modifications for WCNCKL format:
 | |
| 				if (Rtf.Contains("{Backspace}"))
 | |
| 				{
 | |
| 					XOffset -= 22;
 | |
| 					Width += 24;
 | |
| 					Rtf = Rtf.Replace("{Backspace}", "");
 | |
| 				}
 | |
| 				if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate)
 | |
| 				{
 | |
| 					if (itemInfo.FormatStepData.StepLayoutData.AlignWithParentTab 
 | |
| 					|| (itemInfo.Steps != null && itemInfo.Steps.Count > 0 && itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab))
 | |
| 					{
 | |
| 						int stplevl = TheStepLevel(itemInfo);
 | |
| 						if (stplevl >= 0 && MyItemInfo.MyHLS.FormatStepData.VertPos[stplevl] > 0)
 | |
| 							XOffset = float.Parse(MyItemInfo.MyHLS.FormatStepData.VertPos.Split(",".ToCharArray())[stplevl]) + (float)itemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 					}
 | |
| 				}
 | |
| 				if (itemInfo.IsTablePart)			// Not for grid, this is for old-style tables.
 | |
| 				{
 | |
| 					Width = GetTableWidth(cb, IParagraph, MyItemInfo.MyDocStyle.Layout.PageWidth);
 | |
| 					CalculateXOffset(itemInfo, maxRNO, formatInfo);
 | |
| 				}
 | |
| 				else
 | |
| 					if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null) XOffset += (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0);
 | |
| 
 | |
| 				bool printMetaHdr = false;
 | |
| 				if (itemInfo.Steps != null && itemInfo.IsSection && itemInfo.Sections != null && itemInfo.Sections.Count > 0)
 | |
| 				{
 | |
| 					SectionConfig sc = itemInfo.MyConfig as SectionConfig;
 | |
| 					if ((sc != null && sc.Section_PrintHdr == "Y") && itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections) printMetaHdr = true;
 | |
| 				}
 | |
| 
 | |
| 				// If WCN checklists, the substeps are printed in a row, need to keep track of the 'longest' in
 | |
| 				// y direction (bottommost) across the row.
 | |
| 				if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate && (TheStepLevel(itemInfo)>0))
 | |
| 				{
 | |
| 					// do I need to get max of savCheckListBottomMost & (yoff+Height+SixLinesPerInch)
 | |
| 					savCheckListBottomMost = yoff + Height + SixLinesPerInch;
 | |
| 				}
 | |
| 				// Get Y offset for regular steps, or if section title is output or if not within row (not last column of
 | |
| 				// text) for wcn checklist, i.e. .
 | |
| 				if ((!itemInfo.IsStepSection && !itemInfo.MyHLS.FormatStepData.UseSmartTemplate)
 | |
| 					|| printMetaHdr ||
 | |
| 					(formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles 
 | |
| 					&& !MyItemInfo.MyDocStyle.CancelSectTitle
 | |
| 					&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
 | |
| 					// In WCN Checklist: I don't have children or if I have children the first child doesn't alignwithparent.
 | |
| 					|| (!itemInfo.IsStepSection && itemInfo.MyHLS.FormatStepData.UseSmartTemplate
 | |
| 						&& ((itemInfo.Steps == null || itemInfo.Steps.Count == 0)
 | |
| 						|| !itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab)))
 | |
| 				{
 | |
| 					yoff += Height;
 | |
| 					yoff += AdjustForBlankLines();
 | |
| 					if (dropCheckoff)
 | |
| 						yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text
 | |
| 				}
 | |
| 			}
 | |
| 			CheckOff co = itemInfo.GetCheckOffStep();
 | |
| 			if (co != null)
 | |
| 			{
 | |
| 				//float xloc_co = (float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation + (float)itemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 				float xloc_co = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 				if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation != null)
 | |
| 					xloc_co += (float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation;
 | |
| 				PartsRight.Add(new vlnMacro(xloc_co, yForCheckoff, co.Macro));
 | |
| 			}
 | |
| 			float yOffRight = yoff;
 | |
| 			float RnoOffset = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
 | |
| 			if (rnoLevel < maxRNO && itemInfo.RNOs != null) yOffRight = ChildrenRight.Add(cb, itemInfo.RNOs, XOffset + RnoOffset, YTop, YTop, rnoLevel + 1, maxRNO, formatInfo);
 | |
| 			// Need code to determine if the table will overlap the Right Column if it does then 
 | |
| 			// use YOffRight rather than yoff
 | |
| 			if (itemInfo.Tables != null)
 | |
| 			{
 | |
| 				bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
 | |
| 				if(!aerTableOrFigure && itemInfo.RNOLevel == 0) // Centered Table
 | |
| 					yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yOffRight, yOffRight, rnoLevel, maxRNO, formatInfo);
 | |
| 				else // AER or RNO Table
 | |
| 					yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
 | |
| 			}
 | |
| 
 | |
| 			// Look for the meta section case where the 'Editable' flag is set to 'N', which means that
 | |
| 			// these steps should not be printed:
 | |
| 			bool printsteps = true;
 | |
| 			if (itemInfo.Steps != null && itemInfo.IsSection && itemInfo.Sections!=null && itemInfo.Sections.Count>0)
 | |
| 			{
 | |
| 				SectionConfig sc = itemInfo.MyConfig as SectionConfig;
 | |
| 				if (sc != null && sc.SubSection_Edit != "Y") printsteps = false;
 | |
| 			}
 | |
| 
 | |
| 			if (itemInfo.Steps != null && printsteps) yoff = ChildrenBelow.Add(cb, itemInfo.Steps, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
 | |
| 			if (itemInfo.Sections != null) yoff = ChildrenBelow.Add(cb, itemInfo.Sections, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
 | |
| 			if (itemInfo.Procedures != null) yoff = ChildrenBelow.Add(cb, itemInfo.Procedures, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
 | |
| 			if (rnoLevel >= maxRNO && itemInfo.RNOs != null) yoff = ChildrenBelow.Add(cb, itemInfo.RNOs, XOffset, yoff, yoff, rnoLevel + 1, maxRNO, formatInfo);
 | |
| 			yoff = Math.Max(yoff, yOffRight);
 | |
| 			// TODO - use RNOSepAfterAER flag too:
 | |
| 			string tmpRnoSepStr = formatInfo.MyStepSectionPrintData.RNOSepString;
 | |
| 			if (rnoLevel < maxRNO && itemInfo.RNOs != null && tmpRnoSepStr != null)
 | |
| 			{
 | |
| 				vlnParagraph rno = ChildrenRight[0];
 | |
| 				vlnParagraph bottomChild = BottomChild;
 | |
| 				float xsep = MyHighLevelParagraph.XOffset + RnoOffset;
 | |
| 				vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff, formatInfo, bottomChild==null?true:bottomChild.MyItemInfo.HasChangeBar);
 | |
| 				// TODO: May need to handle more than one RNO column for RNO Separator
 | |
| 				if (rno.LastRNO.MyItemInfo.HasChangeBar == false && bottomChild != null && bottomChild.MyItemInfo.HasChangeBar)
 | |
| 					bottomChild.PartsBelow.Add(myRnoSep);
 | |
| 				else
 | |
| 					rno.LastRNO.PartsBelow.Add(myRnoSep);
 | |
| 				yoff += myRnoSep.Height + SixLinesPerInch;
 | |
| 			}
 | |
| 			YBottomMost = yoff;
 | |
| 
 | |
| 			// For WCN Checklist, the substeps are in rows of data.  The YBottomMost is the bottom most for
 | |
| 			// the row.
 | |
| 			if (savCheckListBottomMost != 0 && savCheckListBottomMost>YBottomMost) YBottomMost = savCheckListBottomMost;
 | |
| 		}
 | |
| 
 | |
| 		private int TheStepLevel(ItemInfo itemInfo)
 | |
| 		{
 | |
| 			if (itemInfo.IsHigh) return -1;
 | |
| 			int lev = 0;
 | |
| 			ItemInfo ii = itemInfo;
 | |
| 			while (!ii.MyParent.IsHigh)
 | |
| 			{
 | |
| 				lev++;
 | |
| 				ii = ii.MyParent;
 | |
| 			}
 | |
| 			return lev;
 | |
| 		}
 | |
| 
 | |
| 		private string SectionHasCheckOffHeader(ItemInfo itemInfo, ref VE_Font font)
 | |
| 		{
 | |
| 			// If the passed in itemInfo is not a section, get it's parent section.  This may be a subsection, so
 | |
| 			// it will be found here, versus using 'MyActiveSection'.
 | |
| 			while (!itemInfo.IsSection)
 | |
| 			{
 | |
| 				itemInfo = itemInfo.MyParent;
 | |
| 			}
 | |
| 			// See if this section has a checkoffheading index - this value, if set is stored in the config field.
 | |
| 			// -1 flags no entries in the format's CheckOffHeaderList & 0 flags the first
 | |
| 			// entry which is always '{NO HEADING}'.  So only continue if it's greater than 0.
 | |
| 			SectionInfo si = SectionInfo.Get(itemInfo.ItemID);   // sometimes the itemInfo isn't a section info
 | |
| 			int sindx = si.CheckOffHeadingIndex();
 | |
| 
 | |
| 			// If there is a checkoff header for this section, see if this section has subsections.
 | |
| 			// If this has a header but no subsections, put out the header.
 | |
| 			// Else if this section has a header AND subsections, don't put it out...
 | |
| 			//   the subsection's checkoff header will be processed (or lack there of).
 | |
| 			bool doCheckoffHeader = sindx > 0 && (itemInfo.Sections == null || itemInfo.Sections.Count == 0);
 | |
| 
 | |
| 			// if doing it, then grab the string from the format....  CHECK if this works for subsection, it is
 | |
| 			// getting ActiveSection which may return the top section, not subsections.
 | |
| 			if (doCheckoffHeader && itemInfo.SectionCheckOffHeader != "")
 | |
| 			{
 | |
| 				font = itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList[sindx].Font;
 | |
| 				return itemInfo.SectionCheckOffHeader;
 | |
| 			}
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		private void DoCheckOffHeader(PdfContentByte cb, ItemInfo itemInfo, float yLocation, float yTopMargin, float yPageStart)
 | |
| 		{
 | |
| 			// CheckOffHeaders are handled in two different ways:
 | |
| 			//	1) Where the pagelist item puts them - this is at the 'top' of the page, when the current section on the
 | |
| 			//		page has a checkoff header defined. Support for this is here AND in the VlnSvgPageHelper pagelist code.
 | |
| 			//	2) If a continuous section, and it doesn't start at 'top' of the page, then the checkoff header is
 | |
| 			//		printed on the same line as the continuous section.  Support for this is here, the check off header is added
 | |
| 			//		to the 'PartRight' off of the section's VlnParagraph.
 | |
| 	
 | |
| 			// First see if there is any checkoff data in the format file and that there
 | |
| 			// is a pagelist item for the checkoff header.
 | |
| 			if (itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList.Count <= 0) return;
 | |
| 			if (MyPageHelper.PageListCheckOffHeader == null) return;
 | |
| 
 | |
| 			VE_Font font = null;
 | |
| 			ItemInfo mySectionInfo = itemInfo.MyActiveSection;
 | |
| 			ItemInfo mySubSectionInfo = itemInfo;
 | |
| 
 | |
| 			// If the passed in itemInfo is not a section, get it's parent section.  This may be a subsection, so
 | |
| 			// it will be found here, versus using 'MyActiveSection' which is the topmost section.  The passed in
 | |
| 			// item may be a regular step, i.e. if a page break had occurred.
 | |
| 			if (!itemInfo.IsSection)
 | |
| 			{
 | |
| 				while (!mySubSectionInfo.IsSection)
 | |
| 				{
 | |
| 					mySubSectionInfo = mySubSectionInfo.MyParent;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 				mySubSectionInfo = (mySectionInfo.Sections == null)?null:mySectionInfo.Sections[0];
 | |
| 
 | |
| 			if (mySectionInfo == mySubSectionInfo) mySubSectionInfo = null;
 | |
| 
 | |
| 			// The following duplicates the 16bit logic.  The 16bit logic only put out a header if:
 | |
| 			//		there is no subsection and section has a header (from config);
 | |
| 			//		OR there is a subsection and the first subsection has a header.
 | |
| 			// For locating the header in 16bit logic:
 | |
| 			//		If no subsections, output with section 
 | |
| 			//		If subsections and continuous section, put out on same line as subsection.  (done here)
 | |
| 			//		If subsections and starts at top of page, (on top of page, use pagelist code in VlnSvgPageHelper)
 | |
| 			
 | |
| 			// Get SectionInfos to access specific section config items...
 | |
| 			SectionInfo si = SectionInfo.Get(mySectionInfo.ItemID);   
 | |
| 			int sindx = si.CheckOffHeadingIndex();
 | |
| 			SectionInfo subi = mySubSectionInfo == null ? null : SectionInfo.Get(mySubSectionInfo.ItemID);
 | |
| 			int subindx = subi==null?-1:subi.CheckOffHeadingIndex();
 | |
| 
 | |
| 			// if there is no subsections & the main section doesn't use a header OR
 | |
| 			// if there is a subsection, & it does not use a header... Return.
 | |
| 			if ((subi==null&&sindx < 1) || (subi!=null&&subindx<1)) return;
 | |
| 
 | |
| 			// figure out location now:
 | |
| 			//	if step, it uses pagelist logic to locate it (this is a page break condition).
 | |
| 			//	if continuous, put out with subsection if there is one, otherwise section.
 | |
| 			//	otherwise, use pagelist logic.
 | |
| 			bool usePageListCOHdr = false;
 | |
| 			
 | |
| 			if (itemInfo.IsStep)
 | |
| 				usePageListCOHdr = true;
 | |
| 			else if (subi == null)		//no subsection
 | |
| 			{
 | |
| 				if ((yPageStart - YOffset) == yTopMargin) usePageListCOHdr = true;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if (mySectionInfo == itemInfo && ((yPageStart - YOffset) == yTopMargin)) usePageListCOHdr = true;
 | |
| 				if (!usePageListCOHdr && mySubSectionInfo != itemInfo) return;
 | |
| 			}
 | |
| 
 | |
| 			// grab the string from the format, depending on whether it should get it from the section or subsection.
 | |
| 			string cohead = (mySubSectionInfo!=null)?mySubSectionInfo.SectionCheckOffHeader:mySectionInfo.SectionCheckOffHeader;
 | |
| 			if (cohead == "" || cohead == null) return;
 | |
| 
 | |
| 			// PageListCheckOffHeader is an svgtext - but really we only need the x/y location for this (pagelist support)
 | |
| 			// The actual text is from the checkoff header selection in the section config. 
 | |
| 			if (cohead != MyPageHelper.PageListLastCheckOffHeader)
 | |
| 			{
 | |
| 				font = mySectionInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList[sindx].Font;
 | |
| 				float chkOffY = CalculateYLocation(YTopMost, yTopMargin);
 | |
| 				if (MyPageHelper.YMultiplier != 1)
 | |
| 				{
 | |
| 					chkOffY = -1 + yTopMargin - (yTopMargin - yLocation) * MyPageHelper.YMultiplier;
 | |
| 					if (Rtf != null)
 | |
| 						IParagraph.Leading = _SevenLinesPerInch;
 | |
| 				}
 | |
| 				if (!usePageListCOHdr)
 | |
| 				{
 | |
| 					vlnText myCOHead = new vlnText(cb, this, cohead, cohead, MyPageHelper.PageListCheckOffHeader.X.Value + (float)MyItemInfo.MyDocStyle.Layout.LeftMargin, chkOffY, font);
 | |
| 					PartsRight.Add(myCOHead);
 | |
| 				}
 | |
| 				else
 | |
| 					MyPageHelper.PageListTopCheckOffHeader = cohead;
 | |
| 				MyPageHelper.PageListLastCheckOffHeader = cohead;
 | |
| 			}
 | |
| 		}
 | |
| 		internal vlnParagraph BottomChild
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				float bottomChildYBottomText = YBottomText;
 | |
| 				vlnParagraph bottomChild = this;
 | |
| 				foreach (vlnParagraph child in ChildrenRight)
 | |
| 				{
 | |
| 					vlnParagraph grandChild = child.BottomChild;
 | |
| 					if (grandChild != null && grandChild.YBottomText > bottomChildYBottomText) bottomChild = grandChild;
 | |
| 					if (grandChild != null && grandChild.YBottomText == bottomChildYBottomText && grandChild.MyItemInfo.HasChangeBar) bottomChild = grandChild;
 | |
| 					bottomChildYBottomText = bottomChild.YBottomText;
 | |
| 				}
 | |
| 				foreach (vlnParagraph child in ChildrenBelow)
 | |
| 				{
 | |
| 					vlnParagraph grandChild = child.BottomChild;
 | |
| 					if (grandChild != null && grandChild.YBottomText > bottomChildYBottomText) bottomChild = grandChild;
 | |
| 					if (grandChild != null && grandChild.YBottomText == bottomChildYBottomText && grandChild.MyItemInfo.HasChangeBar) bottomChild = grandChild;
 | |
| 					bottomChildYBottomText = bottomChild.YBottomText;
 | |
| 				}
 | |
| 				return bottomChild;
 | |
| 			}
 | |
| 		}
 | |
| 		private void CalculateXOffset(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
 | |
| 			vlnParagraph hls1 = MyParent;
 | |
| 			while (hls1.MyParent != null && !hls1.MyItemInfo.IsHigh) hls1 = hls1.MyParent;
 | |
| 			float colR = float.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[itemInfo.ColumnMode]);
 | |
| 			float xLowerLimit = hls1.XOffset;
 | |
| 			float xUpperLimit = hls1.XOffset + hls1.Width + colR * itemInfo.ColumnMode;
 | |
| 			float TableCenterPos = float.Parse(formatInfo.MyStepSectionLayoutData.TableCenterPos.Split(",".ToCharArray())[itemInfo.ColumnMode]);
 | |
| 			if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel)
 | |
| 			{
 | |
| 				float pageWidth = ((float)itemInfo.MyActiveSection.MyDocStyle.Layout.PageWidth); //* (float)MyItemInfo.FormatStepData.Font.CPI / 12;
 | |
| 				float leftMargin = ((float)itemInfo.MyActiveSection.MyDocStyle.Layout.LeftMargin); //* (float)MyItemInfo.FormatStepData.Font.CPI / 12;
 | |
| 				XOffset = leftMargin + (pageWidth - leftMargin - Width) / 2;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				// Determine center of hls
 | |
| 				XOffset = hls1.XOffset + hls1.Width / 2;
 | |
| 				// Determine left edge of the table by subtracting 1/2 of its width.
 | |
| 				XOffset -= Width / 2;
 | |
| 				if (aerTableOrFigure || itemInfo.RNOLevel != 0)	// AER or RNO 
 | |
| 					XOffset = MyParent.XOffset + MyParent.Width / 2 - Width / 2;
 | |
| 				else if (TableCenterPos != 0)
 | |
| 					XOffset = TableCenterPos;
 | |
| 				else  // Centered Table or Figure
 | |
| 				{
 | |
| 					// Add in 1/2 of the width of all RNO columns
 | |
| 					XOffset += (colR * itemInfo.ColumnMode) / 2;
 | |
| 					if (!aerTableOrFigure)
 | |
| 					{
 | |
| 						// 05/14/12 - 16bit code adjusts the center depending upon the CPI of the table font.
 | |
| 						// Start with XOffset of table, then calculate the XOffset adjusted for the table font,
 | |
| 						// based on the default CPI of 12.  Adjust the XOffset by the difference of these
 | |
| 						// two numbers.
 | |
| 						XOffset -= (XOffset - (XOffset * (float)MyItemInfo.FormatStepData.Font.CPI / 12));
 | |
| 					}
 | |
| 					XOffset -= 12;			// This makes the 16bit & 32bit align very closely.
 | |
| 				}
 | |
| 				// 05/14/12 - The PosAdjust is a format flag from 16bit. For WCN2, it appears that this amount equals
 | |
| 				// the amount of difference from a 10 CPI to a 12 CPI font.  See comment above.
 | |
| 				if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null)
 | |
| 					XOffset += (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0);
 | |
| 			}
 | |
| 
 | |
| 
 | |
| 			// if the XOffset < High Level Step Text's XOffset, then align with the High Level Step Text
 | |
| 			if (XOffset < xLowerLimit && Width < (xUpperLimit - xLowerLimit))
 | |
| 				XOffset = xLowerLimit;
 | |
| 
 | |
| 			// if the right margin exceeds the right edge of the rightmost RNO, then adjust right edge to match.
 | |
| 			if (XOffset + Width > xUpperLimit)
 | |
| 				XOffset = xUpperLimit - Width;
 | |
| 
 | |
| 			// because of the above, if it pushes beyond the left margin, use the left margin.
 | |
| 			if (XOffset < (float)itemInfo.MyDocStyle.Layout.LeftMargin)
 | |
| 				XOffset = XOffsetBox = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 		}
 | |
| 		private float AdjustForBlankLines()
 | |
| 		{
 | |
| 			if (MyItemInfo.MyDocStyle.SpecialStepsFoldout) return 0;
 | |
| 			int everyNLines = MyItemInfo.FormatStepData == null ? 1 : MyItemInfo.FormatStepData.StepLayoutData.EveryNLines ?? 1;
 | |
| 			if (MyItemInfo.Ordinal % everyNLines == 0 || MyItemInfo.NextItem == null) return SixLinesPerInch;
 | |
| 			return 0;
 | |
| 		}
 | |
| 		private void AddMacros(ItemInfo itemInfo, vlnTab mytab)
 | |
| 		{
 | |
| 			float y = YOffset;
 | |
| 			float x = mytab == null ? XOffset : mytab.XOffset + mytab.TabOffset;
 | |
| 			List<Macro> myMacros = itemInfo.MyMacros;
 | |
| 			if (myMacros != null)
 | |
| 			{
 | |
| 				foreach (Macro myMacro in myMacros)
 | |
| 				{
 | |
| 					PartsLeft.Add(new vlnMacro(x, y, myMacro.MacroDef));
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		// HLP Change bar flags in format file:
 | |
| 		// Locations:  With Text, Outside Box, AER on Left RNO on Right, To The Left of Text
 | |
| 		// Text:  Date & Change ID, Revision Number, Change ID, None, Custom (use input data)
 | |
| 		// Flag AERChgBarMsgRNOChgBarNoMsg and AERMsgRNONoMsg are NOT Used in 16-bit.
 | |
| 		private string cbMess = null;
 | |
| 		private vlnChangeBar DoChangeBar(PdfContentByte cb, ItemInfo itemInfo, VlnSvgPageHelper myPageHelper, float xoff, float yoff, int maxRNO, FormatInfo formatInfo) //, vlnChangeBar myCB)
 | |
| 		{
 | |
| 			// find column for the change bar based on format flags - this is code from 16-bit
 | |
| 			//		if AbsoluteFixedChangeColumn
 | |
| 			//			if FixedAERChangeColumn
 | |
| 			//				if col>ColsS+ColR+COL_WID+ADJ
 | |
| 			//					FixedChangeColumn
 | |
| 			//				else
 | |
| 			//					AERLeftChangeBarLocation()
 | |
| 			//			else
 | |
| 			//				FixedChangeColumn
 | |
| 			//		else
 | |
| 			//			ChangeBarLocation()
 | |
| 			ChangeBarData cbd = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData;
 | |
| 			float cols = formatInfo.MyStepSectionLayoutData.ColS ?? 0;
 | |
| 			float colr = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
 | |
| // FixedChangeColumn + - Column location for change bars 
 | |
| 			// 0 - Separate AER and RNO change bars to the right of the text 
 | |
| 			// -10 to -1 - Change bars on left (specify # of columns from the text) 
 | |
| 			// <-10 - AER change bars on the left and RNO change bars on the right.
 | |
| // FixedAERChangeColumn	overrides the -5 default setting in chgbar.c, value is converted to a negative by the code
 | |
| 
 | |
| 			float col = (cbd.AbsoluteFixedChangeColumn) ?
 | |
| 							((cbd.FixedAERChangeColumn ?? 0) > 0) ?
 | |
| 							(xoff > (cols + colr + COL_WID_ADJ)) ?
 | |
| 								cbd.FixedChangeColumn ?? 0 : AERLeftChangeBarLocation(formatInfo) :
 | |
| 							cbd.FixedChangeColumn ?? 0 : ChangeBarLocation(xoff, this, formatInfo, maxRNO);
 | |
| 
 | |
| 			if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.ChgID)
 | |
| 				cbMess = itemInfo.MyContent.UserID;
 | |
| 			else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.DateChgID)
 | |
| 			{
 | |
| 				string fmtDate = itemInfo.MyContent.DTS.ToShortDateString();
 | |
| 				if (fmtDate.Length != 10)  // need to add zeros 
 | |
| 				{
 | |
| 					if (fmtDate.IndexOf("/") == 1)
 | |
| 						fmtDate = "0" + fmtDate;
 | |
| 					if (fmtDate.IndexOf("/", 3) == 1)
 | |
| 						fmtDate = fmtDate.Substring(0, 3) + "0" + fmtDate.Substring(3, fmtDate.Length - 3);
 | |
| 				}
 | |
| 				cbMess = itemInfo.MyContent.UserID + @"\n" + fmtDate;
 | |
| 			}
 | |
| 			else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.RevNum)
 | |
| 				cbMess = myPageHelper.Rev;
 | |
| 			else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.UserDef)
 | |
| 				cbMess = myPageHelper.ChangeBarDefinition.MyChangeBarMessage;
 | |
| 
 | |
| 			int msgAlign = Element.ALIGN_LEFT;
 | |
| 			if (myPageHelper.ChangeBarDefinition.MyChangeBarLoc == PrintChangeBarLoc.LeftOfText ||
 | |
| 				(myPageHelper.ChangeBarDefinition.MyChangeBarLoc == PrintChangeBarLoc.AERleftRNOright &&
 | |
| 				!itemInfo.IsInRNO)) msgAlign = Element.ALIGN_RIGHT;
 | |
| 			return new vlnChangeBar(cb, this, (float)itemInfo.MyDocStyle.Layout.LeftMargin + (col * itemInfo.FormatStepData.Font.CharsToTwips), yoff, msgAlign);
 | |
| 		}
 | |
| 
 | |
| 		private int ChangeBarLocation(float c, vlnParagraph paragraph, FormatInfo formatInfo, int maxRNO)
 | |
| 		{
 | |
| 			int fixedChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedChangeColumn ?? 0;
 | |
| 			float cols = formatInfo.MyStepSectionLayoutData.ColS ?? 0;
 | |
| 			int colr = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
 | |
| 			float tmpc = c;
 | |
| 			if (MyItemInfo.IsCaution || MyItemInfo.IsNote)
 | |
| 			{
 | |
| 			// Temporary fix for change bars on Notes and Cautions where the FixedChgCol < -10
 | |
| 				tmpc = (float)formatInfo.MyStepSectionLayoutData.ColT + (float)formatInfo.MyStepSectionLayoutData.WidT; // end position of Caution / Note
 | |
| 				int typ = (int)(MyItemInfo.MyContent.Type % 10000);
 | |
| 				int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
 | |
| 				if (bxIndx != null)
 | |
| 				{
 | |
| 					Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
 | |
| 					if (bx != null)
 | |
| 						tmpc = (float)bx.Start + (float)bx.End; // end position of a boxed Caution / Note
 | |
| 				}
 | |
| 			}
 | |
| 			// if this is a caution or note, put the change bar to the right of the text:
 | |
| 			//if ((paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote) && fixedChgCol < -10) return -fixedChgCol;
 | |
| 			if ((fixedChgCol == 0))// && paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote)
 | |
| 			//if ((fixedChgCol==0) || paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote)
 | |
| 			{
 | |
| 				float rightEdge = (paragraph.XOffset + paragraph.Width + 5);
 | |
| 					rightEdge-=(float)paragraph.MyItemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 				rightEdge = rightEdge/paragraph.MyItemInfo.FormatStepData.Font.CharsToTwips;
 | |
| 				return (int)rightEdge;
 | |
| 			}
 | |
| 			if (fixedChgCol < -10 || fixedChgCol >= 0)
 | |
| 				return ((fixedChgCol > 0) ? fixedChgCol :
 | |
| 					(fixedChgCol == 0) ? (int)c + 1 :
 | |
| 					(tmpc > (cols + colr + COL_WID_ADJ)) ? -fixedChgCol :
 | |
| 					//(c > (cols + colr + COL_WID_ADJ) || (MyItemInfo.IsCaution || MyItemInfo.IsNote)) ? -fixedChgCol :
 | |
| 					AERLeftChangeBarLocation(formatInfo));
 | |
| 			else
 | |
| 				return (int)(fixedChgCol + (((c < cols + Width + colr) || TableTest()
 | |
| 					|| MyItemInfo.IsCaution || MyItemInfo.IsNote) ? 0 : cols + colr)); // || (GetColumnMode() == 0)) ? 0 : cols + colr));
 | |
| 			/* Change bars to left of text -- ColS+WidS+ColR is the end of RNO col*/
 | |
| 		}
 | |
| 		/*
 | |
| 		** Centered tables whose width exceeds the end of the RNO column should
 | |
| 		**  still have their change bars printed on the left.  This procedure checks 
 | |
| 		**  to make sure the step is a table and that it is not an RNO.
 | |
| 		*/
 | |
| 		private bool TableTest()
 | |
| 		{
 | |
| 			return false;
 | |
| 			//return ((s->Type == TABLE || s->Type == BORDERLESSTABLE) &&
 | |
| 			//!(strchr((char *)&s->dbseq[2],RNO_MARKER)));
 | |
| 		}
 | |
| 		private float GetBottomYoff(float bottomY)
 | |
| 		{
 | |
| 			foreach (vlnParagraph child in ChildrenBelow)
 | |
| 			{
 | |
| 				if (child.YOffset > bottomY) bottomY = child.YOffset;
 | |
| 				bottomY = child.GetBottomYoff(bottomY);
 | |
| 			}
 | |
| 			return bottomY;
 | |
| 		}
 | |
| 		private int AERLeftChangeBarLocation(FormatInfo formatInfo)
 | |
| 		{
 | |
| 			// use -5 default unless it is format specified
 | |
| 			int fixedAERChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedAERChangeColumn ?? 0;
 | |
| 			return (fixedAERChgCol != 0) ?
 | |
| 				(fixedAERChgCol > 100) ?
 | |
| 				(fixedAERChgCol % 100) : -fixedAERChgCol : -5;
 | |
| 		}
 | |
| 		private StringBuilder _RtfSB = null;
 | |
| 
 | |
| 		// return rtf and use for tab and other text 
 | |
| 		public string GetRtf(ItemInfo itemInfo)
 | |
| 		{
 | |
| 			_RtfSB = new StringBuilder();
 | |
| 			DisplayText vlntxt = new DisplayText(itemInfo, E_EditPrintMode.Print, E_ViewMode.View, true, E_FieldToEdit.StepText, false);
 | |
| 			System.Drawing.Font myFont = vlntxt.TextFont.WindowsFont;
 | |
| 			if (!itemInfo.IsTable && StepRTB.MyFontFamily != null)
 | |
| 				myFont = new System.Drawing.Font(StepRTB.MyFontFamily, myFont.Size, myFont.Style);
 | |
| 			if (itemInfo.IsHigh && itemInfo.MyDocStyle.UndSpecialStepsFoldout) myFont = new System.Drawing.Font(myFont.FontFamily, myFont.Size, myFont.Style | FontStyle.Underline);
 | |
| 			_RtfSB.Append(AddFontTable(myFont));
 | |
| 			_RtfSB.Append(vlntxt.StartText);
 | |
| 			_RtfSB.Append("}");
 | |
| 			return _RtfSB.ToString();
 | |
| 		}
 | |
| 		private float _XOffsetBox = 0;
 | |
| 		public float XOffsetBox
 | |
| 		{
 | |
| 			get { return _XOffsetBox; }
 | |
| 			set { _XOffsetBox = value; }
 | |
| 		}
 | |
| 		private float SetHeader(vlnParagraph para, PdfContentByte cb, ItemInfo itemInfo, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			float xoff = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
 | |
| 			// The '6' below is really converting from characters to Twips.  But instead of considering the CPI, 16bit assumed
 | |
| 			// it was 12 to center the header.  That's where the 6 comes from.
 | |
| 			float hdrWidth = (itemInfo.MyHeader.CleanText == null) ? 0 : itemInfo.MyHeader.CleanText.Length * 6;
 | |
| 			int typ = ((int)itemInfo.MyContent.Type) % 10000;
 | |
| 			int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
 | |
| 			
 | |
| 			if (itemInfo.MyHeader.Justify == System.Drawing.ContentAlignment.MiddleCenter)
 | |
| 			{
 | |
| 				if (bxIndx != null)
 | |
| 				{
 | |
| 					Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
 | |
| 					if (bx.TabPos > 0)
 | |
| 						xoff += (float)bx.TabPos;							// xoff starts as left margin
 | |
| 					else
 | |
| 						xoff += (float)((bx.TxtStart + XOffsetBox + (bx.TxtWidth / 2)) - (hdrWidth / 2));	// xoff starts as left margin
 | |
| 				}
 | |
| 				else if (formatInfo.MyStepSectionLayoutData.Separator.Location > 0)
 | |
| 					xoff = XOffset + AdjustToCharPosition((float)((para.Width - hdrWidth) / formatInfo.MyStepSectionLayoutData.Separator.Location), itemInfo.MyHeader.MyFont.CPI);
 | |
| 				else
 | |
| 					xoff = XOffset + (para.Width / 2) + (hdrWidth / 2);		// XOffset has left margin included
 | |
| 			}
 | |
| 			else
 | |
| 				xoff = XOffset;												// XOffset has left margin included
 | |
| 			vlnHeader myHeader = new vlnHeader(this, cb, itemInfo.MyHeader.Text, itemInfo.MyHeader.CleanText.TrimStart(" ".ToCharArray()), xoff, YOffset, itemInfo.MyHeader.MyFont);
 | |
| 			PartsAbove.Add(myHeader);
 | |
| 			return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout ? SixLinesPerInch : 0);
 | |
| 		}
 | |
| 		private float AdjustToCharPosition(float position, float? CPI)
 | |
| 		{
 | |
| 			int iPosition = (int)position;
 | |
| 			int charsToTwips = (int)(72 / (CPI ?? 12));
 | |
| 			iPosition = (iPosition / charsToTwips) * charsToTwips;
 | |
| 			position = (position / 7.2F) * 7.2F;
 | |
| 			return (float)iPosition;
 | |
| 		}
 | |
| 		private bool _SectionPageBreak = false;
 | |
| 		public bool SectionPageBreak
 | |
| 		{
 | |
| 			get { return _SectionPageBreak; }
 | |
| 			set { _SectionPageBreak = value; }
 | |
| 		}
 | |
| 		private bool _Processed = false;
 | |
| 		public bool Processed
 | |
| 		{
 | |
| 			get { return _Processed; }
 | |
| 			set { _Processed = value; }
 | |
| 		}
 | |
| 		private vlnParagraph _LastRNO;
 | |
| 		public vlnParagraph LastRNO
 | |
| 		{
 | |
| 			get { return _LastRNO; }
 | |
| 			set { _LastRNO = value; }
 | |
| 		}
 | |
| 		private vlnParagraph _MyTopRNO;
 | |
| 		public vlnParagraph MyTopRNO
 | |
| 		{
 | |
| 			get { return _MyTopRNO; }
 | |
| 			set { _MyTopRNO = value; }
 | |
| 		}
 | |
| 		private static string _Prefix = "";
 | |
| 		public static string Prefix
 | |
| 		{
 | |
| 			get { return vlnParagraph._Prefix; }
 | |
| 			set { vlnParagraph._Prefix = value; }
 | |
| 		}
 | |
| 		protected float _YBottomMost;	// Bottom of the paragraph including the children
 | |
| 		public float YBottomMost
 | |
| 		{
 | |
| 			get { return _YBottomMost; }
 | |
| 			set { _YBottomMost = value; }
 | |
| 		}
 | |
| 		protected float _YTopMost;	// Top of the paragraph including the children
 | |
| 		public float YTopMost
 | |
| 		{
 | |
| 			get { return _YTopMost; }
 | |
| 			set { _YTopMost = value; }
 | |
| 		}
 | |
| 		protected float _YTop;		// Top of the paragraph including parts
 | |
| 		public float YTop
 | |
| 		{
 | |
| 			get { return _YTop; }
 | |
| 			set
 | |
| 			{
 | |
| 				vlnParagraph vp = this as vlnParagraph;
 | |
| 				_YTop = value;
 | |
| 
 | |
| 			}
 | |
| 		}
 | |
| 		public float YSize		// How big this paragraph is with all of its children
 | |
| 		{
 | |
| 			get { return _YBottomMost - _YTopMost; }
 | |
| 		}
 | |
| 		private ItemInfo _MyItemInfo;
 | |
| 		public ItemInfo MyItemInfo
 | |
| 		{
 | |
| 			get { return _MyItemInfo; }
 | |
| 			set { _MyItemInfo = value; }
 | |
| 		}
 | |
| 		private vlnParagraph _MyHighLevelParagraph;
 | |
| 
 | |
| 		public vlnParagraph MyHighLevelParagraph
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_MyHighLevelParagraph == null)
 | |
| 				{
 | |
| 					_MyHighLevelParagraph = GetHighLevelParagraph();
 | |
| 				}
 | |
| 				return _MyHighLevelParagraph;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnParagraph GetHighLevelParagraph()
 | |
| 		{
 | |
| 			if (MyItemInfo.IsHigh) return this;
 | |
| 			return MyParent.GetHighLevelParagraph();
 | |
| 		}
 | |
| 		// Tab, Separator, ChangeBar, Box, Circle, Checkoff
 | |
| 		private vlnPrintObjects _PartsAbove;
 | |
| 		public vlnPrintObjects PartsAbove
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_PartsAbove == null) _PartsAbove = new vlnPrintObjects();
 | |
| 				return _PartsAbove;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnPrintObjects _PartsBelow;
 | |
| 		public vlnPrintObjects PartsBelow
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_PartsBelow == null) _PartsBelow = new vlnPrintObjects();
 | |
| 				return _PartsBelow;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnPrintObjects _PartsRight;
 | |
| 		public vlnPrintObjects PartsRight
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_PartsRight == null) _PartsRight = new vlnPrintObjects();
 | |
| 				return _PartsRight;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnPrintObjects _PartsLeft;
 | |
| 		public vlnPrintObjects PartsLeft
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_PartsLeft == null) _PartsLeft = new vlnPrintObjects();
 | |
| 				return _PartsLeft;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnPrintObjects _PartsContainer;
 | |
| 		public vlnPrintObjects PartsContainer
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_PartsContainer == null) _PartsContainer = new vlnPrintObjects();
 | |
| 				return _PartsContainer;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnParagraphs _ChildrenAbove;
 | |
| 		public vlnParagraphs ChildrenAbove
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_ChildrenAbove == null) _ChildrenAbove = new vlnParagraphs(this);
 | |
| 				return _ChildrenAbove;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnParagraphs _ChildrenBelow;
 | |
| 		public vlnParagraphs ChildrenBelow
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_ChildrenBelow == null) _ChildrenBelow = new vlnParagraphs(this);
 | |
| 				return _ChildrenBelow;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnParagraphs _ChildrenRight;
 | |
| 		public vlnParagraphs ChildrenRight
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_ChildrenRight == null) _ChildrenRight = new vlnParagraphs(this);
 | |
| 				return _ChildrenRight;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnParagraphs _ChildrenLeft;
 | |
| 		public vlnParagraphs ChildrenLeft
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_ChildrenLeft == null) _ChildrenLeft = new vlnParagraphs(this);
 | |
| 				return _ChildrenLeft;
 | |
| 			}
 | |
| 		}
 | |
| 		public void AdjustXOffsetForTab(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab)
 | |
| 		{
 | |
| 			float tabWidth = (myTab == null) ? 0 : myTab.Width;
 | |
| 			if (itemInfo.IsStepSection)
 | |
| 			{
 | |
| 				if (formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Just == "PSLeft")
 | |
| 				{
 | |
| 					int level = 0;
 | |
| 					ItemInfo iilvl = itemInfo;
 | |
| 					while (!iilvl.IsProcedure)
 | |
| 					{
 | |
| 						level++;
 | |
| 						iilvl = iilvl.MyParent;
 | |
| 					}
 | |
| 					level = level <= 2 ? 1 : level - 1;
 | |
| 					if (level==1)
 | |
| 						XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (level * (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos);
 | |
| 					else
 | |
| 						XOffset = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[level].ColSByLevel;
 | |
| 				}
 | |
| 				return;
 | |
| 			}
 | |
| 			int typ = ((int)itemInfo.MyContent.Type) % 10000;
 | |
| 			int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
 | |
| 			float? colOvrd = formatInfo.PlantFormat.FormatData.StepDataList[typ].ColOverride;
 | |
| 			if (bxIndx != null)
 | |
| 			{
 | |
| 				Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
 | |
| 				if (bx == null)
 | |
| 				{
 | |
| 					if ((colOvrd??0)!=0)
 | |
| 					{
 | |
| 						// 16-bit code subtracted the left margin
 | |
| 						//xoff = ((float)colOvrd - (float)itemInfo.MyDocStyle.Layout.LeftMargin) - XOffset;
 | |
| 						//XOffset += xoff;
 | |
| 						//if (myTab != null) myTab.XOffset += xoff;
 | |
| 						//xoff = MyParent.XOffset - myTab.XOffset;
 | |
| 						//XOffset += xoff;
 | |
| 						float tabOffset = (myTab == null?0: myTab.XOffset) - XOffset;
 | |
| 
 | |
| 						XOffset = (float)colOvrd;
 | |
| 						if (myTab != null) myTab.XOffset = XOffset + tabOffset;
 | |
| 						return;
 | |
| 					}
 | |
| 					else
 | |
| 						XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + tabWidth + XOffsetBox;
 | |
| 				}
 | |
| 				else
 | |
| 					XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)bx.TxtStart + tabWidth + XOffsetBox;
 | |
| 				if (myTab != null) myTab.XOffset = XOffset - tabWidth;
 | |
| 			}
 | |
| 			else if (itemInfo.IsHigh)
 | |
| 			{
 | |
| 				float x = 0;
 | |
| 				float xoff = 0;
 | |
| 				if ((colOvrd??0)!=0)
 | |
| 					x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)colOvrd;
 | |
| 				else
 | |
| 					x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
 | |
| 				
 | |
| 				xoff = x - XOffset;
 | |
| 				// ColSByLevel will specify the column in which the High Level Step starts with
 | |
| 				// respect to the overall level calculation based on sections & meta-sections.
 | |
| 				// Only a few of the single column formats use this: WCN1, CAL1, RGEBCK 
 | |
| 				if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel
 | |
| 				&& !(itemInfo.MyDocStyle.SpecialStepsFoldout && itemInfo.MyDocStyle.UseColSByLevel))
 | |
| 				{
 | |
| 					int indxLevel = itemInfo.PrintLevel + itemInfo.CurrentSectionLevel();
 | |
| 					float colsbylevel = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].ColSByLevel;
 | |
| 					float seclvlindent = colsbylevel - (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
 | |
| 					x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS + seclvlindent;
 | |
| 					xoff = x - XOffset;
 | |
| 					if (myTab != null) myTab.XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + colsbylevel;
 | |
| 					LeftJustifyList jstlst = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList;
 | |
| 					if (jstlst.Count > 0)
 | |
| 					{
 | |
| 						float leftJustifyTabSize = jstlst[indxLevel % jstlst.Count].Size ?? 0;
 | |
| 						XOffset = myTab.XOffset + leftJustifyTabSize;
 | |
| 					}
 | |
| 					else
 | |
| 						XOffset = myTab.XOffset + (myTab.Text.Length * (float)itemInfo.FormatStepData.Font.CPI) - colsbylevel;
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					XOffset += xoff;
 | |
| 					if (myTab != null)
 | |
| 					{
 | |
| 						myTab.XOffset += xoff;
 | |
| 						if (myTab.MyMacro != null) myTab.MyMacro.XOffset += xoff;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh)
 | |
| 			{
 | |
| 				// don't adjust for rno
 | |
| 			}
 | |
| 			else if (MyParent != null)
 | |
| 			{
 | |
| 				if (myTab != null && itemInfo.IsSequential && formatInfo.PlantFormat.FormatData.SectData.UseMetaSections && formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList.Count > 0)
 | |
| 				{
 | |
| 					int indxLevels = itemInfo.PrintLevel + itemInfo.CurrentSectionLevel(); // kbr -1;
 | |
| 					LeftJustifyList jstlst = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList;
 | |
| 					float tableftadj = 0;
 | |
| 					foreach (LeftJustify lj in jstlst)
 | |
| 					{
 | |
| 						if (lj.Index == indxLevels)
 | |
| 						{
 | |
| 							tableftadj = lj.Size ?? 0;
 | |
| 							break;
 | |
| 						}
 | |
| 					}
 | |
| 					// the order of this is important.  First adjust the tab's xoffset for the width of
 | |
| 					// the tab. The offset of text needs to be adjusted by the 'leftjustify' format variable 
 | |
| 					// if it existed for this level.
 | |
| 					myTab.XOffset += tabWidth;
 | |
| 					if (tableftadj != 0 && myTab.Width<tableftadj) 
 | |
| 						tabWidth = myTab.Width = tableftadj;
 | |
| 					XOffset += tabWidth;
 | |
| 					myTab.Rtf = myTab.Rtf.Replace(myTab.Text, myTab.Text.TrimStart(" ".ToCharArray()));
 | |
| 					Width = MyParent.Width - myTab.Width;
 | |
| 				}
 | |
| 				else	// if no left justify, right align the tab
 | |
| 				{
 | |
| 					XOffset += tabWidth - (myTab == null ? 0 : myTab.TabAlign);
 | |
| 					if (myTab != null) myTab.XOffset += tabWidth - myTab.TabAlign;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		public void AdjustWidth(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab)
 | |
| 		{
 | |
| 			int typ = ((int)itemInfo.MyContent.Type) % 10000;
 | |
| 			int? bxIndx = itemInfo.IsStep ? formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex : null;
 | |
| 			float? widOvrd = 0;
 | |
| 			float xwid = 0;
 | |
| 			if (itemInfo.IsStep && itemInfo.MyHLS.FormatStepData.UseSmartTemplate && (xwid = GetWidthFromTemplate(itemInfo, formatInfo))>0)
 | |
| 				widOvrd = xwid;
 | |
| 			else
 | |
| 				widOvrd = itemInfo.FormatStepData == null ? null : itemInfo.FormatStepData.WidthOverride;
 | |
| 			if ((widOvrd??0) != 0)
 | |
| 			{
 | |
| 				Width = (float)widOvrd;
 | |
| 				// if there's a box, we may need to do an adjustment on the width, if the tab data was changed
 | |
| 				// so don't return.
 | |
| 				if (bxIndx == null) return;
 | |
| 			}
 | |
| 			float tabWidth = (myTab == null) ? 0 : myTab.Width;
 | |
| 			if (bxIndx != null)
 | |
| 			{
 | |
| 				Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
 | |
| 				if (bx == null)
 | |
| 				{
 | |
| 					// NOT SURE IF WE NEED TO TEST FOR THE NULLBOX FORMAT FLAG, MAYBE "bx == null" IS THE SAME THING
 | |
| 					//if (formatInfo.MyStepSectionLayoutData.NullBox)
 | |
| 						Width = (float)formatInfo.MyStepSectionLayoutData.WidT - tabWidth;
 | |
| 				}
 | |
| 				else
 | |
| 					Width = _WidthAdjustBox + (float)bx.TxtWidth - tabWidth; // add 1 to get it to wrap like 16Bit
 | |
| 			}
 | |
| 			else if (itemInfo.IsHigh)
 | |
| 			{
 | |
| 				float CheckOffAdj = 0;
 | |
| 				if (itemInfo.MyDocStyle.UseCheckOffs)
 | |
| 				{
 | |
| 					if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment != null)
 | |
| 						CheckOffAdj = -(float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment;
 | |
| 					if (!HasCheckOffHeading(itemInfo, formatInfo) && CheckOffAdj < 0)
 | |
| 						CheckOffAdj += (float)(9 * 7.2);   // 9 is the size of the SIGNOFF adjustment
 | |
| 				}
 | |
| 				float adjwidth = CheckOffAdj;
 | |
| 				SectData sd = formatInfo.PlantFormat.FormatData.SectData;
 | |
| 				if (sd.UseMetaSections)
 | |
| 				{
 | |
| 					if (sd.StepSectionData.StepSectionLayoutData.TieTabToLevel)
 | |
| 					{
 | |
| 						if (itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
 | |
| 						&& !itemInfo.MyDocStyle.CancelSectTitle
 | |
| 						&& !(itemInfo.MyDocStyle.SpecialStepsFoldout && itemInfo.MyDocStyle.UseColSByLevel))
 | |
| 						{
 | |
| 							int indxLevel = itemInfo.PrintLevel + itemInfo.CurrentSectionLevel();
 | |
| 							adjwidth += formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].WidSAdjByLevel ?? 0; ;
 | |
| 							float colsbylevel = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].ColSByLevel;
 | |
| 							float seclvlindent = colsbylevel - (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
 | |
| 							adjwidth -= seclvlindent;
 | |
| 							adjwidth -= AdjustForSectionLevelTab();
 | |
| 						}
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						if (formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count > 0)
 | |
| 							adjwidth += (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[itemInfo.PrintLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.Count].ColSByLevel;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				Width = ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
 | |
| 				Width += _WidthAdjust;
 | |
| 				Width += adjwidth;
 | |
| 			}
 | |
| 			else if (itemInfo.IsCaution || itemInfo.IsNote)
 | |
| 			{
 | |
| 				float mycolT = (float)formatInfo.MyStepSectionLayoutData.ColT;
 | |
| 				Width = (float)formatInfo.MyStepSectionLayoutData.WidT - 6 - mycolT;
 | |
| 				XOffset += mycolT; // adjust caution/note text position
 | |
| 				if (PartsLeft != null)// adjust tab position
 | |
| 					foreach(vlnPrintObject vpo in PartsLeft)
 | |
| 						vpo.XOffset += mycolT; 
 | |
| 			}
 | |
| 			else if (itemInfo.IsSection)
 | |
| 			{
 | |
| 				Width = _WidthAdjust + ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
 | |
| 			}
 | |
| 			else if (MyParent == null)
 | |
| 			{
 | |
| 				// 72 points / inch - 7 inches (about width of page)
 | |
| 				Width = 72 * 7;
 | |
| 			}
 | |
| 			else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh)
 | |
| 			{
 | |
| 				Width = MyParent.Width;
 | |
| 			}
 | |
| 			else if (itemInfo.IsTablePart)
 | |
| 			{
 | |
| 				Width = 72 * 7; // TODO: Need to determine the Width of the Table based upon the contents
 | |
| 			}
 | |
| 			else if (itemInfo.MyParent.IsCaution || itemInfo.MyParent.IsNote)
 | |
| 			{
 | |
| 				Width = MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign);
 | |
| 				Width -= 72 * (itemInfo.FormatStepData.CautionOrNoteSubstepIndent == null ? 0 : (float)itemInfo.FormatStepData.CautionOrNoteSubstepIndent / (float)itemInfo.FormatStepData.Font.CPI);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				float adjwidth = 0;
 | |
| 				Width = adjwidth + MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign);
 | |
| 			}
 | |
| 		}
 | |
| 		private float GetWidthFromTemplate(ItemInfo itemInfo, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			float rtnwid = 0;
 | |
| 			int tpIndx = GetSmartTemplateIndex(itemInfo, itemInfo.MyContent.Type, formatInfo);
 | |
| 			if (tpIndx != -1)
 | |
| 			{
 | |
| 				int ncol = formatInfo.PlantFormat.FormatData.Templates[tpIndx].width;
 | |
| 				// now convert to the units for this format.  The template width data is in number of columns.
 | |
| 				rtnwid = ncol * itemInfo.FormatStepData.Font.CharsToTwips;
 | |
| 			}
 | |
| 			return rtnwid;
 | |
| 		}
 | |
| 		private int GetSmartTemplateIndex(ItemInfo itemInfo, int? type, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			int indx = 0;
 | |
| 			// find the starting template in the list for the high level step type:
 | |
| 			int highType = (int)itemInfo.MyHLS.MyContent.Type-20001;
 | |
| 			while (indx < formatInfo.PlantFormat.FormatData.Templates.Count)
 | |
| 			{
 | |
| 				// level of 0 starts a new group. 
 | |
| 				if (formatInfo.PlantFormat.FormatData.Templates[indx].level == 0)
 | |
| 				{
 | |
| 					indx++;
 | |
| 					// now see if we're on the high level step type, if so, look under this one
 | |
| 					// for the step type that we're on.  If found return the index of it.
 | |
| 					if (formatInfo.PlantFormat.FormatData.Templates[indx].type == highType)
 | |
| 					{
 | |
| 						indx++;
 | |
| 						while (indx < formatInfo.PlantFormat.FormatData.Templates.Count && formatInfo.PlantFormat.FormatData.Templates[indx].level != 0)
 | |
| 						{
 | |
| 							if (formatInfo.PlantFormat.FormatData.Templates[indx].type == type - 20001)
 | |
| 								return indx;
 | |
| 							indx++;
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 					indx++;
 | |
| 			}
 | |
| 			return -1;		// didn't find this step type in the template width override list.
 | |
| 		}
 | |
| 
 | |
| 		private float AdjustForSectionLevelTab()
 | |
| 		{
 | |
| 			string sectTab = MyItemInfo.ActiveSection.MyTab.CleanText.TrimEnd();
 | |
| 			if (sectTab.EndsWith(".0")) return 0;
 | |
| 			string myTab = MyItemInfo.MyTab.CleanText;
 | |
| 			// -1 below code, +1 for '.' and -2 for standard wid of tab
 | |
| 			// standard wid of this tab is 2 (ex: '1.')
 | |
| 			// so adjust width if longer than normal
 | |
| 			return (float)(sectTab.Length - 1) * 72/(float)MyItemInfo.FormatStepData.Font.CPI;
 | |
| 		}
 | |
| 		private bool HasCheckOffHeading(ItemInfo itemInfo, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList.Count != 0)
 | |
| 			{
 | |
| 				// does this section have a check off heading?
 | |
| 				SectionConfig sc = itemInfo.MyActiveSection.MyConfig as SectionConfig;
 | |
| 				if (sc != null && sc.Section_CheckoffHeaderSelection > 0) return true;
 | |
| 			}
 | |
| 			return false;
 | |
| 		}
 | |
| 		private bool UseCheckOffsDocStyle(int oldToNew, FormatInfo formatInfo)
 | |
| 		{
 | |
| 			int bit, retval=0;
 | |
| 			int mask=1;
 | |
| 
 | |
| 			for(bit=0; bit < 32; bit++){
 | |
| 				if ((oldToNew & mask) != 0 && ((int)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.UseCheckOffsIn & mask) !=0) retval = 1;
 | |
| 				mask <<= 1;
 | |
| 			}
 | |
| 			return retval > 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/// <summary>
 | |
| 	/// First order by stepLevel, then within a stepLevel, order by descending yLocation on page.
 | |
| 	/// Want to find maximum y value that fits on page, i.e. put the most on page that can 
 | |
| 	/// fit which is defined by the largest yLocation
 | |
| 	/// </summary>
 | |
| 	public class StepLevelList : SortedDictionary<int, SortedDictionary<float, vlnParagraph>>
 | |
| 	{
 | |
| 		public StepLevelList() : base()
 | |
| 		{
 | |
| 		}
 | |
| 		public void Add(int stepLevel, float yLocation, vlnParagraph para)
 | |
| 		{
 | |
| 			if (stepLevel == 0) return;
 | |
| 			if (!this.ContainsKey(stepLevel))
 | |
| 				this.Add(stepLevel, new SortedDictionary<float, vlnParagraph>());
 | |
| 			// using a negative for yLocation so that its in descending order:
 | |
| 			if (!this[stepLevel].ContainsKey(-yLocation))
 | |
| 				this[stepLevel].Add(-yLocation, para);
 | |
| 		}
 | |
| 	}
 | |
| 	public class ParagraphLocations : List<ParagraphLocation>
 | |
| 	{
 | |
| 		public ParagraphLocations()
 | |
| 			: base()
 | |
| 		{
 | |
| 		}
 | |
| 		public void Add(vlnParagraph myParagraph, float yTopMost)
 | |
| 		{
 | |
| 			ParagraphLocation foundOverlap = FindOverlap(myParagraph);
 | |
| 			if (foundOverlap == null)
 | |
| 			{
 | |
| 				this.Add(new ParagraphLocation(yTopMost,myParagraph));
 | |
| 				return;
 | |
| 			}
 | |
| 			ParagraphLocation doubleOverlap = FindOverlap(foundOverlap);
 | |
| 			while (doubleOverlap != null)
 | |
| 			{
 | |
| 				doubleOverlap.Merge(foundOverlap);
 | |
| 				this.Remove(foundOverlap);
 | |
| 				foundOverlap = doubleOverlap;
 | |
| 				doubleOverlap = FindOverlap(foundOverlap);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		private ParagraphLocation FindOverlap(vlnParagraph myParagraph)
 | |
| 		{
 | |
| 			foreach (ParagraphLocation paraLoc in this)
 | |
| 				if (paraLoc.Overlap(myParagraph))
 | |
| 					return paraLoc;
 | |
| 			return null;
 | |
| 		}
 | |
| 		private ParagraphLocation FindOverlap(ParagraphLocation myParaLoc)
 | |
| 		{
 | |
| 			foreach (ParagraphLocation paraLoc in this)
 | |
| 				if (paraLoc != myParaLoc && paraLoc.Overlap(myParaLoc))
 | |
| 					return paraLoc;
 | |
| 			return null;
 | |
| 		}
 | |
| 		internal StepLevelList BuildStepLevelList()
 | |
| 		{
 | |
| 			StepLevelList myList = new StepLevelList();
 | |
| 			foreach (ParagraphLocation paraLoc in this)
 | |
| 				myList.Add(paraLoc.StepLevel, paraLoc.YTop, paraLoc.MyParagraph);
 | |
| 			return myList;
 | |
| 		}
 | |
| 	}
 | |
| 	public class ParagraphLocation
 | |
| 	{
 | |
| 		private float _YTop;
 | |
| 		public float YTop
 | |
| 		{
 | |
| 			get { return _YTop; }
 | |
| 			set { _YTop = value; }
 | |
| 		}
 | |
| 		private float _YBottom;
 | |
| 		public float YBottom
 | |
| 		{
 | |
| 			get { return _YBottom; }
 | |
| 			set { _YBottom = value; }
 | |
| 		}
 | |
| 		private int _StepLevel;
 | |
| 		public int StepLevel
 | |
| 		{
 | |
| 			get { return _StepLevel; }
 | |
| 			set { _StepLevel = value; }
 | |
| 		}
 | |
| 		private vlnParagraph _MyParagraph;
 | |
| 		public vlnParagraph MyParagraph
 | |
| 		{
 | |
| 			get { return _MyParagraph; }
 | |
| 			set { _MyParagraph = value; }
 | |
| 		}
 | |
| 		public ParagraphLocation(float yTopMost,vlnParagraph myParagraph)
 | |
| 		{
 | |
| 			MyParagraph =myParagraph;
 | |
| 			YTop = myParagraph.YVeryTop - yTopMost;
 | |
| 			YBottom = myParagraph.YBottom - yTopMost;
 | |
| 			StepLevel = myParagraph.MyItemInfo.StepLevel;
 | |
| 		}
 | |
| 		public bool Overlap(vlnParagraph otherParagraph)
 | |
| 		{
 | |
| 			if (Between(otherParagraph.YTop, YTop, YBottom)) return true;
 | |
| 			if (Between(otherParagraph.YBottom, YTop, YBottom)) return true;
 | |
| 			if(Between(YTop,otherParagraph.YVeryTop,otherParagraph.YBottom)) return true;
 | |
| 			if(Between(YBottom,otherParagraph.YVeryTop,otherParagraph.YBottom)) return true;
 | |
| 			return false;
 | |
| 		}
 | |
| 		public static bool Between(float x, float lower, float higher)
 | |
| 		{ return x >= lower && x <= higher; }
 | |
| 		public bool Overlap(ParagraphLocation otherParagraphLocation)
 | |
| 		{
 | |
| 			if (Between(otherParagraphLocation.YTop, YTop, YBottom)) return true; // The top is within the other
 | |
| 			if (Between(otherParagraphLocation.YBottom, YTop, YBottom)) return true; // The bottom is within the other
 | |
| 			if(Between(YTop,otherParagraphLocation.YTop,otherParagraphLocation.YBottom)) return true; // the other top is within this one
 | |
| 			if(Between(YBottom,otherParagraphLocation.YTop,otherParagraphLocation.YBottom)) return true;// I believe this is unnecessary
 | |
| 			return false;
 | |
| 		}
 | |
| 		public void Merge(vlnParagraph otherParagraph)
 | |
| 		{
 | |
| 			if (StepLevel < otherParagraph.MyItemInfo.StepLevel) MyParagraph = otherParagraph;
 | |
| 			YTop = Math.Min(YTop, otherParagraph.YVeryTop);
 | |
| 			YBottom = Math.Max(YBottom, otherParagraph.YBottom);
 | |
| 			StepLevel = Math.Max(StepLevel, otherParagraph.MyItemInfo.StepLevel);
 | |
| 		}
 | |
| 		public void Merge(ParagraphLocation otherParagraphLocation)
 | |
| 		{
 | |
| 			if (StepLevel < otherParagraphLocation.StepLevel) MyParagraph = otherParagraphLocation.MyParagraph;
 | |
| 			YTop = Math.Min(YTop, otherParagraphLocation.YTop);
 | |
| 			YBottom = Math.Max(YBottom, otherParagraphLocation.YBottom);
 | |
| 			StepLevel = Math.Max(StepLevel, otherParagraphLocation.StepLevel);
 | |
| 		}
 | |
| 	}
 | |
| }
 |