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 { private vlnParagraph _Parent; public vlnParagraph Parent { get { return _Parent; } set { _Parent = value; } } public vlnParagraphs(vlnParagraph parent) { _Parent = parent; } // Step Designators are used by Comanche Peak and stored in their CAUTION2 type // We need to save this information and not process it like a normal Caution. private string _StepDesignator; public string StepDesignator { get { return _StepDesignator; } set { _StepDesignator = value; } } private float? _StepDesignatorColumn; public float? StepDesignatorColumn { get { return _StepDesignatorColumn; } set { _StepDesignatorColumn = value; } } private VE_Font _StepDesignatorFont; public VE_Font StepDesignatorFont { get { return _StepDesignatorFont; } set { _StepDesignatorFont = value; } } public bool IsEnhancedBackgroundFormat(ItemInfo itminfo) { return ((itminfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds); } public bool IsEnhancedDeviationFormat(ItemInfo itminfo) { return ((itminfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedDeviations) == E_PurchaseOptions.EnhancedDeviations); } public float Add(PdfContentByte cb, ItemInfoList itemInfoList, float xoff, float yoff, float yoffRight, int rnoLevel, int maxRNO, FormatInfo formatInfo) { bool bxHlsDraw = false; int? bxIndex = null; vlnBox box = null; float yTop = yoff; ItemInfo lastChild = null; string lastHeader = null; bool didComponentTableRow = false; float tableBottomMost = 0; float xoffBase = xoff; foreach (ItemInfo iChildItemInfo in itemInfoList) { if (iChildItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox && iChildItemInfo.IsHigh) bxIndex = null; if (iChildItemInfo.IsSection && (iChildItemInfo as SectionInfo).ColumnMode != maxRNO) maxRNO = (iChildItemInfo as SectionInfo).ColumnMode; ItemInfo childItemInfo = iChildItemInfo; int? bxIndx = childItemInfo.FormatStepData == null ? -1 : childItemInfo.FormatStepData.StepLayoutData.STBoxindex; // if the Caution or Note is not boxed, then use ColT to set the starting column of the Note or Caution if (((bxIndx ?? -1) == -1) && (childItemInfo.IsCaution || childItemInfo.IsNote) && !childItemInfo.IsInRNO && !childItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.Dev_Format && !IsEnhancedBackgroundFormat(childItemInfo) && !IsEnhancedDeviationFormat(childItemInfo)) //xoff += (float)childItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColT; xoff = xoffBase + (float)childItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColT; // if in a ComponentTableFormat (FNP sub format 1, component list), column headers are defined // by the first level of children. The data for the column is the child of the column header. // Sometimes the column will not have data, the following handles that case. Also, use // the boolean didComponentTableRow to keep track of the bottom most yoff of the table row. if ((childItemInfo.MyDocStyle.ComponentList) && childItemInfo.MyParent.IsInTemplate()) { // childItemInfo = 'child' and set to use a template for defining size. if (childItemInfo.Steps == null) continue; else { childItemInfo = childItemInfo.Steps[0]; didComponentTableRow = true; } } if (childItemInfo.FormatStepData != null && childItemInfo.FormatStepData.TabData != null && childItemInfo.FormatStepData.TabData.IsTransition) { lastHeader = childItemInfo.DisplayText; } else { if ((childItemInfo.IsCaution || childItemInfo.IsNote) && childItemInfo.MyPrevious != null && childItemInfo.MyPrevious.MyContent.Type != childItemInfo.MyContent.Type && childItemInfo.NextItemCount > 0 && childItemInfo.MyContent.Type == childItemInfo.GetNextItem().MyContent.Type) childItemInfo.SetupTags(); // added for V.C. Summer Transition caution in EOP-15.0 step 5.4 if (lastHeader != null) { childItemInfo.SetHeader(childItemInfo.FormatStepData.TabData.Font, lastHeader); lastHeader = null; } // if the format has MatchUpRNOCautNote, then add a line to yoff, if not at top of rno column. if (childItemInfo.FormatStepData != null && childItemInfo.FormatStepData.MatchUpRNO) { if (childItemInfo.MyParent != null && childItemInfo.MyParent.MyParent != null && !childItemInfo.MyParent.MyParent.IsHigh) yoff += vlnPrintObject.SixLinesPerInch; } // 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; bool boxHLS = false; // If this step has a previous, and its header is different than the previous's header. Allow it to go // into the box code. Without this check, none of the box code is run. This caused a problem // for VCS where two different type notes where not getting separate boxes. bool doSeparateBoxHdrChg = false; if (childItemInfo.MyPrevious != null && ((childItemInfo.MyHeader != null && childItemInfo.MyPrevious.MyHeader != null && childItemInfo.MyHeader.CleanText != childItemInfo.MyPrevious.MyHeader.CleanText) || (childItemInfo.MyHeader == null && childItemInfo.MyPrevious.MyHeader != null || childItemInfo.MyHeader != null && childItemInfo.MyPrevious.MyHeader == null))) doSeparateBoxHdrChg = childItemInfo.MyPrevious.MyContent.Type != childItemInfo.MyContent.Type;//true; if ((bxIndx ?? -1) != -1 && (bxIndex != bxIndx || childItemInfo.FormatStepData.BoxIt || childItemInfo.MyHeader != null || doSeparateBoxHdrChg || childItemInfo.FormatStepData.SeparateBox)) { 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 { if (childItemInfo.IsHigh) boxHLS = true; 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++; if (!boxHLS || (boxHLS && !childItemInfo.HasCautionOrNote)) yoff += ln * vlnPrintObject.SixLinesPerInch; } bxIndex = bxIndx; } else // Change Box Style { bool handleSeparateBox = true; if (childItemInfo.IsCaution && !childItemInfo.FormatStepData.SeparateBox && !childItemInfo.FormatStepData.SeparateBoxCautions) handleSeparateBox = false; if (childItemInfo.IsNote && !childItemInfo.FormatStepData.SeparateBox) handleSeparateBox = false; if (bxIndx != null && (handleSeparateBox || bxIndex != bxIndx || doSeparateBoxHdrChg)) { if (box != null) { box.Height = yoff - box.YOffset; // new height, with children if (childItemInfo.MyHeader != null && childItemInfo.MyPrevious != null && ((childItemInfo.MyPrevious.IsCaution && childItemInfo.IsCaution) || (childItemInfo.MyPrevious.IsNote && childItemInfo.IsNote) || childItemInfo.FormatStepData.SeparateBox)) yoff += vlnPrintObject.SixLinesPerInch * 2; } box = new vlnBox(); box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx]; int ln = 1; // a format flag determines whether there is a space before the note/caution. //if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++; if (childItemInfo.MixCautionNotesDiffType()) ln += 2; box.YOffset = yoff + ((ln - 1) * vlnPrintObject.SixLinesPerInch); if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++; yoff += ln * vlnPrintObject.SixLinesPerInch; } } bxIndex = bxIndx; } // DoubleBoxHls is a format flag used by BGE to draw double lined boxes around their HLS if (childItemInfo.IsHigh && ((childItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)) { boxHLS = true; box = new vlnBox(); box.MyBox = new Box(); box.DefBox = vlnBox.DOUBLEboxHLS; bxHlsDraw = true; } // Comanche peak or WCN bck Step designator if (childItemInfo.IsCaution2 && childItemInfo.SameRowAsParent || childItemInfo.IsCaution1 && childItemInfo.SameRowAsParent) { // Save the Step Designator information _StepDesignator = childItemInfo.DisplayText; int typ = ((int)childItemInfo.MyContent.Type) % 10000; _StepDesignatorColumn = formatInfo.PlantFormat.FormatData.StepDataList[typ].ColOverride; E_Style es = (E_Style)childItemInfo.FormatStepData.Font.Style; _StepDesignatorFont = new VE_Font(childItemInfo.FormatStepData.Font.Family, (int)childItemInfo.FormatStepData.Font.Size, es, (float)childItemInfo.FormatStepData.Font.CPI); } else { 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, null, null, yoffRight); // if doing the component list (FNP), keep track of the bottom most columns' data // so this can be returned after the row is done. tableBottomMost = Math.Max(tableBottomMost, para.YBottomMost); 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 != null && childItemInfo.MyHLS.FormatStepData.UseSmartTemplate && para.ChildrenBelow.Count > 0 && para.ChildrenBelow[0].YBottomMost > para.YBottomMost) yoff = para.ChildrenBelow[0].YBottomMost; // if doing the component list (FNP), yoff for the HLS (if it's the component in the list, // i.e. the leftmost item in the table), the yoff is either the HLS bottom, or the bottom most // of all of the other columns' data. else if (childItemInfo.IsHigh && childItemInfo.FormatStepData.UseOldTemplate && childItemInfo.MyDocStyle.ComponentList) yoff = Math.Max(para.YBottom, para.YBottomMost) + vlnPrintObject.SixLinesPerInch; // increment the y offset if not doing the ComponentTableFormat else if (!para.UseTemplateKeepOnCurLine(childItemInfo)) yoff = para.YBottomMost; if (box != null && 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 (bxHlsDraw) { box.YOffset = para.YTop; box.Height = para.Height; box = null; } else if (boxHLS) { // the following line controls whether there is 1 line or 2 lines between // the box line & the starting/ending yoffset of the HLS. WEP2 had no extra line between // box & top/bottom of step. The DiffContActBox was added for WEP2. int boxLnAdjust = iChildItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox ? 1 : 2; box.YOffset = para.YTop - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); boxLnAdjust = iChildItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox ? 1 : 0; box.Height = para.YBottomMost - box.YOffset - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); // para.YTop - (1.1F * vlnPrintObject.SixLinesPerInch); box = null; } } if (childItemInfo.IsSequential && childItemInfo.NextItemCount > 0 && childItemInfo.MyParent.IsHigh && ((childItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.XBlankW1stLevSub) == E_DocStructStyle.XBlankW1stLevSub)) yoff += vlnPrintObject.SixLinesPerInch; boxHLS = false; lastChild = childItemInfo; } } if (box != null && box.MyBox != null) { box.Height = yoff - box.YOffset; // new height, with children yoff += 2 * vlnPrintObject.SixLinesPerInch; if (lastChild != null && lastChild.FormatStepData.AlwaysUseExtraLines && (lastChild.IsCaution || lastChild.IsNote)) { if (!lastChild.MyParent.IsHigh) yoff += lastChild.ActiveFormat.PlantFormat.FormatData.StepDataList[2].StepLayoutData.STExtraSpace ?? 0; } } // after the last child substep when doing a Component table row (FNP Component Lists), set the value // of the yoff to be the bottom most line in the table. if (didComponentTableRow) yoff = tableBottomMost; return yoff; } public float ToPdf(PdfContentByte cb, float yPageStart, ref float yTopMargin, ref float yBottomMargin) { foreach (vlnParagraph child in this) { yPageStart = child.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); } return yPageStart; } } public partial class vlnParagraph : vlnPrintObject { private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public override string ToString() { return string.Format("{0} - {1} - {2} - '{3}'", this.MyItemInfo.ItemID, this.YTop, this.YSize, this.MyItemInfo.ShortPath); } private bool _PageBreakOnStep = false; public bool PageBreakOnStep { get { return _PageBreakOnStep; } set { _PageBreakOnStep = value; } } private float WidthNoLimit = 0; 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; } } private bool _ShowSectionTitles; public bool ShowSectionTitles { get { return _ShowSectionTitles; } set { _ShowSectionTitles = value; } } public float ParagraphToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin) { if (MyItemInfo.PageNumber == 0) MyItemInfo.PageNumber = MyPageHelper.CurrentPageNumber; else if (MyItemInfo.PageNumberUsed != 0 && MyItemInfo.PageNumberUsed != MyPageHelper.CurrentPageNumber) { if (PromsPrinter.TransPageNumProblems == null) PromsPrinter.TransPageNumProblems = new List(); PromsPrinter.TransPageNumProblems.Add(MyItemInfo.ShortPath); } if (Processed) return yPageStart; //float localYPageStart = yPageStart; Processed = true; if (_PartsAbove != null && _PartsAbove.Count > 0) { // For McGuire and Catawba, they use CustomSpacing which inserts a blank line before high level steps // if we paginate on one of these blank lines, we want to skip that blank line so that there isn't an // extra blank line at the top of the page. if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CustomSpacing && PartsAbove[0].YOffset + yTopMargin == yPageStart && PartsAbove[0].IParagraph.Content == " ") { if (MyItemInfo.IsHigh && ((YOffset - YTopMost) > SixLinesPerInch)) { //Console.WriteLine("==> {0} {1} MOST {2} DIF {3}", MyItemInfo.ShortPath, YOffset, YTopMost, YOffset - YTopMost); yPageStart = yTopMargin + YTopMost; } else yPageStart = yTopMargin + YOffset; } else yPageStart = PartsAbove.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); } if (MyItemInfo.IsHigh && ((MyItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)) yPageStart -= SixLinesPerInch; if (MyItemInfo.IsHigh && MyItemInfo.MyDocStyle.SpecialStepsFoldout) yPageStart -= SixLinesPerInch; if (MyItemInfo.IsHigh && !MyItemInfo.ActiveFormat.MyStepSectionLayoutData.DoSTExtraAtTop && (yPageStart - YTopMost == yTopMargin)) { yPageStart += ((MyItemInfo.FormatStepData == null) ? 0 : MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0); if ((MyItemInfo.Cautions != null && MyItemInfo.Cautions[0].FormatStepData.AlwaysUseExtraLines) || (MyItemInfo.Notes != null && MyItemInfo.Notes[0].FormatStepData.AlwaysUseExtraLines)) yPageStart -= ((MyItemInfo.FormatStepData == null) ? 0 : MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0); } // Save the HLS & RNO string in case the pagelist item uses it (some of the backgrounds): if (MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.PageBreakOnStep) { MyPageHelper.HLSTAB = MyItemInfo.HighLevelStepTabPageList; // find the rno and use it's tab for the HLRNO part. ItemInfo rno = MyItemInfo.RNOs != null && MyItemInfo.RNOs.Count > 0 ? MyItemInfo.RNOs[0] : null; string rnotab = (rno == null) ? null : rno.DisplayText; MyPageHelper.HLRNO = rno == null ? null : MyItemInfo.FormatStepData.TabData.RNOIdent + rnotab; MyPageHelper.ResetSvg(); } 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; // 'doprint' will always be true if not doing NSP's {HLSTEXT} token in page list. The following code is used to prevent // printing the High level step, if the high level step is printed from the pagelist using {HLSTEXT} token. bool doprint = !(MyPageHelper.DidHLSText && MyItemInfo.ItemID == MyPageHelper.HasHLSTextId); 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 || (ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle && !MyItemInfo.MyDocStyle.SpecialStepsFoldout)) // Don't ouput the Step Section title { // if this is a section, then check the section config for printable header too. if (MyItemInfo.IsSection) { SectionConfig sch = MyItemInfo.MyConfig as SectionConfig; //if (!(ShowSectionTitles // && !MyItemInfo.MyDocStyle.CancelSectTitle // && !MyItemInfo.MyDocStyle.SpecialStepsFoldout // && !MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections) // && if (sch != null && sch.Section_PrintHdr != "Y") 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 == null) ? "" : MyItemInfo.MyTab.CleanText + " " + MyItemInfo.DisplayText, new PdfDestination(PdfDestination.FITBH, yLocation + YVeryTop - YTopMost + SixLinesPerInch)); } } if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WolfcreekCKLFormat) { DrawChkOrValveTableLines(cb, MyItemInfo, yPageStart, yTopMargin, yBottomMargin, yLocation); } if (MyItemInfo.IsSection) { SectionConfig sc = MyItemInfo.MyConfig as SectionConfig; if ((MyItemInfo.MyDocStyle != null && MyItemInfo.MyDocStyle.IncludeInTOC && (sc == null || sc.Section_TOC != "Y")) || ((MyItemInfo.MyDocStyle == null || !MyItemInfo.MyDocStyle.IncludeInTOC) && (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.CurrentTOCPageNumber + 1; pc.DrawTemplates(); } } } if (!doprint) return yPageStart; if (_PartsLeft != null && _PartsLeft.Count > 0) yPageStart = PartsLeft.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); if (_PartsRight != null && _PartsRight.Count > 0) yPageStart = PartsRight.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); if (_PartsBelow != null && _PartsBelow.Count > 0) yPageStart = PartsBelow.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); if (_PartsContainer != null && _PartsContainer.Count > 0) yPageStart = PartsContainer.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); //if (localYPageStart != yPageStart) DebugText.WriteLine("ParToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, localYPageStart, yPageStart); return yPageStart; } private void DrawChkOrValveTableLines(PdfContentByte cb, ItemInfo ii, float yPageStart, float yTopMargin, float yBottomMargin, float yLocation) { if (!ii.IsStep || ii.IsCaution || ii.IsNote) return; Box bx = ii.ActiveFormat.PlantFormat.FormatData.BoxList[0]; float lpi = MyPageHelper.YMultiplier == 1.0 ? SixLinesPerInch : _SevenLinesPerInch; bool savedebug = Rtf2Pdf.PdfDebug; Rtf2Pdf.PdfDebug = false; System.Drawing.Font symbFont = new System.Drawing.Font("VESymbFix", (float)ii.FormatStepData.Font.Size); iTextSharp.text.Font iSymblFont = Volian.Svg.Library.VolianPdf.GetFont(symbFont); iSymblFont.Color = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Black)); // The vertPos array from the format defines the column locations: string[] vertPos = ii.MyHLS.FormatStepData.VertPos.Split(",".ToCharArray()); // Count how many vertical lines are in the checklist table: int cntVertPos = vertPos.Length - 1; while (vertPos[cntVertPos] == "0" && cntVertPos > 0) cntVertPos--; cntVertPos++; Paragraph paraVertLine = new Paragraph(ii.ActiveFormat.PlantFormat.FormatData.BoxList[0].BXVert, iSymblFont); float lWidth = 100; float csize = 6 - .3f; // added the .3 to make line up with 16bit. // if High Level Step, just need to do edges for number of lines: if (ii.IsHigh) { // count # of '{\par} commands in prefix and suffix. int countLine = 0; string preSuf_Fix = (ii.FormatStepData.Prefix != null && ii.FormatStepData.Prefix != "") ? ii.FormatStepData.Prefix : null; if (preSuf_Fix != null) countLine++; // account for a line of prefix (if no \par) // if this is a proportional font, need to 'draw' the prefix/suffix. NOTE that the suffix should // just list the headers and the prefix can be 'empty'. if (ii.FormatStepData.Font.FontIsProportional()) { float yLocVertLine = yLocation + (lpi / 2); // Prefix, i.e. Top line: Paragraph topLeftLine = new Paragraph(bx.BXULC, iSymblFont); Rtf2Pdf.TextAt(cb, topLeftLine, float.Parse(vertPos[0]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Paragraph topRightLine = new Paragraph(bx.BXURC, iSymblFont); Rtf2Pdf.TextAt(cb, topRightLine, float.Parse(vertPos[cntVertPos - 1]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Paragraph horzLine = new Paragraph(bx.BXHorz, iSymblFont); float thPos = float.Parse(vertPos[0]) + csize; while (thPos < float.Parse(vertPos[cntVertPos - 1])) { Rtf2Pdf.TextAt(cb, horzLine, thPos + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); thPos += csize; } // Vertical Lines around HLS //int countLine = (int)(this.Height / lpi); yLocVertLine = yLocation - (lpi / 2); for (int i = 0; i < 1; i++) { Rtf2Pdf.TextAt(cb, paraVertLine, float.Parse(vertPos[0]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Rtf2Pdf.TextAt(cb, paraVertLine, float.Parse(vertPos[cntVertPos - 1]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); yLocVertLine -= lpi; } // Suffix, i.e. Column headers. // first do left/right side chars above and below column headers //countLine = (int)(this.Height / lpi); Paragraph sideLeftLine = new Paragraph(bx.BXMLS, iSymblFont); Rtf2Pdf.TextAt(cb, sideLeftLine, float.Parse(vertPos[0]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Rtf2Pdf.TextAt(cb, sideLeftLine, float.Parse(vertPos[0]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine - (2 * lpi), lWidth, 100, null, yBottomMargin); Paragraph sideRightLine = new Paragraph(bx.BXMRS, iSymblFont); Rtf2Pdf.TextAt(cb, sideRightLine, float.Parse(vertPos[6]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Rtf2Pdf.TextAt(cb, sideRightLine, float.Parse(vertPos[6]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine - (2 * lpi), lWidth, 100, null, yBottomMargin); // now do the lines with the 'T' type lines for top/bottom of vertical lines. thPos = float.Parse(vertPos[0]) + csize; while (thPos < float.Parse(vertPos[cntVertPos - 1])) { Rtf2Pdf.TextAt(cb, horzLine, thPos + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Rtf2Pdf.TextAt(cb, horzLine, thPos + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine - (2 * lpi), lWidth, 100, null, yBottomMargin); thPos += csize; } // now do the vertical bar between header words and the column header words. yLocVertLine -= lpi; string[] colHdrs = _MyItemInfo.FormatStepData.Suffix.Substring(_MyItemInfo.FormatStepData.Suffix.IndexOf(";") + 1).Split(",".ToCharArray()); iTextSharp.text.Font iHdrFont = Volian.Svg.Library.VolianPdf.GetFont(_MyItemInfo.FormatStepData.Font.WindowsFont); iHdrFont.Color = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.Black)); Paragraph topT = new Paragraph(bx.BXUMID, iSymblFont); Paragraph crossT = new Paragraph(bx.BXMID, iSymblFont); for (int i = 0; i < cntVertPos; i++) { // do vertical line: Rtf2Pdf.TextAt(cb, paraVertLine, float.Parse(vertPos[i]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); // do the column header text - center it: if (i < colHdrs.Length) { Paragraph parColHdr = new Paragraph(colHdrs[i], iHdrFont); // find the center point of column header and subtract 1/2 width of the text to locate the text. float hloc = (float.Parse(vertPos[i]) + ((float.Parse(vertPos[i + 1]) - float.Parse(vertPos[i])) / 2)); Chunk chk = (Chunk)parColHdr.Chunks[0]; hloc = hloc - (chk.GetWidthPoint() / 2); Rtf2Pdf.TextAt(cb, parColHdr, hloc + (float)ii.MyDocStyle.Layout.LeftMargin, yLocVertLine, lWidth, 100, null, yBottomMargin); } // Do the crosswise table characters, i.e. T and + if (i > 0 && i < colHdrs.Length) { Rtf2Pdf.TextAt(cb, topT, float.Parse(vertPos[i]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine + lpi, lWidth, 100, null, yBottomMargin); Rtf2Pdf.TextAt(cb, crossT, float.Parse(vertPos[i]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine - lpi, lWidth, 100, null, yBottomMargin); } } } else #region OriginalHLS { int hIndx = preSuf_Fix.IndexOf(@"{\par}"); while (preSuf_Fix != null && hIndx >= 0) { hIndx = preSuf_Fix.IndexOf(@"{\par}", hIndx + 1); countLine++; } preSuf_Fix = (ii.FormatStepData.Suffix != null && ii.FormatStepData.Suffix != "") ? ii.FormatStepData.Suffix : null; if (preSuf_Fix != null) countLine++; // account for a line of suffix (if no \par) hIndx = preSuf_Fix.IndexOf(@"{\par}"); while (preSuf_Fix != null && hIndx >= 0) { hIndx = preSuf_Fix.IndexOf(@"{\par}", hIndx + 1); countLine++; } // get first and last vertpos for location of lines: // for each line of text, draw the start & end box line: countLine = (int)(this.Height / lpi) - countLine; float yLocVertLine = yLocation - lpi / 2; for (int i = 0; i < countLine; i++) { Rtf2Pdf.TextAt(cb, paraVertLine, float.Parse(vertPos[0]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); Rtf2Pdf.TextAt(cb, paraVertLine, float.Parse(vertPos[cntVertPos - 1]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yLocVertLine, lWidth, 100, null, yBottomMargin); yLocVertLine -= lpi; } } #endregion OriginalHLS } else { // This section of code draws the lines around the substeps (the actual table part) Paragraph horzLine = new Paragraph(ii.ActiveFormat.PlantFormat.FormatData.BoxList[0].BXHorz, iSymblFont); bool bottomOfTable = (ii.GetNextItem() == null || ii.NextItemCount == 0) || (MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0].MyItemInfo.ItemID == ii.GetNextItem().ItemID); // if bottom of table use different cross/beg/end chars than if in middle of table. Paragraph leftLine = new Paragraph(bottomOfTable ? bx.BXLLC : bx.BXMLS, iSymblFont); Paragraph rightLine = new Paragraph(bottomOfTable ? bx.BXLRC : bx.BXMRS, iSymblFont); // If this item is in the leftmost column in table, this is determined by looking at its parent, // its parent must be a HLS, do the vertical lines since all cells have all vertical lines. // Lines should be drawn from current to ybottommost. Also draw the bottom line. if (ii.MyParent.IsHigh) { // first do the vertical bars. float curY = yLocation; while (curY > (yPageStart - this.YBottomMost + lpi)) { for (int i = 0; i < cntVertPos; i++) Rtf2Pdf.TextAt(cb, paraVertLine, float.Parse(vertPos[i]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, curY + 3, lWidth, 100, null, yBottomMargin); curY -= lpi; } // Now do the bottom line for this item. Paragraph crossLine = new Paragraph(bottomOfTable ? bx.BXLMID : bx.BXMID, iSymblFont); float yloc = yPageStart - this.YBottomMost + 18; Rtf2Pdf.TextAt(cb, leftLine, float.Parse(vertPos[0]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yloc, lWidth, 100, null, yBottomMargin); float hPos = float.Parse(vertPos[0]) + csize; int doHorizCnt = 0; while (doHorizCnt < cntVertPos - 1) { while (hPos < float.Parse(vertPos[doHorizCnt + 1])) { Rtf2Pdf.TextAt(cb, horzLine, hPos + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yloc, lWidth, 100, null, yBottomMargin); hPos += csize; } // put out middle piece, i.e. + (cross) lines or bottom line hPos = float.Parse(vertPos[doHorizCnt + 1]); if (doHorizCnt < cntVertPos - 2) // don't put out crossLine on last one. Rtf2Pdf.TextAt(cb, crossLine, float.Parse(vertPos[doHorizCnt + 1]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, yloc, lWidth, 100, null, yBottomMargin); hPos += csize; doHorizCnt++; } // put out the right side piece Rtf2Pdf.TextAt(cb, rightLine, float.Parse(vertPos[cntVertPos - 1]) + (float)ii.MyDocStyle.Layout.LeftMargin - 6, yloc, lWidth, 100, null, yBottomMargin); } // Now handle middle parts of the table. For whatever sub level we're at, draw the cross character // and the horizontal. This is case where the component number may have multiple descriptions,positions, etc. associated // with it. if (!ii.MyParent.IsHigh && ii.GetNextItem() != null && ii.NextItemCount > 0) { // draw horizontally from this sublevel to the end. int sublev = 0; ItemInfo par = this.MyItemInfo; while (!par.IsHigh) { sublev++; par = par.MyParent; } sublev--; float ylocs = yPageStart - this.YBottomMost + 15; for (int i = sublev; i < cntVertPos - 1; i++) { float hPos = float.Parse(vertPos[i]) + csize; Rtf2Pdf.TextAt(cb, leftLine, float.Parse(vertPos[i]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, ylocs, lWidth, 100, null, yBottomMargin); while (hPos < float.Parse(vertPos[i + 1])) { // do the horizontal line Rtf2Pdf.TextAt(cb, horzLine, hPos + (float)ii.MyDocStyle.Layout.LeftMargin - csize, ylocs, lWidth, 100, null, yBottomMargin); hPos += csize; } } // Do the last cross character Rtf2Pdf.TextAt(cb, rightLine, float.Parse(vertPos[cntVertPos - 1]) + (float)ii.MyDocStyle.Layout.LeftMargin - csize, ylocs, lWidth, 100, null, yBottomMargin); } } Rtf2Pdf.PdfDebug = savedebug; } private float DrawGrid(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation) { //DebugText.WriteLine("{0},'{1}','{2}','<>'", MyItemInfo.ItemID, MyItemInfo.ShortPath, FormattedText); if(DebugText.IsOpen)DebugText.WriteLine("{0},'{1}','{2}','<>',{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")); if (MyGrid.Height > (yTopMargin - yBottomMargin)) { _MyLog.ErrorFormat("<<< ERROR >>> Table is too big to fit on page, expect pagination problems\r\n==>'Table Too Big',{0},'{1}','{2}',{3},{4}" , MyItemInfo.ItemID, MyItemInfo.MyDocVersion.MyFolder.Name, MyItemInfo.ShortPath, MyGrid.Height, (yTopMargin - yBottomMargin)); } return retval; } private float DrawText(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation) { if(DebugText.IsOpen)DebugText.WriteLine("{0},'{1}','{2}','<>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, FormattedText); //Console.WriteLine("{0},{1},'{2}','<>'", 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.GetNextItem() == null) || MyItemInfo.FormatStepData.SeparateBox) && Height < (1.2F * IParagraph.Leading)) IParagraph.Alignment = Element.ALIGN_CENTER; // if this step is centered, but not part of the checklist or valvelist format, use itextsharp to center it. // if it was part of the checklist or valvelist, then the centering is based on the column definitions for the table and // was calculated when the paragraph was made. if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData.StepPrintData.Justify == "Center" && !MyItemInfo.FormatStepData.StepLayoutData.AlignWithParentTab) 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 myAttributes = new List(); 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) { ROImageConfig rc = new ROImageConfig(roImage); int size = Convert.ToInt32(rc.Image_Size); iTextSharp.text.Image it_image = iTextSharp.text.Image.GetInstance(ROImageInfo.Decompress(roImage.Content, size)); 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} Width={6} Left={7}", DebugId, MyItemInfo.ItemID, MyItemInfo.FormatStepType, MyItemInfo.FormatStepData == null ? "NoStepData" : MyItemInfo.FormatStepData.Type, MyItemInfo.StepLevel, MyItemInfo.DBSequence, Width, XOffset); } } private void ResetDocStyleAndValues(ref float yTopMargin, ref float yBottomMargin) { float _PointsPerPage = 792; // if this document style has another style that is for pages other than first, we need to // reset the document style off of this section AND reset docstyle values used. if ((MyItemInfo.MyActiveSection.MyDocStyle.StructureStyle.Where & E_DocStyleUse.UseOnFirstPage) > 0) { ItemInfo ii = (ItemInfo)MyItemInfo.MyActiveSection; int indx = (int)MyItemInfo.MyActiveSection.MyDocStyle.IndexOtherThanFirstPage; foreach (DocStyle ds in ii.ActiveFormat.PlantFormat.DocStyles.DocStyleList) { if (ds.Index == indx) { MyItemInfo.MyActiveSection.MyDocStyle = ds; MyPageHelper.MySection = MyItemInfo.MyActiveSection as SectionInfo; MyPageHelper.MySection.MyDocStyle = ds; MyPageHelper.ResetSvg(); break; } } MyPageHelper.DidFirstPageDocStyle = true; if (DebugPagination.IsOpen) DebugPagination.WriteLine("ResetDocStyleAndValues"); MyPageHelper.MySection = (SectionInfo)MyItemInfo.MyActiveSection; yTopMargin = _PointsPerPage - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.TopMargin; yBottomMargin = Math.Max(0, yTopMargin - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.PageLength); } else if (MyPageHelper.PrintedSectionPage > 0) { MyPageHelper.ResetSvg(); if ((MyItemInfo.MyActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PrintSectOnFirst) == E_DocStructStyle.DSS_PrintSectOnFirst) { yTopMargin = _PointsPerPage - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.TopMargin + MyPageHelper.PrintedSectionPage; MyPageHelper.YTopMargin = yTopMargin; yBottomMargin = Math.Max(0, _PointsPerPage - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.TopMargin - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.PageLength); } } } public override float ToPdf(PdfContentByte cb, float yPageStart, ref float yTopMargin, ref float yBottomMargin) { // For BGE, the very first subsection's pagelist items were not correct - the section/meta section titles were // at the wrong level. Reset the page helper's section. if (MyItemInfo.IsSection && MyItemInfo.MyPrevious == null && MyItemInfo.MyParent.IsSection && !MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseWestinghouse) { MyPageHelper.MySection = MyItemInfo as SectionInfo; MyPageHelper.ResetSvg(); } if (IsWordDocPara) { PdfReader tmp = null; string tmpstr = null; SectionInfo si = SectionInfo.Get(MyItemInfo.ItemID); cb.PdfDocument.NewPage(); //_MyLog.InfoFormat("NewPage 9 {0}", cb.PdfWriter.CurrentPageNumber); 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; if(DebugText.IsOpen) DebugText.WriteLine("ToPdf1:{0},'{1}',{2},{3},{4},{5}", MyItemInfo.ItemID, MyItemInfo.ShortPath, XOffset, yLocation, yPageStart, YTopMost); int paginate = Paginate(yLocation, yTopMargin, yBottomMargin); bool firstHighLevelStep = MyItemInfo.IsHigh && (MyItemInfo.MyPrevious == null); bool doSectionTitleContinued = false; // will add " Continued" to the section title if format flag is set DocStyle docstyle = 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); } if (MyItemInfo.IsHigh && MyItemInfo.MyPrevious != null && ((MyItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)) yPageStart -= SixLinesPerInch; break; case 1: // Break on High Level Step OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin); docstyle = MyItemInfo.MyDocStyle; bool doSectionContinue = ((docstyle.StructureStyle.Style & E_DocStructStyle.BottomSectionContinue) == E_DocStructStyle.BottomSectionContinue); if (doSectionContinue) DoBottomContinueMsg(cb, yBottomMargin, yLocation, docstyle); cb.PdfDocument.NewPage(); //_MyLog.InfoFormat("NewPage 10 {0}", cb.PdfWriter.CurrentPageNumber); if (MyItemInfo.IsSection && MyParent != null && MyParent.MyItemInfo.IsSection && (MyItemInfo as SectionInfo).IsSeparatePagination()) { RefreshDocStyle(); yTopMargin = 792 - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.TopMargin; yBottomMargin = Math.Max(0, yTopMargin - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.PageLength); yPageStart = yTopMargin; } else if (MyItemInfo.IsSection || (MyItemInfo.IsHigh && MyItemInfo.MyPrevious != null)) //do not reset for 1st step ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin); 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.FoldoutIndex() > -1) PromsPrinter.DoFoldoutPage(cb, "HLS", MyPageHelper.TextLayer, MyPageHelper, MyItemInfo.FoldoutIndex(), false); else if (PromsPrinter.MyFoldoutReader.Count > 0 && MyPageHelper.MyPromsPrinter.InsertBlankPages) { // insert a blank page if this step section had a foldout associated and the checkbox // on the print dialog, to add blank pages, is checked AND the page did NOT have a // preceeding foldout. if (MyItemInfo.FoldoutIndex() <= -1) { MyPageHelper.OnBlankPage = true; cb.PdfDocument.Add(new iTextSharp.text.Table(1)); cb.PdfDocument.NewPage(); //_MyLog.InfoFormat("NewPage 10 blank {0}", cb.PdfWriter.CurrentPageNumber); } } yPageStart = yTopMargin + YTopMost; DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart); if (doSectionContinue) DoTopContinueMsg(cb, ref yPageStart, yTopMargin, docstyle); // If "ContinueSectionHeader" (format flag) is true then print the section title with "(Continued)" appended to it if (!MyItemInfo.IsSection && MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ContinueSectionHeader) { SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig; doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y"); } MyPageHelper.YMultiplier = 1; break; case 2: // Break within a Step OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin); docstyle = MyItemInfo.MyDocStyle; DoBottomContinueMsg(cb, yBottomMargin, yLocation, docstyle); cb.PdfDocument.NewPage(); //_MyLog.InfoFormat("NewPage 11 {0}", cb.PdfWriter.CurrentPageNumber); ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin); DebugText.WriteLine("Paginate2"); if (MyItemInfo.MyHLS.FoldoutIndex() > -1) PromsPrinter.DoFoldoutPage(cb, "Break within Step", MyPageHelper.TextLayer, MyPageHelper, MyItemInfo.MyHLS.FoldoutIndex(), false); // temporary foldout else if (PromsPrinter.MyFoldoutReader.Count > 0 && MyPageHelper.MyPromsPrinter.InsertBlankPages) { MyPageHelper.OnBlankPage = true; cb.PdfDocument.Add(new iTextSharp.text.Table(1)); cb.PdfDocument.NewPage(); _MyLog.InfoFormat("NewPage Break within step blank {0}", cb.PdfWriter.CurrentPageNumber); } // if there is a 'container vlnbox' around the HLS, flag that the drawn box must also break: if (MyHighLevelParagraph != null && MyHighLevelParagraph.PartsContainer != null && MyHighLevelParagraph.PartsContainer.Count > 0 && !((MyHighLevelParagraph.MyItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)) { foreach (vlnPrintObject vpo in MyHighLevelParagraph.PartsContainer) { vlnBox vb = vpo as vlnBox; if (vb != null) { vb.ContainsPageBreak = true; PartsContainer.Add(vb); } } } // 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; DoTopContinueMsg(cb, ref yPageStart, yTopMargin, docstyle); // If "ContinueSectionHeader" (format flag) is true then print the section title with "(Continued)" appended to it if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ContinueSectionHeader) { SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig; doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y"); } MyPageHelper.YMultiplier = 1; // Now check if this is a template type step & if so, add the HLS's prefix/suffix to it. if (MyItemInfo.MyHLS != null && MyItemInfo.MyHLS.FormatStepData.UseSmartTemplate) { vlnParagraph smartPara = new vlnParagraph(MyParent.MyParent, cb, MyItemInfo.MyHLS, MyParent.XOffset, 0, 0, 0, MyParent.MyItemInfo.ActiveFormat, null, " (Continued)", 0); float mytmpfloat = smartPara.ParagraphToPdf(cb, smartPara.Height, yTopMargin, yBottomMargin); // .ToPdf(cb, 0, yTopMargin, yBottomMargin); yPageStart -= smartPara.Height; } if (MyItemInfo.IsRNOPart && MyItemInfo.FormatStepData.DoubleSpace && MyItemInfo.FormatStepData.SpaceDouble) yPageStart += SixLinesPerInch; 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) //_MyLog.InfoFormat("NewPage 12 {0}", cb.PdfWriter.CurrentPageNumber); ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin); DebugText.WriteLine("Paginate3"); if (MyItemInfo.IsSection) { SectionInfo si = MyItemInfo as SectionInfo; MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null); } if (MyItemInfo.FoldoutIndex() > -1) PromsPrinter.DoFoldoutPage(cb, "HLS (7 lpi) break", MyPageHelper.TextLayer, MyPageHelper, MyItemInfo.FoldoutIndex(), false); else if (PromsPrinter.MyFoldoutReader.Count > 0 && MyPageHelper.MyPromsPrinter.InsertBlankPages) { // insert a blank page if this step section had a foldout associated and the checkbox // on the print dialog, to add blank pages, is checked MyPageHelper.OnBlankPage = true; cb.PdfDocument.Add(new iTextSharp.text.Table(1)); cb.PdfDocument.NewPage(); //_MyLog.InfoFormat("NewPage 12 lpi blank {0}", cb.PdfWriter.CurrentPageNumber); } // If "ContinueSectionHeader" (format flag) is true then print the section title with "(Continued)" appended to it if (!MyItemInfo.IsSection && MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ContinueSectionHeader) { SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig; doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y"); } } // if printing the section title, we already have the y location (note that only do this for the // first step in the section. if (MyItemInfo.MyPrevious == null && MyItemInfo.MyParent != null && MyItemInfo.MyParent.IsStepSection && ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle && !MyItemInfo.MyDocStyle.SpecialStepsFoldout) yPageStart = yPageStart; else yPageStart = yTopMargin + YTopMost; MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch; DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart); break; } // If "doSectionTitleContinued" is true then print the section title with "(Continued)" appended to it // format must have ContinueSectinHeader format flag set to true if (doSectionTitleContinued) { vlnParagraph sectContPara = new vlnParagraph(MyParent.MyParent, cb, MyItemInfo.ActiveSection, MyParent.XOffset, 0, 0, 0, MyParent.MyItemInfo.ActiveFormat, null, " (Continued)", 0); float mytmpfloat = sectContPara.ParagraphToPdf(cb, yTopMargin, yTopMargin, yBottomMargin); yPageStart -= sectContPara.Height * 2; } yPageStart = ChildrenAbove.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); yPageStart = ChildrenLeft.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); // Handle the PageBreakOnStep flag for a HLS. This will put out the page break right before // a HLS. One example of this use is for backgrounds (CALBCK). if (MyPageHelper.ParaBreaks != null && MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0] == this) { OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin); MyPageHelper.BottomMessage = null; MyPageHelper.TopMessage = null; cb.PdfDocument.NewPage(); MyPageHelper.ParaBreaks.RemoveAt(0); yPageStart = yTopMargin + YTop; } yPageStart = ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin); // If the yPageStart changes by more than a small amount (pagination) in the RNO (right column), then update // yPageStart for the AER (left column). float yPageStartRNO = ChildrenRight.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); if (yPageStartRNO - yPageStart > 24) // 24 is two lines yPageStart = yPageStartRNO; yPageStart = ChildrenBelow.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin); if (MyItemInfo.IsHigh && MyItemInfo.GetNextItem() == null) // last hls, add the 'end' message, if there is one { docstyle = MyItemInfo.MyDocStyle; // if the EndForSingle format flag is set to false, then we do not print an End message if the section // is a single column section. //bool _skipEndMessage = MyPageHelper.MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.One && !MyItemInfo.ActiveFormat.MyStepSectionLayoutData.EndForSingle; SectionInfo si = MyItemInfo.MyActiveSection as SectionInfo; bool _skipEndMessage = si.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.One && !MyItemInfo.ActiveFormat.MyStepSectionLayoutData.EndForSingle; string myMsg = (docstyle.End == null) ? null : docstyle.End.FixedMessage; if (myMsg != null && !_skipEndMessage) { // If the flag is 0 or 1, just put the end message out right below this vlnParagraph: float msg_yLocation = CalculateYLocation(yPageStart - YBottomMost, yTopMargin); //if (MyPageHelper.YMultiplier < 1) // msg_yLocation += 4;// Robinson - if the page is compressed, we need this adjustment. // the following is for IP3 - it was commented out so that an update could be put on // before this was tested. // if end message has {par}, remove these but add a line for each. //int parindx = myMsg.IndexOf("{par}"); //bool foundpar = false; //while (parindx > -1) //{ // foundpar = true; // msg_yLocation += SixLinesPerInch; // parindx = myMsg.IndexOf("{par}", parindx + 1); //} //if (foundpar) myMsg = myMsg.Replace("{par}", ""); // 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 (docstyle.End.Flag < 0) // Adjust this many lines down the page. { float adjMsgY = (float)(-docstyle.End.Flag * SixLinesPerInch); if (msg_yLocation - adjMsgY > docstyle.Layout.FooterLength) msg_yLocation = msg_yLocation - adjMsgY; } if (myMsg.Contains("{Section Number}")) myMsg = myMsg.Replace("{Section Number}", MyItemInfo.ActiveSection.DisplayNumber); //jcb code //if (myMsg.Contains("%-8s")) // myMsg = myMsg.Replace("%-8s", MyItemInfo.MyProcedure.DisplayNumber.PadRight(8)); if (myMsg.Contains("%-12s")) myMsg = myMsg.Replace("%-12s", MyItemInfo.MyProcedure.DisplayNumber.PadRight(12)); float xpos = 0; if ((docstyle.End.Margin ?? 0) != 0) { xpos = (float)docstyle.Layout.LeftMargin + (float)docstyle.End.Margin; MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, xpos, msg_yLocation, docstyle.End.Font); } else { // Center the bottom message float wtpm = (float)docstyle.Layout.PageWidth - (float)docstyle.Layout.LeftMargin; xpos = XOffsetBox + (float)docstyle.Layout.LeftMargin + (wtpm - (myMsg.Length * MyItemInfo.FormatStepData.Font.CharsToTwips)) / 2; xpos = Math.Max(xpos, XOffsetBox + (float)docstyle.Layout.LeftMargin); MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, xpos, msg_yLocation, docstyle.End.Font); MyPageHelper.MyGaps.Add(new Gap(msg_yLocation, msg_yLocation - MyPageHelper.BottomMessage.Height)); } } } if (yLocalypagestart != yPageStart) DebugText.WriteLine("ToPdf-yPagestartDiff:{0},{1},{2},{3}", MyPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, MyItemInfo.ItemID, yLocalypagestart, yPageStart); return yPageStart; } private void DoTopContinueMsg(PdfContentByte cb, ref float yPageStart, float yTopMargin, DocStyle docstyle) { string myMsg = docstyle.Continue.Top.Message; MyPageHelper.TopMessageR = null; if (myMsg != null && myMsg != "") { yPageStart -= 2 * SixLinesPerInch;// Allow two lines for top continue message if (myMsg.IndexOf(@"%sR") > -1) { ItemInfo myAer = MyItemInfo.IsHigh ? MyItemInfo : MyItemInfo.MyParent; if (MyItemInfo.IsInRNO) { // If this is an RNO part, find the parent that is not an RNO (the reason for this is // that RNO parts are structured as parent/child not sibling relationships, for // example, RNO part 1.2 is the child of 1.1 not sibling). Also, if this is a caution // or note of the RNO part, do the same because it should not use the RNO part's tab. // However, the RNO Part will have the combined tab using its parent because this is // needed if any of its children, for example substeps, need the combined tab. if (((MyItemInfo.IsNote || MyItemInfo.IsCaution) && MyItemInfo.MyParent.IsRNOPart) || MyItemInfo.IsRNOPart) { ItemInfo ip = MyItemInfo.MyParent; while (ip.IsRNOPart) ip = ip.MyParent; myMsg = myMsg.Replace(@"%sR", ip.CombinedTab); } else myMsg = myMsg.Replace(@"%sR", MyItemInfo.MyParent.CombinedTab); float xor = MyTopRNO.MyTab.XOffset; MyPageHelper.TopMessageR = new vlnText(cb, this, myMsg, myMsg, xor, yTopMargin + 0.1F, docstyle.Continue.Top.Font); // get aer message, go up parent until find aer and use its combined tab: myAer = MyItemInfo; while (myAer.IsInRNO) myAer = myAer.MyParent; } else if (!MyItemInfo.IsHigh && (MyItemInfo.IsNote || MyItemInfo.IsCaution)) { ItemInfo ip1 = MyItemInfo.MyParent; if (!ip1.IsHigh) myAer = ip1.MyParent; } myMsg = docstyle.Continue.Top.Message.Replace(@"%sR", myAer.CombinedTab); } if (myMsg.IndexOf(@"%s") > -1) { if (MyItemInfo.MyParent.IsSection && (docstyle.StructureStyle.Style & E_DocStructStyle.BottomSectionContinue) == E_DocStructStyle.BottomSectionContinue) myMsg = myMsg.Replace(@"%s", MyItemInfo.MyParent.MyTab.CleanText.Trim()); else myMsg = myMsg.Replace(@"%s", MyItemInfo.MyParent.CombinedTab); } if (myMsg.IndexOf(@"%3d") > -1) myMsg = myMsg.Replace(@"%3d", MyItemInfo.MyHLS.Ordinal.ToString()); if (myMsg.IndexOf(@"%d") > -1) myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanTextNoSymbols.Trim(" .".ToCharArray())); if (myMsg.IndexOf(@"%c") > -1) myMsg = myMsg.Replace(@"%c", " "); if (!PageBreakOnStep) 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); else MyPageHelper.TopMessage = null; } } private void DoBottomContinueMsg(PdfContentByte cb, float yBottomMargin, float yLocation, DocStyle docstyle) { string myMsg = docstyle.Continue.Bottom.Message; // a format flag exists that states to only put a BOTTOM message if it is a certain type (RNO) // check for this.... bool RNOContinueOnly = MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[40].ContinueOnly; bool doBottom = !RNOContinueOnly || (MyItemInfo.IsInRNO && RNOContinueOnly); if (doBottom && myMsg != null && myMsg != "") { myMsg = ReplaceStepBottomContinue(myMsg); float msg_yLocation = 0; if (myMsg.Contains("{par}")) { myMsg = myMsg.Replace("{par}", ""); msg_yLocation = -SixLinesPerInch; } float yBtmMarginForMsg = yBottomMargin; // one of the format flags for FNP had an adjustment for printing the section title only // on the first page of the section. Adjust the location of the bottom continue message // if this adjustment was made (the current topmargin may not reflect the value within // the document style) if (MyPageHelper.PrintedSectionPage > 0) { if ((MyItemInfo.MyActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PrintSectOnFirst) == E_DocStructStyle.DSS_PrintSectOnFirst) { float localYTopMargin = 792 - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.TopMargin; yBtmMarginForMsg = Math.Max(0, localYTopMargin - (float)MyItemInfo.MyActiveSection.MyDocStyle.Layout.PageLength); } } // include space for phone list when determining bottom continue message location if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.PrintPhoneList && MyPageHelper.PhoneListHeight != 0) yBtmMarginForMsg += (MyPageHelper.PhoneListHeight - vlnPrintObject.SixLinesPerInch); switch (docstyle.Continue.Bottom.Location) { case E_ContBottomLoc.EndOfText: // place continue string at end of text msg_yLocation = msg_yLocation + yLocation - SixLinesPerInch; if (yBottomMargin + (docstyle.Layout.FooterLength ?? 0) > msg_yLocation) { // Adjusted Continue Message Y Offset //DebugPagination.WriteLine("====>> {0},'{1}'", msg_yLocation, MyItemInfo.ShortPath); msg_yLocation = yBottomMargin + (docstyle.Layout.FooterLength ?? 0); } break; case E_ContBottomLoc.BtwnTextAndBottom: // place continue string between end of text & bottom of page msg_yLocation = msg_yLocation + yLocation - ((yLocation - yBottomMargin) / 2); // +SixLinesPerInch; // (need this for IP3) if (msg_yLocation < yBottomMargin) msg_yLocation = yBottomMargin; 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 + yBtmMarginForMsg + (float)docstyle.Layout.FooterLength; break; case E_ContBottomLoc.BelowBottom1: msg_yLocation = msg_yLocation + yBtmMarginForMsg; break; case E_ContBottomLoc.EndOfText2: // Like EndOfText but limited within yBottomMargin msg_yLocation = Math.Max(msg_yLocation + yLocation - SixLinesPerInch, yBottomMargin + SixLinesPerInch); break; case E_ContBottomLoc.BtwnTextAndBottom2: // Like BtwnTextAndBottom but accounts for line spacing of step & is 1 line up on page (for BGE - Procedure Steps - 2 column) float adj = (!MyItemInfo.IsSection && MyItemInfo.FormatStepData.StepLayoutData.EveryNLines == 1) ? SixLinesPerInch : 0; msg_yLocation = msg_yLocation + yLocation - ((yLocation - yBottomMargin) / 2) + adj + SixLinesPerInch; if (msg_yLocation < yBottomMargin) msg_yLocation = yBottomMargin; break; default: _MyLog.WarnFormat("**** BOTTOM CONTINUE MESSAGE NOT CODED FOR LOCATION {0}*****", docstyle.Continue.Bottom.Location); break; } if (!PageBreakOnStep) { float xoffB = 0; if (RNOContinueOnly) { // The following line was added for McGuire APs/AP/1/5500/12, Step 13 //if (msg_yLocation < yBottomMargin + SixLinesPerInch) msg_yLocation = yBottomMargin + SixLinesPerInch; float colR = float.Parse(MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColRTable.Split(",".ToCharArray())[MyItemInfo.ColumnMode]); xoffB = colR + docstyle.Layout.LeftMargin + docstyle.Continue.Bottom.Margin ?? 0; } else if (MyItemInfo.IsInRNO && (docstyle.Continue.Bottom.MarginR ?? 0) > 0) { xoffB = (float)docstyle.Layout.LeftMargin + (float)docstyle.Continue.Bottom.MarginR; MyPageHelper.BottomMessageR = new vlnText(cb, this, myMsg, myMsg, xoffB, msg_yLocation, docstyle.Continue.Bottom.Font); xoffB = (float)docstyle.Layout.LeftMargin + (float)docstyle.Continue.Bottom.Margin; } // FloatingContinueMessage format flag: // if breaking at the AER put continue message in left column, // if breaking RNO put continue message in Right column. else if (MyItemInfo.IsInRNO && MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.FloatingContinueMessage) { float colR = float.Parse(MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColRTable.Split(",".ToCharArray())[MyItemInfo.ColumnMode]); xoffB = colR + docstyle.Layout.LeftMargin + docstyle.Continue.Bottom.Margin ?? 0; } else xoffB = docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Bottom.Margin ?? 0; //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); MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, xoffB, msg_yLocation, docstyle.Continue.Bottom.Font); } } if (PageBreakOnStep) MyPageHelper.BottomMessage = null; } private void RefreshDocStyle() { MyItemInfo.ActiveSection = null; MyItemInfo.MyDocStyle = null; MyPageHelper.MySection = MyItemInfo as SectionInfo; MyPageHelper.ResetSvg(); MyPageHelper.PrintedSectionPage = 0; } private string ReplaceStepBottomContinue(string myMsg) { string tb = null; if (MyItemInfo.IsSection) tb = MyItemInfo.MyTab.CleanText.Trim(); else tb = MyItemInfo.MyHLS.MyTab.CleanTextNoSymbols; // if the tab ends with .0, remove it if it was added because of the virtualdotinhls flag. if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.VirtualDotInHLSTab && tb.Contains(".0")) tb = tb.Replace(".0", ""); if (myMsg.IndexOf(@"%d") > -1) myMsg = myMsg.Replace(@"%d", tb.Trim()); if (myMsg.IndexOf(@"%0d") > -1) myMsg = myMsg.Replace(@"%0d", tb.Trim(" .".ToCharArray())); if (myMsg.IndexOf(@"%2d") > -1) myMsg = myMsg.Replace(@"%2d", tb.Trim(" .".ToCharArray()).PadLeft(2)); if (myMsg.IndexOf(@"%3d") > -1) myMsg = myMsg.Replace(@"%3d", MyItemInfo.MyHLS.Ordinal.ToString()); return myMsg; } 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; } /// /// This gets the height of the step with it's Caution's, Notes and potentially any First Substeps /// /// 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 YVeryBottom { get { float bottom = YOffset + Height; if (ChildrenBelow != null) foreach (vlnParagraph child in ChildrenBelow) bottom = Math.Max(child.YVeryBottom, bottom); if (ChildrenLeft != null) foreach (vlnParagraph child in ChildrenLeft) bottom = Math.Max(child.YVeryBottom, bottom); if (ChildrenRight != null) foreach (vlnParagraph child in ChildrenRight) bottom = Math.Max(child.YVeryBottom, bottom); if (PartsBelow != null) foreach (vlnPrintObject part in PartsBelow) bottom = Math.Max(part.YBottom, 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) { // If the substep has a separator (OR, AND) then return the last substep rather than the first. string mySep = ChildrenBelow[0].MyItemInfo.FormatStepData.Sep ?? "{Null}"; if (mySep != "{Null}" && mySep != "") para = ChildrenBelow[ChildrenBelow.Count - 1].GetFirstPieceLastPart(); else { // MNS Pagination - Mike Weiner Case 1a to keep step together with any non-sequential substeps (ANDs, EQ List) bool keepEqListTogether = ChildrenBelow[0].MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PutOnPageByItself; if (keepEqListTogether && !ChildrenBelow[0].MyItemInfo.IsSequential && !this.MyItemInfo.IsHigh) // Extend to the last Item. para = ChildrenBelow[ChildrenBelow.Count - 1].GetFirstPieceLastPart(); else 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; } /// /// 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. /// /// /// 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 CleanupListStepLevel = new List(); foreach (int stepLevel in myList.Keys) { List CleanupListYLocation = new List(); SortedList AdjustYLocation = new SortedList(); 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. if(!myList[stepLevel].ContainsKey(yTop - yLocation)) myList[stepLevel].Add(yTop - yLocation, para); } if (myList[stepLevel].Count == 0) CleanupListStepLevel.Add(stepLevel); } foreach (int stepLevel in CleanupListStepLevel) myList.Remove(stepLevel); } /// /// Builds a list of paragraphs by StepLevel and yLocation in descending order. /// /// /// 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) private bool IsTitleType(ItemInfo itm) { if (itm.FormatStepData != null && (itm.FormatStepData.Index == 42 || itm.FormatStepData.Index == 43)) return true; return false; } private static VlnFlexGrid _MyFlexGrid = new VlnFlexGrid(1, 1); public static VlnFlexGrid MyFlexGrid { get { return _MyFlexGrid; } } private pkParagraph _MyPlaceKeeper = null; public pkParagraph MyPlaceKeeper { get { return _MyPlaceKeeper; } set { _MyPlaceKeeper = value; } } public static bool InList(int id, params int[] ids) { foreach (int listid in ids) if (id == listid) return true; return false; } public vlnParagraph(vlnParagraph parent, PdfContentByte cb, ItemInfo itemInfo, float xoff, float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo, string prefix, string suffix, float yoffRightParent) { BuildPlacekeeper(parent, itemInfo); if (itemInfo.ActiveFormat.MyStepSectionLayoutData.BoxLeftAdj != null) _MyBoxLeftAdj = float.Parse(itemInfo.ActiveFormat.MyStepSectionLayoutData.BoxLeftAdj); ShowSectionTitles = formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles || itemInfo.MyDocStyle.ShowSectionTitles; if (itemInfo.IsSection && itemInfo.ActiveSection.DisplayText.ToUpper().Contains("") && !itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.PrintNoTitle) ShowSectionTitles = false; int MetaLevel = 0; // if meta section, stores what level this section is. float savCheckListBottomMost = 0; //int[] problemIDs = { 889 }; //List lProblemIDs = new List(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; MyItemInfo = itemInfo; if (!MyPageHelper.MyParagraphs.ContainsKey(itemInfo.ItemID)) MyPageHelper.MyParagraphs.Add(itemInfo.ItemID, this); // if this a continuous subsection, refresh the style. // This was commented out to fix a Westinghouse print issue 3-21-2014, orignally put in for Farley //if (itemInfo.IsStepSection && !(itemInfo as SectionInfo).IsSeparatePagination() && itemInfo.MyParent.IsSection) // RefreshDocStyle(); 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; } 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) { // if this is a Note or Caution off of a Note or Caution (Catawba EG/1A/CSAM/SACGR1 step 1) // then indent it the length of its tab if (itemInfo.IsCaution || itemInfo.IsNote) XOffset += (itemInfo.FormatStepData.TabData.IdentPrint.Length -1) * 6; else if (itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset != null) XOffset = float.Parse(itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset); else XOffset += 72 * (itemInfo.FormatStepData.CautionOrNoteSubstepIndent == null ? 0 : (float)itemInfo.FormatStepData.CautionOrNoteSubstepIndent / (float)itemInfo.FormatStepData.Font.CPI); } if (itemInfo.IsStep && itemInfo.MyHLS != null && itemInfo.MyHLS.FormatStepData.UseSmartTemplate && itemInfo.FormatStepData.StepLayoutData.AlignWithParentTab || (itemInfo.Steps != null && itemInfo.Steps.Count > 0 && itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab)) itemInfo.MyTab = null; float xMetaAdj = 0; if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && itemInfo.MyTab.Text != "") { float localXOffset = XOffset; bool doprint = true; if (itemInfo.IsSection) { MyItemInfo.ActiveSection = null; MyItemInfo.MyDocStyle = null; DocStyle ds = MyItemInfo.MyDocStyle; if (!ds.ComponentList && ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle && !MyItemInfo.MyDocStyle.SpecialStepsFoldout) // Don't ouput the Step Section title { SectionConfig sch = MyItemInfo.MyConfig as SectionConfig; if (sch != null && sch.Section_PrintHdr != "Y") { doprint = false; YTopMost = 0; } } else 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.Contains("PSLeft")) { float offset = (float)itemInfo.MyDocStyle.Layout.LeftMargin; if (formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos != null) { ItemInfo iilvl = itemInfo; while (!iilvl.IsProcedure) { // see if this metasection, walking up the tree, has its header printed, // if so, indent for it. SectionConfig sch1 = iilvl.MyConfig as SectionConfig; if (sch1.Section_PrintHdr == "Y" || MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseMetaSections) MetaLevel++; iilvl = iilvl.MyParent; } MetaLevel = MetaLevel <= 2 ? 1 : MetaLevel - 1; if (MetaLevel == 1) offset += (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos; else { xMetaAdj = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[0].ColSByLevel; for (int i = 0; i < MetaLevel; i++) { xMetaAdj += (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos - (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos; xMetaAdj += (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[i].SecNumPositionAdj; } offset += xMetaAdj; itemInfo.MyTab.Text = itemInfo.MyTab.Text.TrimEnd(" ".ToCharArray()); itemInfo.MyTab.CleanText = itemInfo.MyTab.CleanText.TrimEnd(" ".ToCharArray()); } } localXOffset = offset; } } if (!itemInfo.IsSection || doSectTab) { if (itemInfo.MyTab.AltPrintTab != null) mytab = new vlnTab(cb, this, itemInfo.MyTab.AltPrintTab, itemInfo.MyTab.AltPrintTab, localXOffset, yoff, itemInfo.MyTab.MyFont, doSectTab, StepRTB.MySymbolFontName, itemInfo.MyTab.RemovedStyleUnderline); else 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); } } // if this is the High Level RNO step (MyTopRNO) and we are numbering the RNO, adjust the xoffset to start the tab // at the x location rather than starting the text at the x location: AdjustWidth(itemInfo, maxRNO, formatInfo, mytab); bool adjustAgain = ((itemInfo.MyTab != null && itemInfo.MyTab.Position == 0) || (itemInfo.MyPrevious != null && itemInfo.MyPrevious.FormatStepData != null && itemInfo.MyPrevious.FormatStepData.TabData.IsTransition)) ? true : false; if (!itemInfo.IsSection && itemInfo.FormatStepData.NumberHighLevel && itemInfo.IsRNOPart && (MyTopRNO == null || itemInfo.ItemID == MyTopRNO.MyItemInfo.ItemID)) { // adjust the x-offset of the RNO to include the tab. if (itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthSameAsHighParent)// && !itemInfo.MyParent.IsHigh) { vlnParagraph hls = GetHighLevelParagraph(); float RnoOffset1 = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO); float offset = hls.Width + RnoOffset1 + hls.XOffset; vlnTab tb = hls.MyTab; //offset += tb.Width; if (MyTopRNO == null) Width -= (float)itemInfo.ActiveFormat.MyStepSectionLayoutData.SingleColumnRNOIndent; offset -= Width; float inc = offset - XOffset; if (mytab != null) mytab.XOffset += inc;// +(itemInfo.MyParent.IsHigh ? 6.8f : 0); XOffset += inc; adjustAgain = false; } else if (itemInfo.FormatStepData.AdjHighLevelTab != null && itemInfo.ColumnMode > 0) // For Farley (only plant format to use AdjHighLevelTab), determine the xoffset based on // where the right edge of the text is. Their RNO's are numbered with parent numbering // so the calculations for determining the xoffset backs up from the right edge. { float rightTextEdge = this.MyHighLevelParagraph.XOffset + this.MyHighLevelParagraph.Width; int colRx = int.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[itemInfo.ColumnMode]); rightTextEdge += (colRx + (itemInfo.FormatStepData.AdjHighLevelTab ?? 0)); float diff = rightTextEdge - (XOffset + Width); if (mytab != null) mytab.XOffset += diff; XOffset += diff; adjustAgain = false; } else if(mytab != null) { float adjusttab = (itemInfo.MyParent.IsHigh) ? itemInfo.FormatStepData.AdjHighLevelTab ?? 0 : 0; mytab.XOffset += (mytab.Width + adjusttab); XOffset = mytab.XOffset + mytab.Width; if (adjusttab != 0) Width += (mytab.Width); } } if (adjustAgain) AdjustXOffsetForTab(itemInfo, maxRNO, formatInfo, mytab, xMetaAdj); if ((itemInfo.IsCaution || itemInfo.IsNote) && (itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS) { if (itemInfo.IsInRNO) { XOffset = MyTopRNO.MyTab != null ? MyTopRNO.MyTab.XOffset : MyTopRNO.XOffset; Width = MyTopRNO.Width + (MyTopRNO.MyTab != null ? MyTopRNO.MyTab.Width : 0); } else { XOffset = MyHighLevelParagraph.MyTab.XOffset; Width = MyHighLevelParagraph.MyTab.Width + MyHighLevelParagraph.Width - 6; // make width 1/2 char smaller so it doesn't touch line } } if (UseTemplateWidthOrXOff(itemInfo)) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + GetWidthOrStartFromTemplate(itemInfo, itemInfo.ActiveFormat, false); if (itemInfo.MyHeader != null && itemInfo.MyHeader.Text != null && !doSectTab) yoff += SetHeader(this, cb, itemInfo, formatInfo); else if(itemInfo.FormatStepData != null && itemInfo.FormatStepData.SeparateBox && itemInfo.FirstSibling.MyHeader != null && itemInfo.FirstSibling.MyHeader.Text != null) yoff += SetHeader(this, cb, itemInfo.FirstSibling, formatInfo); float yoffLeft = yoff; if (ChildrenAbove != null) ChildrenAbove.StepDesignator = null; //reset StepDesignator if (itemInfo.Cautions != null && !(itemInfo.IsCaution || itemInfo.IsNote)) { if (itemInfo.ActiveFormat.MyStepSectionLayoutData.Dev_Format) { // For deviations, the Cautions are always in the same place. // Fix for Catawba E-1 deviation for step 10. Has note/caution off of a paragraph instead of HLS float xoffDev = (float)itemInfo.MyDocStyle.Layout.LeftMargin; yoffLeft = ChildrenLeft.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); } else yoff = ChildrenAbove.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); } if (itemInfo.Notes != null && !(itemInfo.IsCaution || itemInfo.IsNote)) { if (itemInfo.ActiveFormat.MyStepSectionLayoutData.Dev_Format) { // For deviations, the Cautions are always in the same place. // Fix for Catawba E-1 deviation for step 10. Has note/caution off of a paragraph instead of HLS float xoffDev = (float)itemInfo.MyDocStyle.Layout.LeftMargin + 6 + (float)(itemInfo.ActiveFormat.MyStepSectionLayoutData.WidT); yoffLeft = Math.Max(yoffLeft, ChildrenLeft.Add(cb, itemInfo.Notes, xoffDev, yoff, yoff, rnoLevel, maxRNO, formatInfo)); } else { // Notes/Cautions span the page. If the right (RNO) column is below current yoff, use the // yoff from this. Without this, an overlap of text between the note and the bottom of the // RNO was occurring for FNP - Unit 2/AOP, AOP-4.0. if (yoffRightParent > yoff) yoff = yoffRightParent; yoff = ChildrenAbove.Add(cb, itemInfo.Notes, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo); } } // Comanche Peak uses CAUTION2 type to enter a Step Designator, which is placed to the left of the step number. // The Step Designator information is saved during the processing of the Cautions (ChildrenAbove) // defined in the vlnParagraphs class (of which ChildrenAbove is defined) if (ChildrenAbove.StepDesignator != null) { string pref = ChildrenAbove.StepDesignator; float colOvrd = (float)(ChildrenAbove.StepDesignatorColumn ?? 0); float xPref = (colOvrd > 0) ? colOvrd : mytab.XOffset - (pref.Length * (72 / (float)_MyItemInfo.FormatStepData.Font.CPI)); PartsLeft.Add(new vlnText(cb, this, pref, pref, xPref, yoff, ChildrenAbove.StepDesignatorFont)); ChildrenAbove.StepDesignator = null; ChildrenAbove.StepDesignatorColumn = null; } // if this is a hls with a box, adjust the starting y location for the hls. this is done here // in case this hls had a boxed caution and/or note before it. Also, this code is here rather // than in the vlnparagraphs.add code because the yoff in that code will position the box, but // this code positions the hls (in y direction), without this, the hls starts on the box line. int bxIndx = itemInfo.IsSection ? 0 : itemInfo.FormatStepData.StepLayoutData.STBoxindex ?? 0; if (itemInfo.IsHigh && bxIndx > 0) { int boxLnAdjust = itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox ? 1 : 2; yoff += (boxLnAdjust * SixLinesPerInch); // this yoff is where the BOX starts (boxLnAdjust was added for WEP2) } // If the format has that extra space should be put out before the step, then // handle this by using the 'PartsAbove' structure. By using the parts above, the extra // space above will be done regardless of where page breaks fall. float addExtraSpace = 0; if (MyItemInfo.FormatStepData != null && MyItemInfo.ActiveFormat.MyStepSectionLayoutData.CustomSpacing) addExtraSpace = MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0; if (MyItemInfo.MyParent != null && MyItemInfo.MyParent.FormatStepData != null && MyItemInfo.MyParent.FormatStepData.Type != "TitleWithTextRight") addExtraSpace = (MyItemInfo.FormatStepData == null) ? 0 : MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0; // If a high level 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: // Added check for UseSTExtraRealValue, if set, we want to use what is set for the specific step type // Added check for CustomSpacing (was also in 16-bit logic) if (!MyItemInfo.ActiveFormat.MyStepSectionLayoutData.UseSTExtraRealValue && !MyItemInfo.ActiveFormat.MyStepSectionLayoutData.CustomSpacing && MyItemInfo.IsHigh) addExtraSpace = MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[2].StepLayoutData.STExtraSpace ?? 0; // If CustomSpacing flag is true // then use the STExtraSpace from the step type called "Default" (index number 25) //if (YOffset != 0 && MyItemInfo.IsSection && MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.CustomSpacing) if (YOffset != 0 && MyItemInfo.IsSection && MyItemInfo.ActiveFormat.MyStepSectionLayoutData.CustomSpacing) addExtraSpace = (float)MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[25].StepLayoutData.STExtraSpace; if (YOffset != 0 && MyItemInfo.FormatStepData != null && MyItemInfo.MyPrevious == null && MyItemInfo.FormatStepData.ThreeBlanksAbove && (!MyItemInfo.IsNote || MyItemInfo.MyParent.Cautions == null)) addExtraSpace = 24; // already has one blank line above, added two more //if (YOffset != 0 && MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace > 0) // addExtraSpace = (float)MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace; // if this plant has the AlwaysUseExtraLines and there are notes/cautions above the hls, don't add in the // extra space: if (itemInfo.IsHigh && (itemInfo.Cautions != null || itemInfo.Notes != null)) { if ((itemInfo.Cautions != null && itemInfo.Cautions[0].FormatStepData.AlwaysUseExtraLines) || (itemInfo.Notes != null && itemInfo.Notes[0].FormatStepData.AlwaysUseExtraLines)) addExtraSpace = 0; } if (addExtraSpace > 0 && MyItemInfo.FormatStepData != null) { // We need to strip out the underline style from the font before putting out // the extra line. VE_Font vf=MyItemInfo.FormatStepData.Font; E_Style sty = (E_Style)vf.Style; if ((sty & E_Style.Underline) != 0) sty ^= E_Style.Underline; vf = new VE_Font(vf.Family, (int) vf.Size, sty,(float) vf.CPI); this.PartsAbove.Add(new vlnText(cb, this, " ", " ", 72, yoff, vf)); } yoff += addExtraSpace; YTop = yoff; 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.MyTab != null && itemInfo.MyTab.AsteriskOffset != 0) { // the '-24' in x-direction & '+4' in y-direction was used for the SHE format to get the continuous // HLS's asterisk to match 16bit. The font size was set at 16 to make it match also: VE_Font astFont = new VE_Font(MyItemInfo.FormatStepData.TabData.Font.Family, 16, E_Style.Bold, 10); vlnText myAsterisk = new vlnText(cb, this, "*", "*", mytab.XOffset - 24, YOffset + 4, astFont); PartsLeft.Add(myAsterisk); } if (itemInfo.IsRNOPart && rnoLevel > maxRNO) { // the DoubleSpace & SpaceDouble flags seem redundant. The 2nd line was added for foldout // line spacing for IP2 foldouts (one example can be found in E-1) if (itemInfo.FormatStepData.DoubleSpace && itemInfo.FormatStepData.SpaceDouble) yoff = YOffset = yoff + SixLinesPerInch; if (!itemInfo.FormatStepData.SpaceDouble && itemInfo.MyParent.IsHigh) yoff = YOffset = yoff - SixLinesPerInch; else if (itemInfo.FormatStepData.NoSpaceMultipleRNOs) yoff = YOffset = yoff - SixLinesPerInch; } AddMacros(itemInfo, mytab); if (mytab != null) { mytab.YOffset = yoff; if (mytab.MyMacro != null) mytab.MyMacro.YOffset = yoff; } // For background formats, HLS's or Caution or any Notes have tab on line and then text // on line below (with space in between) if (itemInfo.IsBackgroundStep() && itemInfo.MyTab != null && itemInfo.MyTab.AltPrintTab != null && itemInfo.MyTab.AltPrintTab.Trim() != "") yoff = YOffset = yoff + (2 * SixLinesPerInch); 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) { //Use Static MyFlexGrid - BWD INST2 - FlexGrid Errors MyFlexGrid.LoadGrid(itemInfo); MyGrid = new vlnTable(MyFlexGrid, cb); Height = MyGrid.Height; Width = MyGrid.Width; if (!itemInfo.IsInRNO && yoffRightParent > yoff && itemInfo.FormatStepData.Type.Contains("AER")) { // is the width of this table going to cause the table to overlap the RNO vlnParagraph parRno = FindParentRNO(); float xparRno = parRno.XOffset; if (parRno.MyTab != null) xparRno = parRno.MyTab.XOffset; if (XOffset + Width > xparRno) { yoff = yoffRightParent; YOffset = yoff; } } // if the table does not have a border, only move down one line: float yoffForBorder = 2 * SixLinesPerInch; if (MyFlexGrid.BorderStyle == C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None && !MyFlexGrid.TopRowHasBorder()) yoffForBorder -= SixLinesPerInch; //yForCheckoff = yoff + Height - SixLinesPerInch; if (dropCheckoff) yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text yoff += (Height + yoffForBorder); //(2 * SixLinesPerInch)); CalculateXOffsetGridOrFigure(itemInfo, maxRNO, formatInfo); yoff = (float)Math.Ceiling(yoff); } 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.GetROFSTLookup(dvi); string linkInfoText = itemInfo.MyContent.Text.Replace(@"\v ", ""); Match m = Regex.Match(linkInfoText, @"(.*)[#]Link:([A-Za-z]*):(.*)"); if (m.Groups.Count < 4) { erMsg = "RO was not found during data migration."; } else { 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 bool noborder = MyItemInfo.FormatStepData.Type.ToUpper().Contains("BORDERLESS"); yoff += (Height + ((noborder ? 1 : 2) * SixLinesPerInch)); // RHM 20120925 - Eliminate extra space after Figure } 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); CalculateXOffsetGridOrFigure(itemInfo, maxRNO, formatInfo); } } else { //if (itemInfo.IsSection) // Rtf = GetRtf(itemInfo, prefix, " (Continued)"); //else Rtf = GetRtf(itemInfo, prefix, suffix); // Need the following with some modifications for WCNCKL format: if (Rtf.Contains("{Backspace}")) { XOffset -= 25; Width += 24; Rtf = Rtf.Replace("{Backspace}", ""); } if (itemInfo.IsStep && itemInfo.MyHLS != null && 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) { if (MyItemInfo.FormatStepData.StepPrintData.Justify == "Center") { string[] vertPos = MyItemInfo.MyHLS.FormatStepData.VertPos.Split(",".ToCharArray()); float hloc = (float.Parse(vertPos[stplevl]) + ((float.Parse(vertPos[stplevl + 1]) - float.Parse(vertPos[stplevl])) / 2)); Chunk chk = (Chunk)IParagraph.Chunks[0]; hloc = hloc - (chk.GetWidthPoint() / 2); XOffset = hloc + (float)itemInfo.MyDocStyle.Layout.LeftMargin; } else 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); CalculateXOffsetGridOrFigure(itemInfo, maxRNO, formatInfo); } else if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null && (itemInfo.IsHigh || (!itemInfo.IsHigh && itemInfo.MyContent.Type != itemInfo.MyParent.MyContent.Type))) XOffset += (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0); // point beach wpb subformats 20 & 22 were printing some text past right margin. Limit the width to the right margin, i.e. pagewid if (itemInfo.ActiveFormat.MyStepSectionPrintData.LimitWidToPageWid) { float lim = (MyTab == null ? (XOffset - (float)itemInfo.MyDocStyle.Layout.LeftMargin) : MyTab.XOffset + MyTab.Width) + Width; float docStyleLim = (float)itemInfo.MyDocStyle.Layout.PageWidth - (float)itemInfo.MyDocStyle.Layout.LeftMargin; if (lim > docStyleLim) { WidthNoLimit = Width; // Use this width to calculate childrens' width, without this, code was making children to narrow! Width = docStyleLim - (MyTab == null ? (XOffset - (float)itemInfo.MyDocStyle.Layout.LeftMargin) : MyTab.XOffset + MyTab.Width); } } if (itemInfo.IsSection && ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle) { if (MyItemInfo.MyDocStyle.Layout.SectionMacro != null) { string macro = GetMacroName(MyItemInfo.MyDocStyle.Layout.SectionMacro); PartsAbove.Add(new vlnMacro(xoff, yoff, macro)); } } // if this step has a prefix but it's not checklist... do a partsleft for prefix if (_MyItemInfo.IsStep && !_MyItemInfo.FormatStepData.UseSmartTemplate) { if (_MyItemInfo.FormatStepData.Prefix != null && _MyItemInfo.FormatStepData.Prefix != "") { string pref = _MyItemInfo.FormatStepData.Prefix.Replace("{Backspace}", ""); float xPref = XOffset - (pref.Length * (72 / (float)_MyItemInfo.FormatStepData.Font.CPI)); E_Style es = (E_Style)_MyItemInfo.FormatStepData.Font.Style & E_Style.Bold; VE_Font tmpFont = new VE_Font(_MyItemInfo.FormatStepData.Font.Family, (int)_MyItemInfo.FormatStepData.Font.Size, es, (float)_MyItemInfo.FormatStepData.Font.CPI); PartsLeft.Add(new vlnText(cb, this, pref, pref, xPref, yoff, tmpFont)); } } // If 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 != null && (itemInfo.MyHLS.FormatStepData.UseSmartTemplate || (itemInfo.MyHLS.FormatStepData.UseOldTemplate && itemInfo.MyDocStyle.ComponentList)) && (TheStepLevel(itemInfo) >= 0)) savCheckListBottomMost = yoff + Height + (itemInfo.MyHLS.FormatStepData.UseSmartTemplate ? SixLinesPerInch : 0); // 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 != null && !itemInfo.MyHLS.FormatStepData.UseSmartTemplate) // regular step || (ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle && !MyItemInfo.MyDocStyle.SpecialStepsFoldout) // In 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))) { bool doprint = !(MyPageHelper.DidHLSText && MyItemInfo.ItemID == MyPageHelper.HasHLSTextId); if (MyItemInfo.IsSection) { SectionConfig sch = MyItemInfo.MyConfig as SectionConfig; if (sch != null && sch.Section_PrintHdr != "Y") doprint = false; } if (doprint && !UseTemplateKeepOnCurLine(itemInfo)) { float tyoff = yoff; if (itemInfo.Steps != null) { if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.Type == "TitleWithTextRight") tyoff = ChildrenRight.Add(cb, itemInfo.Steps, XOffset + 72, yoff, yoff, rnoLevel, maxRNO, formatInfo); } yoff += Height; yoff = Math.Max(yoff, tyoff); yoff += AdjustForBlankLines(); if (dropCheckoff) yForCheckoff += Height - SixLinesPerInch; // place checkoff on last row of text } } } CheckOff co = itemInfo.GetCheckOffStep(); if (co != null) { // if this item's content is empty, and the flag is set to 'notonempty', don't print out the // checkoff - this was added for shearon harris: if (!(co.NotOnEmpty && itemInfo.MyContent.Text.Replace(@"\u160?", " ").TrimEnd() == "")) { float xloc_co = (float)itemInfo.MyDocStyle.Layout.LeftMargin; // if the format has 'SkipSpaces', look at the tab, and back up the macros to the number of // spaces in the tab. if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.SkipSpaces) { if (mytab != null) xloc_co = mytab.XOffset; else xloc_co = XOffset; //there's no tab - put checkoff at step's xoff. Macro should back up from step's x. } else { if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation != 0) xloc_co += (float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.XLocation; else if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.RelXLocation != 0) { float relX = (float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.RelXLocation; xloc_co = XOffset + (relX > 0 ? Width : 0) + relX; } } 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); if (ChildrenRight[0].ChildrenAbove.Count > 0) { float adj = ChildrenRight[0].YOffset - YOffset; YOffset = ChildrenRight[0].YOffset; yoff += adj; if (MyTab != null) MyTab.YOffset = ChildrenRight[0].YOffset; if (PartsRight.Count > 0) PartsRight[0].YOffset = ChildrenRight[0].YOffset; if (ChildrenAbove.Count == 0) YTopMost = ChildrenRight[0].ChildrenAbove[0].YOffset; else YTopMost = ChildrenAbove[0].YOffset; } } // if this hls had a box drawn, add a line for substeps. if (itemInfo.IsHigh && ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)) yoff += vlnPrintObject.SixLinesPerInch; // 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.Tables[0].FormatStepData.Type.Contains("AER"); // get the first table & see if it is borderless. If borderless, 16bit code removed a // line (yoffset) before printing it: float yoffadj = 0; if (itemInfo.Tables[0].IsTable) { MyFlexGrid.LoadGrid(itemInfo.Tables[0]); if (MyFlexGrid.BorderStyle == C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None && !MyFlexGrid.TopRowHasBorder()) yoffadj = -SixLinesPerInch; } if (yOffRight < yoffRightParent) yOffRight = yoffRightParent; bool rightLonger = yOffRight > yoff; if (!aerTableOrFigure && itemInfo.RNOLevel == 0) // Centered Table yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, rightLonger ? yOffRight : yoff + yoffadj, yOffRight + yoffadj, rnoLevel, maxRNO, formatInfo); else // AER or RNO Table yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yoff + yoffadj, yOffRight + yoffadj, rnoLevel, maxRNO, formatInfo); } yOffRight = Math.Max(yOffRight, yoffLeft); // 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; } bool rnoBefore = false; bool rnoAfter = false; if (rnoLevel >= maxRNO && itemInfo.RNOs != null && !itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.WolfCreekBackgroundFormat && !itemInfo.RNOs[0].FormatStepData.InPageList) { if ((itemInfo.ActiveFormat.MyStepSectionPrintData.HLRNOStpSeparatorString ?? "") != "" || (itemInfo.ActiveFormat.MyStepSectionPrintData.HLStpSeparatorString ?? "") != "") rnoBefore = true; else rnoAfter = true; } if (rnoBefore) { if ((itemInfo.ActiveFormat.MyStepSectionPrintData.HLStpSeparatorString ?? "") != "") { string tmpSepStr = itemInfo.ActiveFormat.MyStepSectionPrintData.HLStpSeparatorString; float tmpSepLen = itemInfo.ActiveFormat.MyStepSectionPrintData.HLStpSeparatorString.Length; float xsep = MyHighLevelParagraph.PartsLeft.Count > 0 ? MyHighLevelParagraph.PartsLeft[0].XOffset : MyHighLevelParagraph.XOffset; vlnRNOSeparator mySep = new vlnRNOSeparator(this, cb, tmpSepStr, xsep, yoff, itemInfo.ActiveFormat, false); PartsBelow.Add(mySep); yoff += mySep.Height;// +SixLinesPerInch; } yoff = ChildrenBelow.Add(cb, itemInfo.RNOs, MyTab.XOffset, yoff, yoff, rnoLevel + 1, maxRNO, formatInfo); if ((itemInfo.ActiveFormat.MyStepSectionPrintData.HLRNOStpSeparatorString ?? "") != "") { string tmpSepStr = itemInfo.ActiveFormat.MyStepSectionPrintData.HLRNOStpSeparatorString; float tmpSepLen = itemInfo.ActiveFormat.MyStepSectionPrintData.HLRNOStpSeparatorString.Length; float xsep = MyHighLevelParagraph.PartsLeft.Count > 0 ? MyHighLevelParagraph.PartsLeft[0].XOffset : MyHighLevelParagraph.XOffset; vlnRNOSeparator mySep = new vlnRNOSeparator(this, cb, tmpSepStr, xsep, yoff, itemInfo.ActiveFormat, false); PartsBelow.Add(mySep); yoff += mySep.Height;// +SixLinesPerInch; } } if (itemInfo.Steps != null && printsteps) { if (itemInfo.FormatStepData == null || itemInfo.FormatStepData.Type != "TitleWithTextRight") if(rnoBefore) yoff = ChildrenBelow.Add(cb, itemInfo.Steps, MyTab.XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo); else 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); // Don't add the RNO to print if doing backgrounds. That piece of data is part of the pagelist item. if (rnoAfter) 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; float tmpRnoSepLen = formatInfo.MyStepSectionPrintData.RNOSepLineLength ?? 0; if (rnoLevel < maxRNO && itemInfo.RNOs != null && (tmpRnoSepStr != null || tmpRnoSepLen != 0)) { 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 Checklist, the substeps are in rows of data. The YBottomMost is the bottom most for // the row. if (savCheckListBottomMost != 0) YBottomMost = Math.Max(savCheckListBottomMost, YBottomMost); if (XOffsetCenter != null) XOffset = (float)XOffsetCenter; } private void BuildPlacekeeper(vlnParagraph parent, ItemInfo itemInfo) { if (itemInfo is SectionInfo && (itemInfo as SectionInfo).SectionConfig.Section_Placekeeper.ToUpper() != "N") // if is a section type and the section is marked to create placekeeper { MyPlaceKeeper = new pkParagraph(this); if (parent != null && parent.MyItemInfo.IsSection) parent.MyPlaceKeeper = MyPlaceKeeper; } else if (parent != null && parent.MyPlaceKeeper != null && itemInfo is StepInfo)//InList(parent.MyItemInfo.ItemID, 513, 514, 519, 520, 525)) { StepConfig sc = itemInfo.MyConfig as StepConfig; if (sc != null && sc.Step_Placekeeper.ToUpper() != "N") { if (itemInfo.IsCautionPart || itemInfo.IsNotePart) MyPlaceKeeper = parent.MyPlaceKeeper.AddCautionsAndNotes(this); else MyPlaceKeeper = parent.MyPlaceKeeper.AddChild(this); } } } private vlnParagraph FindParentRNO() { if (ChildrenRight != null && ChildrenRight.Count > 0) return ChildrenRight[0]; return MyParent.FindParentRNO(); } private string GetMacroName(string str) { int mindx = str.IndexOf(@"{!"); string macro = str.Substring(mindx + 2, str.Length - 3); return macro; } 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 CalculateXOffsetGridOrFigure(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 = (aerTableOrFigure && hls1.PartsLeft != null && hls1.PartsLeft.Count > 0) ? hls1.PartsLeft[0].XOffset : hls1.XOffset; float xUpperLimit = 0; float pageWidth = ((float)itemInfo.MyActiveSection.MyDocStyle.Layout.PageWidth); float leftMargin = ((float)itemInfo.MyActiveSection.MyDocStyle.Layout.LeftMargin); //* (float)MyItemInfo.FormatStepData.Font.CPI / 12; if (itemInfo.IsInRNO) // if in rno column, the upper limit is width of the page (right margin). Subtract off size of a character xUpperLimit = pageWidth - (72 / (float)MyItemInfo.FormatStepData.Font.CPI); else // in the following calculation, the hls width (hls1.Width) == rno column width, so xUpperLimit is // the around the right margin, i.e. 'hls xoffset' + 'location of rno (colR) * columnmode' + 'width of rno' 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) XOffset = leftMargin + (pageWidth - leftMargin - Width) / 2; else { if (TableCenterPos != 0) { XOffset = TableCenterPos; XOffset = XOffset - (this.Width / 2) + (float)itemInfo.MyDocStyle.Layout.LeftMargin; } else if (itemInfo.RNOLevel != 0) // RNO XOffset = MyParent.XOffset + MyParent.Width / 2 - Width / 2; else if (aerTableOrFigure) XOffset = MyHighLevelParagraph.XOffset + MyHighLevelParagraph.Width / 2 - Width / 2; else // Centered Table or Figure { // 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; // 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. // if outside of the page margins then center within the page margins float xOffset2 = (float)itemInfo.MyDocStyle.Layout.LeftMargin; float xWidth2 = (float)itemInfo.MyDocStyle.Layout.PageWidth; if (XOffset + Width > xOffset2 + xWidth2) XOffset = xOffset2 / 2 + xWidth2 / 2 - Width / 2; } // 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. float posAdjust = (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0); if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null && posAdjust > 0) { if (Width < hls1.Width - posAdjust) XOffset += posAdjust; else if (Width < hls1.Width) XOffset = hls1.XOffset + hls1.Width - Width; // align with the right edge of hls text } } // 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 (MyParent != null && MyParent.MyItemInfo.FormatStepData != null && MyParent.MyItemInfo.FormatStepData.Type == "TitleWithTextRight") return 0; if (MyItemInfo.MyDocStyle.SpecialStepsFoldout) return 0; if (MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.Prefix != null && MyItemInfo.FormatStepData.Suffix != null && MyItemInfo.FormatStepData.UseSmartTemplate) return 0; int everyNLines = MyItemInfo.FormatStepData == null ? 1 : MyItemInfo.FormatStepData.StepLayoutData.EveryNLines ?? 1; if (everyNLines == -99) return 0; if (MyItemInfo.Ordinal % everyNLines == 0 || MyItemInfo.GetNextItem() == null) return SixLinesPerInch; // Pagination issue to be used with yEndsWithBlankLine in Pagination code, but not checked in yet. //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 myMacros = itemInfo.MyMacros; if (myMacros != null) { foreach (Macro myMacro in myMacros) { // if the format has the 'LocWithXOff' locate the macro along with the tab's offset. // however, if the tab is more than 2 characters long, adjust so that it aligns with the // last two characters, not the first 2. string tabText = mytab == null ? null : mytab.Text.Trim(" .".ToCharArray()); int tablen = (tabText == null) ? 0 : (tabText.Length <= 2) ? 0 : tabText.Length - 2; if (myMacro.LocWithXOff ?? false) x = mytab == null ? XOffset : ((float)mytab.XOffset + (tablen * (float)mytab.MyFont.CharsToTwips)); 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); string chgIdTxt = null; if (itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ChgBarMessageFromEdit) { StepConfig sc = itemInfo.MyConfig as StepConfig; chgIdTxt = sc == null ? null : sc.Step_ChangeID; } if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.ChgID) cbMess = chgIdTxt!=null?chgIdTxt: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 = (chgIdTxt!=null?chgIdTxt:itemInfo.MyContent.UserID) + @"\n" + fmtDate; } else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.RevNum) { string lRev = myPageHelper.Rev; // Now check the format flags to determine if/how the Rev string should be parsed. if ((itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.DoRevDate && lRev.Contains("/")) || (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.RevDateWithForwardSlash && lRev.Contains("\\"))) { int indx = lRev.IndexOf(itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.DoRevDate ? '/' : '\\'); cbMess = lRev.Substring(0, indx > -1 ? indx : lRev.Length); } else cbMess = lRev; } 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; float coltotwips = col * itemInfo.FormatStepData.Font.CharsToTwips; if (itemInfo.IsFigure) coltotwips = col * itemInfo.ActiveFormat.PlantFormat.FormatData.Font.CharsToTwips; return new vlnChangeBar(cb, this, (float)itemInfo.MyDocStyle.Layout.LeftMargin + coltotwips, yoff, msgAlign, myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.RevNum); } 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; Box bxCautNote = null; // used for notes and cautions in the Prairie Island Alarms format 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) { bxCautNote = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx]; if (bxCautNote != null) tmpc = (float)bxCautNote.Start + (float)bxCautNote.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; if (bxCautNote != null) rightEdge = (float)bxCautNote.End + 10; // used for notes and cautions in the Prairie Island Alarms format 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; public string GetRtf(ItemInfo itemInfo, string prefix, string suffix) { _RtfSB = new StringBuilder(); DisplayText vlntxt = new DisplayText(itemInfo, E_EditPrintMode.Print, E_ViewMode.View, true, E_FieldToEdit.StepText, false, prefix, suffix); System.Drawing.Font myFont = vlntxt.TextFont.WindowsFont; if (!itemInfo.IsTable && StepRTB.MyFontFamily != null) myFont = new System.Drawing.Font(StepRTB.MyFontFamily, myFont.Size, myFont.Style); string stText = vlntxt.StartText; if (itemInfo.IsHigh && itemInfo.MyDocStyle.UndSpecialStepsFoldout) { myFont = new System.Drawing.Font(myFont.FontFamily, myFont.Size, myFont.Style | FontStyle.Underline); stText = stText.Replace(@"\ulnone ", ""); stText = stText.Replace(@"\ulnone", ""); } if (stText.Contains("{IND}")) stText = stText.Replace("{IND}", "\x5"); if (itemInfo.IsSection && itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.SectionNumber.Level0Big && itemInfo.MyParent.IsProcedure) myFont = new System.Drawing.Font(myFont.FontFamily, 14, myFont.Style | FontStyle.Bold); _RtfSB.Append(AddFontTable(myFont)); _RtfSB.Append(stText); if (_MyItemInfo.IsStep && !itemInfo.FormatStepData.UseSmartTemplate && _MyItemInfo.FormatStepData.Suffix != null && _MyItemInfo.FormatStepData.Suffix != "") _RtfSB.Append(_MyItemInfo.FormatStepData.Suffix.Replace("{ulnone}", @"\ulnone ")); _RtfSB.Append("}"); string rtf = _RtfSB.ToString(); UnderlineTerminateList utl = MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.UnderlineTerminateList; if (utl != null && myFont.Underline) { foreach (UnderlineTerminate ut in utl) { MatchCollection mc = Regex.Matches(rtf, "(? 0) { Match m = mc[mc.Count - 1]; rtf = rtf.Substring(0, m.Index) + @"\ulnone " + rtf.Substring(m.Index); } } } return rtf; } private float _XOffsetBox = 0; public float XOffsetBox { get { return _XOffsetBox; } set { _XOffsetBox = value; } } private float _MyBoxLeftAdj = 0; 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 + _MyBoxLeftAdj + 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 if (itemInfo.IsInRNO && itemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[40].NumberWithLevel) xoff = XOffset + (para.Width / 2) - (hdrWidth / 2); else if (itemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[40].NumberWithLevel) xoff = XOffset + (para.Width / 2) - (hdrWidth / 2); 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 + _MyBoxLeftAdj, YOffset, itemInfo.MyHeader.MyFont); PartsAbove.Add(myHeader); //return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout || (MyItemInfo.MyDocStyle.ExtraLineHeader && (MyItemInfo.IsCaution || MyItemInfo.IsNote)) ? SixLinesPerInch : 0); // Only use SpaceIn property for Cautions or Notes bool bSpaceIn = (MyItemInfo.IsCaution || MyItemInfo.IsNote) ? MyItemInfo.FormatStepData.SpaceIn : true; return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout || (MyItemInfo.MyDocStyle.ExtraLineHeader && (MyItemInfo.IsCaution || MyItemInfo.IsNote)) ? bSpaceIn ? SixLinesPerInch : 0 : 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 SmartTemplateAdjust { // If we're in a smart template (WCNCKL checklists) then account for the bottom line in the // table. get { return (MyItemInfo.IsHigh && MyItemInfo.FormatStepData.UseSmartTemplate) ? SixLinesPerInch : 0; } } public float YSize // How big this paragraph is with all of its children { get { return SmartTemplateAdjust + _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 vlnTab _MyTab; public vlnTab MyTab { get { if (_MyTab == null) { foreach (vlnPrintObject po in PartsLeft) { if (po is vlnTab) { _MyTab = po as vlnTab; break; } } } return _MyTab; } } 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; } } private float? _XOffsetCenter = null; public float? XOffsetCenter { get { return _XOffsetCenter; } set { _XOffsetCenter = value; } } public void AdjustXOffsetForTab(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab, float xMetaAdj) { 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)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[level].ColSByLevel; XOffset += (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[level].SecTitlePositionAdj; XOffset -= xMetaAdj; } } else if (formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Just == "PSCenter") { float hdrWidth = itemInfo.MyContent.Text.Length * 6; float ctr = (((float)itemInfo.MyDocStyle.Layout.PageWidth - (float)itemInfo.MyDocStyle.Layout.LeftMargin)) / 2; XOffsetCenter = (float)itemInfo.MyDocStyle.Layout.LeftMargin + ctr - (hdrWidth / 2); } return; } int? bxIndx = itemInfo.FormatStepData.StepLayoutData.STBoxindex; float? colOvrd = itemInfo.FormatStepData.ColOverride; if (itemInfo.IsBackgroundStep()) { if (myTab != null) myTab.XOffset = XOffset; XOffset += (itemInfo.FormatStepData.Font.CharsToTwips * 2); // indent 2 characters for background steps return; } else if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.Type == "TitleWithTextBelow") { if ((colOvrd ?? 0) != 0) XOffset = (float)colOvrd; else XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin; return; } else if (itemInfo.MyParent.FormatStepData != null && itemInfo.MyParent.FormatStepData.Type == "TitleWithTextBelow") { float childindent = itemInfo.MyParent.FormatStepData.ChildIndent ?? 0; if (myTab != null) { float delta = childindent + MyParent.XOffset - myTab.XOffset; myTab.XOffset += delta; XOffset += delta; } else XOffset = childindent + MyParent.XOffset;//(itemInfo.FormatStepData.Font.CharsToTwips * 2); return; } else if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.Type == "TitleWithTextRight") { if ((colOvrd ?? 0) != 0) XOffset = (float)colOvrd; else XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin; return; } else if (itemInfo.MyParent.FormatStepData != null && itemInfo.MyParent.FormatStepData.Type == "TitleWithTextRight") { XOffset = MyParent.MyParent.XOffset; return; } 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; float adjCols = (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS + seclvlindent; float xtabcol = adjCols - ((myTab == null || myTab.Text == null) ? 0 : (myTab.Text.Length * 7.2f)); if (indxLevel > 1 && myTab != null) myTab.XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + xtabcol; else if (myTab != null) myTab.XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + colsbylevel; if (myTab != null) { myTab.Rtf = myTab.Rtf.Replace(myTab.Text, myTab.Text.TrimStart(" ".ToCharArray())); if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList != null && formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.LeftJustifyList.Count > 0) XOffset = myTab.XOffset + GetLeftJustify(formatInfo, indxLevel); else XOffset = myTab.XOffset + (myTab.Text.Length * (float)itemInfo.FormatStepData.Font.CPI) - colsbylevel; } } else { XOffset += xoff; // For Calvert, adjust from the left margin and current section's tab. if (myTab == null && itemInfo.FormatStepData.AlignNullTabWSectHead && itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos; else if (myTab == null && itemInfo.FormatStepData.AlignNullTabWSectHead) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos; if (myTab != null) { if (itemInfo.MyDocStyle.AlignHLSTabWithSect || itemInfo.FormatStepData.AlignHLSTabWithSectOvride) { myTab.XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos; XOffset = myTab.XOffset + myTab.Width; } else { myTab.XOffset += xoff; if (myTab.MyMacro != null) myTab.MyMacro.XOffset += xoff; } } else { if (itemInfo.MyDocStyle.AlignHLSTabWithSect) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos; } } } else if (((colOvrd ?? 0) != 0) && formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.NullBox) { float tabOffset = (myTab == null ? 0 : myTab.XOffset) - XOffset; XOffset = (float)colOvrd; if (myTab != null) myTab.XOffset = XOffset + tabOffset; return; } else 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 + _MyBoxLeftAdj + tabWidth + XOffsetBox; if (myTab != null) myTab.XOffset = XOffset - tabWidth; } else if (itemInfo.IsRNOPart && itemInfo.MyParent != null && itemInfo.MyParent.IsRNOPart && itemInfo.FormatStepData.NumberWithLevel) { // xoffset is same as parent RNO (this is a BGE format flag). Instead of RNO's being siblings, // they had a parent/child relationship. So want the child to have same xoffset as parent, i.e. // the same xoffset. XOffset = MyParent.XOffset; myTab.XOffset = MyParent.MyTab.XOffset; return; } else if (itemInfo.IsRNOPart && (colOvrd > 0 || !((ItemInfo)itemInfo.ActiveParent).IsHigh) && itemInfo.FormatStepData.OffsetTab) { if (colOvrd > 0) { XOffset = (int)colOvrd; if (!((ItemInfo)itemInfo.MyParent).IsHigh) { ItemInfo hls = itemInfo.MyHLS; XOffset -= (itemInfo.MyTab.Offset - hls.MyTab.Offset); } } // if the step is within the rno and we're numbering the high level rno, we've got to account for the // indenting (increased x offset) for the top level rno's tab, if there is no top level rno: if (itemInfo.FormatStepData.NumberHighLevel && (itemInfo.MyHLS.RNOs == null || itemInfo.MyHLS.RNOs.Count <= 0)) { // add in the size that an RNO off HLS would take. tabWidth += itemInfo.MyTab.RNOTabWidthAdjust; XOffset += tabWidth; if (myTab != null) myTab.XOffset += tabWidth; } if (itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset != null) { MyTab.XOffset = float.Parse(itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset); XOffset = MyTab.XOffset + tabWidth - MyTab.TabAlign; } } else if (MyParent != null) { if (myTab == null && itemInfo.FormatStepData.AlignNullTabWSectHead && itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos; else if (itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset != null) { if (MyTab != null) { MyTab.XOffset = float.Parse(itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset); XOffset = MyTab.XOffset + tabWidth - MyTab.TabAlign; if (myTab.MyMacro != null && myTab.MyMacro.XOffset != 0) myTab.MyMacro.XOffset += tabWidth - myTab.TabAlign; } } else if (itemInfo.IsSequential && itemInfo.MyParent.IsHigh && ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.Align1StLevSubWHLS) == E_DocStructStyle.Align1StLevSubWHLS)) { XOffset = MyParent.XOffset; if (myTab != null) myTab.XOffset = (MyParent.MyTab != null ? MyParent.MyTab.XOffset : XOffset); } else 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(); float tableftadj = GetLeftJustify(formatInfo, indxLevels); // 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 ((itemInfo.FormatStepData.ColOverride ?? 0) > 0) //{ // XOffset = (float)itemInfo.FormatStepData.ColOverride; // MyTab.XOffset = XOffset; // return; //} else // if no left justify, right align the tab { XOffset += tabWidth - (myTab == null ? 0 : myTab.TabAlign); if (myTab != null) { myTab.XOffset += tabWidth - myTab.TabAlign; if (myTab.MyMacro != null && myTab.MyMacro.XOffset != 0) myTab.MyMacro.XOffset += tabWidth - myTab.TabAlign; } } } // if format had a tab adjustment for step type, use it. MyTab.Offset is only set for FNP formats // to get the correct xoffset for their tabs/text. The issue is that they use very large tabs // because levels of substeps include the parent tab. This code will only be run for FNP. if (itemInfo.MyTab != null && itemInfo.MyTab.Offset != 0) { float xOffTabNew = (MyParent.MyTab != null ? MyParent.MyTab.XOffset : MyParent.XOffset) + itemInfo.MyTab.Offset; xOffTabNew += MyParent.MyTab == null ? 0 : MyParent.MyTab.TabOffset; float xIncrement = xOffTabNew - MyTab.XOffset; myTab.XOffset += xIncrement; XOffset += xIncrement; Width -= xIncrement; } } private static float GetLeftJustify(FormatInfo formatInfo, int indxLevels) { 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; } } return tableftadj; } public void AdjustWidth(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab) { int? bxIndx = itemInfo.IsStep ? itemInfo.FormatStepData.StepLayoutData.STBoxindex : null; float? widOvrd = 0; float xwid = 0; if (itemInfo.IsStep && itemInfo.MyHLS != null && UseTemplateWidthOrXOff(itemInfo) && (xwid = GetWidthOrStartFromTemplate(itemInfo, formatInfo, true)) > 0) widOvrd = xwid; else widOvrd = itemInfo.FormatStepData == null ? null : itemInfo.FormatStepData.WidthOverride == null ? null : (float?)ToInt(itemInfo.FormatStepData.WidthOverride, maxRNO); //widOvrd = itemInfo.FormatStepData == null ? null : itemInfo.FormatStepData.WidthOverride; // Don't adjust the RNO width if in single column mode: if (itemInfo.IsRNOPart && itemInfo.MyParent.IsHigh && itemInfo.MyActiveSection.ColumnMode != 0 && itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAlt != null) { string[] splitRNOWidthAlt = itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAlt.Split(','); float ovrd = (itemInfo.RNOLevel < splitRNOWidthAlt.Length) ? float.Parse(splitRNOWidthAlt[itemInfo.RNOLevel]) : 0; if (ovrd > 0) widOvrd = ovrd; // + 6; // Change bars on RNO column (signoff line) would not line up with 16-bit without this - NSP Alarms } 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 (itemInfo.IsHigh) { float CheckOffAdj = 0; if (itemInfo.MyDocStyle.UseCheckOffs) { bool FmtHasAdj = false; if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment != null) { FmtHasAdj = true; 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 else if (!FmtHasAdj && HasCheckOffHeading(itemInfo, formatInfo)) // For Robinson, tried using font's CharsToTwips but it made it too narrow, so used hardcoded 6: CheckOffAdj = -((float)9 * 6); } float adjwidth = CheckOffAdj; SectData sd = formatInfo.PlantFormat.FormatData.SectData; if (sd.UseMetaSections) { if (sd.StepSectionData.StepSectionLayoutData.TieTabToLevel) { if (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; // if AlignHLSTabWithSect is set, we moved the starting x location of the HLS, and following steps // to be under section header. Adjust the width accordingly, or the text may go out of the margin. if (myTab == null && itemInfo.FormatStepData.AlignNullTabWSectHead && itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) Width = Width + (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos - (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos; else if (myTab == null && itemInfo.FormatStepData.AlignNullTabWSectHead) Width = Width + (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos; else if (itemInfo.MyDocStyle.AlignHLSTabWithSect) Width = Width - (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos; } else 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) if (widOvrd != 0) Width = (float)widOvrd - tabWidth; else 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.IsCaution || itemInfo.IsNote) { float mycolT = (float)formatInfo.MyStepSectionLayoutData.ColT; if (formatInfo.MyStepSectionLayoutData.Dev_Format) Width = (float)formatInfo.MyStepSectionLayoutData.WidT + 1; else if (itemInfo.IsInRNO) { if (MyItemInfo.FormatStepData.CenterOneLineAdjust) { int rnoOff = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO); XOffset = rnoOff + MyHighLevelParagraph.XOffset; Width = MyParent.Width; } else Width = (MyParent.XOffset + MyParent.Width) - (XOffset + mycolT); } else Width = (float)formatInfo.MyStepSectionLayoutData.WidT - 6 - mycolT; XOffset += mycolT; // adjust caution/note text position if (PartsLeft != null && PartsLeft.Count > 0)// adjust tab position { if(myTab!=null && (itemInfo.IsNote || itemInfo.IsCaution)) Width -= myTab.Width; 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) { if (itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAdj != null && !((ItemInfo)itemInfo.ActiveParent).IsInRNO) Width = MyParent.Width + float.Parse(itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAdj); else 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) { if(itemInfo.ActiveFormat.MyStepSectionLayoutData.DevNoteOrCautionTabOffset != null) Width = MyParent.MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign); else 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; if (itemInfo.IsRNOPart && itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthSameAsHighParent && itemInfo.MyParent.IsHigh) Width = adjwidth + MyParent.Width; else if (itemInfo.MyTab.Position != 0) Width = adjwidth + MyParent.Width; else if (MyParent.WidthNoLimit != 0) Width = adjwidth + MyParent.WidthNoLimit - tabWidth + (myTab == null ? 0 : myTab.TabAlign); else Width = adjwidth + MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign); } if (itemInfo.IsSequential && itemInfo.MyParent.IsHigh && ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.Align1StLevSubWHLS) == E_DocStructStyle.Align1StLevSubWHLS)) Width += 10; // FIX THIS!!! } // for Component Table, don't increment yoff unless last item in table that HAS data associated // with it (there may be empty cells at end). public bool UseTemplateKeepOnCurLine(ItemInfo itemInfo) { if (!itemInfo.IsStep || !itemInfo.MyDocStyle.ComponentList) return false; if (itemInfo.MyHLS.FormatStepData.UseOldTemplate) return true; return false; } private bool UseTemplateWidthOrXOff(ItemInfo itemInfo) { if (!itemInfo.IsStep) return false; if (itemInfo.MyHLS == null) return false; if (itemInfo.MyHLS.FormatStepData.UseSmartTemplate) return false; if (!itemInfo.MyDocStyle.ComponentList) return false; if (itemInfo.MyHLS.FormatStepData.UseOldTemplate) { ItemInfo useForTemplate = itemInfo.IsHigh ? itemInfo : itemInfo.MyParent; int topIndx = useForTemplate.GetSmartTemplateTopLevelIndx(); int tpIndx = useForTemplate.GetSmartTemplateIndex(topIndx, (int)useForTemplate.MyContent.Type); if (tpIndx > -1) return true; } return false; } private float GetWidthOrStartFromTemplate(ItemInfo itemInfo, FormatInfo formatInfo, bool bGetWidth) { int topIndx = itemInfo.GetSmartTemplateTopLevelIndx(); int tmplIndx = 0; if (itemInfo.MyDocStyle.ComponentList && !itemInfo.IsHigh) { // The ComponentTable format (FNP component table as one example), uses a template // where the items in the template below the HLS are all paragraphs (the intermediate steps // are TitleWithTextRight). Find the ordinal of in this list to get the index. Use the ordinal // as an offset from the HLS's index into the template. tmplIndx = itemInfo.MyParent.Ordinal + topIndx; if (tmplIndx < 0 || tmplIndx > formatInfo.PlantFormat.FormatData.Templates.Count - 1) return 0; } else { tmplIndx = itemInfo.GetSmartTemplateIndex(topIndx, (int)itemInfo.MyContent.Type); if (tmplIndx == -1) return 0; } int ncol = bGetWidth ? formatInfo.PlantFormat.FormatData.Templates[tmplIndx].width : formatInfo.PlantFormat.FormatData.Templates[tmplIndx].start; // now convert to the units for this format. The template width data is in number of columns. return (ncol * itemInfo.FormatStepData.Font.CharsToTwips) + (bGetWidth ? 1 : 0); // + 1 is slight adjustment so column doesn't wrap } 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; } // Currently not used. // //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; //} } /// /// 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 /// public class StepLevelList : SortedDictionary> { 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()); // 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 { 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(bool KeepStepsOnPage) { StepLevelList myList = new StepLevelList(); foreach (ParagraphLocation paraLoc in this) { int level = paraLoc.StepLevel; if (KeepStepsOnPage && paraLoc.MyParagraph.MyItemInfo.MyContent.Type == 20001) { if (DontBreakHere(paraLoc)) //if (paraLoc.MyParagraph.MyItemInfo.MyPrevious == null) // First substep level = 0; else level = 1; } myList.Add(level, paraLoc.YTop, paraLoc.MyParagraph); } return myList; } private bool DontBreakHere(ParagraphLocation paraLoc) { if (paraLoc.MyParagraph.MyItemInfo.MyPrevious == null) // First substep return true; vlnParagraph myPara = paraLoc.MyParagraph; while (!myPara.MyItemInfo.IsHigh) { if (myPara.MyItemInfo.IsCaution) return true; if (myPara.MyItemInfo.IsNote) return true; myPara = myPara.MyParent; } return false; } } public class ParagraphLocation { public override string ToString() { return string.Format("{0} {1} - {2} - '{3}'", this.MyParagraph.MyItemInfo.ItemID, this.StepLevel, this.YTop, this.MyParagraph.MyItemInfo.ShortPath); } 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); } } }