John 67a19a4358 F2022-024 – added logic to generate a Time Critical Action Summary report
F2022-024 – logic to replace {!Clock} with the defined genmac macro when step tab is printed from the pagelist (Enhanced Backgrounds)
2022-08-11 18:27:03 +00:00

7119 lines
361 KiB
C#
Raw Blame History

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)
{
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))
{
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)
yoff += vlnPrintObject.SixLinesPerInch * 2;
}
box = new vlnBox();
box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
int ln = 1; // a format flag determines whether there is a space before the note/caution.
//if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
if (childItemInfo.MixCautionNotesDiffType()) ln += 2;
box.YOffset = yoff + ((ln - 1) * vlnPrintObject.SixLinesPerInch);
if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
yoff += ln * vlnPrintObject.SixLinesPerInch;
}
}
bxIndex = bxIndx;
}
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);
if ((MyItemInfo.Cautions != null && MyItemInfo.Cautions[0].FormatStepData.AlwaysUseExtraLines) || (MyItemInfo.Notes != null && MyItemInfo.Notes[0].FormatStepData.AlwaysUseExtraLines))
yPageStart -= ((MyItemInfo.FormatStepData == null) ? 0 : MyItemInfo.FormatStepData.StepLayoutData.STExtraSpace ?? 0);
}
// Save the HLS & RNO string in case the pagelist item uses it (some of the backgrounds):
if (MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.PageBreakOnStep)
{
MyPageHelper.HLSTAB = MyItemInfo.HighLevelStepTabPageList;
// find the rno and use it's tab for the HLRNO part.
ItemInfo rno = MyItemInfo.RNOs != null && MyItemInfo.RNOs.Count > 0 ? MyItemInfo.RNOs[0] : null;
string rnotab = (rno == null) ? null : rno.DisplayText;
MyPageHelper.HLRNO = rno == null ? null : MyItemInfo.FormatStepData.TabData.RNOIdent + rnotab;
MyPageHelper.ResetSvg();
}
float yLocation = CalculateYOffset(yPageStart, yTopMargin);
if (MyItemInfo.HasChangeBar && MyPageHelper.ChangeBarDefinition.MyChangeBarType != PrintChangeBar.Without) MyPageHelper.AddChangeBar(DoChangeBar(cb, MyItemInfo, MyPageHelper, XOffset, yLocation, MyPageHelper.MaxRNO, MyItemInfo.ActiveFormat), cbMess);
float retval = yLocation;
// 'doprint' will always be true if not doing NSP's {HLSTEXT} token in page list. The following code is used to prevent
// printing the High level step, if the high level step is printed from the pagelist using {HLSTEXT} token.
bool doprint = !(MyPageHelper.DidHLSText && MyItemInfo.ItemID == MyPageHelper.HasHLSTextId);
if (MyItemInfo.IsFigure)
{
yLocation -= (SixLinesPerInch * MyPageHelper.YMultiplier);
if (ImageText != null)
retval = DrawFigure(cb, yBottomMargin, yLocation, 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.
bool doAlign = false;
if (MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert && (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
if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.CenterOneLineOnly && ((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}",
DebugId, MyItemInfo.ItemID, MyItemInfo.FormatStepType, MyItemInfo.FormatStepData == null ? "NoStepData" : MyItemInfo.FormatStepData.Type, MyItemInfo.StepLevel, MyItemInfo.ShortPath, Width, XOffset, YOffset);
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)
if (!MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.WCNTraining && !MyItemInfo.ActiveFormat.Name.ToUpper().StartsWith("FNP") && (MyParent.MyItemInfo 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())
{
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);
else if (PromsPrinter.MyFoldoutReader.Count > 0 && MyPageHelper.MyPromsPrinter.InsertBlankPages && (MyItemInfo.IsHigh && MyItemInfo.MyPrevious != null)) // B2018-108 if paginating on first step don't add blank page (it was already added at this point)
{
// 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();
if (MyItemInfo.IsStep && (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
{
// 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;
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();
if (!par.IsSection && 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);
}
// 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>
private float GetFirstPieceSize()
{
vlnParagraph paraLast = GetFirstPieceLastPart();
float retval = (paraLast.YBottom) - YTopMost;
//Console.WriteLine(MyItemInfo.DBSequence);
return retval;
}
public override float YBottom
{
get
{
float bottom = YOffset + Height;
if (PartsBelow != null)
{
foreach (vlnPrintObject part in PartsBelow)
{
float partBottom = part.YBottom;
bottom = Math.Max(partBottom, bottom);
}
}
return bottom;
}
}
public float YVeryBottom
{
get
{
float bottom = YOffset + Height;
if (ChildrenBelow != null)
foreach (vlnParagraph child in ChildrenBelow)
bottom = Math.Max(child.YVeryBottom, bottom);
if (ChildrenLeft != null)
foreach (vlnParagraph child in ChildrenLeft)
bottom = Math.Max(child.YVeryBottom, bottom);
if (ChildrenRight != null)
foreach (vlnParagraph child in ChildrenRight)
bottom = Math.Max(child.YVeryBottom, bottom);
if (PartsBelow != null)
foreach (vlnPrintObject part in PartsBelow)
bottom = Math.Max(part.YBottom, bottom);
return bottom;
}
}
public float YBottomText
{
get
{
return YOffset + Height;
}
}
private float _YBottomForBox = 0;
public float YBottomForBox
{
get { return _YBottomForBox; }
set { _YBottomForBox = value; }
}
private vlnParagraph GetFirstPieceLastPart()
{
vlnParagraph para = this;
if (!MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PaginateOnFirstSubstep && ChildrenBelow != null && ChildrenBelow.Count > 0)
{
// If the substep has a separator (OR, AND) then return the last substep rather than the first.
string mySep = ChildrenBelow[0].MyItemInfo.FormatStepData.Sep ?? "{Null}";
if (mySep != "{Null}" && mySep != "")
para = ChildrenBelow[ChildrenBelow.Count - 1].GetFirstPieceLastPart();
else
{
// MNS Pagination - Mike Weiner Case 1a to keep step together with any non-sequential substeps (ANDs, EQ List)
bool keepEqListTogether = ChildrenBelow[0].MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PutOnPageByItself;
if (keepEqListTogether && !ChildrenBelow[0].MyItemInfo.IsSequential && !this.MyItemInfo.IsHigh) // Extend to the last Item.
para = ChildrenBelow[ChildrenBelow.Count - 1].GetFirstPieceLastPart();
else
para = ChildrenBelow[0].GetFirstPieceLastPart();
}
}
if (ChildrenRight != null && ChildrenRight.Count > 0)
{
foreach (vlnParagraph paraRight in ChildrenRight)
{
vlnParagraph paraRightLast = paraRight.GetFirstPieceLastPart();
if (paraRightLast.YBottom > para.YBottom)
para = paraRightLast;
}
}
return para;
}
/// <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;
}
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;
}
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 AP<41>s; 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;
}
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 (!((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;
if (itemInfo.IsStep)
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;
if (MyItemInfo.MyDocStyle.SpecialStepsFoldout) return 0;
if (MyItemInfo.FormatStepData != null && MyItemInfo.FormatStepData.Prefix != null && MyItemInfo.FormatStepData.Suffix != null && MyItemInfo.FormatStepData.UseSmartTemplate) return 0;
int everyNLines = MyItemInfo.FormatStepData == null ? 1 : MyItemInfo.FormatStepData.StepLayoutData.EveryNLines ?? 1;
if (everyNLines == -99) return 0;
if (MyItemInfo.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;
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;
return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout || (MyItemInfo.MyDocStyle.ExtraLineHeader && (MyItemInfo.IsCaution || MyItemInfo.IsNote)) ? bSpaceIn ? SixLinesPerInch : 0 : 0);
}
private float AdjustToCharPosition(float position, float? CPI)
{
int iPosition = (int)position;
int charsToTwips = (int)(72 / (CPI ?? 12));
iPosition = (iPosition / charsToTwips) * charsToTwips;
position = (position / 7.2F) * 7.2F;
return (float)iPosition;
}
private bool _SectionPageBreak = false;
public bool SectionPageBreak
{
get { return _SectionPageBreak; }
set { _SectionPageBreak = value; }
}
private bool _Processed = false;
public bool Processed
{
get { return _Processed; }
set { _Processed = value; }
}
private vlnParagraph _LastRNO;
public vlnParagraph LastRNO
{
get { return _LastRNO; }
set { _LastRNO = value; }
}
private vlnParagraph _MyTopRNO;
public vlnParagraph MyTopRNO
{
get { return _MyTopRNO; }
set { _MyTopRNO = value; }
}
private static string _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;
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)
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.
if (itemInfo.IsBackgroundStepOrChild())
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()));
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)
{
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
if (!paraLoc.MyParagraph.MyItemInfo.IsHigh && paraLoc.MyParagraph.MyItemInfo.IsSequential)
{
if (DontBreakHere(paraLoc))
//if (paraLoc.MyParagraph.MyItemInfo.MyPrevious == null) // First substep
level = 0;
else
level = 1;
}
}
// 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;
}
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);
}
}
}