7276 lines
374 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Text;
//using System.Drawing;
using System.Text.RegularExpressions;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;
using Itenso.Rtf;
using Itenso.Rtf.Parser;
using Itenso.Rtf.Interpreter;
using Itenso.Rtf.Support;
using Volian.Controls.Library;
using VEPROMS.CSLA.Library;
using Volian.Base.Library;
namespace Volian.Print.Library
{
public partial class vlnParagraphs : List<vlnParagraph>
{
private vlnParagraph _Parent;
public vlnParagraph Parent
{
get { return _Parent; }
set { _Parent = value; }
}
public vlnParagraphs(vlnParagraph parent)
{
_Parent = parent;
}
// 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)
{
return Add(cb, itemInfoList, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo, null);
}
public float Add(PdfContentByte cb, ItemInfoList itemInfoList, float xoff, float yoff, float yoffRight, int rnoLevel, int maxRNO, FormatInfo formatInfo, PromsPrinter pp)
{
int profileDepth = ProfileTimer.Push(">>>> vlnParagraphs.Add");
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;
int prevTplRow = 0;
int maxRnoSav = maxRNO;
foreach (ItemInfo iChildItemInfo in itemInfoList)
{
if (pp != null) pp.OnStatusChanged((iChildItemInfo.DisplayNumber ?? "") == "" ? iChildItemInfo.DisplayText : iChildItemInfo.DisplayNumber, PromsPrinterStatusType.LoadVlnParagraph);
if (iChildItemInfo.IsFootnote)
{
vlnParagraph para = new vlnParagraph(Parent, cb, iChildItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo, null, null, yoffRight, true, iChildItemInfo.IsSection ? pp : null);
continue; // don't add it, vlnParagraph adds this item to the footnote list in ToPdf.
}
maxRNO = maxRnoSav;
if (iChildItemInfo.IsHigh) bxIndex = null;
if (iChildItemInfo.IsSection && (iChildItemInfo as SectionInfo).ColumnMode != maxRNO)
maxRNO = (iChildItemInfo as SectionInfo).ColumnMode;
int maxRnoTemplate = iChildItemInfo.TemplateChildColumnMode;
if (maxRnoTemplate >= 0) maxRNO = maxRnoTemplate - 1;
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.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && childItemInfo.IsInTemplate()))
{
if (childItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
// if this template element has a -1 for row, print it (if = 0 this is a heading for edit
// and not printed). if this template element has a width of > 0, then also print it,
// these are headings and should be printed). This was added for Calvert Alarm (BGEALN) format for
// DEVICE/SETPOINT (row=-1), and for POSSIBLE CAUSES, AUTOMATIC ACTIONS, etc (width>0)
// find the indexes into the template for this item. The index must be for the HLS this is
// or this is under.
int tindx = childItemInfo.TemplateIndex;
if (tindx == -1)
xoff = (float)childItemInfo.MyDocStyle.Layout.LeftMargin;
else if (childItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[tindx].row < 0 ||
childItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[tindx].width > 0)
{
// move down for the 'POSSIBLE CAUSES'. To know it's that step type, check
// the column field in template. -1 represents staying on same row but using
// the start template field to get the xoffset.
if (prevTplRow == -1 && prevTplRow != childItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[tindx].row)
{
// position to the furthest down the page of the Device/setpoint/annunciator window:
yoff = Math.Max(yoff, Parent.YBottomMost + vlnPrintObject.SixLinesPerInch);
yoff = Math.Max(yoff, tableBottomMost + vlnPrintObject.SixLinesPerInch);
}
xoff = (float)childItemInfo.MyDocStyle.Layout.LeftMargin + (childItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[tindx].start * 7.2f);
prevTplRow = childItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[tindx].row;
}
}
else
{
// childItemInfo = 'child' and set to use a template for defining size.
// Note that the 'IsCaution1' was added for Calvert Valve lists, i.e.
// the Caution1 is a subheader & must be printed within the valve list table.
if (childItemInfo.Steps == null && !childItemInfo.IsCaution1)
continue;
if (!childItemInfo.IsCaution1) 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.NextItem != null && childItemInfo.MyContent.Type == childItemInfo.NextItem.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;
Parent.AdjustForMatchUpRNO = vlnPrintObject.SixLinesPerInch; // B2020-112
}
}
// 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;
bool alwaysBox = (childItemInfo.IsHigh && childItemInfo.FormatStepData.BoxIt);
if ((alwaysBox || (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;
float colR = float.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)
{
// B2022-130: Barakah warning box prints on bottom of section title if warning is on first HLS
if (box.MyBox.ThickDouble && childItemInfo.MyParent != null && childItemInfo.MyParent.IsHigh && childItemInfo.MyParent.ItemID == childItemInfo.MyParent.FirstSibling.ItemID)
{
if (!childItemInfo.MyParent.MyParent.MyDocStyle.CancelSectTitle)
yoff += vlnPrintObject.SixLinesPerInch;
}
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))
{
// note that in the following line of code, the Calvert Alarms' caution1 is their annunciator window
// so it needs the extra lines as defined by 'ln' or the text will be too close to the top of the box.
if (!formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm || iChildItemInfo.IsCaution1)
yoff += ln * vlnPrintObject.SixLinesPerInch;
else
yoff += 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))
{
bool didSeparateBoxChgYAdjust = false;
if (box != null)
{
box.Height = yoff - box.YOffset; // new height, with children
if (formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm ||
formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
{
if (childItemInfo.MyHeader != null && childItemInfo.MyPrevious != null
&& ((childItemInfo.MyPrevious.IsCautionOrNotePart && childItemInfo.IsCautionOrNotePart)
|| childItemInfo.FormatStepData.SeparateBox))
yoff += vlnPrintObject.SixLinesPerInch * 2;
}
else if (childItemInfo.MyHeader != null && childItemInfo.MyPrevious != null
&& ((childItemInfo.MyPrevious.IsCaution && childItemInfo.IsCaution) ||
(childItemInfo.MyPrevious.IsNote && childItemInfo.IsNote) || childItemInfo.FormatStepData.SeparateBox))
yoff += vlnPrintObject.SixLinesPerInch * 2;
// B2020-026: Farley - Notes before Cautions/cautions and notes in same 'parts' list, so bxIndex what not null, need
// to add an extra line after note box.
else if (formatInfo.Name.ToUpper().StartsWith("FNP") && childItemInfo.MyPrevious != null && childItemInfo.MyPrevious.IsNote && childItemInfo.IsCaution)
yoff += vlnPrintObject.SixLinesPerInch * 2;
else if (doSeparateBoxHdrChg) // F2021-038: SHE/SHEA format - Less space after boxes (removes it below)
{
didSeparateBoxChgYAdjust = true;
yoff += vlnPrintObject.SixLinesPerInch * 2;
}
}
box = new vlnBox();
box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
// F2021-038: SHE/SHEA format - Less space after boxes
if (didSeparateBoxChgYAdjust && childItemInfo.IsStep && childItemInfo.FormatStepData.NoYBxAdjust) yoff -= vlnPrintObject.SixLinesPerInch;
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;
}
else if (((bxIndx ?? -1) == -1) && box != null)
{
// BGE STP has a null box for its 'Date Time Stamp', i.e. Note4,
// without this code if there is a previous sibling the 'Date Time Note' was
// included in its previous sibling's box:
// (STBoxindex="" is how Note4's box in BGE STP is defined - it is the only place
// in the format files that this is done)
box.Height = yoff - box.YOffset; // new height, with children
yoff += 2 * vlnPrintObject.SixLinesPerInch;
box = null;
}
// 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;
}
vlnParagraph para = null;
// Comanche peak or WCN bck Step designator
if (childItemInfo.IsCaution2 && childItemInfo.SameRowAsParent ||
childItemInfo.IsCaution1 && childItemInfo.SameRowAsParent)
{
// Save the Step Designator information
// SameRowAsParentMultiLine currently used in Comanche Peak EOP and Flex formats - handles a hard return in the caution type
_StepDesignator = ((childItemInfo.SameRowAsParentMultiLines) ? childItemInfo.MulitLineStepDesignatorDisplayText : 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);
if (childItemInfo.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.ContActBoxOnSubSteps &&
box != null && box.MyBox != null && bxIndx == null) // point beach boxed substeps
{
box.Height = yoff - box.YOffset - (1F * vlnPrintObject.SixLinesPerInch);
box = null;
yoff += 1 * vlnPrintObject.SixLinesPerInch;
}
para = new vlnParagraph(Parent, cb, childItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo, null, null, yoffRight, true, pp);
// 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);
if (didComponentTableRow && iChildItemInfo.Steps != null && iChildItemInfo.Steps.Count > 1)
tableBottomMost = Math.Max(tableBottomMost, AddComponentTableSiblings(cb, iChildItemInfo.Steps[1], xoff, para.YBottomMost, rnoLevel, maxRNO, formatInfo, yoffRight, pp));
// Calvert Alarm's caution1 is the Annunciator window, i.e. in top right of page. Adjust
// y offset for this caution that is printed BELOW the hls.
if (childItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && iChildItemInfo.IsCaution1) para.MyHighLevelParagraph.YBottomMost = para.YBottomMost;
// 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))
{
// B2019-028: These comments ARE NOT relevant and the code added, the if and the else/console.writeline
// are not correct (left in commented out so that change can be seen):
// Don't set to zero after a Word Section
// Otherwise the step section output will overlap previous step section output
// if in a sub section.
// To see the problem, create a section with three subsections.
// First section a multiple page step section
// Second section a word section
// Third section a step section
// skip the logic in the next three lines. (if to else)
//if (para.YBottomMost > 0)
yoff = para.YBottomMost;
//else
//Console.WriteLine("ERROR Would have changed yoff from {0} to zero",yoff);
}
// don't adjust YBottomost until after yoff is set for the RNO Separator
para.YBottomMost += para.YBottomMostAdjust;
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;
// if the YBottomForBox is set, use it to define height. Note that this property was
// introduced for IP3 continuous hls (surrounded by the asterisk box), no other format/step type uses it.
if (para.YBottomForBox > 0)
box.Height = para.YBottomForBox - box.YOffset - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); // para.YTop - (1.1F * vlnPrintObject.SixLinesPerInch);
else
box.Height = para.YBottomMost - box.YOffset - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); // para.YTop - (1.1F * vlnPrintObject.SixLinesPerInch);
box = null;
}
}
if (boxHLS)
{
// if the next HLS is boxed also, only need 1 line separating, otherwise
// need 2.
ItemInfo nxt = childItemInfo.GetNextItem();
int nxtIsBoxed = 2;
if (nxt != null &&
nxt.FormatStepData.StepLayoutData.STBoxindex != null && nxt.FormatStepData.StepLayoutData.STBoxindex >= 0) nxtIsBoxed--;
if (nxt != null && (nxt.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS) nxtIsBoxed = 0;
yoff += (nxtIsBoxed * vlnPrintObject.SixLinesPerInch);
}
if (childItemInfo.IsSequential && childItemInfo.NextItem != null && childItemInfo.MyParent.IsHigh && ((childItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.XBlankW1stLevSub) == E_DocStructStyle.XBlankW1stLevSub))
{
yoff += vlnPrintObject.SixLinesPerInch;
if (para != null) para.AdjustForXBlankW1stLevSub = vlnPrintObject.SixLinesPerInch; // B2020-112
}
boxHLS = false;
lastChild = childItemInfo;
}
}
if (box != null && box.MyBox != null)
{
box.Height = yoff - box.YOffset; // new height, with children
// C2017-024 Wolf Creek wanted a hold point with out text and no extra blank lines in the caution/note box
// so if they put only a hard space in for the text, then we will print the note/caution box with only the tab text
// B2018-077 added check for parts under the note (ex. a table off of the note text) fix for Calvert OI-27B 6.11.B and 6.12.B
if (box.MyParent.MyItemInfo.MyContent.Text.StartsWith(@"\u160?") && box.MyParent.MyItemInfo.DisplayText.Length == 1 && box.MyParent.MyItemInfo.MyContent.ContentPartCount == 0)
{
box.Height -= 3 * vlnPrintObject.SixLinesPerInch;
yoff -= vlnPrintObject.SixLinesPerInch;
}
else
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;
ProfileTimer.Pop(profileDepth);
return yoff;
}
private float AddComponentTableSiblings(PdfContentByte cb, ItemInfo ii, float xoff, float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo, float yoffRight, PromsPrinter pp)
{
// Some of the data for the valve lists (BGE) and component lists (FARLEY) have
// sibling data within a column, rather than hard returns within the same paragraph.
float tableBottomMost = 0;
while (ii != null)
{
vlnParagraph para = new vlnParagraph(Parent, cb, ii, xoff, yoff, rnoLevel, maxRNO, formatInfo, null, null, yoffRight, true, pp);
tableBottomMost = Math.Max(tableBottomMost, para.YBottomMost);
yoff = para.YBottomMost;
Add(para);
ii = ii.GetNextItem();
}
return tableBottomMost;
}
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
{
// B2020-115 Create Static properties for vlnParagraph to limit the size of a figure and paginate large figures properly onto their own page.
public static float wMax = 0;
public static float hMax = 0;
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 bool HasCalvertMacro = false; // this step has the Calvert (BGE) Alarm CONDITION/RESPONSE macro associated with it
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; }
}
public static bool HasPrefPageBreak = false; // use to track page breaks for supp info
public bool PrefPageBreak = false;
private bool _ShowSectionTitles;
public bool ShowSectionTitles
{
get { return _ShowSectionTitles; }
set { _ShowSectionTitles = value; }
}
public float ParagraphToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
{
// Don't print section titles for supplemental information because the title is 'Supplemental Information':
if (MyItemInfo.IsSection && MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.SupInfoPdfPrint) return yPageStart;
//if(PartsAbove.Count > 0 && PartsAbove[0] is vlnHeader)
// if (PartsLeft.Count > 0 && PartsLeft[0] is vlnTab)
// //if((PartsLeft[0] as vlnTab).Text[0] != '\u25CF')
// _MyLog.WarnFormat("NoteTab '{0}','{1}','{2}','{3}','{4}','{5}','{6}'", (PartsAbove[0] as vlnHeader).Text, (PartsLeft[0] as vlnTab).Text, MyItemInfo.MyProcedure.DisplayNumber, MyItemInfo.MyHLS.DisplayText,
// MyItemInfo.ShortPath, MyItemInfo.FormatStepData.TabData.IdentPrint, MyItemInfo.FormatStepData.TabData.IdentEdit);
//
// B2017-105 if a symbol character was set to a bigger font size, then the positioning of the larger symbol character was printing too high on the line
// found with Wolf Creek use of the empty box symbol
foreach (Chunk chk in IParagraph.Chunks)
{
if (chk.Font.Size > 16) chk.SetTextRise(-2f);
}
if (MyItemInfo.IsFootnote && Processed) return yPageStart;
int pagenumTran = 0;
if ((MyItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DontCountFoldoutPgs) == E_DocStructStyle.DontCountFoldoutPgs)
pagenumTran = MyPageHelper.CurrentPageNumberNoFoldouts;
else
pagenumTran = MyPageHelper.CurrentPageNumber;
if (MyItemInfo.PageNumber == -1) MyItemInfo.PageNumber = pagenumTran;
else if (MyItemInfo.PageNumberUsed != 0 && MyItemInfo.PageNumberUsed != pagenumTran)
{
if (PromsPrinter.TransPageNumProblems == null) PromsPrinter.TransPageNumProblems = new List<string>();
// C2017-018 Insert tabs between columns
string pnErr = string.Format("{0}\t{1}\t{2}\t{3}", MyItemInfo.ItemID, MyItemInfo.ShortPath, MyItemInfo.PageNumberUsed, pagenumTran);
PromsPrinter.TransPageNumProblems.Add(pnErr);
}
MyItemInfo.PageNumberNextPass = pagenumTran;
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);
// F2021-038: SHE/SHEA format - Less space after boxes: the AlwaysUseExtyraLines was removed in SHE/SHEA format, but the
// following adjustment to the y location of HLS when AT TOP of page is still needed, i.e. added the NoYBxAdjust check which is SHE/SHEA specific
if ((MyItemInfo.Cautions != null && (MyItemInfo.Cautions[0].FormatStepData.AlwaysUseExtraLines || MyItemInfo.Cautions[0].FormatStepData.NoYBxAdjust)) || (MyItemInfo.Notes != null && (MyItemInfo.Notes[0].FormatStepData.AlwaysUseExtraLines || MyItemInfo.Notes[0].FormatStepData.NoYBxAdjust)))
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, yPageStart, yTopMargin);
else
retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
if (MyItemInfo.IsInSupInfo) _yPageStartForSupInfo = retval;
}
else if (MyItemInfo.IsRtfRaw)
{
retval = DrawRaw(cb, yBottomMargin, yLocation, yPageStart, yTopMargin);
if (MyItemInfo.IsInSupInfo) _yPageStartForSupInfo = retval * .6f;
}
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)
{
int profileDepth = ProfileTimer.Push(">>>> vlnParagraph.DrawGrid");
// RHM20150507 Include Footer
retval = DrawGrid(cb, ref yPageStart, yTopMargin, yBottomMargin + (float)MyItemInfo.MyDocStyle.Layout.FooterLength, ref yLocation); // RHM20150429 - Table Scrunch
if (MyItemInfo.IsInSupInfo) _yPageStartForSupInfo = (float)MyPageHelper.BottomContent - SixLinesPerInch;
ProfileTimer.Pop(profileDepth);
}
else
{
if (doprint)
{
int profileDepth = ProfileTimer.Push(">>>> vlnParagraph.DrawText");
IsCompressed = (MyPageHelper.YMultiplier != 1 && MyItemInfo != null && MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.Font.Size >= 12 && (MyItemInfo.FormatStepData.Font.Style & E_Style.Underline) != 0);
retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
// _yPageStartForSupInfo is used to move steps down the page for the supinfo pdf. Each supinfo step may not be related to previous in structure, so need this to set y location.
if (MyItemInfo.IsInSupInfo) _yPageStartForSupInfo = retval;
// Wolf Creek Training format puts a separator line after printing the section number/title
if (MyItemInfo.IsSection && MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.WCNTraining)
MyPageHelper.SectionSepLineYoffStart = retval - (SixLinesPerInch / 2);
SectionContinuePrinted = true;
ProfileTimer.Pop(profileDepth);
}
}
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];
if (pc.Total == 0)
{
pc.Total = MyPageHelper.CurrentTOCPageNumber + 1;
pc.DrawTemplates();
}
}
}
}
else if (MyItemInfo.IsHigh && MyItemInfo.MyDocStyle != null && MyItemInfo.MyDocStyle.IncludeInTOC) // && (MyItemInfo.MyActiveSection.MyConfig as SectionConfig).Section_HLS_on_TOC == "Y")
{
// C2021-015: Barakah High Level Steps in Table of Contents
SectionConfig sc = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
StepConfig stc = MyItemInfo.MyConfig as StepConfig;
if ((sc != null && sc.Section_TOC != "Y") && (stc != null && stc.Step_IncludeInTOC))
{
string tocKey = string.Format("TOC{0}", MyItemInfo.ItemID);
if (MyPageHelper.MyTOCPageCounts.ContainsKey(tocKey))
{
PageCount pc = MyPageHelper.MyTOCPageCounts[tocKey];
if (pc.Total == 0)
{
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 float DrawRaw(PdfContentByte cb, float yBottomMargin, float yLocation, float yPageStart, float yTopMargin)
{
if (DebugText.IsOpen) DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, FormattedText);
float retval = yLocation;
System.Drawing.Size sz = RtfRawItem.GetRtfRawSize(MyItemInfo.MyContent.Text);
Height = sz.Height;
Width = sz.Width;
Volian.Controls.Library.RTF myRtb = new RTF();
myRtb.Size = sz;
myRtb.Rtf = MyItemInfo.MyContent.Text;
try
{
System.Drawing.Image image = new System.Drawing.Bitmap((int)Width, (int)Height);
System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(image);
myRtb.RenderClipped(gr, new System.Drawing.Rectangle(0, 0, (int)Width, (int)Height));
// B2017-116 Adjust Image Size by Scaler (Used for Facing Pages - Sup Info)
// B2017-241 Adjust Bottom Message Location for the raw figure (Equation or Visio)
MyPageHelper.BottomContent = yLocation - (.6F * Height * MyPageHelper.YMultiplier * ImageScaler);
retval = Rtf2Pdf.RtfRawAt(cb, image, XOffset + MyItemInfo.FormatStepData.Font.CharsToTwips, yLocation, Width * MyPageHelper.YMultiplier * ImageScaler, Height * MyPageHelper.YMultiplier * ImageScaler, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.ToUpper().Contains("BORDERLESS"));
}
catch (Exception ex)
{
return retval + 2 * SixLinesPerInch; // couldn't print equation, just print 2 blank lines.
}
return retval;
}
private bool _SectionContinuePrinted = false;
public bool SectionContinuePrinted
{
get { return _SectionContinuePrinted; }
set { _SectionContinuePrinted = value; }
}
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;
// follow through in fixing an Out of Window Handles bug, use new function to see if
// we can retrieve the font from a dictionary instead a doing a New and using another
// window handle B2017-117
//System.Drawing.Font symbFont = new System.Drawing.Font("VESymbFix", (float)ii.FormatStepData.Font.Size);
System.Drawing.Font symbFont = VE_Font.GetWinSysFont("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 * 1.5F); // +(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);// -(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.NextItem == null ||
(MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0].MyItemInfo.ItemID == ii.NextItem.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 - csize, 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.NextItem != null)
{
// 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}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.ShortPath, FormattedText);
if (DebugText.IsOpen) DebugText.WriteLine("{0},'{1}','{2}','<<END>>',{3}", MyItemInfo.ItemID, MyItemInfo.ShortPath, MyItemInfo.MyContent.Text, XOffset);
//if (MyItemInfo.InList(11019,11024,111026)) // RHM20150507 Table Scrunch
// Console.WriteLine("here");
float heightBefore = (MyGrid.Height + 4) * MyPageHelper.YMultiplier; // B2020-014 added parenthesis was calculating wrong for 7lpi Callaway FSG-7 Attachment 7
// B2018-033 Account for bottom continue message when seeing if a scrunched table will fit
float ySizeBtmCtnMess = GetBottomContinueMessageSize(MyItemInfo.MyDocStyle);
// B2018-085 Ignore the bottom continue message if the Table is the last part of the step.
if (ySizeBtmCtnMess > 0 && MyParent.MyItemInfo.IsHigh && YBottomMost == MyParent.YBottomMost) ySizeBtmCtnMess = 0;
// TableScrunch Phase 1: Is height of table greater than what will fit on current page.
if (Rtf2Pdf.GetTableScrunchingStatus(TableScrunching.Phase1) && heightBefore > (yLocation - (yBottomMargin + ySizeBtmCtnMess)))
{
// TooBig is the amount of height that the grid is larger than the amount of space on the page. It is set to
// (height of grid w/ compressed setting if needed + line) - (how much room on page)
// NOTE TooBig actually will do the adjustments of the row heights by eliminating the blank space!
MyGrid.TooBig = SixLinesPerInch + MyGrid.Height * MyPageHelper.YMultiplier - (yLocation - yBottomMargin - ySizeBtmCtnMess);
float heightAfter = (MyGrid.Height + 4) * MyPageHelper.YMultiplier; // B2020-014 added parenthesis was calculating wrong for 7lpi Callaway FSG-7 Attachment 7
MyPageHelper.TableAdjustment += (heightBefore - heightAfter);
MyPageHelper.AdjustedTable = this; // B2020-059 - save the information of the table that is being compressed (used in RTF2PDF.cs TextAt())
MyPageHelper.AdjustedTableYtop = yLocation; // B2020-059 save the top location of the compressed table (used in RTF2PDF.cs TextAt())
//B2018-092 Determine if the Table is too big by checking it including either 6 LPI or 7 LPI as appropriate
if (heightAfter * MyPageHelper.YMultiplier < (yLocation - yBottomMargin - ySizeBtmCtnMess))
{
// B2018-081 - Removed error log message if the code was able to properly adjust the table
//_MyLog.WarnFormat("\r\n==> Table is too big to fit on page, Vertical Padding adjusted to fit in\r\n" +
// " [{0}] {1}\r\n" +
// " in {2}\r\n" +
// " Height Before={3:N2} Height After={4:N2} SpaceAvailable={5:N2}\r\n" +
// " No action necessary",
// MyItemInfo.ItemID,_MyItemInfo.ShortPath,
// _MyItemInfo.SearchDVPath.Replace("\a", "/"), heightBefore / 72, MyGrid.Height / 72, (yTopMargin - yBottomMargin) / 72);
//_MyLog.ErrorFormat("<<< WARNING >>> Table is too big to fit on page, Vertical Padding adjusted to fit\r\n==>'Table Adjusted',{0},'{1}','{2}',{3},{4},{5}"
// , MyItemInfo.ItemID, MyItemInfo.MyDocVersion.MyFolder.Name, MyItemInfo.ShortPath, heightBefore, MyGrid.Height, (yTopMargin - yBottomMargin));
}
else
MyGrid.IsTooBig = true;
if (MyItemInfo.HasChangeBar && MyPageHelper.ChangeBarDefinition.MyChangeBarType != PrintChangeBar.Without)
{
foreach (vlnChangeBar vcb in MyPageHelper.MyChangeBars)
{
if (vcb.Height == heightBefore / MyPageHelper.YMultiplier - 4)
{
float heightDif = (heightBefore - heightAfter);
vcb.YChangeBarBottom += heightDif;
FixMessages(vcb, heightDif);
break;
}
}
}
}
//B2018-092 Correct the location of the bottom continue message including either 6 LPI or 7 LPI as appropriate
MyPageHelper.BottomContent = yLocation - (MyGrid.Height + 4) * MyPageHelper.YMultiplier;
float retval = Rtf2Pdf.GridAt(cb, MyGrid, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
//B2018-092 Determine if the Table is too big by checking it including either 6 LPI or 7 LPI as appropriate
if ((MyGrid.Height + 4) * MyPageHelper.YMultiplier > (yLocation - yBottomMargin - ySizeBtmCtnMess))
{
// B2018-081 Changed the Error Log Message to be more useful when a table is too big.
_MyLog.ErrorFormat("\r\n===> Table is too big to fit on page, expect pagination problems in\r\n" +
" 1> Item [{0}] {1}\r\n" +
" 2> in {2}\r\n" +
" 3> Height Before={3:N2} Height After={4:N2} SpaceAvailable={5:N2}\r\n" +
" 4> ACTION REQUIRED: Table should be restructured or split over multiple pages",
MyItemInfo.ItemID, _MyItemInfo.ShortPath,
_MyItemInfo.SearchDVPath.Replace("\a", "/"), heightBefore / 72, MyGrid.Height / 72, (yTopMargin - yBottomMargin) / 72);
//_MyLog.ErrorFormat("<<< ERROR >>> Table is too big to fit on page, expect pagination problems\r\n==>'Table Too Big',{0},'{1}','{2}',{3},{4},{5}" // RHM20150429 - Table Scrunch
// , MyItemInfo.ItemID, MyItemInfo.MyDocVersion.MyFolder.Name, MyItemInfo.ShortPath, heightBefore, MyGrid.Height, (yTopMargin - yBottomMargin));
}
return retval;
}
private void FixMessages(vlnChangeBar vcb, float heightDif)
{
SortedDictionary<float, vlnChangeBarMessage> msd = vcb.Messages;
vcb.Messages = new SortedDictionary<float, vlnChangeBarMessage>();
foreach (float key in msd.Keys)
{
vcb.Messages.Add(key + heightDif, msd[key]);
}
}
private float DrawText(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
{
if (DebugText.IsOpen) DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, FormattedText);
//Console.WriteLine("{0},{1},'{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, IParagraph.Content);
float retval = yLocation;
if (MyItemInfo.IsRtfRaw)
{
retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo + string.Format(",YLines = {0}", YSize / SixLinesPerInch), yBottomMargin, MyItemInfo.ItemID); // C2018-004 ItemID for create meta file for baseline compares
return retval;
}
// Calvert Alarms have a special case, center text if the next/previous is not the same type of caution or note.
// Calvert Alarms have a note1 that is a warning. if a regular note preceeded it, this regular note was not centered.
// F2023-126: Vogtle Alarms - center single line caution/note if more than one type exist off step, added the check for NoteCautionCenterOneAllTypes
bool doAlign = false;
if ((MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert || MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.NoteCautionCenterOneAllTypes) && (MyItemInfo.IsCaution || MyItemInfo.IsNote || MyItemInfo.IsNote1))
{
bool diffAsPrev = MyItemInfo.MyPrevious == null || (MyItemInfo.MyPrevious != null && MyItemInfo.MyContent.Type != MyItemInfo.MyPrevious.MyContent.Type);
bool diffAsNext = MyItemInfo.NextItem == null || (MyItemInfo.NextItem != null && MyItemInfo.MyContent.Type != MyItemInfo.NextItem.MyContent.Type);
if (diffAsPrev && diffAsNext) doAlign = true;
}
// 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.
// B2021-091 added a null reference check - MyItemInfo was a section and didn't have FormatStepData
// F2021-042: Added FormatStepData.AlwaysCenter for BNPP1 - Critical Step text always must be centered
// B2022-146: Left Justify Note & Caution text that has sub-steps (for Beaver Valley)
bool cnWithChildren = !MyItemInfo.IsStepSection && MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.CenterOnlyIfNoSubs && MyItemInfo.HasChildren;
if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.CenterOneLineOnly && !cnWithChildren && ((MyItemInfo.MyPrevious == null && MyItemInfo.NextItem == null)
|| MyItemInfo.FormatStepData.SeparateBox || doAlign || MyItemInfo.FormatStepData.AlwaysCenter) && 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.
// B2021-091 added a null reference check - MyItemInfo was a section and didn't have FormatStepData
if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.StepPrintData.Justify == "Center" && !MyItemInfo.FormatStepData.StepLayoutData.AlignWithParentTab)
IParagraph.Alignment = Element.ALIGN_CENTER;
if (PrefixSpecialCharacter && IParagraph.Chunks.Count > 0)
{
Chunk chk = IParagraph.Chunks[0] as Chunk;
if (chk.Content == " ")
{
PrefixSpecialCharacter = false;
//Console.WriteLine("Special {0}", MyItemInfo.MyHLS.DisplayText);
IParagraph.Chunks.RemoveAt(0);
}
}
// if printing checklist header, adjust ypagestart & ylocation so that won't get forced pagination (pagination is already ok)
//Console.WriteLine("'Q1',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
if (PrintHeader)
{
yPageStart = yTopMargin + YVeryTop;
yLocation = yPageStart - YOffset; // yLocation is physical location from bottom of page.
}
if (yLocation - Height < 24)
{
if (DebugPagination.IsOpen)
DebugPagination.WriteLine("Very Low {0},{1},{2},{3},{4},{5}", MyItemInfo.ShortPath, MyItemInfo.ItemID, yLocation, Height, yLocation - Height, yTopMargin - MyItemInfo.MyDocStyle.Layout.PageLength);
//C2018-015 add debug pagination to meta file
if (BaselineMetaFile.IsOpen)
BaselineMetaFile.WriteLine("!! Very Low {0},{1},{2},{3},{4},{5}", MyItemInfo.ShortPath, MyItemInfo.ItemID, yLocation, Height, yLocation - Height, yTopMargin - MyItemInfo.MyDocStyle.Layout.PageLength);
}
int profileDepth = ProfileTimer.Push(">>>> Rtf2Pdf.TextAt");
// ooooooooo. oooooooooo. oooooooooooo ooooooooooooo o8o . o8o
// `888 `Y88. `888' `Y8b `888' `8 8' 888 `8 `"' .o8 `"'
// 888 .d88' 888 888 888 888 oooo d8b .oooo. ooo. .oo. .oooo.o oooo .o888oo oooo .ooooo. ooo. .oo. .oooo.o
// 888ooo88P' 888 888 888oooo8 888 `888""8P `P )88b `888P"Y88b d88( "8 `888 888 `888 d88' `88b `888P"Y88b d88( "8
// 888 888 888 888 " 888 888 .oP"888 888 888 `"Y88b. 888 888 888 888 888 888 888 `"Y88b.
// 888 888 d88' 888 888 888 d8( 888 888 888 o. )88b 888 888 . 888 888 888 888 888 o. )88b
// o888o o888bood8P' o888o o888o d888b `Y888""8o o888o o888o 8""888P' o888o "888" o888o `Y8bod8P' o888o o888o 8""888P'
//
// Design Suggestion:
// During vlnParagraaph Constuctor Build an end point dictionary
// During toPdf check for end points before adding GoTos for Local
// Need to have a way to get to sections which do not have any output (header only)
// Need to have a way to identify procedures
//
// B2018-034 The following code previously used IParagraph rather than _IParagraph. If the variable IsCompressed (7LPI) is true for this step
// IParagraph would be refreshed each time it was referenced. Thus the link information would be lost when the IParagraph was re-created.
// This resulted in PDFLinks to steps that were not not identified with a LocalDestination. This was changed from the original code to
// fix B2015-076 when the Byron Flex Procedure 0BFSG-6 was printed. The issue for this bug was that the underlining at 7LPI was overlaping the
// top of the next line of text. I was not able to find the case referencedd in the source safe document. However, by adding a line of
// text "One more line" to the end of step 2 in attachment C, I was able to see the effect.
if (_IParagraph.Chunks.Count > 0 && MyPageHelper.MyPromsPrinter.SaveLinks)
{
// B2018-034 The following code previously used IParagraph rather than _IParagraph. See first Comment
Chunk chk1 = _IParagraph.Chunks[0] as Chunk;
if (MyItemInfo.MyContent.Text.ToUpper().Contains("LINK:TR") && MyItemInfo.MyContent.ContentTransitionCount == 0)
Console.WriteLine("Missing Transition {0}", MyItemInfo.ItemID);
chk1.SetLocalDestination(string.Format("ItemID={0}", MyItemInfo.ItemID)); // Destination
// B2019-052: If multiple ROs/Transitions within a step, each should have a their own link rather than all linking to same thing.
// Note the pdf link code that was here was moved to Rtf2iTextSharp.cs in DoVisitText so that each 'chunk' could have a link.
// The code that remained here was the code that marks the destination for each step & the code that does the pdf links for
// enhanced steps.
// Also, the method GetDefaultItemInfo was moved to Rtf2iTextSharp.cs also - it was only called from code that was moved.
StepConfig sc = new StepConfig(MyItemInfo.MyContent.Config);
DVEnhancedDocuments dveds = MyItemInfo.MyDocVersion.DocVersionConfig.MyEnhancedDocuments;
foreach (EnhancedDocument ed in sc.MyEnhancedDocuments)
{
DVEnhancedDocument dved = dveds.GetByType(ed.Type);
AddLinkToEnhancedDocument(cb, yLocation, ed.ItemID, dved.PdfToken, dved.PdfX);
}
// MyPageHelper.BottomContent = yLocation - Height;
//if (MyItemInfo.InList(39048)) Console.WriteLine("Here");
}
MyPageHelper.BottomContent = yLocation - (Height * MyPageHelper.YMultiplier);
retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo + string.Format(",YLines = {0}", YSize / SixLinesPerInch), yBottomMargin, MyItemInfo.ItemID); // C2018-004 ItemID for create meta file for baseline compares
ProfileTimer.Pop(profileDepth);
if (retval == 0) // problem occurred - paragraph was not able to be printed on page
{ // pagination logic needs to be fixed.
// oooooooooooo ooooooooo. o8o . o8o
// `888' `8 `888 `Y88. `"' .o8 `"'
// 888 .ooooo. oooo d8b .ooooo. .ooooo. 888 .d88' .oooo. .oooooooo oooo ooo. .oo. .oooo. .o888oo oooo .ooooo. ooo. .oo.
// 888oooo8 d88' `88b `888""8P d88' `"Y8 d88' `88b 888ooo88P' `P )88b 888' `88b `888 `888P"Y88b `P )88b 888 `888 d88' `88b `888P"Y88b
// 888 " 888 888 888 888 888ooo888 888 .oP"888 888 888 888 888 888 .oP"888 888 888 888 888 888 888
// 888 888 888 888 888 .o8 888 .o 888 d8( 888 `88bod8P' 888 888 888 d8( 888 888 . 888 888 888 888 888
// o888o `Y8bod8P' d888b `Y8bod8P' `Y8bod8P' o888o `Y888""8o `8oooooo. o888o o888o o888o `Y888""8o "888" o888o `Y8bod8P' o888o o888o
// d" YD
// "Y88888P'
ForcePagination(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation, ref retval);
}
else
{
if (MyItemInfo.IsStepSection && MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && (MyItemInfo.ActiveSection as SectionInfo).HasInitials)
{
if (MyPageHelper.PrintInitials(cb, yLocation, (float)MyItemInfo.MyDocStyle.Layout.LeftMargin))
{
//if(yLocation != yTopMargin)
// Console.WriteLine("'{0}',{1},'{2}',{3},{4},{5},{6}", MyItemInfo.MyProcedure.DisplayNumber, MyItemInfo.ItemID
// , MyItemInfo.DisplayNumber, yLocation,yTopMargin,MyItemInfo.HasCautionOrNote,MyPageHelper.CurrentPageNumber+1);
}
}
}
return retval;
}
private static void AddLinkToEnhancedDocument(PdfContentByte cb, float yLocation, int itemID, String token, int xLocation)
{
ItemInfo ii = ItemInfo.Get(itemID);
//B2020-133 if "ii" is null, then the itemid was not found- probable enhanced step was deleted. so just return with out creating a link
if (ii == null) return;
string prefix = ii.MyDocVersion.DocVersionConfig.Print_PDFFilePrefix ?? "";
string suffix = ii.MyDocVersion.DocVersionConfig.Print_PDFFileSuffix ?? "";
ColumnText ct = new ColumnText(cb);
ct.SetSimpleColumn(xLocation, yLocation - 12, xLocation + 30, 12 + yLocation);
iTextSharp.text.Font font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12);
Chunk chk = new Chunk(token);
chk.SetRemoteGoto(prefix + ii.MyProcedure.DisplayNumber.Replace("/", "_") + suffix + ".pdf", string.Format("ItemID={0}", itemID));
chk.SetBackground(new Color(System.Drawing.Color.LemonChiffon));
ct.AddElement(chk);
cb.SetColorFill(Color.BLUE);
ct.Go();
//foreach (Chunk chk in IParagraph.Chunks)
//{
// chk.SetRemoteGoto(ii.MyProcedure.DisplayNumber.Replace("/", "_") + ".pdf", string.Format("ItemID={0}",ii.ItemID));
// chk.SetBackground(new Color(System.Drawing.Color.LemonChiffon));
//}
}
private static bool _MissingInitials = false;
public static bool MissingInitials
{
get { return vlnParagraph._MissingInitials; }
set { vlnParagraph._MissingInitials = value; }
}
public static void TextAt(PdfContentByte cb, VlnSvgPageHelper myPageHelper, PageItem pi, float yloc, float leftMargin)
{
System.Drawing.Color sysColor = PrintOverride.OverrideSvgColor(System.Drawing.Color.Black);
cb.SaveState();
if (myPageHelper.PageListLayer != null) cb.BeginLayer(myPageHelper.PageListLayer);
ColumnText ct = new ColumnText(cb);
iTextSharp.text.Font font;
int fontStyle = 0;
bool underline = false;
if (pi == null) // The header for the signoffs is missing in the current section format.
// An Example can currently be found in Calvert OI-34
{
if (!MissingInitials) // Only show this once.
{
_MyLog.WarnFormat("Initials Header Missing" +
"\r\nInitials header missing for section {0}" +
"\r\nfrom format [{1}], {2}, subformat {3}" +
"\r\nA default Arial font and a default location will be used." +
"\r\nPerhaps another section format should be used.",
myPageHelper.MySection.ShortPath,
myPageHelper.MySection.ActiveFormat.Name,
myPageHelper.MySection.ActiveFormat.Description,
myPageHelper.MySection.MyDocStyle.Name);
MissingInitials = true;
}
ct.SetSimpleColumn(450 + leftMargin, yloc + 6.9F, 550 + leftMargin, yloc - 50);
font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 10F);
}
else
{
ct.SetSimpleColumn((float)pi.Col + leftMargin, yloc + 6.9F, (float)pi.Col + 100 + leftMargin, yloc - 50);
fontStyle = (pi.Font.WindowsFont.Bold ? iTextSharp.text.Font.BOLD : 0) + (pi.Font.WindowsFont.Italic ? iTextSharp.text.Font.ITALIC : 0);
font = FontFactory.GetFont(pi.Font.Family, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, (float)pi.Font.Size, fontStyle);
underline = pi.Font.WindowsFont.Underline;
}
Chunk chk = new Chunk("INITIALS", font);
if (underline)
chk.SetUnderline(new iTextSharp.text.Color(sysColor), 0, 0.05F, 0, -.131F, PdfContentByte.LINE_CAP_ROUND); // Relative Based upon font size
Phrase ph = new Phrase(chk);
ct.AddElement(ph);
cb.SetColorFill(new iTextSharp.text.Color(sysColor));
ct.Go();
if (myPageHelper.PageListLayer != null) cb.EndLayer();
cb.RestoreState();
}
private bool _PrintHeader = false;
public bool PrintHeader
{
get { return _PrintHeader; }
set { _PrintHeader = value; }
}
private bool CalvertPrintedSubSectTitle = false; // B2020-123
private static List<string> myAttributes = new List<string>();
private static void AddAttribute(string attr)
{
if (myAttributes.Contains(attr))
return;
//Console.WriteLine("Attribute = \"{0}\"", attr);
myAttributes.Add(attr);
}
private void CheckAttributes(System.Collections.Hashtable attributes)
{
foreach (string attr in attributes.Keys)
{
AddAttribute(attr);
}
}
private string FormattedText
{
get
{
bool subscript = false;
//if (_MyItemInfo.ItemID == 467)
// Console.Write("");
StringBuilder sb = new StringBuilder();
//if (IParagraph.Chunks.Count > 1)
// Console.WriteLine("{0} Chunks", IParagraph.Chunks.Count);
foreach (Chunk chk in IParagraph.Chunks)
{
string prefix = "";
string suffix = "";
CheckAttributes(chk.Attributes);
if (chk.Font.BaseFont != null && chk.Font.BaseFont.PostscriptFontName.ToUpper().Contains("BOLD"))
{
prefix += "\xD5";
suffix = "\xD6" + suffix;
}
if (chk.Attributes.ContainsKey("SUBSUPSCRIPT"))
{
float sup = (float)(chk.Attributes["SUBSUPSCRIPT"]);
if (sup > 0)
{
prefix += "\xA6";
suffix = "\xD1" + suffix;
}
else if (sup < 0)
{
prefix += "\xD1";
suffix = "\xA6" + suffix;
}
}
if (chk.Attributes.ContainsKey("UNDERLINE"))
{
prefix += "\x16";
suffix = "\x16" + suffix; ;
}
sb.Append(prefix + chk.Content + suffix);
}
string retval = sb.ToString();
retval = retval.Replace("\xD1\xA6", "");// Remove Multiple Superscript commands in a row
retval = retval.Replace("\xA6\xD1", "");// Remove Multiple Superscript commands in a row
retval = retval.Replace("\xD6\xD5", "");
retval = retval.Replace("\xD6\x16\xD5", "\x16");
return retval;
}
}
private float _ImageScaler = 1F;
/// <summary>
/// Scaler used to adjust the Image Size on Sup Info (Facing Pages)
/// </summary>
public float ImageScaler
{
get { return _ImageScaler; }
set { _ImageScaler = value; }
}
//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 yPageStart, float yTopMargin)
{
int profileDepth = ProfileTimer.Push("vlnParagraph.DrawFigure");
float retval = yLocation;
if (ImageText != null)
{
if (ImageText == "figure")
{
ImageConfig ic = new ImageConfig(MyItemInfo.MyContent.MyImage);
// B2016-277: add a try catch in case of there being 'bad' data in the text field for an image/figure
try
{
byte[] idata = (ic != null && ic.Image_DataSize > 0) ? ROImageInfo.Decompress(MyItemInfo.MyContent.MyImage.Data, ic.Image_DataSize) : MyItemInfo.MyContent.MyImage.Data;
MemoryStream ms = new MemoryStream(idata);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
Width = img.Width;
Height = img.Height;
if (ic != null && ic.Image_Height != 0)
{
Width = ic.Image_Width;
Height = ic.Image_Height;
}
// B2020-115 Limit the figure size to the space available in a page.
float mult = 1.0F;
if (Width > (vlnParagraph.wMax - 12)) mult = (vlnParagraph.wMax - 24) / Width;
if (Height > (vlnParagraph.hMax - 36)) mult = Math.Min(mult, (vlnParagraph.hMax - 36) / Height);
if (mult < 1.0F)
{
Width = Width * mult;
Height = Height * mult;
}
iTextSharp.text.Image it_image = iTextSharp.text.Image.GetInstance(idata);
// B2017-241 Adjust Bottom Message Location for the figure
MyPageHelper.BottomContent = yLocation - (Height * MyPageHelper.YMultiplier);
// B2017-112 Adjust Image Size by Scaler (Used for Facing Pages - Sup Info)
retval = Rtf2Pdf.FigureAt(cb, it_image, XOffset + MyItemInfo.FormatStepData.Font.CharsToTwips, yLocation, Width * MyPageHelper.YMultiplier * ImageScaler, Height * MyPageHelper.YMultiplier * ImageScaler, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"), MyItemInfo.ItemID, SixLinesPerInch); // C2018-004 added ItemID for create meta file for baseline compares
}
catch
{
retval += SixLinesPerInch;
}
}
else
{
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) roImage = rofst.GetROImageByFilename(vals[0], MyItemInfo);// need code to go and get an ROImaage if it exists
if (roImage != null)
{
ROImageConfig rc = new ROImageConfig(roImage);
int size = Convert.ToInt32(rc.Image_Size);
byte[] cnt = roImage.Content;
byte[] dcnt = ROImageInfo.Decompress(cnt, size);
iTextSharp.text.Image it_image = null;
try
{
it_image = iTextSharp.text.Image.GetInstance(dcnt);
}
catch
{
MemoryStream ms = new MemoryStream(dcnt);
System.Drawing.Bitmap bm = new System.Drawing.Bitmap(ms);
using (MemoryStream ms2 = new MemoryStream())
{
bm.Save(ms2, System.Drawing.Imaging.ImageFormat.Png);
ms2.Seek(0, SeekOrigin.Begin);
byte[] newdcnt = new byte[ms2.Length];
ms2.Read(newdcnt, 0, (int)ms2.Length);
try
{
it_image = iTextSharp.text.Image.GetInstance(newdcnt);
}
catch (Exception ex)
{
_MyLog.Error(string.Format("{0}", roImage.FileName), ex);
return yLocation;
}
}
}
StepConfig sc = new StepConfig(MyItemInfo as StepInfo);
if (sc != null && sc.Step_ImageWidth != 0)
{
Width = sc.Step_ImageWidth;
Height = sc.Step_ImageHeight;
}
// B2017-241 Adjust Bottom Message Location for the figure
MyPageHelper.BottomContent = yLocation - (Height * MyPageHelper.YMultiplier);
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"), MyItemInfo.ItemID, SixLinesPerInch);
}
}
// The following code was added to fix B2016-219 (for VCS, the centerline drew through a figure). The 'top' value was taken from the code
// that draws the vlnBoxes (Caution/Note, etc)
// The adjustments, adjtop & adjbottom, were necessary to get the vertical centerline to meet up correctly with the top/bottom of the figure. These
// numbers were determined by trial and error.
// only add gap if centered, i.e. in 2 column mode & table is centered
if (MyItemInfo.ColumnMode > 0 && (!MyItemInfo.FormatStepData.Type.Contains("AER") && !MyItemInfo.IsInRNO))
{
float top = CalculateYOffset(yPageStart, yTopMargin) - (7 * MyPageHelper.YMultiplier);
float adjtop = 0;
float adjbottom = 0;
if (MyPageHelper.YMultiplier == 1)
adjtop = -3;
else
adjbottom = -1;
MyPageHelper.MyGaps.Add(new Gap(top + adjtop, top - Height - Rtf2Pdf.Offset.Y + adjbottom));
}
}
ProfileTimer.Pop(profileDepth);
return retval;
}
private string DebugInfo
{
get
{
if (!Rtf2Pdf.PdfDebug) return "No Path";
int profileDepth = ProfileTimer.Push(">>>> vlnParagraph.DebugInfo");
string retval = string.Format("DebugID = {0}, ID={1} Type={2} TypeName='{3}' StepLevel={4} ShortPath={5} Width={6} Left={7} YOffset={8}, PaginationLevel = {9}, yPageSize = {10}",
DebugId, MyItemInfo.ItemID, MyItemInfo.FormatStepType, MyItemInfo.FormatStepData == null ? "NoStepData" : MyItemInfo.FormatStepData.Type, MyItemInfo.StepLevel, MyItemInfo.ShortPath, Width, XOffset, YOffset, levelForPagination, yPageSizeForPagination);
ProfileTimer.Pop(profileDepth);
return retval;
}
}
private void ResetDocStyleAndValues(ref float yTopMargin, ref float yBottomMargin)
{
float _PointsPerPage = PDFPageSize.PaperSizePoints(MyItemInfo.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
// 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.
// C2018-003 fixed use of getting the active section
if (MyItemInfo.ActiveSection != null && (MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Where & E_DocStyleUse.UseOnFirstPage) > 0)
{
ItemInfo ii = (ItemInfo)MyItemInfo.ActiveSection;
int indx = (int)MyItemInfo.ActiveSection.MyDocStyle.IndexOtherThanFirstPage;
foreach (DocStyle ds in ii.ActiveFormat.PlantFormat.DocStyles.DocStyleList)
{
if (ds.Index == indx)
{
// C2018-004 create meta file for baseline compares
// B2020-008: removed some code that was causing the header to not get refreshed, and uncommented
// out the ResetSvg command below.
Volian.Base.Library.BaselineMetaFile.WriteLine("Reset DocStyle to \"{0}\"", ds.Name);
MyItemInfo.ActiveSection.MyDocStyle = ds;
MyPageHelper.MySection = MyItemInfo.ActiveSection as SectionInfo;
MyPageHelper.MySection.MyDocStyle = ds;
MyPageHelper.ResetSvg();
break;
}
}
MyPageHelper.DidFirstPageDocStyle = true;
if (DebugPagination.IsOpen) DebugPagination.WriteLine("ResetDocStyleAndValues");
if (BaselineMetaFile.IsOpen) BaselineMetaFile.WriteLine("!! ResetDocStyleAndValues"); //C2018-015 add debug pagination to meta file
MyPageHelper.MySection = (SectionInfo)MyItemInfo.ActiveSection;
yTopMargin = _PointsPerPage - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.TopMargin;
yBottomMargin = Math.Max(0, yTopMargin - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.PageLength);
}
// B2020-047 move check of PrintSectionPage to after the ResetSvg
// B2020-152 un-did the change for B2020-047 which was put in for Westinghouse. The issue reported for B2020-047 remained corrected
else if (MyPageHelper.PrintedSectionPage > 0)
{
MyPageHelper.ResetSvg();
if (MyItemInfo.ActiveSection != null && (MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PrintSectOnFirst) == E_DocStructStyle.DSS_PrintSectOnFirst)
{
yTopMargin = _PointsPerPage - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.TopMargin + MyPageHelper.PrintedSectionPage;
MyPageHelper.YTopMargin = yTopMargin;
yBottomMargin = Math.Max(0, _PointsPerPage - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.TopMargin - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.PageLength);
}
}
}
private string GetSectCombinedTab(ItemInfo tmp)
{
ItemInfo itemInfo = tmp;
if (itemInfo.IsCautionOrNotePart) itemInfo = itemInfo.ActiveParent as ItemInfo; // if caution/note get to its associated step
itemInfo = itemInfo.ActiveParent as ItemInfo; // don't want this one in the combined tab, start at parent
// B2018-084: continue message had bullets in it that didn't have correct font. The message should not have had bullets at
// all - in the following line, there was an 'if' rather than a 'while' - go up parents until find the correct step type
// don't just go up 1 level.
while (!itemInfo.IsHigh && !itemInfo.IsSequential && !itemInfo.IsSection) itemInfo = itemInfo.ActiveParent as ItemInfo;
string prTab = "";
string thisTab = itemInfo.MyTab.CleanText.Trim();
if (!itemInfo.IsSection || itemInfo.IsSeparateSubsection)
{
ItemInfo mypar = itemInfo.MyParent;
while (mypar != null && !mypar.IsProcedure)
{
// The following check was added for BGE/OI34. Their APPENDIX sections had the subsections
// printing with incorrect tab in the SectionTitleContinued message. Before this
// fix the tabs were A.B Procedure (Continued) rather than B. Procedure (Continued).
// Unfortunately there was not enough time to make the 'if' statement based on config
// or format settings.
bool addTab = true;
if (mypar.IsSection && mypar.DisplayNumber.ToUpper().Contains("APPENDIX "))
{
SectionConfig sch = mypar.MyConfig as SectionConfig;
addTab = (sch == null || sch.Section_PrintHdr == "Y");// && !mypar.MyDocStyle.CancelSectTitle;
}
if (addTab)
{
string pTab = mypar.MyTab.CleanText.Trim();
if (pTab.Length > 0 && char.IsLetterOrDigit(pTab[0]))
{
pTab = pTab.TrimEnd(" .".ToCharArray()) + ".";
prTab = pTab + prTab;
}
else
{
// There' a bullet or some other graphics character.
// clear out the tab we are building so the we can build
// a continue tab up to this bullet or graphic character.
prTab = "";
thisTab = "";
}
}
mypar = (mypar.IsSection && !mypar.IsSeparateSubsection) ? null : mypar.MyParent;
}
}
return (prTab + thisTab.Trim()).TrimEnd(".".ToCharArray());
}
private static bool DoSubs = true; // flag whether to print substeps (don't if doing continued checklist header)
public float AdjustForXBlankW1stLevSub = 0; // B2020-112 this & next line
public float AdjustForMatchUpRNO = 0;
protected float _ContinueHeight = 0;
public virtual float ContinueHeight
{
get
{
int profileDepth = ProfileTimer.Push(">>>> vlnPrintObject.ContinueHeight");
if (_ContinueHeight == 0
&& MyItemInfo.MyDocStyle.Continue.Top.Message != null
&& MyItemInfo.MyDocStyle.Continue.Top.Message.Contains("%s")
&& MyItemInfo.MyDocStyle.Continue.Top.Message.ToUpper().EndsWith(" (Continued)".ToUpper()))
{
string suffix = MyItemInfo.MyDocStyle.Continue.Top.Message.Replace("%sR", "").Replace("%s", "");
_ContinueHeight = GetParagraphHeight(MyContentByte, IParagraph, suffix, Width);
}
ProfileTimer.Pop(profileDepth);
return _ContinueHeight;
}
set { _Height = value; }
}
// Check if the parent section has both an editable steps section and a sub-section
private bool ParentHasSectionAndSteps()
{
if (!MyItemInfo.ActiveParent.IsSection) return false;
SectionInfo parent = MyItemInfo.ActiveParent as SectionInfo;
bool hasSteps = false;
bool hasSections = false;
foreach (PartInfo pi in parent.MyContent.ContentParts)
{
if (pi.FromType == (int)E_FromType.Step && parent.SectionConfig.SubSection_Edit == "Y") hasSteps = true;
if (pi.FromType == (int)E_FromType.Section) hasSections = true;
}
return hasSteps && hasSections;
}
public override float ToPdf(PdfContentByte cb, float yPageStart, ref float yTopMargin, ref float yBottomMargin)
{
int profileDepth = ProfileTimer.Push(">>>> vlnParagraph.ToPdf");
if (MyItemInfo.ActiveFormat.Name.ToUpper().StartsWith("FNP") && MyItemInfo.IsSection && ParentHasSectionAndSteps())
MyPageHelper.BottomMessage.Clear(); // B2017-266 reset the END message on the sub-section
if (MyItemInfo.IsFootnote && Processed)
{
ProfileTimer.Pop(profileDepth);
return yPageStart;
}
if (MyItemInfo.IsInSupInfo) // if generating the pdf for supinfos (facing page) pdf, need a different cb to go to that file.
{
MyContentByte = cb;
MyPageHelper = null;
}
bool doThreeContinues = false;
// 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.IsStepSection)
{
if (MyItemInfo.IsSection && MyItemInfo.MyPrevious == null && MyItemInfo.MyParent.IsSection && !MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseWestinghouse)
{
// don't do the following for the WCN training format:
// if parent was continuous & this is separate, don't reset document style to subsection (next page) type
// this was putting incorrect pagelist item on parent section's page. This occurred in BGE/OI3 set/OI-7 procedure/10.0 Attachments.
// B2017-273 added a check for Farley format, we don't want the subsection pagelist infor to appear on the parent section page - works with Paginate() logic - (section has steps and a sub-section ex: FNP-2-EEP-0 Attachment 4)
// C2024-003 fixed a null exception bug by changing MyParent.MyItemInfo to MyItemInfo.MyParent.
if (!MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.WCNTraining && !MyItemInfo.ActiveFormat.Name.ToUpper().StartsWith("FNP") && (MyItemInfo.MyParent as SectionInfo).IsSeparatePagination() || !(MyItemInfo as SectionInfo).IsSeparatePagination())
{
MyPageHelper.MySection = MyItemInfo as SectionInfo;
MyPageHelper.ResetSvg();
}
}
}
// For Calvert Alarms: A macro exists around the CONDITION/RESPONSE portion. If the page break occurs so that
// this 'table' moved to the following page AND there is an associated note/caution that is not on the next page,
// remove the macro so that the header macro doesn't print on the page with the note (without this, an extraneous
// header for the 'table'is printed.
if (PartsLeft.Count != 0 && (PartsLeft[0] is vlnMacro) && MyPageHelper.ParaBreaks.Count != 0 && MyPageHelper.ParaBreaks[0].MyItemInfo.MyPrevious == null)
if (!MyPageHelper.ParaBreaks[0].MyItemInfo.IsNote && !MyPageHelper.ParaBreaks[0].MyItemInfo.IsCaution)
{
// Only clear the header if it is the first child below
if (ChildrenBelow[0].MyItemInfo.ItemID == MyPageHelper.ParaBreaks[0].MyItemInfo.ItemID)
PartsLeft.Clear();
//else
// _MyLog.WarnFormat("Would Have Cleared PageHeader '{0}','{1}'", MyItemInfo.MyProcedure.DisplayNumber, MyItemInfo.MyHLS.DisplayText);
}
if (IsWordDocPara)
{
SectionInfo si = SectionInfo.Get(MyItemInfo.ItemID);
//Changing this caused Header issues for FNP FNP-1-FRP-1.3 Attachment 3 (Word Sub-Sections)
//SectionInfo si1 = MyItemInfo.GetSectionInfo();
//CompareSectionInfo(si, si1);
MyPromsPrinter.NewPage(true);
//_MyLog.InfoFormat("NewPage 9 {0}", cb.PdfWriter.CurrentPageNumber);
// Add Bookmark for Word Subsections
MyPageHelper.PageBookmarks.Add(si, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
MyPageHelper.MyPromsPrinter.CreateWordDocPdf(cb, si);
Processed = true;
{
ProfileTimer.Pop(profileDepth);
return yPageStart;
}
}
float yLocalypagestart = yPageStart;
// yPageStart is offset into roll; YTopMost is offset of topmost of this paragraph.
float yLocation = yPageStart - YTopMost;
// If this document style has a pagelist item with a continue (some IP2BCK docstyles), clear
// out the variable that flags a continue message
MyPageHelper.OldTemplateContMsg = false;
if (DebugText.IsOpen) DebugText.WriteLine("ToPdf1:{0},'{1}',{2},{3},{4},{5}", MyItemInfo.ItemID, MyItemInfo.ShortPath, XOffset, yLocation, yPageStart, YTopMost);
int profileDepth1 = ProfileTimer.Push(">>>> vlnParagraph.Paginate");
int paginate = Paginate(yLocation, yTopMargin, yBottomMargin);
ProfileTimer.Pop(profileDepth1);
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;
// If SAMG facing page print & doing first pass to generate page break list of supplemental info and
// there was a page break in the step section, but not an associated supinfo item, do the page break when the
// next supinfo item is found:
SectionInfo supInfoSect = MyItemInfo.ActiveSection as SectionInfo; // C2018-003 fixed use of getting the active section
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.DoPageBreaks && MyPromsPrinter.NeedSupInfoBreak && MyItemInfo.SupInfos != null && MyItemInfo.SupInfos.Count > 0)
{
// if this has a caution/note with supinfo, that is id that needs to go in pagination list, unless it is in there.
int aboveSupinfoId = ChildrenAboveHaveSupInfo();
if (supInfoSect != null)
{
if (supInfoSect.StepSectPageBreaksForSupInfo.Contains(aboveSupinfoId)) aboveSupinfoId = -1;
supInfoSect.StepSectPageBreaksForSupInfo.Add(aboveSupinfoId != -1 ? aboveSupinfoId : MyItemInfo.SupInfos[0].ItemID);
}
MyPromsPrinter.NeedSupInfoBreak = false;
}
bool itemIsPrinted = false;
switch (paginate)
{
// .oooooo. .oooo.
// d8P' `Y8b d8P'`Y8b
// 888 .oooo. .oooo.o .ooooo. 888 888
// 888 `P )88b d88( "8 d88' `88b 888 888
// 888 .oP"888 `"Y88b. 888ooo888 888 888
// `88b ooo d8( 888 o. )88b 888 .o `88b d88'
// `Y8bood8P' `Y888""8o 8""888P' `Y8bod8P' `Y8bd8P'
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);
}
// SupInfo has its own pagination and ylocation handling, reset ypagestart & ylocation if continuing on current page.
// The value used was saved when the previous SupInfo step was printed.
if (MyItemInfo.IsSupInfoPart)
{
yPageStart = _yPageStartForSupInfo - SixLinesPerInch;
yLocation = yPageStart - YTopMost;
}
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge)
{
// printing a procedure with section(s) that have supplemental information - determine facing page needed to be merged in. For
// case 0, it is typically at the beginning of the section since the page break occurred in the code that calls this.
// Note that if the procedure has any sections with supinfo, then the entire procedure will need facing pages, either blank page
// or supinfo steps.
// If the section title is printed, then need to get the facing page before the section title is printed and if
// this is the hls where the section title was printed, don't do the facing page.
bool titlePrinted = false;
if (MyItemInfo.IsSection || (MyItemInfo.IsHigh && MyItemInfo.MyPrevious == null))
{
// see if the section title is printed.
SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
titlePrinted = (sch == null || sch.Section_PrintHdr == "Y") || !(MyItemInfo.MyActiveSection as SectionInfo).HasSupInfoSteps;
titlePrinted &= (ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle);
}
// If this is first step section and there is no supinfo, the blank page was done in proms printer.
// If this is first step section and there is supinfo, it needs to be put out
bool notFirstOrFirstHasSupInfo = false;
bool firstSec = true;
foreach (SectionInfo sec in MyItemInfo.MyProcedure.Sections)
{
if (sec.IsStepSection)
{
if (MyItemInfo.ActiveSection != null && sec.ItemID == MyItemInfo.ActiveSection.ItemID) break; // C2018-003 fixed use of getting the active section
firstSec = false;
break;
}
}
notFirstOrFirstHasSupInfo = !firstSec || (MyItemInfo.ActiveSection != null && (MyItemInfo.ActiveSection as SectionInfo).HasSupInfoSteps); // C2018-003 fixed use of getting the active section
if (notFirstOrFirstHasSupInfo && ((MyItemInfo.IsHigh && MyItemInfo.MyPrevious == null && !titlePrinted) || (MyItemInfo.IsStepSection && titlePrinted)) && !MyItemInfo.IsInSupInfo && (MyItemInfo.MyProcedure as ProcedureInfo).ProcHasSupInfoData)
{
// If there is supplemental information to be printed on the facing page, then get the id that has supinfo
// so that it can be retrieved from the pdf for the supinfos for this section.
int sid = GetIdThatHasSupInfoItems(MyItemInfo, MyItemInfo.ItemID);
if (sid != -1)
{
MyPromsPrinter.DoSupInfoPage(cb, "TEMP", MyPageHelper.TextLayer, MyPageHelper, sid, true);
}
else
{
MyPromsPrinter.InsertBlankPage(cb);
}
}
}
if (MyItemInfo.IsHigh && MyItemInfo.MyPrevious != null && ((MyItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS))
yPageStart -= SixLinesPerInch;
if (MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0].CompressFirstPartOfStep)
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
if (CompressFoldout)
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
///else
/// MyPageHelper.YMultiplier = 1;
break;
// .oooooo. .o
// d8P' `Y8b o888
//888 .oooo. .oooo.o .ooooo. 888
//888 `P )88b d88( "8 d88' `88b 888
//888 .oP"888 `"Y88b. 888ooo888 888
//`88b ooo d8( 888 o. )88b 888 .o 888
// `Y8bood8P' `Y888""8o 8""888P' `Y8bod8P' o888o
case 1: // Break on High Level Step
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.DoPageBreaks)
{
// page break here, determine if there is caution/note above where the page break actually needs to go:
int aboveSupinfoId = ChildrenAboveHaveSupInfo();
if (supInfoSect != null && MyItemInfo.SupInfos != null && MyItemInfo.SupInfos.Count > 0 && aboveSupinfoId > 0) supInfoSect.StepSectPageBreaksForSupInfo.Add(aboveSupinfoId);
else if (supInfoSect != null && MyItemInfo.SupInfos != null && MyItemInfo.SupInfos.Count > 0) supInfoSect.StepSectPageBreaksForSupInfo.Add(MyItemInfo.SupInfos[0].ItemID);
else MyPromsPrinter.NeedSupInfoBreak = true;
if (supInfoSect != null) supInfoSect.StepSectPageBreaks.Add(MyItemInfo.ItemID);
}
YTopMost = OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
docstyle = MyItemInfo.MyDocStyle;
if (MyPageHelper.NotesToFootNotes != null && MyPageHelper.NotesToFootNotes.Count > 0) MyPageHelper.NotesToFootNotesYoffset = CalculateYLocation(yLocation, yTopMargin);
bool doSectionContinue = !MyItemInfo.IsSection && ((docstyle.StructureStyle.Style & E_DocStructStyle.BottomSectionContinue) == E_DocStructStyle.BottomSectionContinue);
if (doSectionContinue) DoBottomContinueMsg(cb, yBottomMargin, yLocation, docstyle, false);
MyPromsPrinter.NewPage();
//_MyLog.InfoFormat("NewPage 10 {0}", cb.PdfWriter.CurrentPageNumber);
if (MyItemInfo.IsSection && MyParent != null && MyParent.MyItemInfo.IsSection && (MyItemInfo as SectionInfo).IsSeparatePagination())
{
// F2023-015 for Beaver Valley as two sub-sections that are printed continuously followed by a third sub-section printed
// with separate pagination. This section type uses a different pagelist for the pages after the first page.
// Needed to call ResetDocStyleAndValues to set the new page with the other pagelist sytle.
ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin);
RefreshDocStyle();
yTopMargin = PDFPageSize.PaperSizePoints(MyItemInfo.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize) - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.TopMargin; // C2018-003 fixed use of getting the active section // C2020-002 paper size is now set in the format files
yBottomMargin = Math.Max(0, yTopMargin - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.PageLength); // C2018-003 fixed use of getting the active section
yPageStart = yTopMargin;
}
else if (MyItemInfo.IsSection || (MyItemInfo.IsHigh && MyItemInfo.MyPrevious != null)) //do not reset for 1st step
{
//Console.WriteLine("'b1',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin);
//Console.WriteLine("'a1',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
}
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)
MyPromsPrinter.DoFoldoutPage(cb, "HLS", MyPageHelper.TextLayer, MyPageHelper, MyItemInfo.FoldoutIndex(), false);
// B2018-108 if paginating on first step don't add blank page (it was already added at this point)
// B2023-011: Beaver Valley - continuous section printing on its own page throws off CAS/blank pages
// added the IsSection check to the else if
else if (PromsPrinter.MyFoldoutReader.Count > 0 && MyPageHelper.MyPromsPrinter.InsertBlankPages && (MyItemInfo.IsSection || (MyItemInfo.IsHigh && MyItemInfo.MyPrevious != null)))
{
// 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)
{
MyPromsPrinter.InsertBlankPage(cb);
//_MyLog.InfoFormat("NewPage 10 blank {0}", cb.PdfWriter.CurrentPageNumber);
}
}
// See comments under case 0 explaining supinfo/facing page processing.
itemIsPrinted = IsPrintedStepItemForSupInfo();
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge && !MyPageHelper.CreatingSupInfoPage && itemIsPrinted /*&& !MyItemInfo.IsSection*/ && !MyItemInfo.IsInSupInfo && (MyItemInfo.MyProcedure as ProcedureInfo).ProcHasSupInfoData)
{
int sid = GetIdThatHasSupInfoItems(MyItemInfo, MyItemInfo.ItemID);
if (sid != -1)
{
MyPromsPrinter.DoSupInfoPage(cb, "TEMP", MyPageHelper.TextLayer, MyPageHelper, sid, true);
}
else
{
MyPromsPrinter.InsertBlankPage(cb); // C2019-004: Allow user to define duplex blank page text
}
}
if (MyItemInfo.MyDocStyle.LandscapePageList)
{
System.Drawing.Drawing2D.Matrix myMatrix = new System.Drawing.Drawing2D.Matrix(0, 1, -1, 0, cb.PdfDocument.PageSize.Height, 0);
cb.Transform(myMatrix);
}
yPageStart = yTopMargin + YTopMost;
// B2020-001 Catawba had an extra line at the top of a page that paginated on a section (EP/1/A/5000/E0 section B)
// Needed to remove the extra line spacing that is before the start of section B - (section is set for continuous pagination)
if (MyItemInfo.IsSection && MyItemInfo.ActiveFormat.MyStepSectionLayoutData.CustomSpacing)
yPageStart += (float)MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[25].StepLayoutData.STExtraSpace;
DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
SectionTopMessage(cb, yTopMargin, yLocation); // does wcntraining & suppinfo section title
if (MyPageHelper.CreatingSupInfoPage) yPageStart -= (2 * SixLinesPerInch);
if (doSectionContinue) DoTopContinueMsg(cb, ref yPageStart, yTopMargin, docstyle, null);
// If "ContinueSectionHeader" (format flag) is true then print the section title with "(Continued)" appended to it
// B2020-164 added check for SpecialCaseCalvert to bypass IsSeparateSubsection STP O-67B-2 step 6.5
if ((!MyItemInfo.IsSection || MyItemInfo.IsSubsection) &&
MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ContinueSectionHeader &&
(!MyItemInfo.IsSection || (MyItemInfo.IsSeparateSubsection || MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)))
{
// B2020-162 - SpecialCaseCalvert flag affect single column procedures, use SpecialCaseCalvertPagination for Two Column procedures instead
// B2020-163 - above bug (162) section header breaking from HLS caused forced pagination. turned out we didn't need to change this for B2020-162.
SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y") && !MyItemInfo.MyDocStyle.CancelSectTitle;
//B2020-123 - Calvert - set CalvertPrintedSubSectTitle flag to fix section continue bug
//B2020-166 - Calvert - only set CalvertPrintedSubSectTitle flag if doSectionTitleContinued is set
if (doSectionTitleContinued && MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert) CalvertPrintedSubSectTitle = true; // B2020-123
}
if (MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0].CompressFirstPartOfStep)
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
else
MyPageHelper.YMultiplier = 1;
break;
// .oooooo. .oooo.
// d8P' `Y8b .dP""Y88b
// 888 .oooo. .oooo.o .ooooo. ]8P'
// 888 `P )88b d88( "8 d88' `88b .d8P'
// 888 .oP"888 `"Y88b. 888ooo888 .dP'
// `88b ooo d8( 888 o. )88b 888 .o .oP .o
// `Y8bood8P' `Y888""8o 8""888P' `Y8bod8P' 8888888888
case 2: // Break within a Step'
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.DoPageBreaks)
{
if (supInfoSect != null && MyItemInfo.SupInfos != null && MyItemInfo.SupInfos.Count > 0) supInfoSect.StepSectPageBreaksForSupInfo.Add(MyItemInfo.SupInfos[0].ItemID);
else MyPromsPrinter.NeedSupInfoBreak = true;
if (supInfoSect != null) supInfoSect.StepSectPageBreaks.Add(MyItemInfo.ItemID);
}
YTopMost = OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
docstyle = MyItemInfo.MyDocStyle;
bool doAlarmBox = false;
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
{
// Recognize that the break occurred WITHIN the CONDITION/RESPONSE table.
// Otherwise, we get extraneous header/top of box lines in pdf.
if (MyPageHelper.AlarmYoffStart > 0)
{
// if the first step in box is what broke to next page, then
// don't print the box on this page, only print it on next page:
doAlarmBox = true;
if (MyItemInfo.MyPrevious == null && MyParent.HasCalvertMacro)
MyPageHelper.AlarmYoffStart = 0;
else if (MyPageHelper.AlarmYoffEnd == 0)
{
// doThreeContinues flags when continue messages are printed in the
// bottom of the CONDITION/RESPONSE table columns.
doThreeContinues = MyItemInfo.StepLevel > 1;
MyPageHelper.AlarmYoffEnd = CalculateYLocation(yLocation, yTopMargin);
}
else if (MyPageHelper.AlarmYoffEnd > 0)
doAlarmBox = false;
}
}
}
if (MyPageHelper.NotesToFootNotes != null && MyPageHelper.NotesToFootNotes.Count > 0) MyPageHelper.NotesToFootNotesYoffset = CalculateYLocation(yLocation, yTopMargin);
// B2019-115 Locate Bottom Continue Message below AER Table if necesssary
float bcm_yLocation = TableBottom == -1 ? yLocation : Math.Min(TableBottom, yLocation);
DoBottomContinueMsg(cb, yBottomMargin, bcm_yLocation, docstyle, doThreeContinues);
MyPromsPrinter.NewPage();
// C2018-003 fixed use of getting the active section
// F2023-112 Vogtle Units 3 & 4 background document format DSS_PageListBkgndStpContMsg to print continue message next to step number
if (MyItemInfo.IsStep && (MyItemInfo.ActiveSection != null &&
((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListSpBckgrnd) == E_DocStructStyle.DSS_PageListSpBckgrnd) ||
((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListBkgndStpContMsg) == E_DocStructStyle.DSS_PageListBkgndStpContMsg)))
{
// check if parent (can be HLS, Caution or Note) has the UseOldTemplate. If so,
// flag that a continue message should be printed as part of a pagelist header (if pagelist
// has CM: page list item)
ItemInfo itm = MyItemInfo;
while (itm.IsStep && !itm.FormatStepData.UseOldTemplate) itm = itm.MyParent;
// don't put out continue if the page break item is the same as background step item (caution/note or hls)
if (itm.IsStep && itm.ItemID != MyItemInfo.ItemID)
{
MyPageHelper.OldTemplateContMsg = true;
MyPageHelper.ResetSvg();
}
}
//_MyLog.InfoFormat("NewPage 11 {0}", cb.PdfWriter.CurrentPageNumber);
//Console.WriteLine("'b2',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin);
//Console.WriteLine("'a2',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
DebugText.WriteLine("Paginate2");
if (MyItemInfo.MyHLS.FoldoutIndex() > -1)
MyPromsPrinter.DoFoldoutPage(cb, "Break within Step", MyPageHelper.TextLayer, MyPageHelper, MyItemInfo.MyHLS.FoldoutIndex(), false); // temporary foldout
else if (PromsPrinter.MyFoldoutReader.Count > 0 && MyPageHelper.MyPromsPrinter.InsertBlankPages)
{
MyPromsPrinter.InsertBlankPage(cb);
_MyLog.InfoFormat("NewPage Break within step blank {0}", cb.PdfWriter.CurrentPageNumber);
}
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge && !MyPageHelper.CreatingSupInfoPage && !MyItemInfo.IsSection && !MyItemInfo.IsInSupInfo && (MyItemInfo.MyProcedure as ProcedureInfo).ProcHasSupInfoData)
{
int sid = GetIdThatHasSupInfoItems(MyItemInfo, MyItemInfo.ItemID);
if (sid != -1)
{
MyPromsPrinter.DoSupInfoPage(cb, "TEMP", MyPageHelper.TextLayer, MyPageHelper, sid, true);
}
else
{
MyPromsPrinter.InsertBlankPage(cb);
}
}
// 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 ((MyItemInfo.IsCautionPart || MyItemInfo.IsNotePart) && MyParent.PartsAbove.Count > 0)
yTopMost = MyParent.PartsAbove[0].YOffset;
yTopMost = Math.Min(yTopMost, YVeryTop);
yPageStart = yTopMargin + yTopMost;// -2 * SixLinesPerInch;
DoCheckOffHeader(cb, MyItemInfo, yLocation, yTopMargin, yPageStart);
if (EmptyTopMostPart) yPageStart += SixLinesPerInch;
bool addExtraLines = false;
// If "ContinueSectionHeader" (format flag) is true then print the section title with "(Continued)" appended to it
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ContinueSectionHeader)
{
// if this is calvert OI/STP, then also check that docstyle has a top continue message
// in the document style that includes 'Continued'
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
{
string myMsg = MyItemInfo.MyDocStyle.Continue.Top.Message;
if (myMsg == null || myMsg == "")
{
// There is no message, but still need to check if there is a Section Title Continued message:
// This was added for BGE OI34 (if break was within step, no section title continue message was printed)
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ContinueSectionHeader)
{
SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y") && !MyItemInfo.MyDocStyle.CancelSectTitle;
}
else
doSectionTitleContinued = false;
}
else
{
SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y") && !MyItemInfo.MyDocStyle.CancelSectTitle;
}
}
else
{
SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
doSectionTitleContinued = (sch == null || sch.Section_PrintHdr == "Y") && !MyItemInfo.MyDocStyle.CancelSectTitle;
}
}
addExtraLines = SectionTopMessage(cb, yTopMargin, yLocation); // this does wcntraining top section continue message and supplemental info message
if (MyPageHelper.CreatingSupInfoPage) yPageStart -= (2 * SixLinesPerInch);
if (!addExtraLines && (!doSectionTitleContinued || !SectionShowTitles))
addExtraLines = DoTopContinueMsg(cb, ref yPageStart, yTopMargin, docstyle, doThreeContinues && MyItemInfo.MyParent != null && MyItemInfo.MyParent.MyTab != null ? MyItemInfo.MyParent.MyTab.CleanText : null);
// B2020-128: If compression flag is on RNO, see if there is an AER to the left and do the 7lpi multiplier
if (CompressPartOfStep || CompressRnoWithAerToTheLeft())
{
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
CompressPartOfStep = false;
}
else
MyPageHelper.YMultiplier = 1;
// For Calvert Alarms, if there was a page break and there is an box around the current
// step, need to add the header for the box, which is stored in a macro. Also set the
// 'AlarmYoffStart' value to where the vertical lines of the box start on this page.
if (doAlarmBox && MyItemInfo.StepLevel > 1)
{
float alrmY = yTopMargin - (2 * SixLinesPerInch); // CalculateYOffset(yPageStart, yTopMargin);
vlnMacro vlnm = new vlnMacro((float)docstyle.Layout.LeftMargin - 12, alrmY, "H4");
vlnm.UseInternalY = true; // B2020-121: Account for Header on Caution or Note
PartsLeft.Add(vlnm);
MyPageHelper.AlarmYoffStart = alrmY - SixLinesPerInch;
yPageStart -= (4 * SixLinesPerInch);
if (ChildrenRight.Count > 0 && ChildrenRight[0].ChildrenAbove.Count > 0 && ChildrenRight[0].ChildrenAbove[0].MyItemInfo.IsCautionOrNotePart)
yPageStart += (SixLinesPerInch); // B2020-121: Account for Header on Caution or Note
}
// For Calvert Alarms, if there is no box & this is top of page, if previous step
// had box (macro), adjust up page. The constructor (vlnParagraph), inserted these
// lines after the box so that the following text did not print right next to box.
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
if (MyItemInfo.MyPrevious != null && MyItemInfo.MyPrevious.TemplateIndex > 0 && MyItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[MyItemInfo.MyPrevious.TemplateIndex].hmacro > 0)
yPageStart += (3 * SixLinesPerInch);
}
// Now check if this is a template type step & if so, add the HLS's prefix/suffix to it.
// Since the entire checklist HLS (checklist table header) is printed as part of the
// continue, create a new paragraph to handle pagination and printing.
if (MyItemInfo.MyHLS != null && MyItemInfo.MyHLS.FormatStepData.UseSmartTemplate)
{
DoSubs = false;
vlnParagraph smartPara = new vlnParagraph(MyParent.MyParent, cb, MyItemInfo.MyHLS, MyParent.XOffset, yPageStart, 0, 0, MyParent.MyItemInfo.ActiveFormat, null, " (Continued)", 0, false, MyPromsPrinter);
smartPara.PrintHeader = true;
float mytmpfloat = smartPara.ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
yPageStart -= smartPara.Height;
DoSubs = true;
}
if (addExtraLines) yPageStart -= (2 * SixLinesPerInch);
if (MyItemInfo.IsRNOPart && MyItemInfo.FormatStepData.DoubleSpace && MyItemInfo.FormatStepData.SpaceDouble) yPageStart += SixLinesPerInch;
break;
// .oooooo. .oooo.
// d8P' `Y8b .dP""Y88b
// 888 .oooo. .oooo.o .ooooo. ]8P'
// 888 `P )88b d88( "8 d88' `88b <88b.
// 888 .oP"888 `"Y88b. 888ooo888 `88b.
// `88b ooo d8( 888 o. )88b 888 .o o. .88P
// `Y8bood8P' `Y888""8o 8""888P' `Y8bod8P' `8bd88P'
case 3: // Break on High Level Step (SevenLinesPerInch)
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.DoPageBreaks)
{
if (supInfoSect != null && MyItemInfo.SupInfos != null && MyItemInfo.SupInfos.Count > 0) supInfoSect.StepSectPageBreaksForSupInfo.Add(MyItemInfo.SupInfos[0].ItemID);
else MyPromsPrinter.NeedSupInfoBreak = true;
if (supInfoSect != null) supInfoSect.StepSectPageBreaks.Add(MyItemInfo.ItemID);
}
if (!firstHighLevelStep || (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge && !MyPageHelper.CreatingSupInfoPage)) // B2017-229: Added supinfo print check to run facing page logic
{
YTopMost = OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
if (MyPageHelper.NotesToFootNotes != null && MyPageHelper.NotesToFootNotes.Count > 0) MyPageHelper.NotesToFootNotesYoffset = CalculateYLocation(yLocation, yTopMargin);
MyPromsPrinter.NewPage(); // HLS (7 lpi) breakif (MyItemInfo.IsSection)
//_MyLog.InfoFormat("NewPage 12 {0}", cb.PdfWriter.CurrentPageNumber);
//Console.WriteLine("'b3',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
ResetDocStyleAndValues(ref yTopMargin, ref yBottomMargin);
//Console.WriteLine("'a3',{0},'{1}',{2},{3},{4},{5},{6}", MyItemInfo.ItemID, MyItemInfo.ShortPath, yTopMargin, yPageStart, yLocation, YTopMost, YOffset);
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)
MyPromsPrinter.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
MyPromsPrinter.InsertBlankPage(cb);
//_MyLog.InfoFormat("NewPage 12 lpi blank {0}", cb.PdfWriter.CurrentPageNumber);
}
// See comments under case 0 explaining supinfo/facing page processing.
itemIsPrinted = IsPrintedStepItemForSupInfo();
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge && !MyPageHelper.CreatingSupInfoPage && itemIsPrinted /*&& !MyItemInfo.IsSection */ && !MyItemInfo.IsInSupInfo && (MyItemInfo.MyProcedure as ProcedureInfo).ProcHasSupInfoData)
{
int sid = GetIdThatHasSupInfoItems(MyItemInfo, MyItemInfo.ItemID);
if (sid != -1)
{
MyPromsPrinter.DoSupInfoPage(cb, "TEMP", MyPageHelper.TextLayer, MyPageHelper, sid, true);
}
else
{
// B2020-031: Don't put out an extra blank page if section has title that is printed (blank page is output then)
bool titlePrinted = false;
if (MyItemInfo.IsSection || (MyItemInfo.IsHigh && MyItemInfo.MyPrevious == null))
{
// see if the section title is printed.
SectionConfig sch = MyItemInfo.ActiveSection.MyConfig as SectionConfig;
titlePrinted = (sch == null || sch.Section_PrintHdr == "Y") || !(MyItemInfo.MyActiveSection as SectionInfo).HasSupInfoSteps;
titlePrinted &= (ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle);
}
if (MyItemInfo.IsHigh && MyItemInfo.MyPrevious == null && !titlePrinted)
MyPromsPrinter.InsertBlankPage(cb);
}
}
if (MyItemInfo.MyDocStyle.LandscapePageList)
{
System.Drawing.Drawing2D.Matrix myMatrix = new System.Drawing.Drawing2D.Matrix(0, 1, -1, 0, cb.PdfDocument.PageSize.Height, 0);
cb.Transform(myMatrix);
}
// 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") && !MyItemInfo.MyDocStyle.CancelSectTitle;
}
}
// 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;
string contMsg = (MyItemInfo.ActiveSection != null) ? MyItemInfo.ActiveSection.MyDocStyle.Continue.SectionTitle.AppendToTitle : ""; // C2018-003 fixed use of getting the active section
// For Calvert, the xoffset will be the highest level sections xoffset (there are metasections,
// don't use their xoffset or the continue message is indented too much)
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
{
float secContinueTabXoff = (float)MyItemInfo.MyDocStyle.Layout.LeftMargin;
float secContinueXoff = 0f;
float secContinueTabWidth = 0f;
vlnParagraph fndTopSect = this;
while (fndTopSect.MyParent != null)
{
fndTopSect = fndTopSect.MyParent;
}
if (fndTopSect != null && fndTopSect.MyTab != null)
{
secContinueTabXoff = fndTopSect.MyTab.XOffset;
secContinueTabWidth = fndTopSect.MyTab.Width;
secContinueXoff = fndTopSect.XOffset;
}
// get to the correct section for the message, i.e. if on a section, the message should be the parent
// section (not the activesection which is myself); if on a step, the message should be the active section
ItemInfo sectForCont = MyItemInfo.IsSection && MyItemInfo.MyParent.IsSection ? MyItemInfo.MyParent : MyItemInfo.ActiveSection;
sectContPara = new vlnParagraph(MyParent.MyParent, cb, sectForCont, MyParent.XOffset, 0, 0, 0, MyParent.MyItemInfo.ActiveFormat, null, (contMsg == null || contMsg == "") ? " (Continued)" : contMsg, 0, false, MyPromsPrinter);
if (sectContPara.PartsLeft.Count > 0)
{
vlnTab vt = sectContPara.MyTab;
string ctab = GetSectCombinedTab(MyItemInfo);
vt.Rtf = GetRtf(ctab, vt.MyFont);
float wd = vt.GetTextWidth(vt.MyFont, ctab);
vt.XOffset = secContinueTabXoff;
vt.Width = secContinueXoff - secContinueTabXoff;
sectContPara.XOffset = secContinueXoff;
if ((wd + 12) > secContinueXoff - secContinueTabXoff) // 12 is 2 characters
{
float dif = wd + 12 - (secContinueXoff - secContinueTabXoff);
vt.Width += dif;
sectContPara.XOffset += dif;
sectContPara.Width -= dif;
}
}
float mytmpfloat = sectContPara.ParagraphToPdf(cb, yTopMargin, yTopMargin, yBottomMargin);
if (sectContPara.SectionContinuePrinted)
yPageStart -= sectContPara.Height + SixLinesPerInch;
}
else
{
sectContPara = new vlnParagraph(MyParent.MyParent, cb, MyItemInfo.ActiveSection, MyParent.XOffset, 0, 0, 0, MyParent.MyItemInfo.ActiveFormat, null, (contMsg == null || contMsg == "") ? " (Continued)" : contMsg, 0, false, MyPromsPrinter);
float mytmpfloat = sectContPara.ParagraphToPdf(cb, yTopMargin, yTopMargin, yBottomMargin);
if (sectContPara.SectionContinuePrinted)
yPageStart -= sectContPara.Height + SixLinesPerInch;
}
}
// see if this hls has footnotes, add to the footnote datastructure for processing at end of page.
if (MyItemInfo.IsHigh && MyPageHelper.NotesToFootNotesHLS.ContainsKey(MyItemInfo.ItemID)) AddFootNote(cb);
yPageStart = ChildrenAbove.ToPdf(cb, yPageStart, ref yTopMargin, ref yBottomMargin);
// B2017-122: if doing supinfo pagebreaks, if there should be a break on a step (not hls) that has a caution/note do it here:
if (!MyItemInfo.IsHigh && ChildrenAbove != null && ChildrenAbove.Count > 0 && MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.DoPageBreaks && MyPromsPrinter.NeedSupInfoBreak && MyItemInfo.SupInfos != null && MyItemInfo.SupInfos.Count > 0)
{
// if this has a caution/note with supinfo, that is id that needs to go in pagination list, unless it is in there.
int aboveSupinfoId = ChildrenAboveHaveSupInfo();
if (supInfoSect != null)
{
if (supInfoSect.StepSectPageBreaksForSupInfo.Contains(aboveSupinfoId)) aboveSupinfoId = -1;
supInfoSect.StepSectPageBreaksForSupInfo.Add(MyItemInfo.SupInfos[0].ItemID);
}
MyPromsPrinter.NeedSupInfoBreak = false;
}
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).
// 'this' below is a highlevel step, and the only time that ParaBreaks[0] will == 'this' is
// when the PageBreakOnStep flag is true.
if (MyPageHelper.ParaBreaks != null && MyPageHelper.ParaBreaks.Count > 0 &&
MyPageHelper.ParaBreaks[0] == this && this.MyItemInfo.FormatStepData.PageBreakOnStep)// B2017-224 Top Continue Messages Add check for PageBreakOnStep 9/26/2017 Ginna SAMGs SAG-8 Step 4
{
ShowPageBreak(1, CheckForCompression("PageBreakOnStep/Caution/Note HLS"), "Yes", YTop - YBottomMost, yTopMargin - yBottomMargin, yTopMargin - yBottomMargin, false);
YTopMost = OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
MyPageHelper.BottomMessage.Clear();
MyPageHelper.TopMessage = null;
MyPromsPrinter.NewPage();
if (CompressPartOfStep)
{
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
CompressPartOfStep = false;
}
MyPageHelper.ParaBreaks.RemoveAt(0);
yPageStart = yTopMargin + YTop;
}
// The following sets the beginning/ending y location for the lines around the
// CONDITION/RESPONSE text for Calvert Alarm format
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
int tindx = MyItemInfo.TemplateIndex;
if (tindx >= 0)
{
// save this position to start drawing the alarm box lines around substeps:
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.Templates[MyItemInfo.TemplateIndex].row > 0)
MyPageHelper.AlarmYoffStart = CalculateYOffset(yPageStart, yTopMargin) - SixLinesPerInch;
else if (MyPageHelper.AlarmYoffStart > 0 && MyPageHelper.AlarmYoffEnd == 0)
MyPageHelper.AlarmYoffEnd = CalculateYOffset(yPageStart, yTopMargin) + (2 * SixLinesPerInch);
}
}
int profileDepth2 = ProfileTimer.Push(">>>> vlnParagraph.ParagraphToPdf");
// B2020-162 - SpecialCaseCalvert flag affect single column procedures, use SpecialCaseCalvertPagination for Two Column procedures instead
if (MyItemInfo.IsSubsection && MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertPagination) CalvertPrintedSubSectTitle = true; // B2020-123
yPageStart = ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
ProfileTimer.Pop(profileDepth2);
// 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.NextItem == 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.ActiveSection as SectionInfo; // C2018-003 fixed use of getting the active section
// B2017-201 if si is null we need to get it via the ItemID
if (si == null)
si = SectionInfo.Get(MyItemInfo.MyActiveSection.ItemID); // MyActiveSection does not try to resolve anything - ActiveSection is call above and will resolve and set MyActiveSection
bool _skipEndMessage = (si == null || si.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.One) && !MyItemInfo.ActiveFormat.MyStepSectionLayoutData.EndForSingle;
bool _lastSect = true;
if (si != null && si.MyActiveParent.IsSection) // is this meta/subsection. Only put end message out on last section
{
ItemInfo mysect = si as ItemInfo;
if (mysect.NextItem != null && !docstyle.End.EndMessageOnEachSubSection) _lastSect = false;
}
string myMsg = (docstyle.End == null) ? null : docstyle.End.FixedMessage;
if (myMsg != null && !_skipEndMessage && _lastSect)
{
// 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);
}
float adjMsgY = 0;
if (docstyle.End.Flag < 0) // Adjust this many lines down the page.
{
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 (yTopMargin - docstyle.Layout.PageLength >= msg_yLocation && docstyle.End.Message != null && docstyle.End.Message != "" && docstyle.End.Flag <= 2)
{
// B2018-037: adjust location of end message to bottom of page if it is too low. This occurs when data just doesn't
// fit on the page, but will locate end message at a more reasonable location.
msg_yLocation = (float)yTopMargin - (float)docstyle.Layout.PageLength;
_MyLog.WarnFormat("End Message LOW on page: {0}, {1}, {2}, Page {3}", msg_yLocation, MyItemInfo.ItemID, MyItemInfo.ShortPath, MyPageHelper.CurrentPageNumber + 1);
}
if ((docstyle.End.Margin ?? 0) != 0)
{
xpos = (float)docstyle.Layout.LeftMargin + (float)docstyle.End.Margin;
MyPageHelper.BottomMessage.Add(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;
//B2022-126 was using the wrong font definition to calaculate the centering position
// ** B2023-099 commented out and restored the previous calculation. This caused problems centering the END message in Ginna
// their END message prints with the Prestige Elite font but he centering calc uses Courier New
//xpos = XOffsetBox + (float)docstyle.Layout.LeftMargin + (wtpm - (myMsg.Length * docstyle.End.Font.CharsToTwips)) / 2;
xpos = XOffsetBox + (float)docstyle.Layout.LeftMargin + (wtpm - (myMsg.Length * MyItemInfo.FormatStepData.Font.CharsToTwips)) / 2;
xpos = Math.Max(xpos, XOffsetBox + (float)docstyle.Layout.LeftMargin);
vlnText vttmp = new vlnText(cb, this, myMsg, myMsg, xpos, msg_yLocation, docstyle.End.Font);
MyPageHelper.BottomMessage.Add(vttmp);
MyPageHelper.MyGaps.Add(new Gap(msg_yLocation, msg_yLocation - vttmp.Height));
yPageStart -= (vttmp.Height + adjMsgY);
}
}
}
if (yLocalypagestart != yPageStart) DebugText.WriteLine("ToPdf-yPagestartDiff:{0},{1},{2},{3}", MyPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, MyItemInfo.ItemID, yLocalypagestart, yPageStart);
// if doing NotesToFootnotes (Calvert valve list format), get the bottom location so that
// footnotes will be printed after last text on page. This is used for the end of the section.
// Pages that broke within pagination logic above had footnote location set during pagination code.
if (MyPageHelper.NotesToFootNotes != null && MyPageHelper.NotesToFootNotes.Count > 0)
MyPageHelper.NotesToFootNotesYoffset = CalculateYLocation(yPageStart - YBottomMost, yTopMargin);
ProfileTimer.Pop(profileDepth);
return yPageStart;
}
// B2020-128: If compression flag is on RNO, see if there is an AER to the left and do the 7lpi multiplier
private bool CompressRnoWithAerToTheLeft()
{
if (!MyItemInfo.IsInRNO) return false;
foreach (vlnParagraph vPara in MyPageHelper.MyParagraphs.Values)
{
if (!vPara.Processed)
{
if (vPara.YOffset <= YOffset && vPara.CompressPartOfStep) return true;
}
}
return false;
}
private bool IsPrintedStepItemForSupInfo()
{
bool printedMySectTitle = true;
if (MyItemInfo.IsSection)
{
// see if the section title is printed.
SectionConfig sch = (MyItemInfo.ActiveSection != null) ? MyItemInfo.ActiveSection.MyConfig as SectionConfig : null; // C2018-003 fixed use of getting the active section
printedMySectTitle = (sch == null || sch.Section_PrintHdr == "Y") || !(MyItemInfo.ActiveSection as SectionInfo).HasSupInfoSteps;
printedMySectTitle &= (ShowSectionTitles && !MyItemInfo.MyDocStyle.CancelSectTitle);
}
return printedMySectTitle;
}
private int ChildrenAboveHaveSupInfo()
{
if (ChildrenAbove == null || ChildrenAbove.Count < 1) return -1;
foreach (vlnParagraph p in ChildrenAbove)
{
if (p.MyItemInfo.SupInfos != null && p.MyItemInfo.SupInfos.Count > 0) return p.MyItemInfo.SupInfos[0].ItemID;
}
return -1;
}
// Find the step that has supplemental information from this step down page until a preferred page break is found
// or a regular page break.
// It is used to determine whether there is a supinfo facing page or if there should be a blank page.
private bool FoundStepPageBreak = false;
private int GetIdThatHasSupInfoItems(ItemInfo ii, int startid)
{
if (ii == null) return -1;
FoundStepPageBreak = false;
// if this item has supinfo, return its id
if (ii.SupInfos != null && ii.SupInfos.Count > 0) return ii.SupInfos[0].ItemID;
// see if any substeps of this item have supinfo, and if so, return the substep's id
int id = GetSubThatHasSupInfoItems(ii, startid);
if (id != -1) return id;
if (FoundStepPageBreak) return -1; // Set in GetSubThatHasSupInfoItems
// Now go to the next item, check if it or any of its substeps have supinfo, and if so, return the id
ItemInfo sib = ii.NextItem;
id = GetIdThatHasSupInfoItemsSibNext(sib, startid);
if (id != -1) return id;
if (FoundStepPageBreak) return -1; // Set in GetIdThatHasSupInfoItemsSibNext
// B2017-122: if this is a note or caution off substep, check if substep has supinfo:
if ((ii.IsNote || ii.IsCaution) && !ii.MyParent.IsHigh)
{
if (ii.MyParent.SupInfos != null && ii.MyParent.SupInfos.Count > 0) return ii.MyParent.SupInfos[0].ItemID;
int sbfromNC = GetSubThatHasSupInfoItems(ii.MyParent, startid);
if (sbfromNC != -1) return sbfromNC;
if (FoundStepPageBreak) return -1; // Set in GetSubThatHasSupInfoItems
}
// Go to the parent, and find its next and check if it or any of its substeps or next steps or any of their substeps have supinfo,
// and if so, return the id.
ItemInfo par = ii.MyParent;
ItemInfo parsnxt = par.GetNext();
//B2023-068 check if we are already at the section or procedure level
if (!par.IsSection && !par.IsProcedure && parsnxt != null)
{
par = parsnxt;
while (par != null && !par.IsSection)
{
id = GetIdThatHasSupInfoItemsSibNext(par, startid);
if (id != -1) return id;
par = par.MyParent;
ItemInfo sparsnxt = par.GetNext();
if (!par.IsSection && sparsnxt != null) par = sparsnxt;
else return -1;
}
}
return -1;
}
private int GetIdThatHasSupInfoItemsSibNext(ItemInfo ii, int startid)
{
int id = -1;
while (ii != null)
{
SectionInfo supInfoSect = ii.ActiveSection as SectionInfo;
// B2017-193 Error occured when a section in the MRU was being loaded as an iteminfo
if (supInfoSect == null) supInfoSect = SectionInfo.Get(ii.ActiveSection.ItemID);
// if there is a pagebreak on this step section step, quit looking for supinfos. The
// break has to occur here.
if (supInfoSect.StepSectPageBreaks.Contains(ii.ItemID))
{
FoundStepPageBreak = true;
return -1;
}
if (ii.SupInfos != null && ii.SupInfos.Count > 0)
{
// check if this is in the list of page breaks for supinfos, if not it may have one of its cautions/notes rather than its id:
if (!supInfoSect.StepSectPageBreaksForSupInfo.Contains(ii.SupInfos[0].ItemID))
{
if (ii.Cautions != null)
{
foreach (ItemInfo caution in ii.Cautions)
if (caution.SupInfos != null && caution.SupInfos.Count > 0 && supInfoSect.StepSectPageBreaksForSupInfo.Contains(caution.SupInfos[0].ItemID)) return caution.SupInfos[0].ItemID;
}
if (ii.Notes != null)
{
foreach (ItemInfo note in ii.Notes)
if (note.SupInfos != null && note.SupInfos.Count > 0 && supInfoSect.StepSectPageBreaksForSupInfo.Contains(note.SupInfos[0].ItemID)) return note.SupInfos[0].ItemID;
}
}
return ii.SupInfos[0].ItemID;
}
id = GetSubThatHasSupInfoItems(ii, startid);
if (id == -2) return -1;
if (id != -1) return id;
ii = ii.NextItem;
}
return -1;
}
private int GetSubThatHasSupInfoItems(ItemInfo ii, int startid)
{
if (ii.MyContent.ContentParts != null)
{
SectionInfo supInfoSect = ii.ActiveSection as SectionInfo;
if (supInfoSect == null) supInfoSect = SectionInfo.Get(ii.ActiveSection.ItemID);
foreach (PartInfo pi in ii.MyContent.ContentParts)
{
if ((E_FromType)pi.FromType != E_FromType.SupInfo)
{
foreach (ItemInfo iic in pi.MyItems)
{
// B2018-021: added code to be sure that check isn't on current step, i.e. startid != iic.ItemID &
// flag when the following page break is found so the next supplemental information page isn't printed
// on a step where the step is on the following page from the one we are looking for.
if (startid != iic.ItemID)
{
if (supInfoSect.StepSectPageBreaks.Contains(iic.ItemID))
{
FoundStepPageBreak = true;
return -1;
}
if (iic.SupInfos != null && iic.SupInfos.Count > 0) return iic.SupInfos[0].ItemID;
int id = GetSubThatHasSupInfoItems(iic, startid);
if (id != -1) return id;
}
}
}
}
}
return -1;
}
private float GetSectionTopMessageSize()
{
// B2016-134: Account for wcntraining section top continue if item has container
float retval = 0;
if (MyItemInfo.MyDocStyle.SectTop != null && MyItemInfo.MyDocStyle.SectTop.Message != null)
{
if (PartsContainer != null && PartsContainer.Count > 0) retval = SixLinesPerInch * 1;
}
return retval;
}
// For WCNTRN (Wolf Creek Training format): the following prints the section number (and continued, if
// section is continued from previous page) in the Responsibility column.
private bool SectionTopMessage(PdfContentByte cb, float yTopMargin, float yLocation)
{
if (MyPageHelper.CreatingSupInfoPage)
{
float scttopWidths = "Supplemental Information".Length * 6;
float ctrs = ((float)MyItemInfo.MyDocStyle.Layout.PageWidth - (float)MyItemInfo.MyDocStyle.Layout.LeftMargin) / 2;
float sctcntrXs = (float)MyItemInfo.MyDocStyle.Layout.LeftMargin + ctrs - (scttopWidths / 2);
VE_Font vf = MyItemInfo.MyDocStyle.Font;
// F2017-039: The following null check was added in case the format's doc style does not have a font defined:
if (vf == null || vf.Style == null || vf.Family == null || vf.Size == null || vf.CPI == null) vf = MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font;
E_Style sty = E_Style.Underline;
if (vf != null && vf.Style != null) sty = (E_Style)(vf.Style | E_Style.Underline);
vf = new VE_Font(vf.Family, (int)vf.Size, sty, (float)vf.CPI);
MyPageHelper.TopMessage = new vlnText(cb, this, "Supplemental Information", "Supplemental Information", sctcntrXs, yTopMargin + 0.1F, vf);
return true;
}
bool addextra = false;
if (MyItemInfo.MyDocStyle.SectTop != null && MyItemInfo.MyDocStyle.SectTop.Message != null)
{
float sectMsgY = 0;
if (PartsContainer == null || PartsContainer.Count == 0)
sectMsgY = CalculateYLocation(YTop, yTopMargin);
else
{
// B2016-134: Account for section top continue if item has container, i.e. move section top continue message above the container
sectMsgY = CalculateYLocation(YTopMost - (SixLinesPerInch * 3), yTopMargin); // 3 is # of lines: header, box, blank line moving up page
addextra = true;
}
VE_Font sctMsgFont = MyItemInfo.MyDocStyle.SectTop.Font;
string scttop = null;
if (!MyItemInfo.IsStepSection && MyItemInfo.MyDocStyle.SectTop.Message != null)
scttop = MyItemInfo.MyDocStyle.SectTop.Message.Replace("%s", (MyItemInfo.ActiveSection as SectionInfo).DisplayNumber);
else
scttop = (MyItemInfo as SectionInfo).DisplayNumber;
float scttopWidth = scttop.Length * 6;
float ctr = (float)MyItemInfo.MyDocStyle.SectTop.Margin;
float sctcntrX = (float)MyItemInfo.MyDocStyle.Layout.LeftMargin + ctr - (scttopWidth / 2);
vlnText mySectMsg = new vlnText(cb, this, scttop, scttop, sctcntrX, sectMsgY, sctMsgFont);
PartsLeft.Add(mySectMsg);
}
return addextra;
}
// Added to try to resolve a problem when printing FNP-1-FRP-I.3 Attachment 3 Table 1.
// May be needed to evaluate this problem in the future.
//private void CompareSectionInfo(SectionInfo si, SectionInfo si1)
//{
// if (si.ItemID != si1.ItemID)
// Console.WriteLine("Different");
// if (si.ActiveFormat.FullName != si1.ActiveFormat.FullName)
// Console.WriteLine("Different");
// if (si.ActiveParent != si1.ActiveParent)
// Console.WriteLine("Different");
// if (si.ActiveSection.ItemID != si1.ActiveSection.ItemID)
// Console.WriteLine("Different");
// if (si.MyDocStyle.Name != si1.MyDocStyle.Name)
// Console.WriteLine("Different");
//}
private void AddFootNote(PdfContentByte cb)
{
// for calvert valve lists footnotes, if there is footnote data, save it for vlnSvgPageHelper
// which puts the footnotes out when page is printed.
List<int> myNotes = MyPageHelper.NotesToFootNotesHLS[MyItemInfo.ItemID];
foreach (int myNote in myNotes)
{
ItemInfo inote = StepInfo.Get(myNote);
// first check if this exact text is already in the foot note list. If it is
// in there, don't add it.
bool inlist = false;
if (MyPageHelper.NotesToFootNotes != null)
{
foreach (vlnParagraph vp in MyPageHelper.NotesToFootNotes)
{
if (vp.MyItemInfo.MyContent.Text == inote.MyContent.Text)
{
inlist = true;
break;
}
}
}
if (!inlist)
{
vlnParagraph vpFNote = new vlnParagraph(null, cb, inote, (float)MyItemInfo.MyDocStyle.Layout.LeftMargin, 0, 0, 0, MyItemInfo.ActiveFormat, null, null, 0, false, MyPromsPrinter);
vpFNote.Width = (float)MyItemInfo.MyDocStyle.Layout.PageWidth - (float)MyItemInfo.MyDocStyle.Layout.LeftMargin;
vpFNote.Height = 0;
vpFNote.XOffset = (float)MyItemInfo.MyDocStyle.Layout.LeftMargin;
if (MyPageHelper.NotesToFootNotes == null) MyPageHelper.NotesToFootNotes = new List<vlnParagraph>();
MyPageHelper.NotesToFootNotes.Add(vpFNote);
}
}
MyPageHelper.NotesToFootNotesHLS.Remove(MyItemInfo.ItemID);
}
private bool DoTopContinueMsg(PdfContentByte cb, ref float yPageStart, float yTopMargin, DocStyle docstyle, string subTab)
{
bool addExtraLine = false;
if ((bool)docstyle.Continue.Top.UseStepTabs)
{
// UseStepTabs is a format flag added for Comanche Peak to print out step tabs as
// a top comtinue message. This code will go up through parents putting out
// their tabs - at this y location, but at the tabs' x location
vlnParagraph myPar = this;
MyPageHelper.TopMessageRs = new List<vlnText>();
while (!myPar.MyItemInfo.IsHigh)
{
myPar = myPar.MyParent;
foreach (vlnPrintObject vpo in myPar.PartsLeft)
{
if (vpo is vlnTab)
{
vlnTab vt = vpo as vlnTab;
string cltxt = vt.Text;
// Originally the Comache Peak customer did not want the '*'. As of 6/22/15, CP wants the asterisk in continue msg
///cltxt = cltxt.Replace("*", " ");
// replace C# representation of unicode character "\u25CF" which is hex
// with the rtf representation @"\u9679?"
if (cltxt.Contains("\u25CF")) cltxt = cltxt.Replace("\u25CF", @"\u9679?"); // handle a bullet, if it isn't unicode yet
float msgTopMargin = yTopMargin;
// B2017-106: if caution/note move the message up a little so it doesn't touch the caution/note lines:
if (MyItemInfo.IsNote || MyItemInfo.IsCaution) msgTopMargin += 4;
// B2018-140: if table move the message up a little so it doesn't touch the table lines:
if (MyItemInfo.IsTable) msgTopMargin += 6;
MyPageHelper.TopMessageRs.Add(new vlnText(cb, this, cltxt, cltxt, vt.XOffset, msgTopMargin, vt.MyFont));
}
else if (vpo is vlnText) // As of 6/22/15, CP wants the step designator in the continue message also.
{
vpo.YOffset = yTopMargin;
int nlcnt = 1; // number of lines to adjust the yoffset for the next step designator we are adding to TopMessageRs
string rtxt = "";
int istr = 0;
int Rsidx = 0;
MyPageHelper.TopMessageRs.Add(vpo as vlnText); // this appends a previous step designator associated with this sub-step (there may be more than one and/or might have multiple lines)
// we are processing the step designator on the top continue message in reverse order
// we therefore need to adjust the y location of multiple step designors attached tothe top continue message
if (MyPageHelper.TopMessageRs.Count > 3)
{
Rsidx = MyPageHelper.TopMessageRs.Count - 1;
rtxt = MyPageHelper.TopMessageRs[Rsidx].Text;
// find the number of lines to shift existing TopMessageRs step designators down
istr = rtxt.IndexOf("\\line", 0);
while (istr != -1)
{
nlcnt++;
istr = rtxt.IndexOf("\\line", istr + 1);
}
// move the previous TopMessageRs step designators down
Rsidx -= 2; // index to the previous step desginator
while (Rsidx > 0)
{
MyPageHelper.TopMessageRs[Rsidx].YOffset -= (nlcnt * SixLinesPerInch);
Rsidx -= 2;// every other TopMessageRs is a step designator
}
}
// for Comanche Peak - if step breaks on a sub-step, and both the high level step and the sub-step have a step designator
// then since the high level step and its step designator are printed as part of the top continue message,
// move the step designator associated with the sub-step down so that it does not print on top of the
// ones in the top continue message.
if (this.PartsLeft.Count > 1) // was a step designator printed for the sub-step?
{
// count the number of lines in the step designator text in the top continue message
nlcnt = 0; // reset for the number of lines to push the sub-step's step designator down
Rsidx = MyPageHelper.TopMessageRs.Count - 1; // note that TopMessageRs[0] is a tab not a step designator
while (Rsidx > 0)
{
nlcnt++;
rtxt = MyPageHelper.TopMessageRs[Rsidx].Text;
istr = rtxt.IndexOf("\\line", 0);
while (istr != -1)
{
nlcnt++;
istr = rtxt.IndexOf("\\line", istr + 1);
}
Rsidx -= 2; // every other TopMessageRs is a step designator
}
if (nlcnt > 0)
{
for (int idx = 1; idx < this.PartsLeft.Count; idx++)
{
vlnPrintObject vpol = this.PartsLeft[idx];
vpol.YOffset += (nlcnt * SixLinesPerInch); // move the existing step designator down
}
}
}
}
}
}
return false;
}
string myMsg = docstyle.Continue.Top.Message;
MyPageHelper.TopMessageRs = new List<vlnText>();
// bug fix B2106-099
// when there are more than one Caution/Note off of a high level background step,
// the second, third, etc background Caution/Note pages begin printing two additional lines from the top of the page
// to fix, added a check to see the the item we are printing has the PageBrrakOnStep flag set, if it's set,
// then DON'T add two lines to the yPageStart (for the top conitnue message)
if (myMsg != null && myMsg != "" && !MyItemInfo.IsSection && !MyItemInfo.FormatStepData.PageBreakOnStep) // B2020-123
{
// C2019-044 for BNPP put the top continue message on the same row as the Checkoff/Signoff header
// This is done by specifing a row positon in the top continue definition in the format.
// If the top continue messsage RowOverride is being used, don't move the yPageStart down (don't need to make room for it)
if (docstyle.Continue.Top.RowOverride == null)
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);
}
// B2020-154: Incorrect top continue message tab in RNO column if for single level substep with a Caution/Note
else if ((MyItemInfo.IsNote || MyItemInfo.IsCaution) && MyItemInfo.MyParent.MyParent.IsRNOPart)
{
if (DebugPagination.IsOpen) DebugPagination.WriteLine("***===>,'Yes','Case 1:Changed RNO Continue Message',{0},{1},,{3},'{4}'", MyItemInfo.ItemID, YSize, 0, 0, this);
ItemInfo ip = MyItemInfo.MyParent;
while (!ip.IsRNOPart) ip = ip.MyParent;
myMsg = myMsg.Replace(@"%sR", ip.CombinedTab);
}
// B2020-154: Incorrect top continue message tab in RNO column for substep with a Caution/Note within parent substeps
else if ((MyItemInfo.IsNote || MyItemInfo.IsCaution) && MyItemInfo.MyParent.MyParent.IsInRNO)
{
if (DebugPagination.IsOpen) DebugPagination.WriteLine("***===>,'Yes','Case 2:Changed RNO Continue Message',{0},{1},,{3},'{4}'", MyItemInfo.ItemID, YSize, 0, 0, this);
myMsg = myMsg.Replace(@"%sR", MyItemInfo.MyParent.MyParent.CombinedTab);
}
else
myMsg = myMsg.Replace(@"%sR", MyItemInfo.MyParent.CombinedTab);
float xor = MyTopRNO.MyTab.XOffset;
MyPageHelper.TopMessageRs.Add(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
{
// F2020-023: tab includes parent tab and if caution/note don't use its parent, go up another level
string noBullet = MyItemInfo.IsCautionOrNotePart ? MyItemInfo.MyParent.MyParent.CombinedTab : MyItemInfo.MyParent.CombinedTab;
// C2021-024: WCN1 if bullet exists in combined tab, stop right before bullet.
// B2021-085 & 087: crash if noBullet was null. Also, if null, see if text in parent. if no text, replace the
// "%s." with noBullet (null) which won't put out just a '.' as step number.
if (docstyle.Continue.Top.RemoveBullet)
{
if (noBullet == null && MyItemInfo.IsCautionOrNotePart) noBullet = MyItemInfo.MyParent.CombinedTab;
if (noBullet != null)
{
int ind = noBullet.IndexOf(".o");
if (ind < 0) ind = noBullet.IndexOf(".*");
if (ind > -1) noBullet = noBullet.Substring(0, ind);
}
else
{
myMsg = myMsg.Replace(@"%s.", noBullet);
}
}
myMsg = myMsg.Replace(@"%s", noBullet);
}
}
if (myMsg.IndexOf(@"%3d") > -1)
myMsg = myMsg.Replace(@"%3d", MyItemInfo.MyHLS.Ordinal.ToString());
if (myMsg.IndexOf(@"%2d") > -1)
myMsg = myMsg.Replace(@"%2d", MyItemInfo.MyHLS.MyTab.CleanTextNoSymbols.Trim(" .".ToCharArray()).PadLeft(2));
if (myMsg.IndexOf(@"%d") > -1)
myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanTextNoSymbols.Trim(" .".ToCharArray()));
if (myMsg.IndexOf(@"%c") > -1)
myMsg = myMsg.Replace(@"%c", " ");
// Top Continue message includes high level step tab and text
if ((docstyle.Continue.Top.HLS ?? 0) == 1)
{
myMsg = docstyle.Continue.Top.Message; // reset because we did replace strings in code above
ItemInfo parentStep = MyItemInfo.MyHLS; // get the high level step
myMsg = string.Format(myMsg, parentStep.CombinedTab, parentStep.DisplayTextKeepSpecialChars);
}
// B2023-115 Top continue message for Vogtle Alarms: 1st version done on 12/6/23. Changes to logic as per request
// from engineering done on 12/12/23. See comment below for logic for 12/12/23 (history of this file has previous
// logic)
if ((docstyle.Continue.Top.HLS ?? 0) == 4)
{
// Vogtle Alarms: Their alarms are set up differently than standard procedures - the HLS in Vogtle
// alarms is a section in other procedures. The top continue message is shown when a break occurs:
// • A continued message will appear on the top of the page ONLY if the pagination occurs anywhere
// within the first level substep. If, for example, the page break occurs between substep 3 and substep
// 4 as in example 2, no continued message will appear on the top of the page.
// • If a continued message is needed, the continued message will include the first level substep number
// if it is a sequential substep, such as “5. (continued)”. If it is NOT a sequential substep, then only
// the word “(continued)” will appear.
// • If a page break occurs between high level steps, such as before “Causes:”, then no continued message is needed.
bool doMessage = true;
if (MyItemInfo.IsHigh) doMessage = false; // at high, don't do message
if (MyItemInfo.MyParent.IsHigh) doMessage = false; // at first level, don't do message
// Caution/Note on first level, don't do message
if ((MyItemInfo.IsCaution || MyItemInfo.IsNote) && MyItemInfo.MyParent.MyParent.IsHigh) doMessage = false;
myMsg = docstyle.Continue.Top.Message;
if (doMessage)
{
// Get to highest level below HLS
ItemInfo cur = MyItemInfo;
while (!cur.MyParent.IsHigh) cur = cur.MyParent;
// if sequential, add on step number, otherwise just put out message:
myMsg = !cur.IsSequential ? myMsg : cur.CombinedTab + ". " + myMsg;
}
else // if not doing message, clear it & set yPageStart back to what it was before handling message
{
myMsg = "";
yPageStart += 2 * SixLinesPerInch;
}
}
// B2021-138: Top continue message for Barakah Single column New (2021) format was incorrect for some lower
// sub-steps.
if ((docstyle.Continue.Top.HLS ?? 0) == 6)
{
myMsg = docstyle.Continue.Top.Message; // reset because we did replace strings in code above
ItemInfo parentStep = MyItemInfo.MyHLS;
string ctab = parentStep.CombinedTab;
if (!MyItemInfo.MyParent.IsHigh) // If lower sub-step, get parent substep tab, skipping caution/note if in one of those
ctab = (MyItemInfo.IsInCautionOrNote) ? MyItemInfo.MyParent.MyParent.CombinedTab : MyItemInfo.MyParent.CombinedTab;
myMsg = string.Format(myMsg, ctab, parentStep.DisplayTextKeepSpecialChars);
}
// Calvert Alarms, step description have the alarm number as part of the top continue message
// Also, if the break is within the CONDITION/RESPONSE, there are continue messages in both columns at the top
// of the table, note that the continue messages WITHIN table are only printed when the
// steplevel is greater than 2 - this is from 16bit.
// NOTE THAT this code is not complete - the positioning & addition of step tab for within table are not working correctly
if ((docstyle.Continue.Top.HLS ?? 0) == 3)
{
MyPageHelper.TopMessageSub1s = new List<vlnText>();
MyPageHelper.TopMessageSub2s = new List<vlnText>();
//string HLSTabTextForContMsg = MyHighLevelParagraph.MyItemInfo.MyTab.CleanText + " " + MyHighLevelParagraph.MyItemInfo.MyContent.Text;
//int len = (HLSTabTextForContMsg.Length - 10) * 6;
string tabText = @"\ul\b " + MyHighLevelParagraph.MyItemInfo.MyTab.CleanText.Trim() + @"\b0\ulnone";
// B2017-185: added the replace of unicode dash to regular dash for the continue message so it matches the step text:
string stepText = @"\b " + MyHighLevelParagraph.MyItemInfo.MyContent.Text.Replace(@"\u8209?", "-") + @"\b0";
//HLSTabTextForContMsg = @"\ul\b " + MyHighLevelParagraph.MyItemInfo.MyTab.CleanText.Trim() + @"\b0\ulnone \b " + MyHighLevelParagraph.MyItemInfo.MyContent.Text + @"\b0";
vlnText vt1 = new vlnText(cb, this, tabText, tabText, MyHighLevelParagraph.MyTab.XOffset, yTopMargin + 0.1F, docstyle.Continue.Top.Font);
vt1.Width = MyHighLevelParagraph.MyTab.Width;
MyPageHelper.TopMessageRs.Add(vt1);
vlnText vt2 = new vlnText(cb, this, stepText, stepText, MyHighLevelParagraph.XOffset, yTopMargin + 0.1F, docstyle.Continue.Top.Font);
vt2.Width = MyHighLevelParagraph.Width;
MyPageHelper.TopMessageRs.Add(vt2);
// the following code is used to print the top continue messages in the Calvert Alarm format
// CONDITION/RESPONSE table. Messages only get printed if the break is on a substep at steplevel > 2.
// see comments within code for what the tab contains, it varies depending on which side
// break occurred & how deep in the step the break occurred.
if (subTab != null && MyItemInfo.StepLevel > 2)
{
bool incond = !MyItemInfo.IsInRNO;
float ybot = yTopMargin + (4 * SixLinesPerInch);
string concatrnoTab = ""; // constructed tab for Response side
string concataerTab = ""; // constructed tab for Condition side
float xoffTab = 0; // position for Response tab
float xoffMsg = 0; // position for Response message
vlnParagraph useAerParaForTab = null; // use this paragraph under Conditions for locating tab & message
if (incond)
{
// If break is in Condition side of table, use Condition tab of parent & no tab for Response side.
// Both sides have the message '(continued)'.
useAerParaForTab = MyParent;
concataerTab = MyParent.MyTab != null ? MyParent.MyTab.Text.TrimEnd() : "";
xoffTab = 0; // no rno tab
xoffMsg = ToInt(MyItemInfo.ActiveFormat.MyStepSectionLayoutData.ColRTable, 1) + (float)MyItemInfo.MyDocStyle.Layout.LeftMargin + ((useAerParaForTab != null && useAerParaForTab.MyTab != null) ? useAerParaForTab.MyTab.Width : 7.2f);
}
else
{
// break occurred in Response side. Use the tabs up to highest RNO concatenated together.
vlnParagraph useRnoParaForTab = MyParent;
vlnParagraph useParaForTab = MyParent;
while (useParaForTab.MyItemInfo.IsInRNO)
{
concatrnoTab = (useParaForTab.MyTab != null ? useParaForTab.MyTab.Text.TrimEnd() : "") + concatrnoTab.Trim();
if (concatrnoTab.Length > 0 && concatrnoTab[0] > '\xff') concatrnoTab = "";
useRnoParaForTab = useParaForTab;
useParaForTab = useParaForTab.MyParent;
}
xoffTab = useRnoParaForTab.MyTab.XOffset;
xoffMsg = useRnoParaForTab.XOffset;
// aer message when rno broke. Need to concatenate up the Condition side also until
// hitting 1st non-sequential, i.e. moves out of Condition/Response table.
useAerParaForTab = useParaForTab; // useParaForTab is 1st found non-Response step, i.e. moved into Condition side of table
while (useParaForTab.MyItemInfo.IsSequential)
{
concataerTab = (useParaForTab.MyTab != null ? useParaForTab.MyTab.Text.TrimEnd() : "") + concataerTab.Trim();
useAerParaForTab = useParaForTab;
useParaForTab = useParaForTab.MyParent;
}
}
// For RNO tab, add a vlntext for tab and one for continue message:
float xoff1 = xoffMsg;
if (!incond)
{
vlnText vtc = new vlnText(cb, this, concatrnoTab, concatrnoTab, xoffTab, ybot, docstyle.Continue.Bottom.Font);
MyPageHelper.TopMessageSub1s.Add(vtc);
Chunk chk = (vtc.IParagraph.Chunks[0]) as Chunk;
if (chk != null)
{
float xoff2 = xoffTab + chk.GetWidthPoint() + 6;
// If the "(continue)" is going to overlap the tab, then move the "Continue)" so that it doesn't overlap.
if (xoff2 > xoff1) xoff1 = xoff2;
}
}
MyPageHelper.TopMessageSub1s.Add(new vlnText(cb, this, myMsg, myMsg, xoff1, ybot, docstyle.Continue.Bottom.Font));
// for aer tab, add a vlntext for tab and one for continue message:
MyPageHelper.TopMessageSub2s.Add(new vlnText(cb, this, concataerTab, concataerTab, useAerParaForTab.MyTab.XOffset, ybot, docstyle.Continue.Bottom.Font));
MyPageHelper.TopMessageSub2s.Add(new vlnText(cb, this, myMsg, myMsg, useAerParaForTab.XOffset, ybot, docstyle.Continue.Bottom.Font));
addExtraLine = true;
}
}
if (!PageBreakOnStep)
{
float colPos = docstyle.Layout.LeftMargin + docstyle.Continue.Top.Margin ?? 0;
if (!docstyle.Continue.Top.PlaceAtLeftMargin) //F2019-033 when true position with respect only to the left margin
colPos += XOffsetBox; //XOffsetbox get set when the tables, figures & equations were beyond the border and needed repositioned
// C2019-044 for BNPP, put the top continue message on the same row as the checkoff/signoff heading
// RowOverride specifies the position of the top continue message
// For BNPP, RowOverride is set to the same row as the checkoff header is set to in the pagelist
if (docstyle.Continue.Top.RowOverride != null)
{
float adjRowPosition = (float)docstyle.Layout.TopMargin - (float)docstyle.Continue.Top.RowOverride;
MyPageHelper.TopMessage = new vlnText(cb, this, myMsg, myMsg, colPos, yTopMargin + 0.1F + adjRowPosition, docstyle.Continue.Top.Font);// MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
}
else
MyPageHelper.TopMessage = new vlnText(cb, this, myMsg, myMsg, colPos, yTopMargin + 0.1F, docstyle.Continue.Top.Font);// MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
}
else
MyPageHelper.TopMessage = null;
}
return addExtraLine;
}
private void DoBottomContinueMsg(PdfContentByte cb, float yBottomMargin, float yLocation, DocStyle docstyle, bool doThreeContinues)
{
// Console.WriteLine("Page {0} - yLocation {1}", cb.PdfWriter.PageNumber, yLocation);
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.ActiveSection != null && (MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PrintSectOnFirst) == E_DocStructStyle.DSS_PrintSectOnFirst) // C2018-003 fixed use of getting the active section
{
float localYTopMargin = PDFPageSize.PaperSizePoints(MyItemInfo.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize) - (float)MyItemInfo.ActiveSection.MyDocStyle.Layout.TopMargin; // C2020-002 paper size is now set in the format files
yBtmMarginForMsg = Math.Max(0, localYTopMargin - (float)MyItemInfo.ActiveSection.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);
// B2019-079: Account for compression when locating the bottom continue message
if (MyPageHelper.YMultiplier != 1)
{
//float topOfPage = PDFPageSize.PaperSizePoints(MyItemInfo.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize) - (float)MyItemInfo.MyDocStyle.Layout.TopMargin; // A4 paper logic
float topOfPage = 792 - (float)MyItemInfo.MyDocStyle.Layout.TopMargin;
yLocation = topOfPage - (topOfPage - yLocation) * MyPageHelper.YMultiplier;
}
switch (docstyle.Continue.Bottom.Location)
{
case E_ContBottomLoc.EndOfText: // place continue string at end of text
// msg_yLocation accounts for extra lines in message from docstyle; and BottomContent is the actual
// location of the last line of text on page.
//msg_yLocation = ((float)(MyPageHelper.BottomContent??0) - (SixLinesPerInch * MyPageHelper.YMultiplier)); // B2018-080 null reference check added
// B2019-079 changed yLocaton - msg_yLocation to '+'. The msg_ylocation has an adjustment for adding an extra line by moving down the page, this was moving
// the line up the page (double negative).
msg_yLocation = yLocation + msg_yLocation - (SixLinesPerInch * MyPageHelper.YMultiplier); //B2019-021 yLocation accounts for checkoffs
if (yBottomMargin + (docstyle.Layout.FooterLength ?? 0) > msg_yLocation)
{ // Adjusted Continue Message Y Offset
//DebugPagination.WriteLine("====>> {0},'{1}'", msg_yLocation, MyItemInfo.ShortPath);
//msg_yLocation = (float) MyPageHelper.BottomContent - SixLinesPerInch; // Account for how low the lowest Item is on the page
float msg_yLocationOld = msg_yLocation = yBottomMargin + (docstyle.Layout.FooterLength ?? 0);
if (MyPageHelper.BottomContent != null)
msg_yLocation = Math.Min(yBottomMargin + (docstyle.Layout.FooterLength ?? 0), (float)MyPageHelper.BottomContent - SixLinesPerInch);// RHM20150525 - Table Scrunch
if (msg_yLocationOld != msg_yLocation)
_MyLog.WarnFormat("Continue Message Moved from {0} to {1} for {2}", msg_yLocationOld, msg_yLocation, this);// RHM20150525 - Table Scrunch
}
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)
msg_yLocation = Math.Max(msg_yLocation, yBottomMargin + SixLinesPerInch);
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;
// if (MyPageHelper.YMultiplier != 1.0F) msg_yLocation = msg_yLocation / MyPageHelper.YMultiplier;
break;
case E_ContBottomLoc.BelowBottom1:
msg_yLocation = msg_yLocation + yBtmMarginForMsg;
break;
case E_ContBottomLoc.BottomWithFooter: // put bottom message AND if in CONDITION/RESPONSE table, in both columns.
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;
// Added for Calvert Alarms: if 'doThreeContinues', continue message at bottom of page
// and a continue message at the bottom of each column.
if (doThreeContinues)
{
float ybot = yLocation;
xoffB = (float)docstyle.Layout.LeftMargin + docstyle.Continue.Bottom.Margin ?? 0;
MyPageHelper.BottomMessageA = new vlnText(cb, this, myMsg, myMsg, xoffB, ybot, docstyle.Continue.Bottom.Font);
xoffB = docstyle.Layout.LeftMargin + docstyle.Continue.Bottom.MarginR ?? 0;
MyPageHelper.BottomMessageR = new vlnText(cb, this, myMsg, myMsg, xoffB, ybot, docstyle.Continue.Bottom.Font);
MyPageHelper.AlarmYoffEnd -= SixLinesPerInch;
float tmp = (((float)docstyle.Layout.PageWidth - (float)docstyle.Layout.LeftMargin) / 2) - (myMsg.Length / 2 * 5);
xoffB = (float)docstyle.Layout.LeftMargin + tmp;
}
else if (docstyle.Continue.Bottom.Location == E_ContBottomLoc.BottomWithFooter)
{
float tmp = (((float)docstyle.Layout.PageWidth - (float)docstyle.Layout.LeftMargin) / 2) - (myMsg.Length / 2 * 5);
xoffB = (float)docstyle.Layout.LeftMargin + tmp;
}
else 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 + 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.Clear(); // B2017-207 should be only one continue message - was putting an extra continue message in middle of page for V.S.Summer (ex. AOP set, 900.4 Attachment 12)
MyPageHelper.BottomMessage.Add(new vlnText(cb, this, myMsg, myMsg, xoffB, msg_yLocation, docstyle.Continue.Bottom.Font));
}
}
if (PageBreakOnStep) MyPageHelper.BottomMessage.Clear();
}
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());
// F2020-023: tab includes parent tab and if caution/note don't use its parent, go up another level
if (myMsg.IndexOf(@"%s") > -1) // %s was added for F2020-023
{
string tmp = tb.Trim();
if (!MyItemInfo.MyParent.IsHigh)
{
tmp = MyItemInfo.IsCautionOrNotePart ? MyItemInfo.MyParent.MyParent.CombinedTab : MyItemInfo.MyParent.CombinedTab;
// C2021-024: WCN1 if bullet exists in combined tab, stop right before bullet.
// B2021-085 & 087: crash if noBullet was null. Also, if null, see if text in parent. if no text, replace the
// "%s." with noBullet (null) which won't put out just a '.' as step number.
if (MyItemInfo.MyDocStyle.Continue.Top.RemoveBullet)
{
if (tmp == null && MyItemInfo.IsCautionOrNotePart) tmp = MyItemInfo.MyParent.CombinedTab;
if (tmp != null)
{
int ind = tmp.IndexOf(".o");
if (ind < 0) ind = tmp.IndexOf(".*");
if (ind > -1) tmp = tmp.Substring(0, ind);
}
else
{
myMsg = myMsg.Replace(@"%s.", tmp);
}
}
}
myMsg = myMsg.Replace(@"%s", tmp);
}
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;
if (TopMostChild.PartsContainer != null && TopMostChild.PartsContainer.Count > 0) return false; // B2016-198: not 'EmptyTopMostPart' if there is a box.
foreach (vlnPrintObject po in TopMostChild.PartsAbove)
{
vlnHeader hd = po as vlnHeader;
if (hd == null) return false;
if (hd.Text != "") return false;
}
return true;
}
}
// B2019-115 Locate Bottom Continue Message below AER Table if necesssary
private float _TableBottom = -1;
public float TableBottom
{
get { return _TableBottom; }
set { _TableBottom = value; }
}
private float OutputOtherPageSteps(PdfContentByte cb, float YTopMost, float yPageStart, float yTopMargin, float yBottomMargin)
{
// B2019-115 Locate Bottom Continue Message below AER Table if necessary - Initialize TableBottom to -1
TableBottom = -1;
float retval = YTopMost;
// Find any items remaining in MyPageHelper.MyParagraphs that should be printed on this page.
vlnParagraphs process = new vlnParagraphs(null);
int processed = 0;
foreach (vlnParagraph vPara in MyPageHelper.MyParagraphs.Values)
{
if (!vPara.Processed)
{
if (vPara.MyItemInfo.IsTable && (vPara.YOffset <= YTopMost) && vPara.MyItemInfo.ActiveSection.ColumnMode > 0 && vPara.Height + yBottomMargin < yPageStart - vPara.YOffset) //B2019-120 Byron ELEC-1 step 3 second table was not printing on following page
{
if (this.MyItemInfo.ItemID != vPara.MyItemInfo.ItemID)
{
// B2019-115 Locate Bottom Continue Message below AER Table if necessary
_MyLog.WarnFormat("\r\n=-=-=> Table Print on First Page {0} {1} ColumnMode = {2}", vPara.MyItemInfo.ItemID, vPara.MyItemInfo.ShortPath, vPara.MyItemInfo.ActiveSection.ColumnMode);
process.Add(vPara);
// Console.WriteLine("Table YOffset {0} height {1} Bottom = {2} yPageStart = {3} Bottom {4}", vPara.YOffset, vPara.Height, vPara.YOffset + vPara.Height - yPageStart, yPageStart, this.YBottom);
}
}
else if (((vPara.YOffset + vPara.Height) < YTopMost))
{
// B2019-028: Added check for active section in next line so that following section text doesn't overlap or start too far down on page for case where there is a subsection
// with subsections of type Step/Word/Step
//if (vPara.MyItemInfo.ActiveSection.ItemID == this.MyItemInfo.ActiveSection.ItemID && (this.MyItemInfo.ItemID != vPara.MyItemInfo.ItemID)) // 20150701 Complicated RNO change
if (this.MyItemInfo.ItemID != vPara.MyItemInfo.ItemID)
{
// B2019-077: 2.0 SCOPE empty section not printing for WES (revert to previous code line versus above)
process.Add(vPara);
}
else // 20150701 Complicated RNO change
_MyLog.WarnFormat("Less Than: Step Could Have Fit {0}, {1}", MyItemInfo.ItemID, MyItemInfo.ShortPath);
}
else if (((vPara.YOffset + vPara.Height) == YTopMost))
{
// B2019-028: see above comment (same check was added)
//if (vPara.MyItemInfo.ActiveSection.ItemID == this.MyItemInfo.ActiveSection.ItemID && (this.MyItemInfo.ItemID != vPara.MyItemInfo.ItemID)) // RHM20150507 Table Scrunch
if (this.MyItemInfo.ItemID != vPara.MyItemInfo.ItemID) // B2019-077: see above
{
process.Add(vPara);
_MyLog.WarnFormat("New AerRno PageBreak Logic: Step Could Have Fit {0}, {1}", MyItemInfo.ItemID, MyItemInfo.ShortPath);
}
else // RHM20150507 Table Scrunch
_MyLog.WarnFormat("Equal: Step Could Have Fit {0}, {1}", MyItemInfo.ItemID, MyItemInfo.ShortPath);
}
else if (((vPara.YOffset) < YTopMost))
{
retval = Math.Min(retval, vPara.YTopMost);
}
}
else
processed++;
}
//Console.WriteLine("~~~ {0} has {1} Steps {2} Processed {3} to Process", MyItemInfo.ShortPath, MyPageHelper.MyParagraphs.Count
// , processed,process.Count);
foreach (vlnParagraph vPara in process)
{
vPara.ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
// B2019-115 Locate Bottom Continue Message below AER Table if necessary
if (vPara.MyItemInfo.IsTable)
{
if (TableBottom == -1)
TableBottom = (yPageStart - vPara.YOffset) - vPara.Height - SixLinesPerInch;
else
TableBottom = Math.Min(TableBottom, (yPageStart - vPara.YOffset) - vPara.Height - SixLinesPerInch);
}
}
return retval;
}
private float _YVeryTop = -1;
public float YVeryTop
{
get
{
if (_YVeryTop == -1)
{
_YVeryTop = YTop;
_YVeryTop = VeryTop(PartsAbove, _YVeryTop);
_YVeryTop = VeryTop(PartsContainer, _YVeryTop);
}
return _YVeryTop;
}
}
private float VeryTop(vlnPrintObjects parts, float yVeryTop)
{
if (parts != null)
foreach (vlnPrintObject part in parts)
if (part.YOffset < yVeryTop)
yVeryTop = part.YOffset;
return yVeryTop;
}
/// <summary>
/// This gets the height of the step with it's Caution's, Notes and potentially any First Substeps
/// </summary>
/// <returns></returns>
// F2024-006: Vogtle Alarms pagination - added 'includeFirstSub' to get that size of the first substep with the parent step
// to help determine pagination
private float GetFirstPieceSize(bool includeFirstSub = false)
{
vlnParagraph paraLast = GetFirstPieceLastPart(includeFirstSub);
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 float _YBottomForBox = 0;
public float YBottomForBox
{
get { return _YBottomForBox; }
set { _YBottomForBox = value; }
}
// F2024-006: Vogtle Alarms pagination - added 'includeFirstSub' to get that size of the first substep with the parent step
// to help determine pagination - even when PaginateOnFirstSubstep is turned on
private vlnParagraph GetFirstPieceLastPart(bool includeFirstSub = false)
{
vlnParagraph para = this;
if ((!MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PaginateOnFirstSubstep || includeFirstSub) && 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(includeFirstSub);
}
}
if (ChildrenRight != null && ChildrenRight.Count > 0)
{
foreach (vlnParagraph paraRight in ChildrenRight)
{
vlnParagraph paraRightLast = paraRight.GetFirstPieceLastPart(includeFirstSub);
if (paraRightLast.YBottom > para.YBottom)
para = paraRightLast;
}
}
return para;
}
/// <summary>
/// Find items from previous page (yLocation less than yTop) and remove them from the list.
/// yTop is the new starting location on the next page for this step.
/// </summary>
/// <param name="myList"></param>
/// <param name="yTop"></param>
private void RemoveProcessedParagraphs(StepLevelList myList, float yTop)
{
// the two CleanUpLists are used to remove items from
// the original list because list items cannot be removed in a
// 'foreach'.
List<int> CleanupListStepLevel = new List<int>();
foreach (int stepLevel in myList.Keys)
{
List<float> CleanupListYLocation = new List<float>();
SortedList<float, float> AdjustYLocation = new SortedList<float, float>();
foreach (float yLocation in myList[stepLevel].Keys)
{
if (-yLocation <= yTop)
CleanupListYLocation.Add(yLocation);
else
AdjustYLocation.Add(-yLocation, yLocation); // order in ascending order
}
foreach (float yLocation in CleanupListYLocation)
myList[stepLevel].Remove(yLocation);
foreach (float yLocation in AdjustYLocation.Keys)
{
vlnParagraph para = myList[stepLevel][-yLocation];
myList[stepLevel].Remove(-yLocation);
// shift yLocation by yTop to work with items whose locations
// are defined from the top of the new page rather than
// from the beginning of the step.
// Note that yLocation is negative to have items in descending
// order so that adding yTop decrements their values.
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);
}
/// <summary>
/// Builds a list of paragraphs by StepLevel and yLocation in descending order.
/// </summary>
/// <param name="yTopMost"></param>
/// <param name="myList"></param>
private void BuildLocationList(float yTopMost, ParagraphLocations myLocations)
{
foreach (vlnParagraph child in ChildrenAbove)
child.BuildLocationList(yTopMost, myLocations);
foreach (vlnParagraph child in ChildrenLeft)
child.BuildLocationList(yTopMost, myLocations);
// Add a list entry consisting of StepLevel, yoffset from the beginning of this step, paragraph itself
myLocations.Add(this, yTopMost);
foreach (vlnParagraph child in ChildrenRight)
child.BuildLocationList(yTopMost, myLocations);
foreach (vlnParagraph child in ChildrenBelow)
child.BuildLocationList(yTopMost, myLocations);
}
private int COL_WID_ADJ = 6; // adjusts for incorrect use of WidSTable when breaking a line (it breaks 6 chars too short)
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; }
}
private pkParagraph _MyContAct = null;
public pkParagraph MyContAct
{
get { return _MyContAct; }
set { _MyContAct = value; }
}
// F2022-024 Time Critical Action
private pkParagraph _MyTimeCriticalAction = null;
public pkParagraph MyTimeCriticalAction
{
get { return _MyTimeCriticalAction; }
set { _MyTimeCriticalAction = value; }
}
public static bool InList(int id, params int[] ids)
{
foreach (int listid in ids)
if (id == listid) return true;
return false;
}
private bool _PrefixSpecialCharacter = false;
public bool PrefixSpecialCharacter
{
get { return _PrefixSpecialCharacter; }
set { _PrefixSpecialCharacter = value; }
}
private string _Prefix;
public string Prefix
{
get { return _Prefix; }
set { _Prefix = value; }
}
private string _Suffix;
public string Suffix
{
get { return _Suffix; }
set { _Suffix = value; }
}
private float RoughSizeOfPage
{
get
{
return (float)(MyItemInfo.MyDocStyle.Layout.PageLength /*- MyItemInfo.MyDocStyle.Layout.TopMargin*/ - MyItemInfo.MyDocStyle.Layout.FooterLength);
}
}
private PromsPrinter _MyPromsPrinter;
public PromsPrinter MyPromsPrinter
{
get { return _MyPromsPrinter; }
set { _MyPromsPrinter = value; }
}
public static float _yPageStartForSupInfo = 0;
public vlnParagraph(vlnParagraph parent, PdfContentByte cb, ItemInfo itemInfo, float xoff, float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo, string prefix, string suffix, float yoffRightParent, bool loadChildren, PromsPrinter pp)
{
MyPromsPrinter = pp ?? parent.MyPromsPrinter;
int profileDepth = ProfileTimer.Push(">>>> vlnParagraph");
Prefix = prefix;
Suffix = suffix;
MyItemInfo = itemInfo;
MyContentByte = cb;
if (itemInfo.IsFootnote && loadChildren)
{
// notestofootnoteshls is a list, a hls can have more than one note
if (MyPageHelper.NotesToFootNotesHLS.ContainsKey(itemInfo.MyHLS.ItemID))
MyPageHelper.NotesToFootNotesHLS[itemInfo.MyHLS.ItemID].Add(itemInfo.ItemID);
else
{
List<int> notesList = new List<int>();
notesList.Add(itemInfo.ItemID);
MyPageHelper.NotesToFootNotesHLS.Add(itemInfo.MyHLS.ItemID, notesList);
}
Processed = true; // don't want to print during normal ToPdf/ParagraphToPdf cycle - print in vlnsvgpagehelper
ProfileTimer.Pop(profileDepth);
return;
}
// do some 'setup' for Calvert Alarms:
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
// The CONDITION/RESPONSE portion of the alarm uses a macro to print the 'table' heading,
// i.e. the lines/boxes and text for CONDITION and RESPONSE. This does not have a tab,
// tabs are where the macros are usually stored, so flag this for future reference.
// The 2nd if is executed when the step is at the same y offset as the parent, i.e. DEVICE & SETPOINT text.
if (itemInfo.TemplateIndex > 0 && itemInfo.ActiveFormat.PlantFormat.FormatData.Templates[itemInfo.TemplateIndex].hmacro > 0)
HasCalvertMacro = true;
if (KeepOnParentLine(itemInfo)) yoff = parent.YOffset;
}
float yOffOrig = yoff;
// Save step text information to be used to create a PlaceKeeper (Calver Cliffs)
BuildPlacekeeper(parent, itemInfo);
// Save step text information to be used to create a Continuous Action Summary
BuildContinuousActionSummary(parent, itemInfo);
// F2022-024 Time Critical Step
// Save step text information to be used to create a Time Critical Action Summary
BuildTimeCriticalActionSummary(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("<NO TITLE>") && !itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.PrintNoTitle) ShowSectionTitles = false;
HasIndent = itemInfo.IsStep && itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.DontResetIndentOnNewline;
int MetaLevel = 0; // if meta section, stores what level this section is.
float savCheckListBottomMost = 0;
//int[] problemIDs = { 889 };
//List<int> lProblemIDs = new List<int>(problemIDs);
//if (lProblemIDs.Contains(itemInfo.ItemID))
// Console.WriteLine("Found Item {0}", itemInfo.ItemID);formatInfochecko
MyParent = parent;
// The following code determines the last paragraph for an RNO
// MyTopRNO finds the Top paragraph for an RNO
if (itemInfo.IsInRNO)
{
if (rnoLevel <= maxRNO && itemInfo.IsRNOPart) // Not top level RNO
MyTopRNO = this;
else
MyTopRNO = MyParent.MyTopRNO;
if (MyTopRNO != null) MyTopRNO.LastRNO = this;
}
if (!MyPageHelper.MyParagraphs.ContainsKey(itemInfo.ItemID) && !itemInfo.IsFootnote)
{
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 && MyItemInfo.MyContent.MyEntry != null)
{
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;
ProfileTimer.Pop(profileDepth);
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.IsBackgroundStep()) ? (itemInfo.FormatStepData.TabData.IdentPrint.Length - 1) * 6 : 0; // B2018-139 don't adjust XOffset when processing a Caution, or Note background text is is off of Caution or Note WCN BG SAG-10 step 4
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.IsFootnote) itemInfo.MyTab = null;
if (itemInfo.IsSupInfoPart) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
//if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && itemInfo.MyTab.Text != "")
// bug fix - if the section does not have a section number, then we need to build an empty tab for the itemInfo
// so that we place the section title in the correct location. so we need to go into this IF code block
// even if itemInfo has a MyTab that is an empty string when itemInfo is a section - 2/11/2015
if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && (itemInfo.MyTab.Text != "" || itemInfo.IsSection))
{
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 printing the supplemental info facing page, don't put out the section title. ToPdf will put out 'Supplemental Information' title.
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge && MyPageHelper.CreatingSupInfoPage && itemInfo.IsSection) doprint = false;
if (doprint && itemInfo.IsSection && !itemInfo.MyDocStyle.CancelSectTitle && (itemInfo.MyConfig as SectionConfig).Section_IsFoldout != "Y") //C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
{
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;
}
if (formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
{
if (MetaLevel == 1)
offset += (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos;
else
{
SectionConfig sc = itemInfo.MyParent.MyConfig as SectionConfig;
if (MyParent != null)
{
// if the parent is not printed, then adjust the xoffset based on
// the level of the metasection. Note that the 'if (MetaLevel==20) MetaLevel = 1'
// line of code was added so that the xoffsets between 16 & 32 bit are closer.
// This code was added to fix problems in BGE OI34, Appendix sections/subsection xoffsets.
if (sc != null && sc.Section_PrintHdr == "N")
{
if (MetaLevel == 2) MetaLevel = 1;
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;
}
else
{
offset = (sc != null && sc.SubSection_AutoIndent == "Y") ? MyParent.XOffset
: (MyParent.MyTab != null) ? MyParent.MyTab.XOffset : XOffset;
}
}
}
}
else
{
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());
if (((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_SameXOffSubsections) == E_DocStructStyle.DSS_SameXOffSubsections))
offset += (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos;
}
}
}
localXOffset = offset;
}
}
if (!itemInfo.IsSection || doSectTab)
{
if (itemInfo.IsSupInfoPart) // get combined tab if on a supinfo facing page:
mytab = GetSupInfoTab(cb, itemInfo, yoff, mytab, doSectTab, localXOffset);
else 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);
}
}
else if (itemInfo.IsSupInfoPart) // if it was an empty tab - it may have been a caution/note
{
mytab = GetSupInfoTab(cb, itemInfo, yoff, mytab, doSectTab, XOffset);
PartsLeft.Add(mytab);
}
// 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);
// Used in Ginna's Attachment format.
// if the Note/Caution is off of a sub-step, then adjust the width so that the Caution/Note text box does not extend past the HLS text box
if (itemInfo.IsCautionOrNotePart && maxRNO == 0 && (itemInfo.ActiveSection != null && itemInfo.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.LimitCautionNoteWidthToHLS)) // C2018-003 fixed use of getting the active section
{
float wMax = MyHighLevelParagraph.Width + MyHighLevelParagraph.XOffset - XOffset;
if (wMax < Width && (Width + XOffset > MyItemInfo.MyDocStyle.Layout.PageWidth)) Width = wMax;
}
}
if (itemInfo.IsSection && MyParent == null && itemInfo.MyDocStyle.SupplementalInformation && MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge)
{
_SupInfoSection = new vlnParagraph(this, cb, itemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo, null, null, yoffRightParent, false, pp);
MyPromsPrinter.SupInfoPdfPageCount = -1;
}
// For Calvert Alarms: if within the CONDITION/RESPONSE table, indent by 1 character.
// Sequential substeps are ok because of the tab string, but items without a tab & other step
// types were writing over the CONDITION/RESPONSE vertical table line. This code uses
// 7.2 for the character size to match 16bit output.
if (itemInfo.IsStep && !itemInfo.IsSequential && !itemInfo.IsCaution && !itemInfo.IsNote && MyParent.HasCalvertMacro)
{
XOffset += 7.2f;
if (mytab != null) mytab.XOffset += 7.2f;
}
if ((itemInfo.IsCaution || (itemInfo.IsNote && !itemInfo.IsFootnote)) && (itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)
{
if (itemInfo.IsInRNO)
{
XOffset = MyTopRNO.MyTab != null ? MyTopRNO.MyTab.XOffset : MyTopRNO.XOffset;
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - XOffset - 10;
}
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))
{
float txoff = GetWidthOrStartFromTemplate(itemInfo, itemInfo.ActiveFormat, false);
if (txoff > 0) XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + txoff; // 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 (DoSubs && itemInfo.Cautions != null && (!itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm || itemInfo.Cautions[0].FormatStepData.Type != "Caution1") && !(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;
if (loadChildren) yoffLeft = ChildrenLeft.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
}
else
{
if (yoffRightParent > yoff && ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) != E_DocStructStyle.DoubleBoxHLS)) yoff = yoffRightParent;
if (loadChildren) yoff = ChildrenAbove.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
}
}
if (DoSubs && 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);
if (loadChildren) 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 && ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) != E_DocStructStyle.DoubleBoxHLS)) yoff = yoffRightParent;
if (loadChildren)
{
float yoffadj = 0;
if (itemInfo.IsTable && MyFlexGrid.BorderStyle == C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None && !MyFlexGrid.TopRowHasBorder())
yoffadj = SixLinesPerInch; // adjust the yoffset if the note is off of a borderless table
yoff = ChildrenAbove.Add(cb, itemInfo.Notes, xoff, yoff + yoffadj, yoff + yoffadj, rnoLevel, maxRNO, formatInfo) - yoffadj;
}
}
}
if (itemInfo is StepInfo && ((itemInfo as StepInfo).MyConfig as StepConfig).Step_PreferredPagebreak) HasPrefPageBreak = true;
// The following adds supplemental information items to the SupInfoSection list off of the section level paragraph for printing
// of the sup info pdf. The SupInfoSection list is just a flat list of all supplemental information within the section.
if (MyPromsPrinter.SupInfoPrintType == E_SupInfoPrintType.Merge && loadChildren && itemInfo.SupInfos != null)
{
SupInfoSection.ChildrenBelow.Add(cb, itemInfo.SupInfos, XOffset, 0, 0, rnoLevel, maxRNO, formatInfo);
}
// Without the following, BGE had gaps in y-direction if the AER/RNO both had cautions/notes.
// The only time this needs done is if caution/notes are printed in separate columns in dual
// column mode (used the DoubleBoxHLS BGE flag for this - if another plant needs this, make it
// a more generic flag).
if (itemInfo.IsRNOPart && ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS) &&
rnoLevel == maxRNO && ChildrenAbove.Count > 0 && MyParent.ChildrenAbove.Count > 0)
{
float yDeltaRno = yoff - yOffOrig;
float yDeltaAer = SixLinesPerInch + yOffOrig - MyParent.ChildrenAbove[0].YTopMost;
if (yDeltaRno > yDeltaAer)
{
foreach (vlnParagraph chlda in MyParent.ChildrenAbove)
{
chlda.AdjustYOffset(yDeltaAer - yDeltaRno);
}
foreach (vlnParagraph chld in ChildrenAbove)
chld.AdjustYOffset(yDeltaAer);
yoff -= yDeltaAer;
}
else
{
foreach (vlnParagraph chld in ChildrenAbove)
chld.AdjustYOffset(yDeltaRno);
yoff -= yDeltaRno;
}
}
// 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;
}
DoAnnotationPrintableText(cb, itemInfo, yoff); // Look in annotation type to see if annotation has text that should be printed (like a step designator)
// 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 (MyItemInfo.MyParent != null && MyItemInfo.MyParent.FormatStepData != null)
addExtraSpace = (MyItemInfo.MyParent.FormatStepData.Type == "TitleWithTextRight" || 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;
// F2021-038: SHE/SHEA format - Less space after boxes
if (itemInfo.Cautions != null && itemInfo.Cautions[itemInfo.Cautions.Count - 1].FormatStepData.NoYBxAdjust)
addExtraSpace = 0;
if (itemInfo.Notes != null && itemInfo.Notes[itemInfo.Notes.Count - 1].FormatStepData.NoYBxAdjust)
addExtraSpace = 0;
}
// F2021-038: SHE/SHEA format - Less space after boxes. The following is for when a HLS has an RNO that has Cautions/Notes
if (itemInfo.IsHigh && itemInfo.RNOs != null)
{
if (itemInfo.RNOs[0].Notes != null && itemInfo.RNOs[0].Notes[0].FormatStepData.NoYBxAdjust)
addExtraSpace = 0;
if (itemInfo.RNOs[0].Cautions != null && itemInfo.RNOs[0].Cautions[0].FormatStepData.NoYBxAdjust)
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.SpaceDouble && itemInfo.MyParent.IsHigh)
{
// but it we are in single column mode, don't remove the blank line. (Wolf Creek Admin Instructions - wcn1)
if (itemInfo.ActiveSection != null && (itemInfo.ActiveSection as SectionInfo).SectionConfig.Section_ColumnMode != SectionConfig.SectionColumnMode.One) // C2018-003 fixed use of getting the active section
yoff = YOffset = yoff - SixLinesPerInch;
}
else if (itemInfo.FormatStepData.NoSpaceMultipleRNOs) yoff = YOffset = yoff - SixLinesPerInch;
if (itemInfo.FormatStepData.DoubleSpace && itemInfo.FormatStepData.SpaceDouble) 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);
CheckOff co = itemInfo.GetCheckOffStep();
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
|| (co != null && co.DropCheckOff);
if (itemInfo.MyContent.MyGrid != null)
{
vlnCells.DefaultFont = itemInfo.FormatStepData.Font.WindowsFont;// Set the default text font based upon the format
int profileDepth1 = ProfileTimer.Push(">>>> Before vlnParagraph.Grid");
//Use Static MyFlexGrid - BWD INST2 - FlexGrid Errors
MyFlexGrid.LoadGrid(itemInfo);
MyGrid = new vlnTable(MyFlexGrid, cb);
Height = MyGrid.Height;
Width = MyGrid.Width;
// Adjust the XOffset before determining if the table will overlap the RNO column RHM 20150529
CalculateXOffsetGridOrFigure(itemInfo, maxRNO, formatInfo);
yoff = AdjustLocIfLongerRNO(itemInfo, yoff, yoffRightParent);
// 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));
yoff = (float)Math.Ceiling(yoff);
ProfileTimer.Pop(profileDepth1);
}
else if (itemInfo.IsRtfRaw)
{
CalculateXOffsetGridOrFigure(itemInfo, maxRNO, formatInfo);
YOffset = yoff;
yoff += Height * .6f; // .6 is used as a scale factor in RtfRawAt (rtf2pdf). Use it here too for moving down page after equation.
yoff = (float)Math.Ceiling(yoff);
yoff += AdjustForBlankLines();
}
else if (itemInfo.IsFigure) // if a figure we've got to determine the size:
{
int profileDepth2 = ProfileTimer.Push(">>>> Before vlnParagraph.Figure");
string erMsg = null;
if (itemInfo.MyContent.Text != null) // ro image
{
if (itemInfo.MyContent.Text != "") // also check for text, there is an RO image then:
{
ProcedureInfo proc = itemInfo.MyProcedure;
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]*):(.*)");
string val = null;
if (m.Length > 0) // if m.lengh is zero, then no match was found - no RO was entered in the figure substep
{
if (m.Groups.Count < 4)
{
//erMsg = "RO was not found during data migration.";
// added newlines in the RO number (shown in figure substep type with figure RO)
// if we are here, then there is no RO link information, use this number to find the RO image to print
val = string.Format("{0}\n{1}\n{2}\n{3}",
linkInfoText.Substring(0, linkInfoText.Length - 16),
linkInfoText.Substring(linkInfoText.Length - 16, 8),
linkInfoText.Substring(linkInfoText.Length - 8, 4),
linkInfoText.Substring(linkInfoText.Length - 4, 4));
val = val.Replace(@"\u8209?", "-").Replace(@"\u9586?", @"\"); // replace dash and backslash symbols with dash and backslash characters
}
else
{
string[] subs = m.Groups[3].Value.Split(" ".ToCharArray());
// B2022-088: Find Doc Ro button not working in Word Sections
val = lookup.GetRoChild(subs[1]).value;
if (val == null || val == "?") val = lookup.GetRoChild(subs[1].Substring(0, 12)).value;
if (val == "?")
{
erMsg = string.Format("Referenced Object does not exist.");
_MyLog.WarnFormat("\r\nMissing Referenced Object {0} in {1}", subs[1], itemInfo.ShortPath);
yoff += 2 * SixLinesPerInch;
}
}
}
GC.Collect(); // memory garbage collection (Regex memory bug)
if (val != null && val != "?")
{
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);
// Check that the Height of figure isn't too big to fit on the page, if it is
// set the Height to the printable part of page - Height of the HLS and an extra line
// for between HLS & figure.
float h1 = lines * SixLinesPerInch;
float h2 = RoughSizeOfPage - MyParent.Height - SixLinesPerInch;
Height = Math.Min(h1, h2);
if (h1 > h2)
{
Width *= (h2 / h1);
}
StepConfig sc = new StepConfig(MyItemInfo as StepInfo);
if (sc != null && sc.Step_ImageWidth != 0)
{
Width = sc.Step_ImageWidth;
Height = sc.Step_ImageHeight;
}
yoff = AdjustLocIfLongerRNO(itemInfo, yoff, yoffRightParent);
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
{
roImage = rofst.GetROImageByFilename(vals[0], MyItemInfo);// need code to go and get an ROImaage if it exists
if (roImage == null)
erMsg = string.Format("Image {0} does not exist.", vals[0]);
else
ImageText = val;
}
}
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
{
// figure
ImageText = "figure";
}
if (ImageText == null && erMsg == null)
{
ImageText = "figure";
ImageConfig ic = new ImageConfig(MyItemInfo.MyContent.MyImage);
// B2016-277: add a try catch in case of there being 'bad' data in the text field for an image/figure
try
{
byte[] idata = (ic != null && ic.Image_DataSize > 0) ? ROImageInfo.Decompress(MyItemInfo.MyContent.MyImage.Data, ic.Image_DataSize) : MyItemInfo.MyContent.MyImage.Data;
MemoryStream ms = new MemoryStream(idata);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
Width = img.Width;
Height = img.Height;
if (ic != null && ic.Image_Height != 0)
{
Width = ic.Image_Width;
Height = ic.Image_Height;
// B2022-041: extra whitespace after resized image. Make same adjustment here that gets made in ParagrphToPdf
// B2023-040: WCN pagination changed for And steps with large image after - add format flag for
// Barakah
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.AdjustLargeImage)
{
float mult = 1.0F;
if (Width > (vlnParagraph.wMax - 12)) mult = (vlnParagraph.wMax - 24) / Width;
if (Height > (vlnParagraph.hMax - 36)) mult = Math.Min(mult, (vlnParagraph.hMax - 36) / Height);
if (mult < 1.0F)
{
Width = Width * mult;
Height = Height * mult;
}
}
}
yoff = AdjustLocIfLongerRNO(itemInfo, yoff, yoffRightParent);
bool noborder = MyItemInfo.FormatStepData.Type.ToUpper().Contains("BORDERLESS");
yoff += (Height + SixLinesPerInch); // B2019-059 only one extra line after a figure (does not matter if it has a border or not)
CalculateXOffsetGridOrFigure(itemInfo, maxRNO, formatInfo);
}
catch (Exception ex)
{
_MyLog.WarnFormat("Bad figure content data: item = {0}, {1}", MyItemInfo.ItemID, MyItemInfo.ShortPath);
}
}
ProfileTimer.Pop(profileDepth2);
}
else
{
// For Calvert Alarms, the 'CONDITION/RESPONSE' portion uses a macro to print
// the CONDITION and RESPONSE text with the lines around it. Add the macro here because
// there is no tab for the step & that's where the macro is usually stored:
if (HasCalvertMacro) PartsLeft.Add(new vlnMacro(xoff - 12f, yoff, "H4"));
//if (itemInfo.IsSection)
// Rtf = GetRtf(itemInfo, prefix, " (Continued)");
//else
// BuildRtf(); // not necessary, RTF is lazyloaded
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));
yoff += SixLinesPerInch;
YOffset = yoff;
}
}
// 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);
// The following was added for BGE valve lists, this format (BGEVLV) used caution1 as
// a subheader within the valve list. To print correctly, a line needs to be added to
// where the bottom of this (subheader) is located and XOffset is set to the leftmargin.
if (itemInfo.IsStep && itemInfo.MyHLS != null && !itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && itemInfo.IsCaution1 && itemInfo.MyHLS.FormatStepData.UseOldTemplate && itemInfo.MyDocStyle.ComponentList)
{
savCheckListBottomMost += SixLinesPerInch;
yoff += Height;
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
}
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && itemInfo.IsCaution1) savCheckListBottomMost = yoff + Height;
// 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 != null && itemInfo.MyHLS.FormatStepData.UseSmartTemplate
&& ((itemInfo.Steps == null || itemInfo.Steps.Count == 0)
|| !itemInfo.Steps[0].FormatStepData.StepLayoutData.AlignWithParentTab))
|| ((MyItemInfo.IsNote || MyItemInfo.IsCaution) && MyItemInfo.MyParent.IsSection)) // B2016-222 check if is a caution or note and parent is a section
{
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")
if (loadChildren) 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
}
}
}
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
// For Calvert Alarms, the row has formatting that makes this template item have a header & box
// (CONDITION/RESPONSE), header with box around it is defined in genmac whereas the lines around
// substeps are drawn in pagehelper. Adjust some yoffsets around this box.
// Need to:
// 1) move the text down a bit for top line (1.5f * SixLinesPerInch)
// 2) move the substep down 2 lines (2 * SixLinesPerInch) for bottom of box
// and space before substep
// 3) if the previous item had this condition, add space for the
// line below.
if (HasCalvertMacro)
{
YOffset += (1.5f * vlnPrintObject.SixLinesPerInch);
yoff += (2 * vlnPrintObject.SixLinesPerInch);
}
if (itemInfo.MyPrevious != null && itemInfo.MyPrevious.TemplateIndex > 0)
{
if (itemInfo.MyPrevious.ActiveFormat.PlantFormat.FormatData.Templates[itemInfo.MyPrevious.TemplateIndex].hmacro > 0)
{
YOffset += (3 * vlnPrintObject.SixLinesPerInch);
yoff += (3 * vlnPrintObject.SixLinesPerInch);
}
}
}
if (co != null && !MyItemInfo.IsInSupInfo) // C2018-002: don't print checkboxes on supplemental infromation pages.
{
// 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;
}
}
// if there is ucf value for adjusting the alignment for checkoffs, use it:
FormatConfig fc = PlantFormat.GetFormatConfig(formatInfo);
if (fc != null && fc.PlantFormat.FormatData.CheckOffXOffAdj != null)
{
if (co.Index > 99) xloc_co += ((float)fc.PlantFormat.FormatData.CheckOffXOffAdj * 72);
}
// CheckOffXtraLines was introduced for the additional lines needed for the longer signoffs
// for VCBA (&WST1), for F2016-061.
float checkOffNumberOfLines = (co.CheckOffNumberOfLines ?? 0);
if (checkOffNumberOfLines > 0)
{
yForCheckoff += (2 * SixLinesPerInch);
PartsRight.Add(new vlnMacro(xloc_co, yForCheckoff/* + xtraCheckOffLines */, co.Macro));
yoff += ((checkOffNumberOfLines *= SixLinesPerInch) + (2 * SixLinesPerInch));
}
else
{
// if xtraCheckOffLines is a negative number, start the checkoff on the same line
// as text and adjust the y-offset after the checkoff by the amount of the absolute
// value of xtraCheckOffLines.
// if xtraCheckOffLines is a positive number, start the checkoff xtraCheckOffLines - 1
// down from the text and adjust the y-offset after the checkoff by the amount
// of xtraCheckOffLines.
float xtraCheckOffLines = (co.CheckOffXtraLines ?? 0);
if (xtraCheckOffLines < 0)
{
xtraCheckOffLines = -xtraCheckOffLines;
xtraCheckOffLines *= SixLinesPerInch;
PartsRight.Add(new vlnMacro(xloc_co, yForCheckoff/* + xtraCheckOffLines */, co.Macro));
yoff += xtraCheckOffLines;
}
else
{
xtraCheckOffLines *= SixLinesPerInch;
xtraCheckOffLines -= ((xtraCheckOffLines > 0) ? SixLinesPerInch : 0);
PartsRight.Add(new vlnMacro(xloc_co, yForCheckoff + xtraCheckOffLines, co.Macro));
yoff += (xtraCheckOffLines != 0) ? xtraCheckOffLines + SixLinesPerInch : 0;
}
}
}
}
// for WCNTRN, do the responsibility:
if (formatInfo.PlantFormat.FormatData.PrintData.WCNTraining) DoResponsibility(cb, YOffset);
float yOffRight = yoff;
float RnoOffset = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
if (DoSubs && rnoLevel < maxRNO && itemInfo.RNOs != null)
{
if (loadChildren) 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;
//B2020-160 use YTopMost instead of Yoffset if there are children above.
// Get the minimun value between the AER and RNO YtopMost.
// example. Calvert AOP-7E/XIII/Step A5.h Unit 2 Approved set
//B2021-027 use YOffset if there isn't any children above (AER).
// example: Catawba Unit 1 APs; AP/1/A/5500/050; Enclosure 8 step 1
if (ChildrenAbove.Count == 0)
YTopMost = ChildrenRight[0].ChildrenAbove[0].YOffset; //B2021-027
else
YTopMost = Math.Min(ChildrenAbove[0].YTopMost, ChildrenRight[0].ChildrenAbove[0].YTopMost); //B2020-160
}
}
// 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 (DoSubs && 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]);
// B2018-077 added check for caution and note parts in which case we want the blank line - fix for Calvert OI-27B 6.11.B and 6.12.B
if (MyFlexGrid.BorderStyle == C1.Win.C1FlexGrid.Util.BaseControls.BorderStyleEnum.None && !MyFlexGrid.TopRowHasBorder() && !MyItemInfo.IsCautionOrNotePart)
yoffadj = -SixLinesPerInch;
}
// B2023-008: when an equation is off a paragraph sub-step in single column mode, extra lines were added so
// when in single column mode & the substep has an equation (rtfraw), then don't reset yoffright to yverybottom
bool rtfRawInSingleCol = (itemInfo.ColumnMode == ((int)VEPROMS.CSLA.Library.SectionConfig.SectionColumnMode.One - 1)) && (itemInfo.Tables != null && itemInfo.Tables.Count > 0 && itemInfo.Tables[0].IsRtfRaw);
if (yOffRight < yoffRightParent) yOffRight = yoffRightParent;
// find the very bottom Yoffset (don't do this is in single column mode for cautions/notes: B2016-261)
vlnParagraph parentPar = parent;
if (!rtfRawInSingleCol && (!((MyItemInfo.IsCaution || MyItemInfo.IsNote) && itemInfo.RNOLevel == 0)))
{
while (parentPar != null && parentPar.MyItemInfo.IsStep)
{
float vb = parentPar.YVeryBottom;
if (yOffRight < vb) yOffRight = vb;
parentPar = parentPar.MyParent;
}
}
bool rightLonger = yOffRight > yoff;
if (!aerTableOrFigure && itemInfo.RNOLevel == 0) // Centered Table
{
if (loadChildren)
yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, rightLonger ? yOffRight : yoff + yoffadj, yOffRight + yoffadj, rnoLevel, maxRNO, formatInfo);
}
else // AER or RNO Table
if (loadChildren)
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;
}
if (loadChildren) 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;
}
}
// For Calvert Alarms, 'Caution1' was used to implement the Annunciator Window, i.e. is printed
// below the HLS and close to the right margin.
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && itemInfo.Cautions != null && itemInfo.Cautions[0].FormatStepData.Type == "Caution1")
{
if (loadChildren)
yoff = ChildrenBelow.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
savCheckListBottomMost = yoff;
}
if (DoSubs && itemInfo.Steps != null && printsteps)
{
if (itemInfo.FormatStepData == null || itemInfo.FormatStepData.Type != "TitleWithTextRight")
if (rnoBefore)
{
if (loadChildren)
yoff = ChildrenBelow.Add(cb, itemInfo.Steps, MyTab.XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
}
else
if (loadChildren) yoff = ChildrenBelow.Add(cb, itemInfo.Steps, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
}
if (itemInfo.Sections != null)
if (loadChildren)
yoff = ChildrenBelow.Add(cb, itemInfo.Sections, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo, pp);
if (itemInfo.Procedures != null)
if (loadChildren)
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)
if (loadChildren)
yoff = ChildrenBelow.Add(cb, itemInfo.RNOs, XOffset, yoff, yoff, rnoLevel + 1, maxRNO, formatInfo);
YBottomPagination = yoff;// B2019-111 Exclude Right for Pagination
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;
// ip3 has an rno separator and also has asterisk boxes around continous HLS. If
// the hls has RNOs off of it, then the rno separator line is outside of the box. If
// there are RNOs, but not off of HLS, then rno separator line is within the box (this is
// how 16bit proms did this). The following use of yadjSep and YBottomForBox handle that
float yadjSep = (MyItemInfo.MyHLS.FormatStepData.StepLayoutData.STBoxindex != null && MyItemInfo.MyHLS.FormatStepData.StepLayoutData.STBoxindex >= 0 &&
MyItemInfo.MyHLS.RNOs != null && MyItemInfo.MyHLS.RNOs.Count > 0) ? 2 * SixLinesPerInch : 0;
vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff + yadjSep, 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 != null && bottomChild.YBottom > rno.LastRNO.YBottomMost))
bottomChild.PartsBelow.Add(myRnoSep);
else
rno.LastRNO.PartsBelow.Add(myRnoSep);
MyHighLevelParagraph.YBottomForBox = 0;
if (yadjSep > 0)
{
MyHighLevelParagraph.YBottomForBox = yoff; // if hlrno, box before sep
YBottomMostAdjust = SixLinesPerInch; // added for IP3 pagination, the RNO separator is outside asterisk box
}
yoff += (myRnoSep.Height + SixLinesPerInch);
}
// if in WCNTRN (Wolf Creek Training), need to consider the ysize of the Responsibility text when setting
// YBottomMost, i.e. if the Responsibilty has more height (y-direction) compared to the actual step text,
// need to move down on page the height of the responsibility.
if (formatInfo.PlantFormat.FormatData.PrintData.WCNTraining && MyItemInfo.IsHigh)
{
if (PartsLeft.Count > 0 && PartsLeft[0] is vlnText)
{
foreach (vlnText vt in PartsLeft)
yoff = Math.Max(yoff, vt.YOffset + vt.Height);
}
}
YBottomMost = yoff;
if ((MyItemInfo.IsHigh || MyItemInfo.IsCaution1) && MyItemInfo.MyDocStyle.LandscapePageList && MyItemInfo.MyDocStyle.ComponentList)
{
// put out line after step (for BGEVLV format)
float macroY = YBottomMost - (0.25f * SixLinesPerInch);
PartsLeft.Add(new vlnMacro((float)MyItemInfo.MyDocStyle.Layout.LeftMargin, macroY, "B9"));
}
// 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;
ProfileTimer.Pop(profileDepth);
}
private vlnTab GetSupInfoTab(PdfContentByte cb, ItemInfo itemInfo, float yoff, vlnTab mytab, bool doSectTab, float localXOffset)
{
string strmytab = null;
if (itemInfo.MyParent.IsHigh)
strmytab = itemInfo.MyTab.CleanText;
else if (itemInfo.MyParent.IsCaution)
strmytab = "Caution";
else if (itemInfo.MyParent.IsNote)
strmytab = "Note";
else
{
// B2018-022: use flag to determine whether to pre-pend the parent's tab as part of the supplemental info tab
// (if the procedure tab is long, such as in Farley, the tab overwrites text in the supplemental info pages)
strmytab = itemInfo.ActiveSection.ActiveFormat.PlantFormat.FormatData.PrintData.SupInfoIncludeParTab
? ItemInfo.GetCombinedTab(itemInfo.MyParent, itemInfo.MyParent.MyParent.CombinedTab)
: itemInfo.MyTab.CleanText;
}
strmytab = strmytab.Trim();
mytab = new vlnTab(cb, this, strmytab, strmytab, localXOffset, yoff, itemInfo.MyTab.MyFont, doSectTab, StepRTB.MySymbolFontName, itemInfo.MyTab.RemovedStyleUnderline);
return mytab;
}
private static VE_Font _AnnotationFont;
public static VE_Font AnnotationFont
{
get { return vlnParagraph._AnnotationFont; }
set { vlnParagraph._AnnotationFont = value; }
}
// Check to see if the procedure has any printable text in the annotations
private bool? _CanDoPrintableText = null;
public bool CanDoPrintableText
{
get
{
if (_CanDoPrintableText == null)
{
_CanDoPrintableText = false;
AnnotationTypeInfoList atil = AnnotationTypeInfoList.Get();
foreach (AnnotationTypeInfo ati in atil)
{
AnnotationTypeConfig atc = new AnnotationTypeConfig(ati.Config);
if (atc.PrintableText_XLocation != 0)
{
_CanDoPrintableText = true;
break;
}
}
}
return (bool)_CanDoPrintableText;
}
}
private void DoAnnotationPrintableText(PdfContentByte cb, ItemInfo itemInfo, float yoff)
{
// check to see if this procedure has any printable annotations.
// if it does not, then there is no need to spin through checking for the given itemInfo
if (!CanDoPrintableText) return;
// if this step has an Annotation and it has config data to define location, parse out '[xx]' and print it at the location
// this was added for VC Summer (unit 2 & 3) but is available for any data that has defined the location in the config (from the folder properties
// at the top node - annotationtype tab.
if (itemInfo.ItemAnnotationCount > 0)
{
foreach (AnnotationInfo ai in itemInfo.ItemAnnotations)
{
// get the annotation type from the annotation, and see if it has a print location:
AnnotationTypeInfo at = ai.MyAnnotationType;
AnnotationTypeConfig atc = new AnnotationTypeConfig(at.Config);
if (atc.PrintableText_XLocation != 0)
{
int st = ai.SearchText.IndexOf("[");
int end = ai.SearchText.IndexOf("]");
if (st != -1 && end != -1 && end > st)
{
string pref = ai.SearchText.Substring(st + 1, end - st - 1); // annotation - parse out [xx]
pref = Regex.Replace(pref, "{Up}", @"\u8593?", RegexOptions.IgnoreCase);
pref = Regex.Replace(pref, "{Down}", @"\u8595?", RegexOptions.IgnoreCase);
float xPref = atc.PrintableText_XLocation;
if (AnnotationFont == null)
AnnotationFont = new VE_Font(_MyItemInfo.FormatStepData.Font.Family, 6, (E_Style)_MyItemInfo.FormatStepData.Font.Style, 20F);
PartsLeft.Add(new vlnText(cb, this, pref, pref, xPref, yoff, AnnotationFont));
break;
}
}
}
}
}
private float AdjustLocIfLongerRNO(ItemInfo itemInfo, float yoff, float yoffRightParent)
{
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 xMinRno = FindMinXOffsetRno(parRno);
if (XOffset + Width > xMinRno - 12) // 12 = 2 characters, so that tables don't almost touch & look like an overlap
{
if ((float)MyItemInfo.MyDocStyle.Layout.LeftMargin + Width > xMinRno)
{
yoff = yoffRightParent;
YOffset = yoff;
}
else
XOffset = (float)MyItemInfo.MyDocStyle.Layout.LeftMargin;
}
}
return yoff;
}
private float FindMinXOffsetRno(vlnParagraph parRno)
{
// Find the minimum xoffset in the rno column that overlaps in the y direction with
// the table that is currently being processed. This is necessary in order to fix the
// case where the AER table overlaps an RNO table (or tab/text)
float xcur = 0;
// YOffset/Height is for the current table, check it against the rno's yoffset & height
// if aer & rno are within y range of each other
if (YOffset <= (parRno.YOffset + parRno.Height) && (YOffset + Height) >= parRno.YOffset)
{
xcur = parRno.XOffset;
if (parRno.MyTab != null) xcur = parRno.MyTab.XOffset;
}
// recursively look at steps in the rno column to get the smallest xoffset which will
// then be used to compare to table's xoffset/width to see if there is an overlap
if (parRno.ChildrenBelow != null)
{
foreach (vlnParagraph vp in parRno.ChildrenBelow)
{
// yoffset is past where the table is, so don't consider it:
if (vp.YOffset > (YOffset + Height)) return xcur;
float xchild = FindMinXOffsetRno(vp);
if (xchild > 0 && (xcur == 0 || xchild < xcur))
xcur = xchild;
}
}
return xcur;
}
private void DoResponsibility(PdfContentByte cb, float yoff) // WCNTRN's text in 1st column (saved in config for HLS)
{
StepConfig sc2 = MyItemInfo.MyConfig as StepConfig;
if (sc2 != null)
{
string resp = sc2.Step_Responsibility;
if (resp != null && resp != "") // lines are separated by "\r\n"
{
resp = DelimitResponse((int)MyItemInfo.MyDocStyle.SectTop.MaxLen, resp);
if (!resp.EndsWith("\r\n")) resp = resp + "\r\n"; // parsing needs this.
int indx = resp.IndexOf("\r\n");
int stindx = 0;
float y = yoff;
while (indx > -1)
{
string subresp = resp.Substring(stindx, indx - stindx);
float respWidth = subresp.Length * 6;
float ctr = (float)MyItemInfo.MyDocStyle.SectTop.Margin;
float respcntrX = (float)MyItemInfo.MyDocStyle.Layout.LeftMargin + ctr - (respWidth / 2);
vlnText myResp = new vlnText(cb, this, subresp, subresp, respcntrX, y, MyItemInfo.FormatStepData.Font);
PartsLeft.Add(myResp);
y += SixLinesPerInch;
stindx = indx + 2;
indx = stindx < resp.Length ? resp.IndexOf("\r\n", stindx) : -1;
}
}
}
}
private string DelimitResponse(int maxLen, string responsStr)
{
// This code handles whether user enters \r\n to separate lines or not. The
// max width that a line can be in the Responsibility column is a format flag (passed in)
List<string> results = new List<string>();
int width = 0; // keep track of current width of current 'line' while looking for space to break
int start = 0; // start of line (index into string 'text')
int lastspace = 0; // location of lastspace (index into string)
for (int indx = 0; indx < responsStr.Length; indx++)
{
if ((indx + 1) < responsStr.Length && responsStr.Substring(indx, 2) == "\r\n")
{
results.Add(responsStr.Substring(start, indx - start).Trim(" ".ToCharArray()) + "\r\n");
start = indx + 2;
width = 0;
}
else
{
if (responsStr[indx] == ' ') lastspace = indx;
width++;
if (width > maxLen)
{
// what should be done if lastspace == 0
// cannot find space char to split on, so break the word
bool spFound = true;
if (lastspace == 0)
{
lastspace = indx;
spFound = false;
}
results.Add(responsStr.Substring(start, lastspace - start).Trim(" ".ToCharArray()) + "\r\n");
start = lastspace + (spFound ? 1 : 0); // increment start based on whether a space is found, i.e. if no space keep at 'indx'
// width either is equal to width of text after the last space, or is zero if at the maxlen of width:
width = (indx - lastspace - 1) > 0 ? indx - lastspace - 1 : 0;
lastspace = 0;
}
}
}
if (width > 0 || start < responsStr.Length) results.Add(responsStr.Substring(start).Trim(" ".ToCharArray()));
string retval = null;
foreach (string st in results) retval = retval + st;
return retval;
}
public override string Rtf
{
get
{
if (_Rtf == null) BuildRtf();
return _Rtf;
}
set { _Rtf = value; }
}
private void BuildRtf()
{
int profileDepth = ProfileTimer.Push(">>>> BuildRtf");
if (_Rtf == null)
{
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && MyItemInfo.IsCaution1 &&
MyItemInfo.MyContent.Text.StartsWith(@"\u") && !MyItemInfo.MyContent.Text.StartsWith(@"\u160?"))
{
Rtf = GetRtf(MyItemInfo, " " + (Prefix ?? ""), Suffix);
PrefixSpecialCharacter = true;
}
else
{
Rtf = GetRtf(MyItemInfo, Prefix, Suffix);
}
// Need the following with some modifications for WCNCKL format:
if (Rtf.Contains("{Backspace}"))
{
XOffset -= 25;
Width += 24;
Rtf = Rtf.Replace("{Backspace}", "");
}
}
Rtf = FixRTFToPrint(MyItemInfo, Rtf);
ProfileTimer.Pop(profileDepth);
}
// C2018-024 I in Arial font changed to I in TimesNewRoman
private static System.Drawing.Font _TNR;
// F2018-013 Changed to static and public so that it can be used with step identifiers for bullets
public static string FixRTFToPrint(ItemInfo myItemInfo, string rtf)
{
// Only do this if the text contains symbols.
if ((rtf.Contains("VESymbFix") || rtf.Contains(Volian.Base.Library.vlnFont.ProportionalSymbolFont))) // C2017-036 get best available proportional font for symbols
{
// bug fix: B2017-117 was getting an out of window handles error when doing a print all for Bryon
// add the using statment to free up window handle that is created doing a New RichTextBox()
using (System.Windows.Forms.RichTextBox rtb = new System.Windows.Forms.RichTextBox())
{
rtb.Rtf = rtf.Replace(@"\\", "<dblbs>"); // rename backslash character to avoid RTF confusion
//string showRTF = rtf;
bool changed = false;
// C2018-024 I in Arial font changed to I in TimesNewRoman
if (myItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.ChangeFontUpperCaseIinArial)
{
bool lastWasNumber = false;
for (int i = 0; i < rtb.TextLength - 1; i++)
{
rtb.Select(i, 2);
if (rtb.SelectionLength == 2)
{
if ((rtb.SelectedText == ".I") && rtb.SelectionFont.FontFamily.Name == "Arial")
{
if (_TNR == null)
_TNR = new System.Drawing.Font("Times New Roman", rtb.SelectionFont.Size, rtb.SelectionFont.Style);
if (lastWasNumber)
{
rtb.SelectionFont = _TNR;
changed = true;
lastWasNumber = false;
}
}
else
lastWasNumber = Regex.IsMatch(rtb.SelectedText, @"[0-9]\.");
}
}
}
// C2017-008 - WCN wants the box symbol to look like their checkoff/signoff box
// Check for a list of replacement character for symbols in the format file
// ReplaceSymbolChars lets you do one or more of the following with a symbol character:
// - change the point size
// - change the style
// - change the font family
// - change the symbol character
//
// below is taken from the BaseAll format file - is currently commentout and there for reference
// Wolf Creek (WCN) currently uses this to increase the size of the box symbol
//
//<!--example of replacing a symbol character (VESymbFix)-->
//<!--ReplaceSymbolChars>
// <ReplaceChar Index="#" Unicode=[decimal char #] Replace=[optional char #] Family=[option font family name] Style=[optional font style] Size=[optional font size]>
//</ReplaceSymbolChars-->
//
// get the list of symbol replacements
FormatData fmtdata = (myItemInfo.ActiveFormat != null) ? myItemInfo.ActiveFormat.PlantFormat.FormatData : FormatInfo.PROMSBaseFormat.FormatData;
ReplaceSymbolCharList SymReplaceList = (fmtdata != null && fmtdata.SectData.ReplaceSymbolCharList != null) ? fmtdata.SectData.ReplaceSymbolCharList : null;
// Look at one character at a time
for (int i = 0; i < rtb.TextLength; i++)
{
rtb.Select(i, 1);
if ((rtb.SelectedRtf.Contains("VESymbFix") || rtb.SelectedRtf.Contains(Volian.Base.Library.vlnFont.ProportionalSymbolFont)) && rtb.SelectedText.Length > 0) // C2017-036 get best available proportional font for symbols
{
for (int j = 0; j < SymReplaceList.MaxIndex; j++)
{
ReplaceChar rc = SymReplaceList[j];
if (rc.Unicode != null && (rc.Family != null || rc.Size != null || rc.Style != null))
{
char rc_uchar = Convert.ToChar(Convert.ToInt32(rc.Unicode));
if (rc_uchar == rtb.SelectedText[0])
{
//use bolding underline italics from local font
System.Drawing.Font fnt = rtb.SelectionFont;
// follow through in fixing an Out of Window Handles bug, use new function to see if
// we can retrieve the font from a dictionary instead a doing a New and using another
// window handle B2017-117
//System.Drawing.Font fntw = new System.Drawing.Font((rc.Family != null) ? rc.Family : fnt.FontFamily.Name, (rc.Size != null) ? (float)rc.Size : fnt.Size, (rc.Style != null) ? (System.Drawing.FontStyle)rc.Style : fnt.Style);
System.Drawing.Font fntw = VE_Font.GetWinSysFont((rc.Family != null) ? rc.Family : fnt.FontFamily.Name, (rc.Size != null) ? (float)rc.Size : fnt.Size, (rc.Style != null) ? (System.Drawing.FontStyle)rc.Style : fnt.Style);
rtb.SelectionFont = fntw;
if (rc.Replace != null)
{
char rc_RplChar = Convert.ToChar(Convert.ToInt32(rc.Replace));
rtb.SelectedText = rc_RplChar.ToString();
}
changed = true;
break; // break out of foreach loop since we changed the character
}
}
}
}
}
if (changed)
{
if (rtb.Rtf.EndsWith(" \\par\r\n}\r\n") && rtf.EndsWith(" }")) //B2018-060 rtb.RTF added extra new line characters and commands to the end. so remove it.
rtf = rtb.Rtf.Replace(" \\par\r\n}\r\n", " }");
else
rtf = rtb.Rtf;
return rtf.Replace("<dblbs>", @"\\"); // put back the backslash character
}
}
}
return rtf;
}
// for Calvert (BGE) alarms, some step text is kept on the same line as its parent. This
// is flagged by the -1 row in the template definition.
private bool KeepOnParentLine(ItemInfo itemInfo)
{
int tindx = itemInfo.TemplateIndex;
if (tindx < 0) return false;
if (itemInfo.ActiveFormat.PlantFormat.FormatData.Templates[tindx].row == -1) return true;
return false;
}
private void AdjustYOffset(float yDelta)
{
YOffset -= yDelta;
foreach (vlnPrintObject vpo in PartsAbove)
vpo.YOffset -= yDelta;
foreach (vlnParagraph vp in ChildrenBelow)
vp.AdjustYOffset(yDelta);
}
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 void BuildContinuousActionSummary(vlnParagraph parent, ItemInfo itemInfo)
{
if (itemInfo is SectionInfo)
{
MyContAct = new pkParagraph(this);
if (parent != null && parent.MyItemInfo.IsSection)
parent.MyContAct = MyContAct;
}
else if (itemInfo is StepInfo)
{
StepConfig sc = itemInfo.MyConfig as StepConfig;
if ((sc != null && sc.Step_CAS == "True") || ((sc == null || sc.Step_CAS == null) && itemInfo.IncludeOnContActSum))
{
// save this step info for use on the Continuous Action Summary
vlnParagraph tparent = parent;
while (tparent != null && tparent.MyContAct == null)
tparent = tparent.MyParent;
if (parent.MyContAct != null)
{
if (itemInfo.IsCautionPart || itemInfo.IsNotePart)
MyContAct = parent.MyContAct.AddCautionsAndNotes(this);
else
MyContAct = parent.MyContAct.AddChild(this);
}
else
MyContAct = tparent.MyContAct.AddChild(this);
}
}
}
private void BuildTimeCriticalActionSummary(vlnParagraph parent, ItemInfo itemInfo)
{
if (itemInfo is SectionInfo)
{
MyTimeCriticalAction = new pkParagraph(this);
if (parent != null && parent.MyItemInfo.IsSection)
parent.MyTimeCriticalAction = MyTimeCriticalAction;
}
else if (itemInfo is StepInfo)
{
StepConfig sc = itemInfo.MyConfig as StepConfig;
if ((sc != null && sc.Step_TCAS == "True") || ((sc == null || sc.Step_TCAS == null) && itemInfo.IncludeOnTimeCriticalActionSum))
{
// save this step info for use on the Continuous Action Summary
vlnParagraph tparent = parent;
while (tparent != null && tparent.MyTimeCriticalAction == null)
tparent = tparent.MyParent;
if (parent.MyTimeCriticalAction != null)
{
if (itemInfo.IsCautionPart || itemInfo.IsNotePart)
MyTimeCriticalAction = parent.MyTimeCriticalAction.AddCautionsAndNotes(this);
else
MyTimeCriticalAction = parent.MyTimeCriticalAction.AddChild(this);
}
else
MyTimeCriticalAction = tparent.MyTimeCriticalAction.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
SectionInfo si = itemInfo.GetSectionInfo(); // 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.
int maxindx = itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffUCF ? itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList.MaxIndex : itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffList.MaxIndexNoInherit;
if (maxindx <= 0) return;
if (MyPageHelper.PageListCheckOffHeader == null) return;
VE_Font font = null;
ItemInfo mySectionInfo = itemInfo.ActiveSection; // C2018-003 fixed use of getting the active section
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 == null || 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);
SectionInfo si = (mySectionInfo != null) ? mySectionInfo.GetSectionInfo() : null;
int sindx = si.CheckOffHeadingIndex();
//SectionInfo subi = mySubSectionInfo == null ? null : SectionInfo.Get(mySubSectionInfo.ItemID);
SectionInfo subi = (mySubSectionInfo == null) ? null : mySubSectionInfo.GetSectionInfo();
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;
// B2022-129: Barakah - Adjust the INITIAL header location, i.e. make it a pagelist item
if (itemInfo.IsStep || itemInfo.MyDocStyle.AdjSectTitleLoc)
{
usePageListCOHdr = true;
}
// This checks to see if the section is starting at the top of the page.
// If it is, then we want to use PageList to print the checkoff/sighoff header
// else the checkoff/signoff header will be printed across from the section title where ever it is on the page (i.e. section pagination set to continuous)
else if (subi == null) //no subsection
{
// B2021-106 added check if the section has a note or caution
if ((yPageStart - YOffset) == yTopMargin || mySectionInfo.HasCautionOrNote) usePageListCOHdr = true;
}
else // there is a sub-section
{
// B2021-106 added check if the section has a note or caution
if (mySectionInfo == itemInfo && ((yPageStart - YOffset) == yTopMargin) || mySectionInfo.HasCautionOrNote) 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 != null) ? mySectionInfo.SectionCheckOffHeader : null;
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(YTop, 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)
{
float scale = itemInfo.IsRtfRaw ? 0.6f : 1.0f;
bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
vlnParagraph hls1 = MyParent;
if (!formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && !itemInfo.IsInSupInfo)
while (hls1.MyParent != null && !hls1.MyItemInfo.IsHigh) hls1 = hls1.MyParent;
else if (itemInfo.IsInSupInfo)
while (hls1.MyParent != null && !hls1.MyItemInfo.IsSupInfoPart) 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.ActiveSection.MyDocStyle.Layout.PageWidth); // C2018-003 fixed use of getting the active section
float leftMargin = ((float)itemInfo.ActiveSection.MyDocStyle.Layout.LeftMargin); // C2018-003 fixed use of getting the active section
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 + hls1.CheckOffWidth + colR * itemInfo.ColumnMode;
// If a table is within the alarm section and its parent is a template item is single column
// adjust the xoffset so that the table is centered around center of page
bool ctrCalvertAlarmTbl = false;
if (formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
ctrCalvertAlarmTbl = MyItemInfo.IsWithInSingleColumnTemplate();
// B2019-049 added check for table being in a Caution or Note - if so, use the single column setting for the format variable TableCenterPos
float TableCenterPos = float.Parse(formatInfo.MyStepSectionLayoutData.TableCenterPos.Split(",".ToCharArray())[(itemInfo.IsInCautionOrNote) ? 0 : itemInfo.ColumnMode]);
if (ctrCalvertAlarmTbl || formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TieTabToLevel)
XOffset = leftMargin + (pageWidth - leftMargin - (scale * Width)) / 2;
else
{
if (!aerTableOrFigure && itemInfo.RNOLevel == 0 && TableCenterPos != 0) // Only adjust TableCenterPos for Non-RNO Cenetered Tables
{
XOffset = TableCenterPos;
XOffset = XOffset - (this.Width / 2) + (float)itemInfo.MyDocStyle.Layout.LeftMargin;
}
else if (itemInfo.RNOLevel != 0) // RNO
XOffset = MyParent.XOffset + (MyParent.Width / 2) - ((scale * Width) / 2);
else if (aerTableOrFigure)
{
// if in the BGE alarm format and the hls is a Window (upper right corner when it prints), use the parent of the table
// to print in aer column (B2014-105)
if (MyItemInfo.IsInCalvertConditionResponse)
XOffset = hls1.XOffset + hls1.Width / 2 - Width / 2;
else
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 && !MyItemInfo.IsRtfRaw)
{
// 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 (itemInfo.MyDocStyle.Layout.CenterToStepThenPage)
{
if (Width > hls1.Width)
{
float XOffsetPage = leftMargin + ((pageWidth - leftMargin) - Width) / 2;
float fraction = (Width - hls1.Width) / ((pageWidth - leftMargin) - hls1.Width);
float XOffsetNew = (1 - fraction) * XOffset + fraction * XOffsetPage;
_MyLog.WarnFormat("***XOffsetAdjust-CenterToStepThenPage*** ItemID, XOffset, XOffsetPage, XOffsetNew ={0},{1},{2},{3}", itemInfo.ItemID, XOffset, XOffsetPage, XOffsetNew);
XOffset = XOffsetNew;
}
}
else
{
// if the XOffset < High Level Step Text's XOffset , then align with the High Level Step Text'
// B2020-161 - needed to substract the checkoff width when deterniming the XOffset
// fixes centered tables in Calvert Unit 2 STP O-90-2 step 6.3.A
if (XOffset < xLowerLimit && Width < (xUpperLimit - xLowerLimit - hls1.CheckOffWidth))
XOffset = xLowerLimit;
// if the right margin exceeds the right edge of the rightmost RNO, then adjust right edge to match.
// In lines below, the 12 was used for Wolf Creek 2 column format, the pagewidth goes beyond the right border line so that
// the tables, figures & equations were beyond the border. -12 takes it enough so that if boxed, it won't print out of border
// We know this is not ideal.
if (MyItemInfo.IsRtfRaw && (XOffset + (scale * Width) > xUpperLimit - 12))
XOffset = xUpperLimit - (scale * Width) - 12;
if (!MyItemInfo.IsRtfRaw && 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;
// F2022-121 added SpecialStepsFoldoutKeepWhiteSpace flag to allow for all of the other special foldout formatting, but
// not compress the page
if (MyItemInfo.MyDocStyle.SpecialStepsFoldout && !MyItemInfo.MyDocStyle.SpecialStepsFoldoutKeepWhiteSpace) 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 (everyNLines == -1) return -SixLinesPerInch;
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm ||
(MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && MyItemInfo.IsStep && MyItemInfo.FormatStepData.StepLayoutData.STBoxindex != null))
{
if ((MyItemInfo.IsCaution || MyItemInfo.IsNote || MyItemInfo.MyParent.IsCaution || MyItemInfo.MyParent.IsNote) && !MyItemInfo.FormatStepData.SpaceIn
&& (MyItemInfo.Steps == null || MyItemInfo.Steps.Count == 0)
&& (MyItemInfo.NextItem == null || MyItemInfo.MyContent.Type != MyItemInfo.NextItem.MyContent.Type))
{
// C2014-009: Don't add another blank line - print the calvert Condition/Response RNO Caution/Notes without it.
if (!(MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && MyItemInfo.IsInRNO))
return 0;
}
//B2020-117 for multiple Calvert Condition/Response Cautions,Note, and Warnings, do add an extra blank line
// between them
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm &&
MyItemInfo.IsInRNO && (MyItemInfo.IsCaution || MyItemInfo.IsNote) &&
MyItemInfo != MyItemInfo.LastSibling)
return 0;
if (everyNLines == 99 && MyItemInfo.NextItem == null)
{
if (MyItemInfo.Steps != null && MyItemInfo.Steps.Count > 0 && MyItemInfo.Steps[0].MyContent.Type == MyItemInfo.MyContent.Type) return 0;
if (MyItemInfo.MyParent.NextItem != null && MyItemInfo.MyParent.NextItem.MyContent.Type == MyItemInfo.MyContent.Type) return 0;
}
}
// B2015-005: if there isn't a blank line after this step && it has children, see if there shouldn't be
// a blank line, i.e. if the first substep child's type is the same as this.
if (!MyItemInfo.IsHigh && everyNLines == 99 && MyItemInfo.NextItem == null && MyItemInfo.HasChildren)
{
ItemInfo chld = MyItemInfo.FirstChild(E_FromType.Step);
if (chld != null && chld.MyContent.Type == MyItemInfo.MyContent.Type) return 0;
}
// F2021-033: No blank line between hls and its first substep:
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.NoBlankHlsAndFirstSub && MyItemInfo.IsHigh)
{
// F2021-060 Do not remove blank line between step and Caution, Note or Warning below it (Caution, Note, Warning are off 1st sub step)
if (MyItemInfo.Steps != null && MyItemInfo.Steps.Count > 0 && !MyItemInfo.Steps[0].HasCautionOrNote) return 0;
}
// F2021-025: Barakah single column no blank line between last Note/Caution/Warning text and bottom line of box
// C2021-049: Barakah no blank line between last Note/Caution/Warning text, include sub-step text by using 'IsInCautionOrNote'
// B2022-017: Barakah within note/caution, if note has substeps, there should be a blank line between note & 1st substep
// B2022-027: Barakah blank line not printing after list within another list. Rewrote code for all of these issues so that
// code looks up parents to see if they have next before returning a 0 (no blank line)
// B2022-042: double Caution followed by Critical Step missing bullet
// F2022-010: substeps in multiple notes, cautions, warning print differently
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.NoBlankLastNoteCautionWarn && (MyItemInfo.IsInCautionOrNote))
{
if ((MyItemInfo.Steps == null || MyItemInfo.Steps.Count == 0) && (MyItemInfo.NextItem == null)) // there are no sub-steps, see if any parents have next
{
ItemInfo par = MyItemInfo.MyParent;
while (par.IsInCautionOrNote) // while in the caution or note, see if there is anything below this item
{
// if there is no next item, or content types are different, go up to see if the parent has any next item. If note
// keep going up tree, otherwise there is a next so don't return 0, i.e. continue on with code to determine
// whether there is a blank line
if ((par.NextItem == null) || (par.MyContent.Type != par.NextItem.MyContent.Type)) par = par.MyParent;
else break;
}
if (!par.IsInCautionOrNote || (par != null && par.MyContent.Type != par.NextItem.MyContent.Type)) return 0;
}
if ((MyItemInfo.Steps == null || MyItemInfo.Steps.Count == 0) && MyItemInfo.NextItem != null && MyItemInfo.MyContent.Type != MyItemInfo.NextItem.MyContent.Type) return 0;
}
if (MyItemInfo.Ordinal % everyNLines == 0 || MyItemInfo.NextItem == null) return SixLinesPerInch;
// B2022-003: BNPP Alarms (BNPPalr) - incorrect line spacing for substeps off substeps. Added a format flag so as not to affect other plants.
if (MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.StepPrintData != null && MyItemInfo.FormatStepData.StepPrintData.BlankAfterSubWithSub && MyItemInfo.NextItem != null && MyItemInfo.HasChildren && MyItemInfo.Steps != null && MyItemInfo.Steps.Count > 0) return SixLinesPerInch;
// If the next table child is a figure, equation or a visio drawing add a blank line
if (MyItemInfo.Tables != null && MyItemInfo.Tables.Count > 0 && MyItemInfo.Tables[0].MyContent.MyGrid == 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<Macro> myMacros = itemInfo.MyMacros;
if (myMacros != null)
{
int colMode = (MyItemInfo.ActiveSection != null) ? MyItemInfo.ActiveSection.ColumnMode : 0; // C2018-003 fixed use of getting the active section
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));
if (colMode == 0 && myMacro.SingleColMacroDef != null && myMacro.SingleColMacroDef.Length > 0)
{
float macroXOffset = myMacro.MacroXOffSet ?? 0;
float widthAdj = myMacro.SingleColWidthAdjust ?? 0; // set as negative number in format
float rightTextEdge = (itemInfo.IsHigh) ? XOffset + Width + mytab.XOffset : this.MyHighLevelParagraph.XOffset + this.MyHighLevelParagraph.Width;
x = (macroXOffset > 0) ? macroXOffset : rightTextEdge;
if (rightTextEdge > x)
Width += widthAdj;
PartsRight.Add(new vlnMacro(x, y, myMacro.SingleColMacroDef));
}
else
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.ChangeIds)
{
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 (cbd.AbsoluteFixedChangeColumn) coltotwips = col * itemInfo.ActiveFormat.PlantFormat.FormatData.Font.CharsToTwips;
// B2023-052: Beaver Valley - Inconsistent change bar location - used AbsoluteFixedChangeColumn flag, but the LeftMargin
// was still added in, thus sections had different locations for change bar if sections had different left margin. Use
// adjustment, 'AbsChgBarAdj'
coltotwips += itemInfo.MyDocStyle.Layout.AbsChgBarAdj ?? 0;
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,
itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ChangeIds);
}
// changed this function to return a float instead of an int to correct a rounding error which cause change bars
// to inconsistantly position next to changed text. Bug B2015-033
private float 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 MyItemInfo.IsFigure ? rightEdge + 1 : rightEdge; // B2017-111: Add a little more space between figure & change bar
}
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 (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)
{
int profileDepth = ProfileTimer.Push(">>>> GetRtf");
_RtfSB = new StringBuilder();
DisplayText vlntxt = new DisplayText(itemInfo, E_EditPrintMode.Print, E_ViewMode.View, true, E_FieldToEdit.StepText, false, prefix, suffix, MyPageHelper.MyPromsPrinter.RemoveTrailingHardReturnsAndSpaces != null);
// C2021-010: Remove trailing returns/spaces & manual page breaks & allow save.
if (DisplayText.RemoveTrailingBlankID > 0 && !MyPageHelper.MyPromsPrinter.RemoveTrailingHardReturnsAndSpaces.Contains(itemInfo.ItemID)) MyPageHelper.MyPromsPrinter.RemoveTrailingHardReturnsAndSpaces.Add(DisplayText.RemoveTrailingBlankID);
System.Drawing.Font myFont = vlntxt.TextFont.WindowsFont;
if (!itemInfo.IsTable && StepRTB.MyFontFamily != null)
// follow through in fixing an Out of Window Handles bug, use new function to see if
// we can retrieve the font from a dictionary instead a doing a New and using another
// window handle B2017-117
//myFont = new System.Drawing.Font(StepRTB.MyFontFamily, myFont.Size, myFont.Style);
myFont = VE_Font.GetWinSysFont(StepRTB.MyFontFamily, myFont.Size, myFont.Style);
string stText = null; // if Calvert (BGE) Alarms, the text is included in the macro, so save text as a blank:
if (HasCalvertMacro)
{
stText = " ";
// turn underline off
// follow through in fixing an Out of Window Handles bug, use new function to see if
// we can retrieve the font from a dictionary instead a doing a New and using another
// window handle B2017-117
//myFont = new System.Drawing.Font(myFont.FontFamily, myFont.Size, System.Drawing.FontStyle.Regular); //myFont.Style. | FontStyle.Underline);
myFont = VE_Font.GetWinSysFont(myFont.FontFamily, myFont.Size, System.Drawing.FontStyle.Regular); //myFont.Style. | FontStyle.Underline);
}
else
stText = vlntxt.StartText;
if (itemInfo.IsHigh && itemInfo.MyDocStyle.UndSpecialStepsFoldout)
{
// follow through in fixing an Out of Window Handles bug, use new function to see if
// we can retrieve the font from a dictionary instead a doing a New and using another
// window handle B2017-117
//myFont = new System.Drawing.Font(myFont.FontFamily, myFont.Size, myFont.Style | System.Drawing.FontStyle.Underline);
myFont = VE_Font.GetWinSysFont(myFont.FontFamily, myFont.Size, myFont.Style | System.Drawing.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)
// follow through in fixing an Out of Window Handles bug, use new function to see if
// we can retrieve the font from a dictionary instead a doing a New and using another
// window handle B2017-117
//myFont = new System.Drawing.Font(myFont.FontFamily, 14, myFont.Style | System.Drawing.FontStyle.Bold);
myFont = VE_Font.GetWinSysFont(myFont.FontFamily, 14, myFont.Style | System.Drawing.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, "(?<!Link|ReferencedObject|Transition|TransitionRange)" + ut.Text);
if (mc.Count > 0)
{
Match m = mc[mc.Count - 1];
rtf = rtf.Substring(0, m.Index) + @"\ulnone " + rtf.Substring(m.Index);
}
}
}
ProfileTimer.Pop(profileDepth);
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.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && itemInfo.IsInRNO && (itemInfo.IsCaution || itemInfo.IsNote)) // C2014-009
xoff = XOffset + (para.Width / 2) - (hdrWidth / 2);
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
// KEEP: This may be needed in the future to fix location of 'OR's when Separator location="0"
// the following code would place the 'OR' at the location of the tab rather than text. This
// is how 16bit was. However, a number of plants had been sent out with the xoffset at the xlocation
// of text (does not match 16bit) when this was found for BGE OI3/OI-1B/6.1.B.4. Previous releases
// went to CAT, MCG, FPL, NSP.
//{
// if (this.MyTab != null)
// xoff = this.MyTab.XOffset;
// else
// xoff = XOffset;
//}
// B2018-096 AEP 082.002CD Note Box overlapping Step Box
vlnHeader myHeader = new vlnHeader(this, cb, itemInfo.MyHeader.Text, itemInfo.MyHeader.CleanText.TrimStart(" ".ToCharArray()), xoff + AdjustHeader + _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;
// F2022-121 added SpecialStepsFoldoutKeepWhiteSpace flag to allow for all of the other special foldout formatting, but
// not compress the page - this need to handle explicit OR and AND sub-steps to ensure there are blank lines before and after
// the separator text.
return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout || (MyItemInfo.MyDocStyle.SpecialStepsFoldout && MyItemInfo.MyDocStyle.SpecialStepsFoldoutKeepWhiteSpace) || (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 _PathPrefix = "";
public static string PathPrefix
{
get { return vlnParagraph._PathPrefix; }
set { vlnParagraph._PathPrefix = value; }
}
protected float _YBottomMost; // Bottom of the paragraph including the children
public float YBottomMost
{
get { return _YBottomMost; }
set
{
_YBottomMost = value;
}
}
private float _YBottomPagination; // B2019-111 Keep table with Parent
protected float YBottomPagination
{
get { return _YBottomPagination; }
set { _YBottomPagination = value; }
}
protected float _YBottomMostAdjust = 0; // the RNO separator is outside asterisk box, account for additional Y space
public float YBottomMostAdjust
{
get { return _YBottomMostAdjust; }
set { _YBottomMostAdjust = 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
{
float ysize = SmartTemplateAdjust + _YBottomMost - _YTopMost;
if (MyItemInfo.IsHigh && ((MyItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS))
ysize += SixLinesPerInch;
return ysize;
}
}
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();
}
private vlnParagraph _SupInfoSection;
public vlnParagraph SupInfoSection
{
get
{
if (_SupInfoSection == null)
{
_SupInfoSection = GetSupInfoSectionParagraph();
}
return _SupInfoSection;
}
}
private vlnParagraph GetSupInfoSectionParagraph()
{
if (MyItemInfo.IsSection) return this._SupInfoSection;
return MyParent.GetSupInfoSectionParagraph();
}
// 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 bool IsEnhancedBackgroundFormat(ItemInfo itminfo)
{
return ((itminfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds);
}
public void AdjustXOffsetForTab(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab, float xMetaAdj)
{
if (itemInfo.IsSupInfoPart)
{
// The SupInfoTabOff was added to the base format during initial development to shift the tab over by 3/4 inch (54) to allow for enough space for Note/Caution tab
int sitabloc = itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SupInfoTabOff == null ? 0 : (int)itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SupInfoTabOff;
// B2023-069 allow for the adjustment of the Supplemental Information tab at the section level (SecOvrideSupInfoTabOff).
// this will also override the SupInoTabOff setting which is for the entire format
int secOvrSupInfoTab = itemInfo.MyDocStyle.SecOvrideSupInfoTabOff == null ? 0 : (int)itemInfo.MyDocStyle.SecOvrideSupInfoTabOff;
if (secOvrSupInfoTab != 0) sitabloc = secOvrSupInfoTab;
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + sitabloc;
if (myTab != null)
{
myTab.XOffset = XOffset - ((myTab == null) ? 0 : myTab.Width) - 12;
// B2017-253 - Limit the tab offset to 2 points inside the left margin
myTab.XOffset = Math.Max(myTab.XOffset, itemInfo.MyDocStyle.Layout.LeftMargin ?? 72) + 2;
float mytbwidth = myTab.Width;
myTab.Width = 2.5f * myTab.Width;
// C2018-022: adjust xoffset of text by 12 if the tab would overwrite the text and the format flag is on:
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SupInfoAdjustXOffForLongTab && ((myTab.XOffset + mytbwidth + 12) > XOffset))
XOffset = 12F + myTab.XOffset + mytbwidth;
}
// B2017-102: need to set width here since using Xoffset because AdjustWidth is called before this adjustment.
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - XOffset - (sitabloc / 2);
return;
}
// F2019-069: Hold Point designator for Barakah, use parent's tab for xoffset
if (itemInfo.IsStep && itemInfo.FormatStepData.ColUseParentTab && (myTab == null || myTab.Text == ""))
{
if (MyParent != null)
{
XOffset = (MyParent.MyTab == null || MyParent.MyTab.Text == null || MyParent.MyTab.Text.Trim() == "") ? MyParent.XOffset : MyParent.MyTab.XOffset;
return;
}
}
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;
}
if (formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
{
XOffset = (myTab == null ? 0 : myTab.XOffset) + ((float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos - (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos);
}
else
{
level = level <= 2 ? 1 : level - 1;
if (level == 1)
{
// Use the section number position for the section title when the section number is blank
if (formatInfo.PlantFormat.FormatData.SectData.SectionHeader.UseNumPosWhenNumBlank && MyTab != null && MyTab.Text.Trim().Length == 0)
{
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + ((float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos);
}
else
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (level * (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos);
}
else if (formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
XOffset = (myTab == null ? 0 : myTab.XOffset) + ((float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos - (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.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;
}
// B2021-091 added a null reference check - itemInfo was a section and didn't have FormatStepData so just return
if (itemInfo.FormatStepData == null) return;
int? bxIndx = itemInfo.FormatStepData.StepLayoutData.STBoxindex;
float? colOvrd = itemInfo.FormatStepData.ColOverride;
if (itemInfo.IsBackgroundStep())//WolfCreekBackgroundFormat && IsHigh||IsNote||IsCaution or ImplicitOR
{
int adj = 2;
if (myTab != null)
{
//B2018-139 use XOffset when processing HLS, Caution, or Note background text and tab
if (itemInfo.IsHigh || (itemInfo.IsNote && (itemInfo.MyParent.IsHigh || itemInfo.MyParent.IsCaution || itemInfo.MyParent.IsNote)) || (itemInfo.IsCaution && (itemInfo.MyParent.IsHigh || itemInfo.MyParent.IsCaution || itemInfo.MyParent.IsNote)))
myTab.XOffset = XOffset;
else
{
// F2018-041 seq tabs off of TitleWithTextBelow were running into the step text
myTab.XOffset = XOffset + (itemInfo.FormatStepData.Font.CharsToTwips * adj); // F2018-041 move tab over 2 chars so it positions like paragraphs under TitleWithTextBelow
adj += myTab.Text.Length; // F2018-041 add the length of the tab to the adjustment of the XOffset
}
}
XOffset += (itemInfo.FormatStepData.Font.CharsToTwips * adj); // indent 2 characters for background steps
// B2018-146 Adjust the width to match the HLS Right Margin.
//if (itemInfo.ActiveFormat.Name.StartsWith("WCN")) -- Not needed since IsBackgroundStep
Width = this.MyHighLevelParagraph.Width + this.MyHighLevelParagraph.XOffset - this.XOffset;
//else
// Width -= (itemInfo.FormatStepData.Font.CharsToTwips * adj); // Adjust width by 2 characters
return;
}
else if (itemInfo.FormatStepData.UseOldTemplate && itemInfo.IsInTemplate() &&
(MyItemInfo.ActiveSection != null && (MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListSpBckgrnd) == E_DocStructStyle.DSS_PageListSpBckgrnd)) // C2018-003 fixed use of getting the active section
{
if (myTab != null) myTab.XOffset = XOffset;
XOffset += myTab.Width;
return;
}
else if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.Type == "TitleWithTextBelow")
{
if ((colOvrd ?? 0) != 0)
XOffset = (float)colOvrd;
else
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
// B2018-146 Adjust the width to match the HLS Right Margin.
if (itemInfo.IsPartOfBackgroundStep())
//if(itemInfo.ActiveFormat.Name.StartsWith("WCN"))
Width = this.MyHighLevelParagraph.Width + this.MyHighLevelParagraph.XOffset - this.XOffset;
return;
}
else if (itemInfo.IsParagraph &&
(((itemInfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds) ||
((itemInfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedDeviations) == E_PurchaseOptions.EnhancedDeviations)) &&
itemInfo.FormatStepData != null && PreviousIsTitleWithTextBelow(itemInfo))
{
// This code was needed for fix for B2015-183 &&
// IP2 backgrounds so that any 'paragraph's that were at the same
// level as the 'TitleWithTextBelow's would have same left margin (xoffset) as the 'TitleWithTextBelow'.
// an example of this can be found in IP2 Backgrounds, 2-E-0, Step Description Table, Step 22, PLANT-SPECIFIC INFORMATION.
// (NOTE that the IP2 exaxmple was no longer in the data when the work on B2015-183 was done)
if ((colOvrd ?? 0) != 0)
XOffset = (float)colOvrd;
else
{
//Adjuust Indent for Wolf Creek Background format flag
float indentBG1 = itemInfo.IsPartOfBackgroundStep() ? itemInfo.FormatStepData.Font.CharsToTwips * 2 : 0;
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + indentBG1;
// B2018-146 Adjust the width to match the HLS Right Margin.
if (itemInfo.IsPartOfBackgroundStep())
//if (itemInfo.ActiveFormat.Name.StartsWith("WCN"))
Width = this.MyHighLevelParagraph.XOffset + this.MyHighLevelParagraph.Width - XOffset;
else
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - (float)itemInfo.MyDocStyle.Layout.LeftMargin - indentBG1;
}
return;
}
else if (itemInfo.MyParent.FormatStepData != null && itemInfo.MyParent.FormatStepData.Type == "TitleWithTextBelow" && (!itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm || (!itemInfo.IsCaution && !itemInfo.IsNote)))
{
float childindent = itemInfo.MyParent.FormatStepData.ChildIndent ?? 0;
if (myTab != null)
{
float delta = childindent + MyParent.XOffset - myTab.XOffset;
myTab.XOffset += delta;
XOffset += delta;
// B2018-036: set the width of (background/deviation/alarms/etc) steps that have a tab
if (!itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm || !UseTemplateWidthOrXOff(itemInfo.MyParent))
{
// B2018-146 Adjust the width to match the HLS Right Margin.
// F2023-112 added format flag for Vogtle Units 3 & 4 backgrounds. This allows use of override width on AND and List sub-step types
if (itemInfo.IsBackgroundStepOrChild() || itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.Vogtle3and4BackgroundFormat)
Width = this.MyHighLevelParagraph.Width + this.MyHighLevelParagraph.XOffset - this.XOffset;
else
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - (float)itemInfo.MyDocStyle.Layout.LeftMargin - delta;
}
}
else
{
//Adjust Indent for Wolf Creek Background format flag
float indentBG2 = itemInfo.IsPartOfBackgroundStep() ? itemInfo.FormatStepData.Font.CharsToTwips * 2 : 0;
XOffset = childindent + MyParent.XOffset + indentBG2;//(itemInfo.FormatStepData.Font.CharsToTwips * 2);
// B2016-164: Added the following 'if' so that the width is not recalculated if in the alarm format & the parent has a template
// B2016-168: The fix for 164 broke deviation document printing. The if statement was fixed for both:
// B2019-057 Added a check to see if there is a width override for this step element (Robinson AOP Backgrounds - paragraphs)
float wdthovrd = (itemInfo.FormatStepData.WidthOverride == null) ? 0 : (float)ToInt(itemInfo.FormatStepData.WidthOverride, maxRNO);
if ((!itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm || !UseTemplateWidthOrXOff(itemInfo.MyParent)) && wdthovrd == 0)
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - (float)itemInfo.MyDocStyle.Layout.LeftMargin - indentBG2;
}
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;
// if the step text has a tab, then we need to position the tab to the XOffset and then ajust the text XOffset
// by the length of the tab. - fix for IP2 backgrounds (ex. 2-ECA-3.3, step 6)
if (myTab != null)
{
myTab.XOffset = XOffset;
XOffset += (myTab.Text.Length * myTab.MyFont.CharsToTwips);//myTab.Width - myTab.XOffset;
}
return;
}
if (itemInfo.IsHigh)
{
if (formatInfo.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm ||
((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_SameXOffSubsections) == E_DocStructStyle.DSS_SameXOffSubsections))
{
// the HLS in the template prints the tab/step on the right edge of page. Don't
// do the other calculations to relocate it.
if (itemInfo.FormatStepData.UseOldTemplate && itemInfo.IsInTemplate())
{
MyTab.XOffset = XOffset - MyTab.Width;
return;
}
// the following code handles the xoffsets of tabs/HLS in the non-alarm sections for
// the Calvert Alarm format.
if (itemInfo.MyDocStyle.UseColSByLevel)
{
if (myTab != null)
{
myTab.Rtf = myTab.Rtf.Replace(myTab.Text, myTab.Text.TrimStart(" ".ToCharArray()));
// B2022-129: don't indent HLS when flag is on (Barakah - single column step attachment with meta sect)
if (itemInfo.MyDocStyle.AdjSectTitleLoc)
{
myTab.XOffset = MyParent.MyTab.XOffset;
XOffset = MyParent.XOffset;
}
else
{
myTab.XOffset = MyParent.XOffset;
XOffset = myTab.XOffset + MyTab.Width;
}
}
else
XOffset = MyParent.XOffset; // unnumbered hls
return;
}
}
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();
// B2021-113: BNPP1new - subsection & HLS should be same level (xoffset of tab & text)
if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.SubSectAndHighSameLevel && !MyItemInfo.MyActiveSection.MyParent.IsProcedure) indxLevel++;
float colsbylevel = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.MaxIndex].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)
// B2021-113: BNPP1new - subsection & HLS should be same level (xoffset of tab & text)
if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.SubSectAndHighSameLevel && !MyItemInfo.MyActiveSection.MyParent.IsProcedure)
XOffset += tabWidth;
else
XOffset = myTab.XOffset + GetLeftJustify(formatInfo, indxLevel); // 2.1.1 goes here xoffset = 136
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. This is used
// in BGEEOP (see EOP-0/Purpose ). However, it caused BGESTP's to print LossOfAC steps (unnumbered HLS) too
// far to the left. The ForceAlignNullTabWSectHead was introduced so that for that step type (LossOfAC) in STP/OI format,
// the SectData.SectionHeader.Pos was used rather than SectData.SectionNumber.Pos
if (myTab == null && !itemInfo.FormatStepData.ForceAlignNullTabWSectHead && 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 (((colOvrd ?? 0) != 0) && (IsEnhancedBackgroundFormat(itemInfo) && (itemInfo.IsNote || itemInfo.IsCaution)))
{
float tabOffset = (myTab == null ? 0 : myTab.XOffset);
// Adjust the position of the Note/Caution text by the difference of the colOverride and the tab xoffset
XOffset += ((float)colOvrd - tabOffset);
if (myTab != null) myTab.XOffset = (float)colOvrd; // set the note/caution tab offset to the colOverride
return;
}
// put in for Point Beach (wep2) we don't want to do this if we are processing a boxed substep (cont. action substep)
else if (bxIndx != null && (itemInfo.IsCaution || itemInfo.IsNote ||
!itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.ContActBoxOnSubSteps))
{
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 this format has the centerline & numberwithlevel (special tabbing for rno) then
// position rno xoffset of the tab to be close to centerline & text indented from there (only BGE)
if (itemInfo.MyDocStyle.CenterLineX != null && itemInfo.FormatStepData.NumberWithLevel)
{
// if the tab is 3 char or smaller, make the indent amount for the rno text 4 characters.
// if bigger, make it the additional tab size.
int len = myTab.Text.Trim().Length;
int adj = len <= 3 ? 4 : (len - 3) + 4;
float rnoOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)itemInfo.MyDocStyle.CenterLineX + 5;
float tPtPerChar = itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.TabPtsPerChar ?? 6;
XOffset = rnoOffset + tPtPerChar * adj;
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - XOffset - 11; // 11 is about size of char, so don't touch right line.
if (myTab != null) myTab.XOffset = rnoOffset;
}
// 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:
else 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 (itemInfo.IsSequential && itemInfo.MyHLS.FormatStepData.AppendDotZero)// F2018-025 shift first level substep to column position of high level step Westinghouse wst1 step type 50
{
if (itemInfo.MyParent.IsHigh)
{
XOffset = MyParent.XOffset;
if (myTab != null) myTab.XOffset = (MyParent.MyTab != null ? MyParent.MyTab.XOffset : XOffset);
}
else
{
myTab.XOffset = MyParent.XOffset;
XOffset = myTab.XOffset + MyTab.Width;
}
}
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();
// B2021-113: BNPP1new - subsection & HLS should be same level (xoffset of tab & text)
if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.SubSectAndHighSameLevel && !MyItemInfo.MyActiveSection.MyParent.IsProcedure) indxLevels++;
float tableftadj = GetLeftJustify(formatInfo, indxLevels);
if (tableftadj != 0)
{
// the order of this is important. First adjust the tab's xoffset for the width of
// the tab. The offset of text needs to be adjusted by the 'leftjustify' format variable
// if it existed for this level.
myTab.XOffset += tabWidth;
if (tableftadj != 0 && myTab.Width < tableftadj)
tabWidth = myTab.Width = tableftadj;
XOffset += tabWidth;
myTab.Rtf = myTab.Rtf.Replace(myTab.Text, myTab.Text.TrimStart(" ".ToCharArray()));
Width = MyParent.Width - myTab.Width;
}
else // if no left justify, right align the tab
{
XOffset += tabWidth - (myTab == null ? 0 : myTab.TabAlign);
if (myTab != null)
{
myTab.XOffset += tabWidth - myTab.TabAlign;
if (myTab.MyMacro != null && myTab.MyMacro.XOffset != 0) myTab.MyMacro.XOffset += tabWidth - myTab.TabAlign;
}
}
}
//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
{
// The following fixes F2016-033: Print the Verification Point at left margin.
if (itemInfo.ActiveFormat.Name.ToUpper().StartsWith("VCB") && (itemInfo.FormatStepData.ColOverride ?? 0) > 0)
{
XOffset = (float)itemInfo.FormatStepData.ColOverride;
}
else
{
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;
}
// B2018-146 Adjust the width to match the HLS Right Margin.
if (itemInfo.IsBackgroundStepOrChild())
Width = this.MyHighLevelParagraph.Width + this.MyHighLevelParagraph.XOffset - this.XOffset;
}
}
}
// 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 bool PreviousIsTitleWithTextBelow(ItemInfo itemInfo)
{
while (itemInfo.MyPrevious != null)
{
if (itemInfo.MyPrevious.FormatStepData.Type == "TitleWithTextBelow") return true;
itemInfo = itemInfo.MyPrevious;
}
return false;
}
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;
}
private float _CheckOffWidth = 0;
public float CheckOffWidth
{
get { return _CheckOffWidth; }
set { _CheckOffWidth = value; }
}
private float _AdjustHeader = 0;// B2018-096 AEP 082.002CD Note Box overlapping Step Box
public float AdjustHeader
{
get { return _AdjustHeader; }
set { _AdjustHeader = value; }
}
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);
// Calvert subheaders in valve lists - the text gets centered, so the width is the width
// of the page (also, don't do this for alarms, thus the !SpecialCaseCalvert Alarms, since
// alarms use Caution1 as the annunciator):
if (itemInfo.IsStep && itemInfo.MyHLS != null && !itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm &&
itemInfo.MyHLS.FormatStepData.UseOldTemplate && itemInfo.MyDocStyle.ComponentList && itemInfo.IsCaution1)
{
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - (float)itemInfo.MyDocStyle.Layout.LeftMargin;
return;
}
// Calvert Alarms had a case where the Title With Text Below (type 42) did not match
// any of the template items, but needed the width from the template. The previous step (of
// same type) was in the template. Check for this case. The issue can be found in
// Unit 1 Alarms/1c06/Alarm E-48/'General Information' section.
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm && widOvrd == 0)
{
if (itemInfo.MyPrevious != null && itemInfo.MyPrevious.TemplateIndex > 1) widOvrd = GetWidthOrStartFromTemplate(itemInfo.MyPrevious, itemInfo.MyPrevious.ActiveFormat, true);
}
// for IP2 backgrounds, set widths appropriately for template items:
if (itemInfo.IsStep && (itemInfo.ActiveSection != null && (itemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListSpBckgrnd) == E_DocStructStyle.DSS_PageListSpBckgrnd)) // C2018-003 fixed use of getting the active section
{
if (itemInfo.FormatStepData.Type.ToUpper() == "TITLEWITHTEXTBELOW")
{
Width = MyParent.Width;
return;
}
if (itemInfo.MyPrevious != null && itemInfo.MyPrevious.FormatStepData.Type == "TitleWithTextBelow")
{
Width = MyParent.MyParent.Width;
return;
}
if (widOvrd == 0 && itemInfo.MyParent.IsStep &&
(itemInfo.MyParent.FormatStepData.Type.ToUpper() == "TITLEWITHTEXTBELOW" ||
(((itemInfo.ActiveSection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListSpBckgrnd) == E_DocStructStyle.DSS_PageListSpBckgrnd) &&
itemInfo.FormatStepData != null && MyParent.MyItemInfo.MyPrevious != null && MyParent.MyItemInfo.MyPrevious.FormatStepData.Type == "TitleWithTextBelow")))
{
Width = MyParent.MyParent.Width + (MyParent.MyParent.MyTab != null ? MyParent.MyParent.MyTab.Width : 0);
Width -= (MyTab != null ? MyTab.Width : 0);
return;
}
}
//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.ActiveSection != null && itemInfo.ActiveSection.ColumnMode != 0 && itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAlt != null) // C2018-003 fixed use of getting the active section
{
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)
{
//F2023-112 Vogtle Units 3 & 4 Backgrounds. Don't use override width of paragraph when it's off of TitleWithTextRight
// We need to allow the code to calculate the width of that paragraph for this case (later in this function)
if (!(itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.Vogtle3and4BackgroundFormat && itemInfo.MyParent.FormatStepData != null && itemInfo.MyParent.FormatStepData.Type == "TitleWithTextRight"))
{
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;
bool ChkOff = itemInfo.MyDocStyle.UseCheckOffs;
// C2019-040 use format flag to see if any of the steps in this section have a checkoff set - previously we check if the format file name starts with VCB (VCB no longer a customer)
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert || itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckoffsWithoutHeader)
{
SectionInfo si = itemInfo.ActiveSection.GetSectionInfo();
ChkOff = si.HasInitials; // this determines if any steps within the section have checkoffs.
}
bool FmtHasAdj = false;
if (ChkOff)
{
if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment != null)
{
FmtHasAdj = true;
CheckOffAdj = -(float)formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffAdjustment;
}
// C2019-040 use format flag to not readjust the CheckOffAdj value - previously we check if the format file name starts with VCB (VCB no longer a customer)
if (!itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckoffsWithoutHeader) // Don't do the following if in a vcb format (part of fix F2016-039)
{
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;
CheckOffWidth = -CheckOffAdj;
adjwidth = AdjustMetaWidth(itemInfo, formatInfo, adjwidth, FmtHasAdj);
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;
// B2022-002: Section text is printing into the INITIAL column (BNPP1new). If this flag is set adjust the width of the
// section text to that of the first hls (child) text and its tab. This is to prevent the very long section titles (that should have
// been steps) from extending into the INITIAL (checkoff) column.
if (formatInfo.PlantFormat.FormatData.SectData.AdjWidthForCheckOff && MyParent != null && MyParent.MyItemInfo.IsSection && ChkOff && CheckOffWidth != 0 && itemInfo.ItemID == itemInfo.FirstSibling.ItemID)
{
SectionInfo si = MyParent.MyItemInfo.GetSectionInfo();
if (si.HasInitials) MyParent.Width = Width + ((myTab == null) ? 0 : myTab.Width);
}
}
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
{
float oldWidth = _WidthAdjustBox + (float)bx.TxtWidth - tabWidth; // add 1 to get it to wrap like 16Bit
// B2018-096 AEP 082.002CD Note Box overlapping Step Box
if (MyParent.MyItemInfo.FormatStepData != null && MyParent.MyItemInfo.FormatStepData.BoxIt) // B2018-100 not for parents that are sections // B2018-098 only adjust width if parent has Boxit turned on
{
Width = Math.Min(MyParent.Width + MyParent.XOffset - XOffset, oldWidth);
AdjustHeader = (Width - oldWidth) / 2;
}
else
Width = oldWidth;
}
}
else if ((itemInfo.IsCaution || itemInfo.IsNote) && !itemInfo.FormatStepData.UseOldTemplate)
{
float mycolT = (float)formatInfo.MyStepSectionLayoutData.ColT;
if (formatInfo.MyStepSectionLayoutData.Dev_Format)
Width = (float)formatInfo.MyStepSectionLayoutData.WidT + 1;
else if (itemInfo.IsInRNO)
{
// C2014-009: Condition/Response adjust xoffset & width
// B2020-117 add a check that there is only one Caution/Note/Warning
if (MyItemInfo.FormatStepData.CenterOneLineAdjust && MyItemInfo.FirstSibling == MyItemInfo.LastSibling)
{
int rnoOff = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
XOffset = MyTopRNO.MyTab.XOffset + 7.2f;
Width = MyParent.Width + (MyParent.XOffset - XOffset);
}
else
{
XOffset = rnoOff + MyHighLevelParagraph.XOffset;
Width = MyParent.Width;
}
}
// B2020-117 There are muliple Cautions, Notes, or Warnings in the Calvert Alarm Contition/Response
// Need to adjust the starting positon of the bulleted tab, text and width
else if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
XOffset = MyTopRNO.MyTab.XOffset + 7.2f;
this.MyTab.XOffset = XOffset;
XOffset += this.MyTab.Width;
Width = MyParent.Width + (MyParent.XOffset - XOffset);
}
else
Width = (MyParent.XOffset + MyParent.Width) - (XOffset + mycolT);
}
else
{
// B2016-269: if caution/note & not boxed, with tab adjust width based on xoffset of tab
// so text doesn't print out of right border.
// B2017-027: Added a check for column mode - we only want to do this if in single column mode
if (!MyItemInfo.MyParent.IsHigh && MyTab != null && MyTab.YOffset == YOffset && MyItemInfo.ActiveSection != null && MyItemInfo.ActiveSection.ColumnMode == 0) // C2018-003 fixed use of getting the active section
{
// B2017-xxx if this is a caution/note off of a substep in the supinfo column, need to look up for its supinfo part, not
// its HLS.
if (MyItemInfo.IsInSupInfo)
{
vlnParagraph supinfopart = this;
while (supinfopart.MyParent != null && !supinfopart.MyItemInfo.IsSupInfoPart) supinfopart = supinfopart.MyParent;
XOffset = supinfopart.XOffset;
MyTab.XOffset = XOffset - MyTab.Width - 10;
Width = supinfopart.Width;
}
else
Width = MyHighLevelParagraph.Width - MyTab.Width - (MyTab.XOffset - MyHighLevelParagraph.XOffset) - 6;
}
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 = ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
float adjwidths = 0;
adjwidths = AdjustMetaWidth(itemInfo, formatInfo, adjwidths, false);
Width += (adjwidths + _WidthAdjust);
}
else if (MyParent == null)
{
// 72 points / inch - 7 inches (about width of page)
Width = 72 * 7;
}
else if (itemInfo.IsRNOPart && itemInfo.ActiveSection != null && itemInfo.ActiveSection.ColumnMode != 0 && itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAltAll != null) // C2018-003 fixed use of getting the active section
{
// This code was added for AEP. Other code that adjusted RNO widths was only adjusting the RNO widths
// off of the HLS. AEP needed adjusting for all RNOs.
float ovrd = (float)itemInfo.ActiveFormat.MyStepSectionLayoutData.RNOWidthAltAll;
if (ovrd > 0)
Width = ovrd - tabWidth;
if (XOffset + Width > (float)itemInfo.MyDocStyle.Layout.PageWidth)
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - XOffset - 5;
}
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.IsRtfRaw) // this needs to be before the check for 'IsTablePart' - the rtfraw may be a table part, but the size is defined by raw rtf
{
System.Drawing.Size sz = RtfRawItem.GetRtfRawSize(MyItemInfo.MyContent.Text);
Height = sz.Height;
Width = sz.Width;
Rtf = MyItemInfo.MyContent.Text;
}
else if (itemInfo.IsTablePart)
{
Width = 72 * 7; // TODO: Need to determine the Width of the Table based upon the contents
}
else if (itemInfo.MyParent.FormatStepData != null && itemInfo.MyParent.FormatStepData.Type == "TitleWithTextRight") // B2019-141: Background steps width too small
{
Width = (float)itemInfo.MyDocStyle.Layout.PageWidth - XOffset;
}
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 != null && itemInfo.MyTab.Position != 0)
Width = adjwidth + MyParent.Width;
else if (MyParent.WidthNoLimit != 0)
Width = adjwidth + MyParent.WidthNoLimit - tabWidth + (myTab == null ? 0 : myTab.TabAlign);
else if ((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListSpBckgrnd) == E_DocStructStyle.DSS_PageListSpBckgrnd)
Width = adjwidth + MyParent.Width - (MyTab != null ? MyTab.Width : 0);
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!!!
}
private float AdjustMetaWidth(ItemInfo itemInfo, FormatInfo formatInfo, float adjwidth, bool coadj)
{
SectData sd = formatInfo.PlantFormat.FormatData.SectData;
if (((itemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_SameXOffSubsections) == E_DocStructStyle.DSS_SameXOffSubsections))
{
// don't adjust the width if there already was an adjustment for checkoffs - for VCB only (F2016-039) - VCB no longer a customer
// C2019-040 use format flag to adjust the width (was already don for checkoffs) - previously we check if the format file name starts with VCB (VCB no longer a customer)
if (!(itemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckoffsWithoutHeader && coadj))
adjwidth = MyTab != null ? -MyTab.Width : 0;
}
else 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();
//F2022-023 Used the SubSectAndHighSameLevel (BNPP1New format) flag to get the proper level if we have sub-sections so that we get the proper WidSAdjByLevel value
if (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.SubSectAndHighSameLevel && !MyItemInfo.MyActiveSection.MyParent.IsProcedure) indxLevel++;
adjwidth += formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.MaxIndex].WidSAdjByLevel ?? 0; ;
float colsbylevel = (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[indxLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.MaxIndex].ColSByLevel;
float seclvlindent = colsbylevel - (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
adjwidth -= seclvlindent;
if (itemInfo.IsStep) adjwidth -= AdjustForSectionLevelTab();
if (itemInfo.IsSection && itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.WCNTraining)
adjwidth -= (float)((itemInfo.MyTab.CleanText.Trim().Length * 72) / itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.SectionHeader.Font.CPI);
}
}
else
{
if (formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.MaxIndex > 0)
adjwidth += (float)formatInfo.PlantFormat.FormatData.SectData.MetaSectionList[itemInfo.PrintLevel % formatInfo.PlantFormat.FormatData.SectData.MetaSectionList.MaxIndex].ColSByLevel;
}
}
return adjwidth;
}
// 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.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert
&& 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 || (itemInfo.MyDocStyle.ComponentList && itemInfo.MyHLS.FormatStepData.UseOldTemplate))
{
ItemInfo useForTemplate = itemInfo.IsHigh ? itemInfo : itemInfo.MyParent;
int topIndx = useForTemplate.GetSmartTemplateTopLevelIndx();
int tpIndx = -1;
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
if (itemInfo.IsCaution1) return false;
else tpIndx = useForTemplate.GetSmartTemplateIndex(topIndx, itemInfo.MyContent.Text);
}
else
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 following was added so that the Calvert Alarms sequentials under the CONDITION/RESPONSE would be
// printed as 2 column (data within the template definition set the columns to 2)
if (itemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
if (itemInfo.IsSequential && itemInfo.MyParent.TemplateIndex > 0)
{
if (bGetWidth && itemInfo.MyParent.ColumnMode == 1) // 2 columns
return (ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, itemInfo.ColumnMode) - MyTab.Width);
}
tmplIndx = itemInfo.TemplateIndex;
if (tmplIndx == -1) return 0;
}
else
{
// 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;
}
// Calvert Alarms' template defines number of columns & their width.
if (bGetWidth && formatInfo.PlantFormat.FormatData.Templates[tmplIndx].width == 0)
{
int nocol = formatInfo.PlantFormat.FormatData.Templates[tmplIndx].nocolm == 0 ? 0 : formatInfo.PlantFormat.FormatData.Templates[tmplIndx].nocolm - 1;
return ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, nocol);
}
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.MaxIndex != 0)
{
// does this section have a check off heading?
SectionConfig sc = (itemInfo.ActiveSection != null) ? itemInfo.MyActiveSection.MyConfig as SectionConfig : null; // C2018-003 fixed use of getting the active section
if (sc != null && sc.Section_CheckoffHeaderSelection > 0) return true;
}
if (formatInfo.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderInPagelist) 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;
//}
}
/// <summary>
/// First order by stepLevel, then within a stepLevel, order by descending yLocation on page.
/// Want to find maximum y value that fits on page, i.e. put the most on page that can
/// fit which is defined by the largest yLocation
/// </summary>
public class StepLevelList : SortedDictionary<int, SortedDictionary<float, vlnParagraph>>
{
public StepLevelList()
: base()
{
}
public void Add(int stepLevel, float yLocation, vlnParagraph para)
{
if (stepLevel == 0) return;
if (!this.ContainsKey(stepLevel))
this.Add(stepLevel, new SortedDictionary<float, vlnParagraph>());
// using a negative for yLocation so that its in descending order:
// B2020-112: Make various adjustments to location if there are format flags used
// B2020-116: Only make the 112 change for Calvert
// B2020-151: check for SpecialCaseCalvertPagination flag instead of SpecialCase Calvert flag so only EOPs/AOPs are affected
float adjust = 0;
if (para.MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertPagination)
adjust = para.YVeryTop - para.YTop;
//if (para.MyItemInfo.MyParent.IsHigh && (para.ChildrenAbove == null || para.ChildrenAbove.Count == 0))
//{
// //Console.WriteLine("Adjust Add extra Line (flag) = '{0}'", para);
// adjust -= para.AdjustForXBlankW1stLevSub;
//}
//else if (para.MyParent.MyItemInfo.IsHigh && (para.MyParent.ChildrenAbove != null && para.MyParent.ChildrenAbove.Count > 0)
// && para.MyParent.ChildrenAbove[0] == para)
//{
// //Console.WriteLine("Adjust Add extra Line (flag) = '{0}'", para);
// adjust -= para.MyParent.AdjustForXBlankW1stLevSub;
//}
//if (para.AdjustForMatchUpRNO != 0 && (para.ChildrenAbove == null || para.ChildrenAbove.Count == 0))
// adjust -= para.AdjustForMatchUpRNO;
//else if (para.MyParent.AdjustForMatchUpRNO != 0 && (para.MyParent.ChildrenAbove != null && para.MyParent.ChildrenAbove.Count > 0)
// && para.MyParent.ChildrenAbove[0] == para)
// adjust -= para.MyParent.AdjustForMatchUpRNO;
if (!this[stepLevel].ContainsKey(-(yLocation + adjust)))
this[stepLevel].Add(-(yLocation + adjust), para);
}
}
public class ParagraphLocations : List<ParagraphLocation>
{
public ParagraphLocations()
: base()
{
}
public void Add(vlnParagraph myParagraph, float yTopMost)
{
ParagraphLocation foundOverlap = FindOverlap(myParagraph);
if (foundOverlap == null)
{
this.Add(new ParagraphLocation(yTopMost, myParagraph));
return;
}
ParagraphLocation doubleOverlap = FindOverlap(foundOverlap);
while (doubleOverlap != null)
{
doubleOverlap.Merge(foundOverlap);
this.Remove(foundOverlap);
foundOverlap = doubleOverlap;
doubleOverlap = FindOverlap(foundOverlap);
}
}
private ParagraphLocation FindOverlap(vlnParagraph myParagraph)
{
foreach (ParagraphLocation paraLoc in this)
if (paraLoc.Overlap(myParagraph))
return paraLoc;
return null;
}
private ParagraphLocation FindOverlap(ParagraphLocation myParaLoc)
{
foreach (ParagraphLocation paraLoc in this)
if (paraLoc != myParaLoc && paraLoc.Overlap(myParaLoc))
return paraLoc;
return null;
}
internal StepLevelList BuildStepLevelList(bool KeepStepsOnPage)
{
StepLevelList myList = new StepLevelList();
foreach (ParagraphLocation paraLoc in this)
{
int level = paraLoc.StepLevel;
if (KeepStepsOnPage)
{
// B2020-116: change from checking for type 20001 to looking for a non-high sequential since some
// step types were sequential but not 20001
bool keepBullettedTogether = paraLoc.MyParagraph.MyItemInfo.IsSubStep;
if (!paraLoc.MyParagraph.MyItemInfo.IsHigh)
{
bool AlarmPagination = paraLoc.MyParagraph.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.AlarmPagination;
if (paraLoc.MyParagraph.MyItemInfo.IsSequential)
{
if (DontBreakHere(paraLoc))
//if (paraLoc.MyParagraph.MyItemInfo.MyPrevious == null) // First substep
level = 0;
else
level = 1; // AlarmPagination?3:1; // B2023-091: backout B2023-088 make it easier to break on a sequential for alarms
}
else if (AlarmPagination && paraLoc.MyParagraph.MyItemInfo.IsSubStep)
{
// make it harder to break on first caution or note & within a list if doing Alarm Pagination:
vlnParagraph myPara = paraLoc.MyParagraph;
if ((myPara.MyItemInfo.IsCaution || myPara.MyItemInfo.IsNote) && myPara.MyItemInfo.MyPrevious == null) level = 1;
else if (myPara.MyItemInfo.MyPrevious != null || myPara.MyItemInfo.NextItem != null) level = 2;
}
}
}
// For B2015-014, some migrated data for background documents had the TitleWithTextBelow with associated paragraphs
// as siblings rather than children. Pagination was sometimes putting the TitleWithTextBelow on one page and the
// paragraphs on next. The following code checks thse types, if in enhanced documents but not the Short Form Deviations.
if (paraLoc.MyParagraph.MyItemInfo.ActiveFormat != null
&& ((paraLoc.MyParagraph.MyItemInfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds)
|| (((paraLoc.MyParagraph.MyItemInfo.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedDeviations) == E_PurchaseOptions.EnhancedDeviations)
&& paraLoc.MyParagraph.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.EnhancedShortFormDev))
{
if (!paraLoc.MyParagraph.MyItemInfo.IsTitle && paraLoc.MyParagraph.MyItemInfo.MyPrevious != null && paraLoc.MyParagraph.MyItemInfo.MyPrevious.FormatStepData.Type == "TitleWithTextBelow") level = 0;
}
paraLoc.MyParagraph.levelForPagination = level;
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
{
//if (MyParagraph.MyItemInfo.InList(97960,84472,91010))
// Console.WriteLine("stop");
_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;
// B2020-115 Set a very large figure's Step Level so that pagination will happen prior to the figure.
if (myParagraph.MyItemInfo.IsFigure && myParagraph.MyParent.Height + myParagraph.Height > vlnParagraph.hMax)
{
StepLevel = 1;// Set figure as a guaranteed break location
}
}
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);
}
}
}