SourceCode/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs

3276 lines
139 KiB
C#
Raw Blame History

using System;
using System.Collections.Generic;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.factories;
using Volian.Svg.Library;
using System.Text.RegularExpressions;
using System.Xml;
using VEPROMS.CSLA.Library;
using Volian.Base.Library;
namespace Volian.Print.Library
{
public partial class VlnSvgPageHelper:SvgPageHelper
{
private float _TableAdjustment = 0;// RHM20150525 - Table Scrunch
public float TableAdjustment
{
get { return _TableAdjustment; }
set { _TableAdjustment = value; }
}
private vlnParagraph _AdjustedTable; // B2020-059 - save info of table that was compressed (set in vlnParagraph.cs DrawGrid() and used in RTF2PDF.cs TextAt())
public vlnParagraph AdjustedTable
{
get { return _AdjustedTable; }
set { _AdjustedTable = value; }
}
private float _AdjustedTableYtop;
public float AdjustedTableYtop // B2020-059 - save the Ytop of the compressed table (set in vlnParagraph.cs DrawGrid() and used in RTF2PDF.cs TextAt())
{
get { return _AdjustedTableYtop; }
set { _AdjustedTableYtop = value; }
}
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private pkParagraphs _MyPlacekeepers = new pkParagraphs();
public pkParagraphs MyPlacekeepers
{
get { return _MyPlacekeepers; }
}
private pkParagraphs _MyContActSteps = new pkParagraphs();
public pkParagraphs MyContActSteps
{
get { return _MyContActSteps; }
}
// F2022-024 Time Critical Action Step
private pkParagraphs _MyTimeCriticalActionSteps = new pkParagraphs();
public pkParagraphs MyTimeCriticalActionSteps
{
get { return _MyTimeCriticalActionSteps; }
}
private float? _BottomContent = null;// RHM20150525 - Table Scrunch
public float? BottomContent
{
get
{
return _BottomContent;
}
set
{
if(value == null || _BottomContent == null || _BottomContent > value)
_BottomContent = value;
}
}
private PageBookmarks _PageBookmarks = new PageBookmarks();
public PageBookmarks PageBookmarks
{
get { return _PageBookmarks; }
set { _PageBookmarks = value; }
}
private List<PdfOutline> _MyPdfOutlines = new List<PdfOutline>();
public List<PdfOutline> MyPdfOutlines
{
get { return _MyPdfOutlines; }
}
private ChkListBoxesHelper _CheckListBoxes = null;
private ChkListBoxesHelper CheckListBoxes
{
get { return _CheckListBoxes; }
set { _CheckListBoxes = value; }
}
private vlnText _TopMessage;
public vlnText TopMessage
{
get { return _TopMessage; }
set { _TopMessage = value; }
}
private List<vlnText> _TopMessageRs=new List<vlnText>(); // Added if there are 2 messages, in AER AND RNO (for BGE)
public List<vlnText> TopMessageRs
{
get { return _TopMessageRs; }
set { _TopMessageRs = value; }
}
private List<vlnText> _TopMessageSub1s=new List<vlnText>(); // BGE Alarms: in CONDITION/RESPONSE if break within substep
public List<vlnText> TopMessageSub1s
{
get { return _TopMessageSub1s; }
set { _TopMessageSub1s = value; }
}
private List<vlnText> _TopMessageSub2s=new List<vlnText>(); // BGE Alarms: in CONDITION/RESPONSE if break within substep
public List<vlnText> TopMessageSub2s
{
get { return _TopMessageSub2s; }
set { _TopMessageSub2s = value; }
}
private List<vlnText> _BottomMessage = new List<vlnText>(); // B2017-203) any continuous sections with end messages may have more than 1 message on a page
public List<vlnText> BottomMessage
{
get { return _BottomMessage; }
set { _BottomMessage = value; }
}
private vlnText _BottomMessageR; // Added if there are 2 messages, in AER AND RNO (for BGE)
public vlnText BottomMessageR
{
get { return _BottomMessageR; }
set { _BottomMessageR = value; }
}
private vlnText _BottomMessageA; // Added if there are 3 messages, at bottom AND in AER AND RNO (for BGEALARMS)
public vlnText BottomMessageA
{
get { return _BottomMessageA; }
set { _BottomMessageA = value; }
}
private Dictionary<int, List<int>> _NotesToFootNotesHLS = new Dictionary<int, List<int>>();
public Dictionary<int, List<int>> NotesToFootNotesHLS
{
get { return _NotesToFootNotesHLS; }
set { _NotesToFootNotesHLS = value; }
}
private List<vlnParagraph> _NotesToFootNotes = new List<vlnParagraph>();
public List<vlnParagraph> NotesToFootNotes
{
get { return _NotesToFootNotes; }
set { _NotesToFootNotes = value; }
}
private float _NotesToFootNotesYoffset = 0;
public float NotesToFootNotesYoffset
{
get { return _NotesToFootNotesYoffset; }
set { _NotesToFootNotesYoffset = value; }
}
Dictionary<int, vlnParagraph> _MyParagraphs = new Dictionary<int, vlnParagraph>();
public Dictionary<int, vlnParagraph> MyParagraphs
{
get { return _MyParagraphs; }
set { _MyParagraphs = value; }
}
float _YMultiplier = 1;
public float YMultiplier
{
get { return _YMultiplier; }
set { _YMultiplier = value; }
}
float _PhoneListHeight = 0;
public float PhoneListHeight
{
get { return _PhoneListHeight; }
set { _PhoneListHeight = value; }
}
private float _AlarmYoffStart = 0;
public float AlarmYoffStart
{
get { return _AlarmYoffStart; }
set { _AlarmYoffStart = value; }
}
private float _AlarmYoffEnd = 0;
public float AlarmYoffEnd
{
get { return _AlarmYoffEnd; }
set { _AlarmYoffEnd = value; }
}
private float _SectionSepLineYoffStart = 0;
public float SectionSepLineYoffStart
{
get { return _SectionSepLineYoffStart; }
set { _SectionSepLineYoffStart = value; }
}
private PdfWriter _MyPdfWriter;
public PdfWriter MyPdfWriter
{
get { return _MyPdfWriter; }
set
{
MyPageCounts = new PageCounts();
MyTOCPageCounts = new PageCounts();
MyTOCPageNums = new Dictionary<string, int>();
_MyPdfWriter = value;
}
}
private PdfContentByte _MyPdfContentByte;
public PdfContentByte MyPdfContentByte
{
get { return _MyPdfContentByte; }
set { _MyPdfContentByte = value; }
}
private int _FinalMessageSectionID;
public int FinalMessageSectionID
{
get { return _FinalMessageSectionID; }
set { _FinalMessageSectionID = value; }
}
private bool _DidFirstPageDocStyle = false;
public bool DidFirstPageDocStyle
{
get { return _DidFirstPageDocStyle; }
set { _DidFirstPageDocStyle = value; }
}
public override void OnCloseDocument(PdfWriter writer, iTextSharp.text.Document document)
{
AddBookmarks(writer);
MyPageCounts.DrawTemplates();
}
private bool _OnBlankPage = false;
public bool OnBlankPage // used while inserting a blank page when printing a procedure with duplex foldouts
{
get { return _OnBlankPage; }
set { _OnBlankPage = value; }
}
// when false, no page has been printed yet (for determining whether a blank page before print
// needs done if first section has foldouts)
private bool _PrintedAPage = false;
public bool PrintedAPage
{
get { return _PrintedAPage; }
set { _PrintedAPage = value; }
}
// the following two variables are used to handle the 'PSOnlyFirst' page list Justify flag.
// PSOnlyFirst signals that the pagelist token should only be processed for the first page of
// the section. It gets set when this token is processed, so that any remaining pages will
// not get the token. It's value is derived by taking the different the location of this token
// & the location of the previous token, so that this amount can be used to move the text up
// on the 'not first' pages of the section. It's used as an adjustment on the topmargin.
// This is used in FNP formats.
private int _sectLevelNumTtlDiff = 0;
private int _PrintedSectionPage = 0;
public int PrintedSectionPage
{
get { return _PrintedSectionPage; }
set { _PrintedSectionPage = value; }
}
private static int _CountInApplProcs; // B2021-127: BNPPalr - Auto set of serial #
public static int CountInApplProcs
{
get { return _CountInApplProcs; }
set { _CountInApplProcs = value; }
}
//private bool _AddBlankPagesForDuplexPrinting = false;
//public bool AddBlankPagesForDuplexPrinting // Tells us if a the option to add a blank page is turn on (for procedures with duplex foldouts)
//{
// get { return _AddBlankPagesForDuplexPrinting; }
// set { _AddBlankPagesForDuplexPrinting = value; }
//}
private int _prevSectId = 0;
public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document)
{
TableAdjustment = 0;// RHM20150525 - Table Scrunch
//string path = Volian.Base.Library.vlnStackTrace.StackToStringLocal(3, 1);
//Console.WriteLine("End {0}",path);
int profileDepth = ProfileTimer.Push(">>>> OnEndPage");
InitialsPrinted = false;
MyPromsPrinter.OnStatusChanged(string.Format("Page {0}", CurrentPageNumber+1));
// B2019-152: Landscape page merged page numbers
if (this.MySection != null && MySection.MyDocStyle.LandscapePageList) PromsPrinter.AddMergedLandscapePage(this, MyPromsPrinter.PDFFile);
bool onBlankPage = OnBlankPage;
if (OnBlankPage)
{
OnBlankPage = false;
}
else if (!OnFoldoutPage)
{
if (DidFirstPageDocStyle) SetDocStyleAndValues();
AddBookmarks(writer);
MyPageCounts.CanIncrement = true;
base.OnEndPage(writer, document);
DrawFootnotes(writer.DirectContent);
DrawChangeBars(writer.DirectContent);
DrawMessages(writer.DirectContent);
if (!CreatingFoldoutPage && !CreatingSupInfoPage)
{
DrawRuler(writer.DirectContent);
float x = MySection == null ? 555 : (float)MySection.MyDocStyle.Layout.PageWidth;
DrawBottomRuler(writer.DirectContent, x / 2 - 144); //aer column
DrawBottomRuler(writer.DirectContent, x - 144); //rno column
}
}
else
{
E_NumberingSequence numseq = MySection.MyDocStyle.NumberingSequence??0;
// if a foldout is only printing within its section, don't do increments on pagecounts:
if (numseq==E_NumberingSequence.WithinEachSection)
MyPageCounts.CanIncrement = false;
else
MyPageCounts.CanIncrement = true;
base.OnEndPage(writer, document);
if (!CreatingFoldoutPage && !CreatingSupInfoPage)
DrawRuler(writer.DirectContent);
}
// added the check for onBlankPage and Foldouts to fix bug found in V.C. Summer auto table of contents - 03/08/2016
//C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
if (!onBlankPage && (MySection.MyDocStyle.StructureStyle.Style==null || (MySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DontCountInTabOfCont) == 0) &&
!(MySection.ActiveFormat.PlantFormat.FormatData.PrintData.SectionLevelFoldouts && (MySection.MyConfig as SectionConfig).Section_IsFoldout == "Y"))
CurrentTOCPageNumber++;
if (MySection.ActiveFormat.PlantFormat.FormatData.SectData.PrintPhoneList)
{
SectionConfig sc = MySection.MyConfig as SectionConfig;
if (sc.Section_PhoneList != null && sc.Section_PhoneList == "Y")
{
// yoffset the footer length + the size of the phone list:
float yoff = (float)MySection.MyDocStyle.Layout.FooterLength + PhoneListHeight + 12; // 12 is an extra line for the horizontal.
DocVersionConfig dvc = MySection.MyDocVersion.MyConfig as DocVersionConfig;
if (dvc != null)
DrawPhoneList(writer.DirectContent, (float)MySection.MyDocStyle.Layout.LeftMargin, (float)MySection.MyDocStyle.Layout.PageWidth, yoff, dvc.Print_PhoneList);
}
}
if (MySection.MyDocStyle.CenterLineX != null && !onBlankPage)
{
if ((MySection.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS)
DrawHorizontal(writer.DirectContent, (float)MySection.MyDocStyle.Layout.LeftMargin, (float)MySection.MyDocStyle.Layout.PageWidth, (float)MySection.MyDocStyle.CenterLineYTop);
//if (MySection.ColumnMode > 0 && onBlankPage == false)
if (MySection.ColumnMode > 0 || MySection.ActiveFormat.PlantFormat.FormatData.PrintData.WCNTraining)
{
DrawCenterLine(writer.DirectContent, MySection.MyDocStyle.Layout.LeftMargin + MySection.MyDocStyle.CenterLineX ?? 0, MySection.MyDocStyle.CenterLineYTop ?? 0, MySection.MyDocStyle.CenterLineYBottom ?? 0);
if (MySection.ActiveFormat.PlantFormat.FormatData.PrintData.WCNTraining)
{
// only draw the line if this is a new section.
if (MySection.ItemID != _prevSectId) DrawHorizontal(writer.DirectContent, (float)(MySection.ActiveFormat.PlantFormat.FormatData.SectData.SectionHeaderSeparatorLine.XStartPos ?? 0), (float)(MySection.ActiveFormat.PlantFormat.FormatData.SectData.SectionHeaderSeparatorLine.Length ?? 0), SectionSepLineYoffStart);
_prevSectId = MySection.ItemID;
}
}
}
if (MySection.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm)
{
float left = (float)MySection.MyDocStyle.Layout.LeftMargin + 4.40f - 6; // used 4.40 -6 to line up with the macro & not touch two digit sub-step tabs.
float right = (float)MySection.MyDocStyle.Layout.PageWidth - .76f; // used -.76 to make bge alarm lines closest to lining up with macro
if (AlarmYoffStart > 0)
{
// draw vertical - either to the alarmyoffend or bottom of page
if (AlarmYoffEnd > 0) // ends on this page.
{
DrawVertical(writer.DirectContent, left, AlarmYoffStart, AlarmYoffEnd);
DrawVertical(writer.DirectContent, right, AlarmYoffStart, AlarmYoffEnd);
DrawVertical(writer.DirectContent, (right + left) / 2, AlarmYoffStart, AlarmYoffEnd);
DrawHorizontal(writer.DirectContent, left, right, AlarmYoffEnd);
AlarmYoffStart = 0;
AlarmYoffEnd = 0;
}
else
{
float yBottom = (float)(writer.DirectContent.PdfWriter.PageSize.Height - ((float)MySection.MyDocStyle.Layout.TopMargin + (float)MySection.MyDocStyle.Layout.PageLength));
DrawVertical(writer.DirectContent, left, AlarmYoffStart, yBottom);
DrawVertical(writer.DirectContent, right, AlarmYoffStart, yBottom);
DrawVertical(writer.DirectContent, (right + left) / 2, AlarmYoffStart, yBottom);
DrawHorizontal(writer.DirectContent, left, right, yBottom);
AlarmYoffStart = (float)writer.DirectContent.PdfWriter.PageSize.Height - (float)MySection.MyDocStyle.Layout.TopMargin;
}
}
}
PageListTopCheckOffHeader = null;
PageListLastCheckOffHeader = null;
BottomContent = null;
YMultiplier = 1;
PrintedAPage = true;
ProfileTimer.Pop(profileDepth);
}
private void DrawBottomRuler(PdfContentByte cb, float x)
{
VlnSvgPageHelper myPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper;
if (myPageHelper.DebugLayer != null)
{
cb.BeginLayer(myPageHelper.DebugLayer);
cb.SaveState();
cb.SetLineWidth(.1F);
cb.SetColorStroke(new Color(System.Drawing.Color.Plum));
float height = 350;
float yTop = 350;
float yBottom = yTop - height;
cb.MoveTo(x, yTop);
cb.LineTo(x, yBottom);
if (myPageHelper.BottomContent != null)
{
cb.MoveTo(0, (float)myPageHelper.BottomContent);
cb.LineTo(PDFPageSize.PaperSizePoints(MySection.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize), (float)myPageHelper.BottomContent); // C2020-002 paper size is now set in the format files
}
int i = 0;
for (float y = yBottom; y <= yTop; y += 12)
{
float w = 10;
if (i % 6 == 0) w = 30;
else if (i % 3 == 0) w = 20;
cb.SetLineWidth(w / 30);
i++;
cb.MoveTo(x + w, y);
cb.LineTo(x, y);
cb.Stroke();
}
for (float y = yBottom; y <= yTop; y += 10)
{
float w = 10;
if (i % 10 == 0) w = 30;
else if (i % 5 == 0) w = 20;
cb.SetLineWidth(w / 30);
i++;
cb.MoveTo(x - w, y);
cb.LineTo(x, y);
cb.Stroke();
}
i = 0;
cb.Stroke();
cb.RestoreState();
cb.EndLayer();
}
}
private void DrawVertical(PdfContentByte cb, float x, float top, float bottom)
{
cb.SaveState();
if (PageListLayer != null) cb.BeginLayer(PageListLayer);
cb.SetColorStroke(new Color(PrintOverride.SvgColor));
cb.SetLineWidth(1.05f); // Tweak the line width to match vlnmacro
//cb.SetColorStroke(lineColor);
cb.MoveTo(x, top);
cb.LineTo(x, bottom);
cb.Stroke();
if (PageListLayer != null) cb.EndLayer();
cb.RestoreState();
}
private void DrawPhoneList(PdfContentByte pdfContentByte, float leftMargin, float pageWidth, float yOff, string plist)
{
// draw the line above the phone list:
yOff = yOff + 4; // move up 1/2 line:
DrawHorizontal(pdfContentByte, leftMargin, pageWidth, yOff);
pdfContentByte.SaveState();
if (PageListLayer != null) pdfContentByte.BeginLayer(PageListLayer);
pdfContentByte.SetColorStroke(new Color(PrintOverride.SvgColor));
// for each line, break it into phone items for printing. Note that 16bit code also supported
// a tabbing line - BGE wasn't using this in data at time of development. The following code may
// need expanded to support the tabbing/column definitions if this is found in data.
float lyoff = yOff - 4;
plist = plist.Replace("\r", string.Empty);
string[] lines = plist.Split("\n".ToCharArray());
DocStyle docstyle = MySection.MyDocStyle;
try
{
foreach (string clinex in lines)
{
string cline = clinex.TrimEnd();
if (cline != string.Empty)
{
// xoff handles the columns. The separator between phone items is a double space. A phone
// item may have a single space within it (this comes from 16bit implementation)
float xoff = (float)docstyle.Layout.LeftMargin;
int stLineindx = 0;
int endLineindx = cline.IndexOf(" ");
bool endOfLine = false;
while (!endOfLine)
{
if (endLineindx - stLineindx > 0)
{
string phone = cline.Substring(stLineindx, endLineindx - stLineindx);
float tmp = 0;
vlnText vt = new vlnText(pdfContentByte, null, phone, phone, xoff, lyoff, MySection.ActiveFormat.PlantFormat.FormatData.Font);
vt.ToPdf(pdfContentByte, 0, ref tmp, ref tmp);
xoff += 132; // columns in 16bit were a little more than 1 3/4 inches.
stLineindx = endLineindx;
if (stLineindx >= cline.Length) break;
while (cline[stLineindx] == ' ' && stLineindx < cline.Length) stLineindx++;
if (stLineindx >= cline.Length - 1) endOfLine = true;
else
{
endLineindx = cline.IndexOf(" ", stLineindx);
if (endLineindx == -1) endLineindx = cline.Length;
}
}
else
endOfLine = true;
}
lyoff = lyoff - vlnPrintObject.SixLinesPerInch;
}
}
}
catch (Exception ex)
{
_MyLog.Error("Error processing phone list.", ex);
}
if (PageListLayer != null) pdfContentByte.EndLayer();
pdfContentByte.RestoreState();
}
private void DrawHorizontal(PdfContentByte cb, float left, float right, float yoff)
{
// if there are gaps, check to be sure top isn't a double line box. If it's a box, don't draw the top line.
if (MyGaps != null && MyGaps.Count > 0 && MyGaps[0].YTop == (float)MySection.MyDocStyle.CenterLineYTop) return;
cb.SaveState();
if (PageListLayer != null) cb.BeginLayer(PageListLayer);
cb.SetColorStroke(new Color(PrintOverride.SvgColor));
if (MySection.MyDocStyle.CLineWidth != null && MySection.MyDocStyle.CLineWidth != 0) cb.SetLineWidth((float)MySection.MyDocStyle.CLineWidth);
//cb.SetColorStroke(lineColor);
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine("HorzLn X1={0} Y={1} X2={2}", left, yoff, right);
cb.MoveTo(left, yoff);
cb.LineTo(right, yoff);
cb.Stroke();
if (PageListLayer != null) cb.EndLayer();
cb.RestoreState();
}
private Gaps _MyGaps;
public Gaps MyGaps
{
get
{
if (_MyGaps == null)
_MyGaps = new Gaps();
return _MyGaps;
}
}
public void AddGap(float top, float bottom, float left, float right)
{
float center = MySection.MyDocStyle.Layout.LeftMargin + MySection.MyDocStyle.CenterLineX ?? 0;
if(center == 0) return;
if (center > right || center < left) return;
MyGaps.Add(top, bottom);
}
private void DrawCenterLine(PdfContentByte cb, float xLoc, float yTop, float yBottom)
{
//iTextSharp.text.Color lineColor = new iTextSharp.text.Color(PrintOverride.OverrideTextColor(System.Drawing.Color.DarkOrange));
cb.SaveState();
if (PageListLayer != null) cb.BeginLayer(PageListLayer);
float lwidth = MySection.MyDocStyle.CLineWidth ?? .95f;
cb.SetLineWidth(lwidth);
cb.SetColorStroke(new Color(PrintOverride.SvgColor));
//cb.SetColorStroke(lineColor);
cb.MoveTo(xLoc, yTop);
float ylast = yTop;
if (_MyGaps != null)
{
foreach (Gap gap in MyGaps)
{
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine("CntrLn X={0} Top={1} Btm={2}", xLoc, ylast, gap.YTop - (gap.YTop - gap.YBottom) * YMultiplier);
cb.LineTo(xLoc, gap.YTop);
cb.MoveTo(xLoc, gap.YTop - (gap.YTop - gap.YBottom) * YMultiplier);
ylast = gap.YTop - (gap.YTop - gap.YBottom) * YMultiplier;
}
_MyGaps = null;
}
// put in for V.C. Summer
// the end message for EOP procedure 15.2 was at the very bottom of the page.
// the remaining center line was drawn past the page boarder. there was no need
// to print it for cases like that
if (ylast > yBottom)
{
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine("CntrLn X={0} Top={1} Btm={2}", xLoc, ylast, yBottom);
cb.LineTo(xLoc, yBottom);
}
cb.Stroke();
if (PageListLayer != null) cb.EndLayer();
cb.RestoreState();
}
private bool SetDocStyleAndValues()
{
// 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
// AND reset the 'svg' data.
bool forceLoadSvg = false;
if ((MySection.MyDocStyle.StructureStyle.Where & E_DocStyleUse.UseOnFirstPage) > 0)
{
//Console.WriteLine("{0} ResetDocStyleAndValues", MySection.MyDocStyle.Name);
ItemInfo ii = (ItemInfo) MySection;
int indx = (int)MySection.MyDocStyle.IndexOtherThanFirstPage;
foreach (DocStyle ds in ii.ActiveFormat.PlantFormat.DocStyles.DocStyleList)
{
if (ds.Index == indx)
{
MySection.MyDocStyle = ds;
forceLoadSvg = true;
break;
}
}
}
return forceLoadSvg;
}
public void ResetSvg()
{
Volian.Svg.Library.Svg sectSvg = BuildSvg(_MySection, true);
if (sectSvg != null) MySvg = sectSvg;
}
private float? _YTopMargin = null;
public float? YTopMargin
{
get { return _YTopMargin - _AdjustTopMarginForMultiLinePageListItems; }
set { _YTopMargin = value; }
}
private void DrawRuler(PdfContentByte cb)
{
if (DebugLayer == null) return;
Layout layout = MySection.MyDocStyle.Layout;
cb.SaveState();
cb.BeginLayer(DebugLayer);
float x = (cb.PdfWriter.PageSize.Left + cb.PdfWriter.PageSize.Right) / 2;
cb.SetLineWidth(.1F);
cb.SetColorStroke(new Color(System.Drawing.Color.CornflowerBlue));
float yTop = (float)(cb.PdfWriter.PageSize.Height - layout.TopMargin);
//Console.WriteLine("Page,yTop,yTopMargin {0},{1},{2}", cb.PdfDocument.PageNumber, yTop, YTopMargin);
if(YTopMargin != null) yTop = (float)YTopMargin;
float yBottom = (float)(cb.PdfWriter.PageSize.Height - (layout.TopMargin + layout.PageLength));
//Console.WriteLine("'{0}',{1},{2}", MySection.MyDocStyle.Name, yTop, yBottom);
cb.MoveTo(x, yTop);
cb.LineTo(x, yBottom);
int i = 0;
for (float y = yTop; y >= yBottom; y -= 12)
{
float w = 10;
if (Volian.Base.Library.VlnSettings.GetCommandFlag("InchRuler"))
{
if (i % 6 == 0) w = 30;
else if (i % 3 == 0) w = 20;
}
else
{
if (i % 10 == 0) w = 30;
else if (i % 5 == 0) w = 20;
}
cb.SetLineWidth(w / 30);
i++;
cb.MoveTo(x - w, y);
cb.LineTo(x, y);
cb.Stroke();
}
i = 0;
for (float y = yTop; y >= yBottom; y -= 10.1F)
{
float w = 10;
if (Volian.Base.Library.VlnSettings.GetCommandFlag("InchRuler"))
{
if (i % 7 == 0) w = 30;
//else if (i % 5 == 0) w = 20;
}
else
{
if (i % 10 == 0) w = 30;
else if (i % 5 == 0) w = 20;
}
cb.SetLineWidth(w / 30);
i++;
cb.MoveTo(x + w, y-1);
cb.LineTo(x, y-1);
cb.Stroke();
}
cb.SetLineWidth(.1F);
cb.Rectangle((float)layout.LeftMargin, yTop, (float)layout.PageWidth - (float)layout.LeftMargin, yBottom - yTop);
float yFooter = yBottom+(float)layout.FooterLength;
cb.MoveTo((float)layout.LeftMargin,yFooter);
cb.LineTo((float)layout.PageWidth, yFooter);
float yRuler = 612;
cb.MoveTo(0, yRuler);
cb.LineTo(612, yRuler);
for (float x1 = 0; x1 < 612; x1 += 6) // tic marks every 1/12 inch
{
if (x1 % 72 == 0)
{
cb.MoveTo(x1, yRuler-20);
cb.LineTo(x1, yRuler+20);
}
else if (x1 % 36 == 0)
{
cb.MoveTo(x1, yRuler-10);
cb.LineTo(x1, yRuler+10);
}
else
{
cb.MoveTo(x1, yRuler-5);
cb.LineTo(x1, yRuler);
}
}
for (float x1 = 0; x1 < 612; x1 += 7.2f) // tic marks every 1/10 inch
{
if (x1 % 72 == 0)
{
cb.MoveTo(x1, yRuler);
cb.LineTo(x1, yRuler + 20);
}
else if (x1 % 36 == 0)
{
cb.MoveTo(x1, yRuler);
cb.LineTo(x1, yRuler + 10);
}
else
{
cb.MoveTo(x1, yRuler);
cb.LineTo(x1, yRuler + 5);
}
}
//cb.MoveTo(122.4F, 0); //WCN2 HLS
//cb.LineTo(122.4F, cb.PdfWriter.PageSize.Height);
//cb.MoveTo(78, 0); // HLP HLS
//cb.LineTo(78, cb.PdfWriter.PageSize.Height);
//cb.MoveTo(441, 0); // HLP cover page date
//cb.LineTo(441, cb.PdfWriter.PageSize.Height);
//cb.MoveTo(71.4F, 0); // WCN Purpose page, Revision: {REV}
//cb.LineTo(71.4F, cb.PdfWriter.PageSize.Height);
cb.Stroke();
cb.EndLayer();
cb.RestoreState();
}
private void AddBookmarks(PdfWriter writer)
{
foreach (PageBookmark pb in PageBookmarks)
{
int lev = pb.Level;
if (MyPdfOutlines.Count < lev || lev==0)
{
PdfDestination dest = new PdfDestination(PdfDestination.FIT);
PdfOutline pdo = new PdfOutline(writer.DirectContent.RootOutline, dest, pb.Title, false);
if (MyPdfOutlines.Count == lev)
MyPdfOutlines.Add(pdo);
else
MyPdfOutlines[lev] = pdo;
}
else
{
PdfDestination dest =pb.PdfDestination;
if(dest==null) dest = new PdfDestination(PdfDestination.FIT);
PdfOutline pdo = new PdfOutline(MyPdfOutlines[lev-1], dest,Regex.Replace(pb.Title, @"\\{Prerequisite Step: .*?\\}", string.Empty), false);
if (MyPdfOutlines.Count == lev)
MyPdfOutlines.Add(pdo);
else
MyPdfOutlines[lev] = pdo;
}
}
PageBookmarks.Clear();
}
private void DrawFootnotes(PdfContentByte cb)
{
float tmp = 0;
if (NotesToFootNotes != null && NotesToFootNotes.Count > 0)
{
float _PointsPerPage = (float)PDFPageSize.PaperSizePoints(MySection.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize); // C2020-002 paper size is now set in the format files
float yTopMargin = _PointsPerPage - (float)MySection.MyDocStyle.Layout.TopMargin;
float myYOff = NotesToFootNotesYoffset;
foreach (vlnParagraph ntfn in NotesToFootNotes)
{
// subtract from yTopMargin to take the location from the 'roll of paper'
// to the physical page location.
ntfn.YOffset = yTopMargin - myYOff;
ntfn.YTopMost = yTopMargin - myYOff;
ntfn.Processed = false; // process from here
// Only use ParagraphToPdf for printing of a single step.
// This is assuming that footnotes do not have child steps.
ntfn.ParagraphToPdf(cb, yTopMargin, yTopMargin, tmp);
//ntfn.ToPdf(cb, yTopMargin, ref yTopMargin, ref tmp);
myYOff -= (ntfn.Height); // - vlnPrintObject.SixLinesPerInch);
}
NotesToFootNotes = null;
}
}
private void DrawMessages(PdfContentByte cb)
{
float tmp = 0;
if (TopMessage != null)
{
TopMessage.ToPdf(cb, 0, ref tmp, ref tmp);
TopMessage = null; // Only output it once.
}
if (TopMessageRs != null && TopMessageRs.Count > 0)
{
foreach (vlnText vt in TopMessageRs)
{
vt.ToPdf(cb, 0, ref tmp, ref tmp);
}
TopMessageRs = null; // Only output it once.
}
if (TopMessageSub1s != null)
{
foreach (vlnText vts1 in TopMessageSub1s)
{
vts1.YOffset = AlarmYoffStart - 3 * vlnPrintObject.SixLinesPerInch;
vts1.ToPdf(cb, 0, ref tmp, ref tmp);
}
TopMessageSub1s = null; // Only output it once.
}
if (TopMessageSub2s != null)
{
foreach (vlnText vts2 in TopMessageSub2s)
{
vts2.YOffset = AlarmYoffStart - 3 * vlnPrintObject.SixLinesPerInch;
vts2.ToPdf(cb, 0, ref tmp, ref tmp);
}
TopMessageSub2s = null; // Only output it once.
}
if (BottomMessage != null && BottomMessage.Count != 0)
{
foreach (vlnText vts3 in BottomMessage)
{
vts3.ToPdf(cb, 0, ref tmp, ref tmp);
}
BottomMessage.Clear(); // Only output it once.
}
if (BottomMessageR != null)
{
BottomMessageR.ToPdf(cb, 0, ref tmp, ref tmp);
BottomMessageR = null; // Only output it once.
}
if (BottomMessageA != null)
{
BottomMessageA.ToPdf(cb, 0, ref tmp, ref tmp);
BottomMessageA = null; // Only output it once.
}
}
public void DrawBottomMessage(PdfContentByte cb)
{
float tmp = 0;
if (BottomMessage != null && BottomMessage.Count != 0)
{
foreach (vlnText vts in BottomMessage)
{
vts.ToPdf(cb, 0, ref tmp, ref tmp);
}
BottomMessage.Clear(); // Only output it once.
}
}
private void DrawChangeBars(PdfContentByte cb)
{
float tmp = 0;
// B2022-060 Prairie Island Alarms, change bars on second page of Alarm Point would sometimes be printed to far down the page
// The TopMargin setting of the first page is different than the second page and needed to be passed in to ToPDF for change bars
float topMargin = (float)MySection.MyDocStyle.Layout.TopMargin;
foreach (vlnChangeBar vcb in MyChangeBars)
{
// TODO: Pass in zeroes because topdf is inherited.
vcb.ToPdf(cb, topMargin, ref tmp, ref tmp);
}
_MyChangeBars = new List<vlnChangeBar>();
}
#region SectionLevelData
private ChangeBarDefinition _ChangeBarDefinition;
public ChangeBarDefinition ChangeBarDefinition
{
get { return _ChangeBarDefinition; }
set { _ChangeBarDefinition = value; }
}
#endregion
private PdfLayer _TextLayer;
public PdfLayer TextLayer
{
get { return _TextLayer; }
set { _TextLayer = value; }
}
private PdfLayer _DebugLayer;
public PdfLayer DebugLayer
{
get { return _DebugLayer; }
set { _DebugLayer = value; }
}
private VEPROMS.CSLA.Library.SectionInfo _MySection;
public VEPROMS.CSLA.Library.SectionInfo MySection
{
get { return _MySection; }
set
{
_MySection = value;
MySectionTitle = ((_MySection.DisplayNumber ?? string.Empty)==string.Empty ? string.Empty : _MySection.DisplayNumber + " - ") + _MySection.DisplayText;
bool forceLoadSvg = false;
if (value.SectionConfig.Section_Pagination == SectionConfig.SectionPagination.Separate && value.MyDocStyle.ResetFirstPageOnSection)
DidFirstPageDocStyle = false;
if (DidFirstPageDocStyle)
forceLoadSvg = SetDocStyleAndValues(); // this method also gets the SVG (the 'else' part of this)
Volian.Svg.Library.Svg sectSvg = BuildSvg(_MySection, forceLoadSvg);
if (sectSvg != null) MySvg = sectSvg;
_YTopMargin = null;
}
}
private string _MySectionTitle;
public string MySectionTitle
{
get { return _MySectionTitle; }
set { _MySectionTitle = value; }
}
private int _MaxRNO;
public int MaxRNO
{
get
{
return _MySection.ColumnMode;
}
}
private int _CurrentPageOf = 0;
public int CurrentPageOf
{
get { return _CurrentPageOf; }
set { _CurrentPageOf = value; }
}
private string _Rev = string.Empty;
public string Rev
{
get { return _Rev; }
set { _Rev = value; }
}
private string _RevDate = string.Empty;
public string RevDate
{
get { return _RevDate; }
set { _RevDate = value; }
}
private bool _DoFloatingFoldout = true;
public bool DoFloatingFoldout
{
get { return _DoFloatingFoldout; }
set { _DoFloatingFoldout = value; }
}
private List<vlnChangeBar> _MyChangeBars = new List<vlnChangeBar>();
public List<vlnChangeBar> MyChangeBars
{
get { return _MyChangeBars; }
set { _MyChangeBars = value; }
}
public void AddChangeBar(vlnChangeBar vcb, string cbmess)
{
if (vcb == null) return;
vlnChangeBar prevCB = null;
foreach (vlnChangeBar cb in MyChangeBars)
{
// only look at changebars in same column
if (cb.XOffset == vcb.XOffset)
{
// if the two change bars end at same location, set prevCB which will
// adjust the length (top position) of the change bar. This condition
// also flags that the change bar texts overlap.
if (cb.YChangeBarBottom == vcb.YChangeBarBottom) prevCB = cb;
// continuous case, if changes bars overlap, adjust size and don't add new one to
// the MyChangeBars list.
if (MySection.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ContinuousChangeBars ||
MySection.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ChangeIds)
{
if (OverlapOrSpan(cb, vcb))
{
if (prevCB == null) prevCB = cb;
else if (prevCB.YChangeBarBottom > cb.YChangeBarBottom) prevCB = cb;
cb.BottomIsTable = (vcb.MyParent.MyItemInfo.IsTable);
}
}
}
}
// if this and the prevCB overlap, adjust yoffset/height/ybottom in the prevCB so that both change bars are
// included in this Dictionary item. A new vlnChangeBar is not added to the MyChangeBars list, the current
// one that overlaps with the new is adjusted.
if (prevCB != null)
{
// Bottom for both change bars is same, adjust top (YOffset) and height.
if (prevCB.YChangeBarBottom == vcb.YChangeBarBottom)
{
prevCB.YOffset = Math.Max(prevCB.YOffset, vcb.YOffset);
float yChangeBarBottomExtend = prevCB.YChangeBarBottomExtend;
prevCB.Height = Math.Max(prevCB.Height, vcb.Height);
prevCB.YExtendLine = prevCB.YChangeBarBottom - Math.Min(yChangeBarBottomExtend, vcb.YChangeBarBottomExtend); //Math.Max(prevCB.YExtendLine, vcb.YExtendLine);
// if a change bar message at this ychangebarbottom exists, see which message is used
if (cbmess != null && prevCB.Messages.ContainsKey(prevCB.YChangeBarBottom)) UpdateCbMessage(cbmess, prevCB, vcb.XOffset);
return;
}
// Bottom locations are not the same, but another change bar is not added, i.e. the
// length of the line is adjusted.
prevCB.YOffset = Math.Max(prevCB.YOffset, vcb.YOffset);
float yChangeBarBottomExtend1 = prevCB.YChangeBarBottomExtend;
prevCB.YChangeBarBottom = Math.Min(prevCB.YChangeBarBottom, vcb.YChangeBarBottom);
prevCB.YExtendLine = prevCB.YChangeBarBottom - Math.Min(yChangeBarBottomExtend1, vcb.YChangeBarBottomExtend); //Math.Max(prevCB.YExtendLine, vcb.YExtendLine);
// Two messages at this location, determine which one to use
if (cbmess != null && prevCB.Messages.ContainsKey(prevCB.YChangeBarBottom)) UpdateCbMessage(cbmess, prevCB, vcb.XOffset);
// no message at this location, just add it.
else if (cbmess != null)
prevCB.Messages.Add(vcb.YChangeBarBottom, new vlnChangeBarMessage(vcb.MyParent.XOffset, cbmess));
return;
}
// There was no overlap, add a message if it exists, and then add the change bar to the MyChangeBars list.
if (cbmess != null) vcb.Messages.Add(vcb.YChangeBarBottom, new vlnChangeBarMessage(vcb.MyParent.XOffset, cbmess));
MyChangeBars.Add(vcb);
}
private static void UpdateCbMessage(string cbmess, vlnChangeBar prevCB, float xoff)
{
// If there are two messages at the same location, for example an AER change bar & and RNO
// change bar, and the messages have different text, see which change bar message should be
// added, i.e. use the one in 'rno', the greatest x value.
vlnChangeBarMessage tmp = prevCB.Messages[prevCB.YChangeBarBottom];
if (cbmess != tmp.Message)
{
if (xoff > tmp.ParentX)
{
prevCB.Messages.Remove(prevCB.YChangeBarBottom);
prevCB.Messages.Add(prevCB.YChangeBarBottom, new vlnChangeBarMessage(xoff, cbmess));
}
}
}
private bool OverlapOrSpan(vlnChangeBar cb, vlnChangeBar vcb)
{
float tolerance = vlnPrintObject.SixLinesPerInch;
if (cb.MyParent.MyItemInfo.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvertAlarm &&
(vcb.MyParent.MyItemInfo.IsTable || cb.MyParent.MyItemInfo.IsTable || cb.BottomIsTable)) tolerance *= 1.5f;
bool bothFootnotes = cb.MyParent.MyItemInfo.IsFootnote && vcb.MyParent.MyItemInfo.IsFootnote;
if (!bothFootnotes && cb.MyParent.MyItemInfo.MyHLS != null && vcb.MyParent.MyItemInfo.MyHLS != null &&
cb.MyParent.MyItemInfo.MyHLS.ItemID != vcb.MyParent.MyItemInfo.MyHLS.ItemID) return false;
// cb.Yoffset is within range of vcb:
if (cb.YOffset <= vcb.YOffset &&
cb.YOffset >= (vcb.YChangeBarBottomExtend - tolerance)) return true;
// cb.YChangeBarBottom is within range of vcb:
if ((cb.YChangeBarBottomExtend - tolerance) <= vcb.YOffset &&
cb.YChangeBarBottomExtend >= (vcb.YChangeBarBottomExtend - tolerance)) return true;
// vcb.Yoffset is within range of cb:
if (vcb.YOffset <= cb.YOffset &&
vcb.YOffset >= (cb.YChangeBarBottomExtend - tolerance)) return true;
// vcb.YChangeBarBottom is within range of cb:
if ((vcb.YChangeBarBottomExtend - tolerance) <= cb.YOffset &&
vcb.YChangeBarBottomExtend >= (cb.YChangeBarBottomExtend - tolerance)) return true;
return false;
}
private PromsPrinter _MyPromsPrinter;
public PromsPrinter MyPromsPrinter
{
get { return _MyPromsPrinter; }
set { _MyPromsPrinter = value; }
}
private int _MyRomanPage = 1;
public VlnSvgPageHelper(VEPROMS.CSLA.Library.SectionInfo mySection, PromsPrinter myPromsPrinter, string hlsText, int hlsItemId)
: base()
{
HLSText = hlsText;
HasHLSTextId = hlsItemId;
MyPromsPrinter = myPromsPrinter;
CreatingSupInfoPage = myPromsPrinter.DoingFacingPage;
MySection = mySection;
}
private Volian.Svg.Library.Svg BuildSvg(VEPROMS.CSLA.Library.SectionInfo mySection, bool forceLoad)
{
// if mysection uses continuous pagination, and the previous section uses the same format,
// and the docstyle is set to use on first page only,
// then set section to use the Use On Rest of Pages
//SectionConfig.SectionPagination sPag = SectionConfig.SectionPagination.Separate;
//if (mySection.IsStepSection && mySection.MyPrevious != null && mySection.MyPrevious.IsStepSection)
//{
// SectionConfig sc = mySection.MyConfig as SectionConfig;
// sPag = sc.Section_Pagination;
// if (sPag == SectionConfig.SectionPagination.Continuous)
// {
// if (MySection.MyDocStyle.StructureStyle.Where == E_DocStyleUse.UseOnFirstPage)
// MySection.DidFirstPageDocStyle = true;
// }
//}
VEPROMS.CSLA.Library.FormatInfo activeFormat = mySection.ActiveFormat;
VEPROMS.CSLA.Library.DocStyle docStyle = mySection.MyDocStyle;
Volian.Svg.Library.Svg mySvg = null;
// the following line fills in the svg/svggroup/svgparts for all that is defined in the genmac definition (svg for plant)
mySvg = SvgSerializer<Volian.Svg.Library.Svg>.StringDeserialize(BuildMyText(activeFormat));
mySvg.ViewBox.Height = 1100;
mySvg.ViewBox.Width = 850;
mySvg.Height = new SvgMeasurement(11, E_MeasurementUnits.IN);
mySvg.Width = new SvgMeasurement(8.5F, E_MeasurementUnits.IN);
mySvg.LeftMargin = (float)docStyle.Layout.LeftMargin;
mySvg.TopMargin = 9.6F;
VEPROMS.CSLA.Library.PageStyle pageStyle = docStyle.pagestyle;
HasInitials = false;
PIInitials = null;
AddPageListItems(mySvg, pageStyle, mySection, forceLoad);
mySvg.ProcessText += new SvgProcessTextEvent(mySvg_ProcessText);
// if this section had a previous section and this is continuous, don't generate the svg for
// it, we'll use the previous section. The only thing we need to do is to process through the
// pagelist items in case there are some section items, for example the checkoff header needs
// to be processed for each section whether or not it is continuous.
SectionConfig.SectionPagination sPag = SectionConfig.SectionPagination.Separate;
//C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
if ((mySection.MyConfig as SectionConfig).Section_IsFoldout != "Y" && mySection.IsStepSection && mySection.MyPrevious != null && mySection.MyPrevious.IsStepSection)
{
SectionConfig sc = mySection.MyConfig as SectionConfig;
sPag = sc.Section_Pagination;
}
//if (sPag == SectionConfig.SectionPagination.Continuous && !mySection.DidFirstPageDocStyle) return null;
if (forceLoad) return mySvg;
if (sPag == SectionConfig.SectionPagination.Continuous) return null;
return mySvg;
}
public PageCounts MyPageCounts = null;
public PageCounts MyTOCPageCounts = null;
public Dictionary<string, int> MyTOCPageNums = null;
private static Regex regexFindToken = new Regex("{[^{}]*}");
private static Regex regexFindSubToken = new Regex(@"\[[^{}]*\]");
private string mySvg_ProcessText(object sender, SvgProcessTextArgs args)
{
if (args.MyText == null) return string.Empty; // Needed for empty genmac text (was space in 16bit files)
if (!args.MyText.Contains("{"))
return args.MyText;
/*
* Check if tokens for handling page counts ({PAGE} {OF} etc). if so, do templates.
*/
if (args.MyText.Contains("{METACURPAGE}") || args.MyText.Contains("{METATOTPAGE}"))
{
ItemInfo top = MySection;
while (top.MyParent != null && !top.MyParent.IsProcedure)
{
top = top.MyParent;
}
string key = "DocCurPage." + top.ItemID;
string txt = args.MyText.Replace("{METACURPAGE}", "{PAGE}").Replace("{METATOTPAGE}", "{OF}");
MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, txt, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
return string.Empty;
}
if (args.MyText.Contains("{DOCCURPAGE}") || args.MyText.Contains("{DOCTOTPAGE}"))
{
string key = "DocCurPage." + MySection.ItemID;
string txt = args.MyText.Replace("{DOCCURPAGE}", "{PAGE}").Replace("{DOCTOTPAGE}", "{OF}");
MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, txt, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
return string.Empty;
}
//if (args.MyText.Contains("{ROMANPAGE}"))
//{
// //return args.MyText.Replace("{ROMANPAGE}", ItemInfo.RomanNumbering(_MyRomanPage++).ToLower());
// string key = "RomanPage." + MySection.ItemID;
// string txt = args.MyText;
// MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, txt, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
// return string.Empty;
//}
if (args.MyText.Contains("{SECONDARYPAGE}") || args.MyText.Contains("{SECONDARYOF}"))
{
string key = "SecondaryPage." + MySection.DisplayNumber;
string txt = args.MyText.Replace("{SECONDARYPAGE}", "{PAGE}").Replace("{SECONDARYOF}", "{OF}");
MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, txt, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
return string.Empty;
}
//string tocKey = "TOC" + MySection.ItemID.ToString();
if (args.MyText.Contains("{PAGE}") || args.MyText.Contains("{OF}"))
{
#region numberingseq
/*
public enum E_NumberingSequence : uint
{
NoPageNum = 0,
WithSteps = 1, Add to original steps section page count.
WithinEachDocStyle = 2,
WithinEachSection = 3,
WithinEachDocStyle1 = 4,
GroupedByPagination = 5,
GroupedByLevel = 6,
WithStepsAndSecondaryPageNumber = 7,
WithStepsAndSecondaryPageNumberGroupedByLevel = 8,
Like6_ButDoesntNeedSubsection = 9,
Like6_ButDoesntNeedSubsection1 = 10
};
*/
#endregion
// default for the key is to make it NumberingSequence. Then handle
// specific cases.
string key = ((int)MySection.MyDocStyle.NumberingSequence).ToString();
E_NumberingSequence numseq = MySection.MyDocStyle.NumberingSequence??0;
//Console.WriteLine("\"{0}\"\t\"{1}\"\t{2}", MySection.DisplayNumber, MySection.DisplayText, numseq);
switch (numseq)
{
case E_NumberingSequence.GroupedByPagination:
key = ((int)E_NumberingSequence.WithSteps).ToString();
break;
case E_NumberingSequence.WithSteps: // Number with 'originalstepsection'
ProcedureInfo pc = MySection.MyProcedure;
int sectid = 0;
foreach (SectionInfo si in pc.Sections)
{
SectionConfig sc = si.MyConfig as SectionConfig;
if (sc.Section_OriginalSteps == "Y")
{
sectid = si.ItemID;
break;
}
}
if (sectid != 0) key = (int)E_NumberingSequence.WithinEachSection + "." + sectid;
break;
case E_NumberingSequence.WithinEachDocStyle:
key = key + "." + MySection.ActiveFormat.FormatID + "." + MySection.MyDocStyle.Index;
break;
//case E_NumberingSequence.WithinEachDocStyle1:
// key = key + "." + MySection.DisplayNumber;
// break;
case E_NumberingSequence.WithinEachSection:
key = key + "." + MySection.ItemID;
break;
case E_NumberingSequence.WithinEachSectionNumber:
key = key + "." + ( MySection.DisplayNumber == string.Empty ? (MySection.ActiveParent as ItemInfo).DisplayNumber : MySection.DisplayNumber);
break;
case E_NumberingSequence.GroupedByLevel:
case E_NumberingSequence.Like6_ButDoesntNeedSubsection:
if (MySection.MyParent.IsSection)
key = key + "." + MySection.MyParent.ItemID;
else
key = key + "." + MySection.ItemID;
break;
case E_NumberingSequence.WithStepsAndSecondaryPageNumber:
// For this one, we'll do two keys and templates. One will go with the main steps
// section and one will be for this secondary section.
ProcedureInfo pc1 = MySection.MyProcedure;
int psectid = 0;
foreach (SectionInfo si in pc1.Sections)
{
SectionConfig sc = si.MyConfig as SectionConfig;
if (sc.Section_OriginalSteps == "Y")
{
psectid = si.ItemID;
break;
}
}
if (psectid != 0)
{
key = (int)E_NumberingSequence.WithinEachSection + "." + psectid;
PdfTemplate tmp1 = MyPageCounts.AddToTemplateList(key, MyPdfWriter, args.MyText, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor);
}
break;
}
PdfTemplate tmp = MyPageCounts.AddToTemplateList(key, MyPdfWriter, args.MyText, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor);
// Proms page numbering designed requires a "{PAGE}" token to increment the page counter. So the easiest way
// to do that was to add a "{PAGE}" token to every page that is flagged as not to be printed.
if (!args.MyText.StartsWith("Non-printing ")) MyPdfContentByte.AddTemplate(tmp, args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
return string.Empty;
}
if (args.MyText.Contains("{FINALPAGE}"))
{
if (MySection.ItemID == FinalMessageSectionID)
{
string key = "FinalPage";
MyPdfContentByte.AddTemplate(MyPageCounts.AddToTemplateList(key, MyPdfWriter, args.MyText, MySection.MyDocStyle.Final.Message, args.MySvgText.Font, args.MySvgText.Align, args.MySvgText.FillColor), args.MySvgScale.X(args.MySvgText.X), args.MySvgScale.Y(MyPdfContentByte, args.MySvgText.Y));
}
return string.Empty;
}
return regexFindToken.Replace(args.MyText, new MatchEvaluator(ReplacePageListToken));
}
private string BuildMyText(VEPROMS.CSLA.Library.FormatInfo activeFormat)
{
string sGenMac = activeFormat.GenMac;
FormatInfo fibase = activeFormat;
// If this format has checkoffs (go through docstyles to see if any sections 'usecheckoffs'), then see if the ucf checkoffs are
// defined in the format's genmac:
string sGenMacBase = null;
foreach (DocStyle ds in activeFormat.PlantFormat.DocStyles.DocStyleList)
{
if (ds.Inactive == false && ds.UseCheckOffs && !sGenMac.ToUpper().Contains("C100"))
{
while (fibase.FormatID != fibase.ParentID) fibase = fibase.MyParent;
sGenMacBase = fibase.GenMac;
if (sGenMacBase != null && sGenMacBase != string.Empty)
{
XmlDocument xDocGenMacBase = new XmlDocument();
xDocGenMacBase.LoadXml(sGenMacBase);
sGenMacBase = xDocGenMacBase.DocumentElement.InnerXml;
sGenMacBase = sGenMacBase.Replace("xmlns=\"http://www.w3.org/2000/svg\"", "");
// replace fonts with hls fontname & size
string bsfontfamily = activeFormat.PlantFormat.FormatData.StepDataList[0].Font.Family;
string bsfontsize = activeFormat.PlantFormat.FormatData.StepDataList[0].Font.Size.ToString();
sGenMacBase = sGenMacBase.Replace("{family}", bsfontfamily);
sGenMacBase = sGenMacBase.Replace("{size}", bsfontsize);
break;
}
}
}
if (sGenMac == null || sGenMac == string.Empty)
{
// If subformat and does not have its own genmac, find an inherited genmac.
FormatInfo tmpf = FormatInfo.Get(activeFormat.ParentID);
while (tmpf.FormatID!=1 && (sGenMac==null||sGenMac==string.Empty))
{
sGenMac = tmpf.GenMac;
tmpf = FormatInfo.Get(tmpf.ParentID);
}
if (sGenMac == null || sGenMac == string.Empty)
sGenMac = "<svg></svg>";
}
if (sGenMacBase != null && sGenMacBase != string.Empty)
{
sGenMac = sGenMac.Replace("</svg>", sGenMacBase + "</svg>");
}
if (!sGenMac.Contains("xmlns"))
sGenMac = sGenMac.Replace("<svg ", "<svg xmlns='http://www.w3.org/2000/svg' ");
XmlDocument xDocGenMac = new XmlDocument();
xDocGenMac.LoadXml(sGenMac); // Add xmlns if necessary
Volian.Svg.Library.Svg mySvg = new Volian.Svg.Library.Svg();
SvgDefine def = new SvgDefine();
mySvg.Add(def);
def.ID = "GenMac Templates";
string str = SvgSerializer<Volian.Svg.Library.Svg>.StringSerialize(mySvg);
XmlDocument xDocPrintout = new XmlDocument();
xDocPrintout.LoadXml(str);
XmlNode xn = xDocPrintout.DocumentElement.ChildNodes[0];
xn.AppendChild(xDocPrintout.ImportNode(xDocGenMac.DocumentElement, true));
return xDocPrintout.OuterXml;
}
private string FirstAndLast(string token)
{
// strip the curly braces and return the first and last character
// For example Header1 becomes H1 and Box2 becomes B2
return token.Substring(1, 1) + token.Substring(token.Length - 2, 1);
}
private static Regex regexJustTokens = new Regex(@"^{([^{}]*}{)*[^{}]*}$");
// The following variables are used to keep track of whether a check off header should be printed
// if the {CHKOFFHEADING} pagelist item is found. PageListTopCheckOffHeader is the text that
// should be printed at the top of the page. PageListLastCheckOffHeader is the last header that was
// printed (if a header is on the page, and another is to be printed, it doesn't get printed if it
// is the same as the previous) and PageListCheckOffHeader is the page list item converted to a
// SvgText - this stores X/Y location, etc.
public string PageListTopCheckOffHeader = null;
public string PageListLastCheckOffHeader = null;
public SvgText PageListCheckOffHeader = null;
public Dictionary<string, bool> PgLogicals;
private void AddPageListItems(Volian.Svg.Library.Svg mySvg, VEPROMS.CSLA.Library.PageStyle pageStyle, VEPROMS.CSLA.Library.SectionInfo section, bool forceLoad)
{
SectionConfig sc = section.MyConfig as SectionConfig;
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine("SecNum=\"{0}\" SecTitle=\"{1}\" DocStyle=\"{2}\" Format=\"{3}\" ItemID={4}", section.DisplayNumber, section.DisplayText, section.MyDocStyle.Name, sc.FormatSelection, section.ItemID);
Volian.Base.Library.BaselineMetaFile.WriteLine(" Pagination=\"{0}\" MSWordPgCnt={1} NumPages={2} WordMargin={3}", sc.Section_Pagination, section.MSWordPageCount, (string.IsNullOrEmpty(sc.Section_NumPages)) ? "0" : sc.Section_NumPages, (string.IsNullOrEmpty(sc.Section_WordMargin))?"N":sc.Section_WordMargin);
if (PgLogicals == null) PgLogicals = new Dictionary<string, bool>();
else PgLogicals.Clear();
PageListCheckOffHeader = null;
// If this is a continuous section, then the only pagelist items we want are section type since
// we are still on the same page. - CHECK IF ON SAME PAGE!!!!
SectionConfig.SectionPagination sPag = SectionConfig.SectionPagination.Separate;
//C2019-042 Section_IsFoldout checks Section Number, Section Title, and use of check box
if (section.IsStepSection && section.MyPrevious != null && section.MyPrevious.IsStepSection && (section.MyConfig as SectionConfig).Section_IsFoldout != "Y")
{
SectionConfig sc1 = section.MyConfig as SectionConfig;
sPag = sc1.Section_Pagination;
}
SvgGroup svgGroup = new SvgGroup();
//int defPtPerRow = 72 / 6;
//int curLPI = 6; // default
//int prevLPI = 6;
//float PrevRow = 0;
//float rowAdj = 0; // = 18;
bool usePSIvalue = false; // C2021-065 used with ROLkUpMatch pagelist flag (Barakah Alarms)
string otherChildUnit = string.Empty; // C2021-065 used when OTHER applicability information is used for the ROLookUp
// F2023-035: WCN - allow for change in left margin for supplemental information pages by
// setting a value in the DocStyle for the adjustment.
float supInfoMargAdj = 0;
if (CreatingSupInfoPage || MyPromsPrinter.DoingFacingPage) supInfoMargAdj = MySection.MyDocStyle.SupInfoMargAdj == null ? 0 : (float)MySection.MyDocStyle.SupInfoMargAdj;
foreach (VEPROMS.CSLA.Library.PageItem pageItem in pageStyle.PageItems)
{
if (pageItem.Token == null) continue; // can be null if token is dependent on PSI lookup!
DidHLSText = false; // reset to false for this group of tokens.
//if (pageItem.Token.Contains("HLSTEXT"))
// Console.WriteLine("{0} - PageList Token", pageItem.Token);
// the pagelist 'justify="{PSNotFirst}"' flag only puts item out if not on first page of section, check for this
if (((pageItem.Justify & VEPROMS.CSLA.Library.E_Justify.PSNotFirst) == VEPROMS.CSLA.Library.E_Justify.PSNotFirst)
&& PrintedSectionPage == 0)
{
PrintedSectionPage++;
continue;
}
VE_Font useFontForCheckOffHeader = null;
if (forceLoad || (sPag == SectionConfig.SectionPagination.Separate || ((sPag == SectionConfig.SectionPagination.Continuous || sPag ==0 )&& (pageItem.Row < 0))))
{
//if (PrevRow > 0)
//{
// //float pgRow = (float)(pageItem.Row + rowAdj);
// if (curLPI != prevLPI)
// {
// int prow = (int)(PrevRow / defPtPerRow);
// int nrows = ((int)(pageItem.Row / defPtPerRow)) - prow;
// rowAdj += (float)Math.Abs(((nrows * (72 / curLPI)) - ((nrows * defPtPerRow) + rowAdj)));
// //rowAdj += (float)(((pgRow - PrevRow) / (72 * prevLPI)) * (72 / curLPI));
// prevLPI = curLPI;
// }
//}
// C2019-006 - Moved and modified the RO_Lookup() logic here, before we process the tokens in the page list
// this allows us to use RO_Lookup() in a "PS=" conditional token (is usually a PSI check box)
// A while loop was also added to the we can have more than one call to RO_Lookup() on a pagelist line
// this logic was put in for Barakah Alarms
// Note that each Alarm is defined as its own RO in the Referenced Object database, with multiple return values
// to define the Window ID, Alarm, Source, Setpoint, etc. for example.
string pltok = pageItem.Token;
while (pltok.Contains("RO_Lookup("))
{
int idxstart = pltok.IndexOf("RO_Lookup(");
int idxend = pltok.Substring(idxstart).IndexOf(")");
string ROLookupstr = pltok.Substring(idxstart, idxend + 1);
string parms = ROLookupstr.Substring(10, ROLookupstr.Length - 11);
MatchCollection sm = regexFindToken.Matches(parms);
foreach (Match m in sm) // resolve pagelist tokens that are parameters for ROLookup()
{
string tnk = m.Value;
ProcessPaglistToken(section, svgGroup, pageItem, ref useFontForCheckOffHeader, ref parms, tnk, supInfoMargAdj);
}
string[] parts = parms.Split(",".ToCharArray());// split on comma
// B2019-031 Support commas embedded in Alarm ID (Procedure Number)
// B2019-075: Added the check for commas in the procedure number - this code was causing a bug in other alarms.
if (parts.Length > 3 && MySection.MyProcedure.DisplayNumber.IndexOf(",") > 0)// If extra commas combine first part to account for it
{
int n = parts.Length - 3;
string part0 = parts[0];
for (int i = 0; i < n; i++) // append parts based upon the number of parts (commas)
part0 += "," + parts[i + 1];
parts[0] = part0;
parts[1] = parts[n + 1];// Get the last 2 parts
parts[2] = parts[n + 2];
}
string ROLookupVal = string.Empty;
// parts[0] - the RO to look up - for Alarms, is usually the EOP number thus uses the "{EOPNUM}" token
// parts[1] - Which of the multiple return value from the RO to return
// parts[2] - the value to use if not found in ROs - usually defined in a PSI field for that Alarm procedure
// C2021-065 Barakah Alarms - check if child RO alarm ID matches the resolved procedure number
// if not, then use the values stored in the PSI instead of the value returned for ROLookup()
// for all of the Alarm Point window items (ROLookup() items) in the pagelist for this section (BNPP Alarms format)
// Note only one pagelist item has this flag and this special pagelist item needs to be listed before any other ROLoopUP items
if (pageItem.ROLkUpMatch) // check for paglist flag
{
string rawPrcNum = section.MyProcedure.MyContent.Number;
// C2021-065 see if we need to get the Other child info from ROLookUp
if (rawPrcNum.ToUpper().StartsWith("<U\\U8209?OTHER")) // proc number has <u-otherxxx> in its definiation (procedure property page)
{
string procnum = section.MyProcedure.DisplayNumber; // get the cooked (resolved) procedure number
int idx = procnum.IndexOf('-');
otherChildUnit = procnum.Substring(0, idx); // we need to get RO info for the Other child applicability - this gets child's number
}
ROLookupVal = ROLookup(parts[0], parts[1], string.Empty,otherChildUnit); // will return empty string if alarm point is not found in RO database
usePSIvalue = (ROLookupVal != section.MyProcedure.DisplayNumber); // use PSI value if child alarm ID not found or does not match resolved procedure number (alarm point)
}
// C2021-065 if usePSIvalue is true, then we know alarm point info is not in the RO database, so just use the default (PSI) value
if (usePSIvalue)
ROLookupVal = parts[2]; // C2021-065 use the value defined in the PSI
else
ROLookupVal = ROLookup(parts[0], parts[1], parts[2], otherChildUnit);
// F2021-053: Do replace words for Page List items. This uses a DisplayText constructor that flags this case
// and gets the resulting replaced words
if (pageItem.RepWords)
{
DisplayText dt1 = new DisplayText(MyPromsPrinter.MyItem, ROLookupVal, false, true);
ROLookupVal = dt1.StartText;
// B2023-013 translate character sequences for Plus Minus, Greater Than and Less Than or Equal, Right and Left Arrows
// currently only BNPP uses this - 03-23-2023
if (MySection.ActiveFormat.PlantFormat.FormatData.SectData.ConvertGTELTEPMinROValue)
{
ROLookupVal = ROLookupVal.Replace("+/-", @"\'b1"); // Plus Minus
ROLookupVal = ROLookupVal.Replace("+-", @"\'b1"); // Plus Minus (without the forward slash - just in case)
ROLookupVal = ROLookupVal.Replace(">=", @"\u8805?"); // Greater than or equal
ROLookupVal = ROLookupVal.Replace("<=", @"\u8804?"); // Less than or equal
}
if (MySection.ActiveFormat.PlantFormat.FormatData.SectData.UseDashGreaterLessThenForArrowsInROValue)
{
ROLookupVal = ROLookupVal.Replace("->", @"\u8594?"); // Right Arrow
ROLookupVal = ROLookupVal.Replace("<-", @"\u8592?"); // Left Arrow
}
}
// replace the pagelist token with ROLookupVal
pltok = pltok.Substring(0, idxstart) + ROLookupVal + ((idxstart + idxend < pltok.Length) ? pltok.Substring(idxstart + idxend + 1) : string.Empty);
}
// C2021-065 (BNPP Alarms format) we are processing a paglist flag (ROLkUpMatch) to determine how to get Alarm Point information
// Nothing else is on this page list item, so use "continue" to jump to the next pagelist item as nothing gets printed for this item
if (pageItem.ROLkUpMatch)
continue;
MatchCollection matches = regexFindToken.Matches(pltok);//(pageItem.Token);
if (matches.Count > 0)
{
string plstr = string.Empty;
// When a pagelist line (row) has more than one token that is resolved to text, each resolved token text was place on top
// of each other. Use a temporary string (plstr) to process the pagelist tokens for each pagelist line (row) before adding
// it to the svgGroup.
plstr = pltok;//pageItem.Token;
// F2017-046: Remove the '@@' characters that were getting printed on SAMG Sup Info facing pages for Calvert (BGESAM1 format).
if (MyPromsPrinter.DoingFacingPage && plstr.Contains("@@")) plstr = plstr.Replace("@@", string.Empty);
foreach (Match match in matches)
{
string token = match.Value;
//token = Regex.Replace(token, @"[\xB3-\xDF]", " ");
// handle any conditional PS tokens
if (token.Contains(@"PS="))
{
ProcedureConfig procConfig = new ProcedureConfig(section.MyProcedure.MyContent.Config);
if (procConfig != null)
{
int indx = token.IndexOf("=");
int qindx = token.IndexOf("?", indx);
string pstok = token.Substring(indx + 1, qindx - indx - 1);
string val = procConfig.GetValue("PSI", pstok);
int bindx = token.IndexOf("|", indx);
if (val == "Y")
{
val = token.Substring(qindx + 1, bindx - qindx - 1);
// F2017-036: see if there is a RelatedItem in this page item. RelatedItem allows for repositioning
// this current item if both items are set to be printed from the Procedure Specific Information. If both are printed
// the location of this item is defined in the RelatedItem xml.
if (pageItem.RelatedItem.Token != null)
{
// see if the related item is on this page also, if so, use the new row/col/justify:
string reltoken = pageItem.RelatedItem.Token;
string relval = procConfig.GetValue("PSI", reltoken);
if (relval == "Y")
{
//svgGroup.Add(PageItemToSvgText(pageItem.Token, (float)pageItem.RelatedItem.Row, (float)pageItem.RelatedItem.Col, pageItem.RelatedItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft, pageItem.Font, val, MySection));
svgGroup.Add(PageItemToSvgText(pltok, (float)pageItem.RelatedItem.Row, (float)pageItem.RelatedItem.Col, pageItem.RelatedItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft, pageItem.Font, val, MySection));
plstr = string.Empty; // Clear it so it isn't put out twice (used below)
}
}
}
else
{
int eindx = token.IndexOf("}", bindx);
val = token.Substring(bindx + 1, eindx - bindx - 1);
}
if (val != null && val != string.Empty && !PgLogicals.ContainsKey(pstok)) PgLogicals.Add(pstok, val != null);
//if (val == null || val == string.Empty)
//val = " ";
if (val == null)
val = string.Empty;
plstr = plstr.Replace(token, val);
// Get a list of Pagelist token that are inside the PS= conditional result
// Paglist tokens inside a PS= conditional are surrounded by square brackets instead of curley
// ex. [BOX3] instead of {BOX3}
MatchCollection subMatches = regexFindSubToken.Matches(plstr);
if (subMatches.Count > 0)
{
foreach (Match subMatch in subMatches)
{
string subToken = subMatch.Value;
ProcessPaglistToken(section, svgGroup, pageItem, ref useFontForCheckOffHeader, ref plstr, subToken, supInfoMargAdj);
}
}
}
}
else if (token.Contains(@"SI=")) // F2021-068 needed duplicate conditional logic from PSI (above) but make of folder (set) specific info
{
DocVersionConfig dvConfig = new DocVersionConfig(section.MyProcedure.MyDocVersion.Config);
FolderConfig folderConfig = new FolderConfig(section.MyProcedure.MyDocVersion.MyFolder.Config);
if (dvConfig != null || folderConfig != null)
{
int indx = token.IndexOf("=");
int qindx = token.IndexOf("?", indx);
string pstok = token.Substring(indx + 1, qindx - indx - 1);
string val = DocVersionInfo.GetInheritedSIValue(section.MyProcedure, pstok);
int bindx = token.IndexOf("|", indx);
if (val == "Y")
{
val = token.Substring(qindx + 1, bindx - qindx - 1);
// see if there is a RelatedItem in this page item. RelatedItem allows for repositioning
// this current item if both items are set to be printed from the Procedure Specific Information. If both are printed
// the location of this item is defined in the RelatedItem xml.
if (pageItem.RelatedItem.Token != null)
{
// see if the related item is on this page also, if so, use the new row/col/justify:
string reltoken = pageItem.RelatedItem.Token;
string relval = DocVersionInfo.GetInheritedSIValue(section.MyProcedure, reltoken);
if (relval == "Y")
{
svgGroup.Add(PageItemToSvgText(pltok, (float)pageItem.RelatedItem.Row, (float)pageItem.RelatedItem.Col, pageItem.RelatedItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft, pageItem.Font, val, MySection));
plstr = string.Empty; // Clear it so it isn't put out twice (used below)
}
}
}
else
{
int eindx = token.IndexOf("}", bindx);
val = token.Substring(bindx + 1, eindx - bindx - 1);
}
if (val != null && val != string.Empty && !PgLogicals.ContainsKey(pstok)) PgLogicals.Add(pstok, val != null);
//if (val == null || val == string.Empty)
//val = " ";
if (val == null)
val = string.Empty;
plstr = plstr.Replace(token, val);
// Get a list of Pagelist token that are inside the SI= conditional result
// Paglist tokens inside a PS= conditional are surrounded by square brackets instead of curley
// ex. [BOX3] instead of {BOX3}
MatchCollection subMatches = regexFindSubToken.Matches(plstr);
if (subMatches.Count > 0)
{
foreach (Match subMatch in subMatches)
{
string subToken = subMatch.Value;
ProcessPaglistToken(section, svgGroup, pageItem, ref useFontForCheckOffHeader, ref plstr, subToken, supInfoMargAdj);
}
}
}
}
else
{
if (!ProcessPaglistToken(section, svgGroup, pageItem, ref useFontForCheckOffHeader, ref plstr, token, supInfoMargAdj)) break;
}
} // end foreach matches
if (plstr != string.Empty)
{
if (useFontForCheckOffHeader != null)
svgGroup.Add(PageItemToSvgText(pageItem, plstr, useFontForCheckOffHeader, MySection, supInfoMargAdj));
else
svgGroup.Add(PageItemToSvgText(pageItem, plstr, MySection, supInfoMargAdj));
}
}
else
svgGroup.Add(PageItemToSvgText(pageItem, pltok, MySection, supInfoMargAdj));
}
}
// Proms page numbering designed requires a "{PAGE}" token to increment the page counter. So the easiest way
// to do that was to add a "{PAGE}" token to every page that is flagged as not to be printed.
if (sPag == SectionConfig.SectionPagination.Separate)
{
// 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
//SvgText st = new SvgText(new System.Drawing.PointF(300, 300), "Non-printing {PAGE}", new System.Drawing.Font("Arial", 10), System.Drawing.Color.Black);
SvgText st = new SvgText(new System.Drawing.PointF(300, 300), "Non-printing {PAGE}", VE_Font.GetWinSysFont("Arial", 10), System.Drawing.Color.Black);
svgGroup.Add(st);
}
// C2018-004 create meta file for baseline compares
if (svgGroup.Count > 0)
mySvg.Add(svgGroup);
else
Volian.Base.Library.BaselineMetaFile.WriteLine("No Pagelist Information");
}
private string ROLookup(string accpageid, string multiid, string deflt)
{
return ROLookup(accpageid, multiid, deflt, string.Empty);
}
// C2021-065 pass in a override for the child unit - in this case the <u-Otherxxx> token is being used (Barakah Alarms)
private string ROLookup(string accpageid, string multiid, string deflt, string overrideChild)
{
ROFSTLookup myLookup = MySection.MyDocVersion.DocVersionAssociations[0].MyROFst.GetROFSTLookup(MySection.MyDocVersion, overrideChild);
string accpgid = accpageid;
ROFSTLookup.rochild roc = myLookup.GetROChildByAccPageID("<" + accpgid + "." + multiid + ">", MySection.MyDocVersion.DocVersionConfig.RODefaults_setpointprefix, MySection.MyDocVersion.DocVersionConfig.RODefaults_graphicsprefix);
if (roc.value == null)
{
accpgid = accpgid.Replace(@"\u8209?", "-");
roc = myLookup.GetROChildByAccPageID("<" + accpgid + "." + multiid + ">", MySection.MyDocVersion.DocVersionConfig.RODefaults_setpointprefix, MySection.MyDocVersion.DocVersionConfig.RODefaults_graphicsprefix);
}
if (!deflt.StartsWith("[") && !string.IsNullOrEmpty(roc.value) && roc.value.Trim().Length > 0) // don't return val if it's an empty or blank string - jsj 01-28-2019
{
roc.value = roc.value.Replace("[xB3]", "\xB3");
roc.value = roc.value.Replace("[xB2]", "\xB2");
return roc.value;
}
return deflt;
}
private bool _DidHLSText = false;
public bool DidHLSText
{
get { return _DidHLSText; }
set { _DidHLSText = value; }
}
private int _HasHLSTextId = 0;
public int HasHLSTextId
{
get { return _HasHLSTextId; }
set { _HasHLSTextId = value; }
}
private string _HLSText = string.Empty;
public string HLSText
{
get { return _HLSText; }
set
{
if (_HLSText == string.Empty)
_HLSText = value;
}
}
private string _HLSTAB = string.Empty;
public string HLSTAB
{
get { return _HLSTAB; }
set { _HLSTAB = value; }
}
private string _HLRNO = string.Empty;
public string HLRNO
{
get { return _HLRNO; }
set { _HLRNO = value; }
}
private bool _OldTemplateContMsg = false;
public bool OldTemplateContMsg
{
get { return _OldTemplateContMsg; }
set { _OldTemplateContMsg = value; }
}
private float _AdjustTopMarginForMultiLinePageListItems = 0;
public float AdjustTopMarginForMultiLinePageListItems
{
get { return _AdjustTopMarginForMultiLinePageListItems; }
set { _AdjustTopMarginForMultiLinePageListItems = value; }
}
/// <summary>
/// </summary>
/// <param name="section"></param>
/// <param name="svgGroup"></param>
/// <param name="pageItem"></param>
/// <param name="useFontForCheckOffHeader"></param>
/// <param name="plstr"></param>
/// <param name="token"></param>
/// <returns>
/// true - if token is resolved
/// false - if entire text is processed
/// </returns>
private bool ProcessPaglistToken(VEPROMS.CSLA.Library.SectionInfo section, SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, ref VE_Font useFontForCheckOffHeader, ref string plstr, string token, float supInfoMargAdj)
{
bool retval = true;
//Console.WriteLine("{0} ProcessPagelistToken", token);
// Paglist token inside a PS= conditional are surrounded by square brackets instead of curley
// ex. [BOX3] instead of {BOX3}, thus the redunant looking cases
switch (token)
{
case "{!atom}":
// Add an Atom Figure to the SVG
plstr = plstr.Replace(token, string.Empty);
AddImage(svgGroup, 160.5f, 170.5f, 288f, 323f, "atom.bmp");
break;
case "{!cpllogo}":
plstr = plstr.Replace(token, string.Empty);
AddImage(svgGroup, 10f, 10f, 78.7f, 29.8f, "cpllogo.bmp");
break;
//case "{!domlogo}":
// AddImage(svgGroup, 10f, 70f, 123f, 40.1f, "domlogo.bmp");
// break;
//case "{!gpclogo}":
// AddImage(svgGroup, 10f, 150f, 35.2f, 35.8f, "gpclogo.bmp");
// break;
case "{HEADER1}":
case "[HEADER1]":
case "{HEADER2}":
case "[HEADER2]":
case "{HEADER3}":
case "[HEADER3]":
case "{HEADER4}":
case "[HEADER4]":
case "{HEADER5}":
case "[HEADER5]":
case "{BOX1}":
case "[BOX1]":
case "{BOX2}":
case "[BOX2]":
case "{BOX3}":
case "[BOX3]":
case "{BOX4}":
case "[BOX4]":
case "{BOX5}":
case "[BOX5]":
case "{BOX6}":
case "[BOX6]":
case "{BOX7}":
case "[BOX7]":
case "{BOX8}":
case "[BOX8]":
case "{BOX9}":
case "[BOX9]":
plstr = plstr.Replace(token, string.Empty);
svgGroup.Add(PageItemToSvgUse(pageItem, FirstAndLast(token), supInfoMargAdj));
break;
case "{PMODEBOX}": // need to set either 1 or 2 depending on number of columns
case "[PMODEBOX]":
string box = "1";
if (_MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.Four)
box = "4";
else if (_MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.Three)
box = "3";
else if (_MySection.SectionConfig.Section_ColumnMode == SectionConfig.SectionColumnMode.Two)
box = "2";
box = "{BOX" + box + "}";
plstr = plstr.Replace(token, string.Empty);
svgGroup.Add(PageItemToSvgUse(pageItem, FirstAndLast(box), supInfoMargAdj));
break;
case "{DRAFTPAGE}":
//if (!AllowedWatermarks.Contains("Draft")) AllowedWatermarks.Add("Draft"); -- B2018-124 not needed anymore
plstr = plstr.Replace(token, string.Empty);// Remove token since it is handled now
break;
case "{REFERENCEPAGE}":
//if (!AllowedWatermarks.Contains("Reference")) AllowedWatermarks.Add("Reference"); -- B2018-124 not needed anymore
plstr = plstr.Replace(token, string.Empty);// Remove token since it is handled now
break;
case "{MASTERPAGE}":
//if (!AllowedWatermarks.Contains("Master")) AllowedWatermarks.Add("Master"); -- B2018-124 not needed anymore
plstr = plstr.Replace(token, string.Empty);// Remove token since it is handled now
break;
case "{SAMPLEPAGE}":
//if (!AllowedWatermarks.Contains("Sample")) AllowedWatermarks.Add("Sample"); -- B2018-124 not needed anymore
plstr = plstr.Replace(token, string.Empty);// Remove token since it is handled now
break;
//case "{INFORMATIONPAGE}":
// if (!AllowedWatermarks.Contains("Information Only")) AllowedWatermarks.Add("Information Only"); -- B2018-124 not needed anymore
// break;
case "{PROCTITLE}":
case "[PROCTITLE]":
case "{PROCTITLE1}":
case "[PROCTITLE1]":
case "{PROCTITLE2}":
case "[PROCTITLE2]":
case "{PROCTITLE3}":
case "[PROCTITLE3]":
case "{COVERPROCTITLE}":
case "[COVERPROCTITLE]":
int tlen = (token.Contains("COVERPROCTITLE"))?(int)section.ActiveFormat.PlantFormat.FormatData.ProcData.CoverTitleLength : (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength;
//float linelen = (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength * (float)pageItem.Font.CPI / 12;
float linelen = tlen * (float)pageItem.Font.CPI / 12;
string title = section.MyProcedure.MyContent.Text;
if (title.Contains("<NO TITLE>") && !section.ActiveFormat.PlantFormat.FormatData.ProcData.PrintNoTitle)
plstr = string.Empty;
else
{
if (section.ActiveFormat.PlantFormat.FormatData.ProcData.CapitalizeTitle) title = title.ToUpper();
// B2022-035: resolve unit specific designators
if (title.ToUpper().Contains(@"<U")) title = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(section.MyDocVersion, title);
plstr = SplitTitle(svgGroup, pageItem, title, (int)linelen, token, plstr, null); //,rowAdj);
}
break;
case "{COVERTITLE1}":
case "[COVERTITLE1]":
case "{COVERTITLE2}":
case "[COVERTITLE2]":
int ctlen = section.ActiveFormat.PlantFormat.FormatData.ProcData.CoverTitleLength ?? 0;
float coverlinelen = ((ctlen == 0) ? (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength : ctlen) * (float)pageItem.Font.CPI / 12;
string title1 = section.MyProcedure.MyContent.Text;
if (section.ActiveFormat.PlantFormat.FormatData.ProcData.CapitalizeTitle) title1 = title1.ToUpper();
// F2024-012 copied this line from above (processing COVERPROCTITLE) to resolve unit designators in the procedure title
if (title1.ToUpper().Contains(@"<U")) title1 = VEPROMS.CSLA.Library.DisplayText.ResolveUnitSpecific(section.MyDocVersion, title1);
plstr = SplitCoverTitle(svgGroup, pageItem, title1, (int)coverlinelen, token, plstr);//, rowAdj);
break;
case "{TITLE&UNIT}":
case "[TITLE&UNIT]":
tlen = (token.Contains("COVERPROCTITLE"))?(int)section.ActiveFormat.PlantFormat.FormatData.ProcData.CoverTitleLength : (int)section.ActiveFormat.PlantFormat.FormatData.ProcData.TitleLength;
linelen = tlen * (float)pageItem.Font.CPI / 12;
plstr = SplitTitleAndUnit(svgGroup, pageItem, section.MyProcedure.MyContent.Text.ToUpper(), (int)linelen, token, plstr); //,rowAdj);
break;
case "{SPLITEOPNUM}":
case "[SPLITEOPNUM]":
string eopnum1 = section.MyProcedure.MyContent.Number;
string unitnum1 = MySection.MyDocVersion.DocVersionConfig.Unit_ProcedureNumber;
string unitname1 = MySection.MyDocVersion.DocVersionConfig.Unit_Name;
if (unitnum1.Length > 0)
{
if (unitnum1.Contains("#"))
eopnum1 = unitnum1.Replace("#", eopnum1);
if (unitnum1.Contains("!"))
eopnum1 = unitnum1.Replace("!", unitname1);
if (eopnum1 == string.Empty)
eopnum1 = section.MyProcedure.MyContent.Number;
}
plstr = SplitEOPNumber(svgGroup, pageItem, eopnum1, token, plstr);
break;
case "{CM:(Cont)}":
if (OldTemplateContMsg)
plstr = plstr.Replace("{CM:(Cont)}", "(Cont)");
else
plstr = plstr.Replace("{CM:(Cont)}", string.Empty);
break;
case "{RF:REFERENCE}":
// This token is used by IP2. In 16bit it is processed when the PO_DISTRIBUTEAPPROVED
// purchase option is set and a file 'ref.dat' exists. Text from this file replaced
// the token. It was decided by RHM/KBR on 10/7/14 that this would not be implemented
// unless/until it is determined that it is used (no data that Volian currently has
// contains this file). To implement it requires a config item off of the procedure level,
// user interface support on the Procedure Properties dialog and print support.
plstr = plstr.Replace("{RF:REFERENCE}", string.Empty);
break;
case "{NULLDOCCURPAGE}":
// This token is used by IP2. There was no support for it in 16bit and the 16bit to 32bit
// output compared so it is just removed here so that a pagelist token error is not output
// in error log.
plstr = plstr.Replace("{NULLDOCCURPAGE}", string.Empty);
break;
case "{PDFDate}":
plstr = plstr.Replace("{PDFDate}", DateTime.Now.ToString("MM/dd/yyyy"));
break;
case "{PDFTime}":
plstr = plstr.Replace("{PDFTime}", DateTime.Now.ToString("HH:mm:ss"));
break;
// F2023-087: Added PDFDate at PDFTime - note that cannot have multiple tokens in a conditional because of reg expression
// processing.
case "[PDFDateAtTime]":
plstr = plstr.Replace("[PDFDateAtTime]", DateTime.Now.ToString("MM/dd/yyyy") + " at " + DateTime.Now.ToString("HH:mm:ss"));
break;
case "{EOPNUM}":
case "[EOPNUM]":
case "{PREDELIMEOPNUM}":
case "[PREDELIMEOPNUM]":
case "{EOPNUMROLU}":
case "[EOPNUMROLU]":
string eopnum = section.MyProcedure.MyContent.Number;
string unitnum = MySection.MyDocVersion.DocVersionConfig.Unit_ProcedureNumber;
string unitname = MySection.MyDocVersion.DocVersionConfig.Unit_Name;
if (unitnum.Length > 0)
{
if (unitnum.Contains("#"))
eopnum = unitnum.Replace("#", eopnum);
if (unitnum.Contains("!"))
eopnum = unitnum.Replace("!", unitname);
if (eopnum == string.Empty)
eopnum = section.MyProcedure.MyContent.Number;
if (eopnum.ToUpper().Contains(@"<U"))
{
// C2021-064 If we are processing the EOP number or an ROLookUp in the pagelist, then strip out the Parent/Child unit tokens
// so that we are left with just the EOP number. This is used along with Parent/Child RO Values (in RO Editor)
if ((token.Equals("{EOPNUMROLU}") || token.Equals("[EOPNUMROLU]")))
{
// copied Rgex from DisplayText and modifed to remove the Parent/Child Unit information
// i.e. <U>, <U-ID>, <U-NAME>, <U-TEXT>, <U-NUMBER>, <U-OTHERID>, <U-OTHERNAME>, <U-OTHERTEXT>, <U-OTHERNUMBER>
// F2023-078 - for Vogtle Units 3 & 4 Alarms - also remove dash after unit number
eopnum = Regex.Replace(eopnum, @"\<U\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<U\>", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)ID)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)NAME)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)TEXT)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)NUMBER)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
// B2021-148 remove space character after "OTHER"
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)OTHERID)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)OTHERNAME)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)OTHERTEXT)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
eopnum = Regex.Replace(eopnum, @"\<(U(-|\\u8209\?)OTHERNUMBER)\>(-|\\u8209\?)", string.Empty, RegexOptions.IgnoreCase);
}
else
eopnum = section.MyProcedure.DisplayNumber;// B2021-066: found and fixed during proc pc/pc work
}
}
// B2022-066 the "{PREDELIMEOPNUM}" token was not being processed because there was a space after the "{"
if (token.Equals("{PREDELIMEOPNUM}"))
{
// only use up to the first non-alphanumeric character of the procedur number
// Prairie Island (NSP) Alarms use this token
int idx = 0;
while (idx < eopnum.Length && char.IsLetterOrDigit(eopnum[idx])) idx++;
if (idx < eopnum.Length)
eopnum = eopnum.Substring(0, idx);
}
if (pageItem.TrimEnding != null)
eopnum = eopnum.TrimEnd(pageItem.TrimEnding.ToCharArray());
plstr = plstr.Replace(token, eopnum);
//svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token, eopnum)));
//svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token, section.MyProcedure.MyContent.Number)));
break;
case "{SECTIONLEVELTITLE}":
case "[SECTIONLEVELTITLE]":
case "{ATTACHTITLECONT}":
case "[ATTACHTITLECONT]":
// B2020-038: incorrect pagination: Note that if PSOnlyFirst is active and pagination is set to continuous, pagination may be incorrect in printed output (no code change-just info here in case happens again)
bool printsectlevel = ((pageItem.Justify & VEPROMS.CSLA.Library.E_Justify.PSOnlyFirst) != VEPROMS.CSLA.Library.E_Justify.PSOnlyFirst) ||
(((pageItem.Justify & VEPROMS.CSLA.Library.E_Justify.PSOnlyFirst) == VEPROMS.CSLA.Library.E_Justify.PSOnlyFirst) && PrintedSectionPage==0);
// if there is 'no title' for the section, only print it if a format flag says to print it.
if (printsectlevel)
{
if (section.DisplayText.ToUpper().Contains("<NO TITLE>") && !section.ActiveFormat.PlantFormat.FormatData.ProcData.PrintNoTitle) printsectlevel = false;
}
if (MyPromsPrinter.DoingFacingPage) printsectlevel = false; // don't put out section title/number if doing SAMG facing pages
if (printsectlevel)
{
string stitle = section.DisplayText;
if (((section.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DSS_PageListAddSectCont) == E_DocStructStyle.DSS_PageListAddSectCont)
&& token.Contains("ATTACHTITLECONT") && DidFirstPageDocStyle)
{
string myMsg = section.MyDocStyle.Continue.Top.Message;
if (myMsg != null && myMsg != string.Empty)stitle = stitle + myMsg;
}
// B2023-043: Beaver Valley AOP - allow attributes, such as superscript on section titles when printing
if (section.ActiveFormat.PlantFormat.FormatData.PrintData.SectionTitleWithAttributes)
stitle = section.FormattedDisplayText;
// B2021-119: large titles on Landscape Word Attachments are printing on 2 lines.
// B2022-149: crash on cast if null
int? stl = (int?)section.ActiveFormat.PlantFormat.FormatData.SectData.SectionNumberAndTitleLength;
if (section.MyDocStyle.LandscapePageList && section.ActiveFormat.PlantFormat.FormatData.SectData.SectNumAndTlLenLand != null)
stl = section.ActiveFormat.PlantFormat.FormatData.SectData.SectNumAndTlLenLand;
plstr = SplitTitle(svgGroup, pageItem, stitle, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionTitleLength, token, plstr, stl);
if ((pageItem.Justify & VEPROMS.CSLA.Library.E_Justify.PSOnlyFirst) == VEPROMS.CSLA.Library.E_Justify.PSOnlyFirst) // B2020-047 only set PrintedSectionPage if PSOnly is used
PrintedSectionPage = (int)pageItem.Row - _sectLevelNumTtlDiff;
}
else
plstr = plstr.Replace(token, string.Empty);
//svgGroup.Add(PageItemToSvgText(pageItem, section.DisplayText));
break;
case "{METASECTIONTITLE}": // This will print the top level section title (versus level above current) starting from a sub-section
case "[METASECTIONTITLE]":
if (section.MyParent.IsSection)
{
// get top most section:
ItemInfo top = section;
while (top.MyParent != null && !top.MyParent.IsProcedure)
{
top = top.MyParent;
}
// B2023-043: Beaver Valley AOP - allow attributes, such as superscript on section titles when printing
string tmptitle = (section.ActiveFormat.PlantFormat.FormatData.PrintData.SectionTitleWithAttributes) ? top.FormattedDisplayText : top.DisplayText;
plstr = SplitTitle(svgGroup, pageItem, tmptitle, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionTitleLength, token, plstr, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionNumberAndTitleLength);
}
else
plstr = plstr.Replace(token, string.Empty);
break;
case "{TOPSECTIONTITLE}": // This will print the top level section title
case "[TOPSECTIONTITLE]":
// get top most section:
{
ItemInfo top = section;
while (top.MyParent != null && !top.MyParent.IsProcedure)
{
top = top.MyParent;
}
if (top.IsSection)
plstr = SplitTitle(svgGroup, pageItem, top.DisplayText, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionTitleLength, token, plstr, section.ActiveFormat.PlantFormat.FormatData.SectData.SectionNumberAndTitleLength);
else
plstr = plstr.Replace(token, string.Empty);
}
break;
case "{SECTIONLEVELNUMBER}":
case "[SECTIONLEVELNUMBER]":
// don't put out section title/number if doing SAMG facing pages
if (!MyPromsPrinter.DoingFacingPage)
{
plstr = plstr.Replace(token, section.DisplayNumber);
_sectLevelNumTtlDiff = (int)pageItem.Row;
}
else
plstr = plstr.Replace(token, string.Empty);
// B2020-040: pagelist was {SECTIONLEVELNUMBER}, {SECTIONLEVELTITLE} and if no SECTIONLEVELNUMBER exists, printed
// text starts with a ', ' - remove it.
if (plstr.StartsWith(", ") && plstr.IndexOf("{SECTIONLEVELTITLE}") == 2)
plstr = plstr.Substring(2);
// F2021-075 pagelist was {SECTIONLEVELNUMBER} - {SECTIONLEVELTITLE} and if no SECTIONLEVELNUMBER exists, printed
// text starts with a ' - ' - remove it.
else if (plstr.StartsWith(" - ") && plstr.IndexOf("{SECTIONLEVELTITLE}") == 3)
plstr = plstr.Substring(3);
//svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token, section.DisplayNumber)));
break;
case "{METASECTIONNUMBER}": // This will print the top level section number when starting from a sub-section
case "[METASECTIONNUMBER]":
if (section.MyParent.IsSection)
{
// get top most section:
ItemInfo top = section;
while (top.MyParent != null && !top.MyParent.IsProcedure)
{
top = top.MyParent;
}
plstr = plstr.Replace(token, top.DisplayNumber);
}
else
plstr = plstr.Replace(token, string.Empty);
break;
case "{TOPSECTIONNUMBER}": // This will print the top level section number
case "[TOPSECTIONNUMBER]":
// get top most section:
{
ItemInfo top = section;
while (top.MyParent != null && !top.MyParent.IsProcedure)
{
top = top.MyParent;
}
if (top.IsSection)
plstr = plstr.Replace(token, top.DisplayNumber);
else
plstr = plstr.Replace(token, string.Empty);
}
break;
case "{UNITTEXT}":
case "[UNITTEXT]":
plstr = plstr.Replace(token, MySection.MyDocVersion.DocVersionConfig.Unit_Text);
//svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token.Replace(token, MySection.MyDocVersion.DocVersionConfig.Unit_Text)));
break;
case "{UNITNUMBER}":
case "[UNITNUMBER]":
string unbr = MySection.MyDocVersion.DocVersionConfig.Unit_Number;
if (MySection.ActiveFormat.PlantFormat.FormatData.PrintData.PrintCommonForZeroUnit && unbr == "0")
plstr = "COMMON"; // for Comanche Peak, replace "Unit 0" with "COMMON"
else
plstr = plstr.Replace(token, unbr);
break;
case "{VCBUNIT}":
case "[VCBUNIT]":
string unbr2 = MySection.MyDocVersion.DocVersionConfig.Unit_Number;
if (unbr2 == "0")
{
if (MySection.MyProcedure.DisplayNumber.StartsWith("VCS") || MySection.MyProcedure.DisplayNumber.StartsWith("MD"))
plstr = "NSBU";
else if (MySection.MyProcedure.DisplayNumber.StartsWith("VC2"))
plstr = "Unit 2";
else if (MySection.MyProcedure.DisplayNumber.StartsWith("VC3"))
plstr = "Unit 3";
else
plstr = "Units 2 & 3"; // for VC Summer, replace "Unit 0" with "Units 2 & 3"
}
else
plstr = plstr.Replace(token, unbr2);
break;
case "{ATTACHNUM}":
case "[ATTACHNUM]":
plstr = plstr.Replace(token, "1"); // used by SHESDD - but 16bit returns '1' unless has format flag 'MoveParensToToken' that was only in SCE (San Onofre)
break;
case "{ATTACHNUM1}":
case "[ATTACHNUM1]":
string numAtt = GetAttachNum1();
plstr = plstr.Replace(token, numAtt); // used by SHESDD - but 16bit returns '1' unless has format flag 'MoveParensToToken' that was only in SCE (San Onofre)
break;
case "{CHKOFFHEADING}":
case "[CHKOFFHEADING]":
// unfortunately, the font is not stored on the page list item if there is an active
// check off header. It is stored with the checkoff data as defined by user selection
// of the selected header (selection stored in section config).
int sindx = section.CheckOffHeadingIndex();
VE_Font vf = sindx <= 0 ? pageItem.Font :
section.ActiveFormat.PlantFormat.FormatData.ProcData.CheckOffData.CheckOffHeaderList[sindx].Font;
useFontForCheckOffHeader = vf;
PageListCheckOffHeader = PageItemToSvgText(pageItem, pageItem.Token, vf, section, 0);
break;
case "{HLSTEXT}":
DidHLSText = true;
plstr = plstr.Replace(token, HLSText);
break;
case "{VALTYPE}":
ItemInfo firstHigh = ValveGetFirstStep(section);
if (firstHigh != null)
{
int typ = (int)firstHigh.MyContent.Type - 20000;
switch (typ)
{
case 2:
plstr = plstr.Replace(token, "VALVE");
break;
case 9:
plstr = plstr.Replace(token, "SWITCH");
break;
case 3:
plstr = plstr.Replace(token, "BREAKER");
break;
default:
plstr = plstr.Replace(token, string.Empty);
break;
}
}
else
plstr = plstr.Replace(token, string.Empty);
break;
case "{STARTUP}":
ItemInfo firstHighs = ValveGetFirstStep(section);
if (firstHighs != null)
{
int typs = (int)firstHighs.MyContent.Type - 20000;
switch (typs)
{
case 2:
// the following test for OI-3A came from 16bit code:
string num = section.MyProcedure.MyContent.Number.ToUpper().Replace(@"\U8209?", "-");
if (num.Equals("OI-3A"))
plstr = plstr.Replace(token, " SDC/");
else
plstr = plstr.Replace(token, "STARTUP/");
break;
default:
plstr = plstr.Replace(token, string.Empty);
break;
}
}
else
plstr = plstr.Replace(token, string.Empty);
break;
case "{PROCDES}":
ProcDescrList pdl = section.ActiveFormat.PlantFormat.FormatData.PrintData.ProcDescrList;
if (pdl != null && pdl.Count > 0)
{
string procnum = section.MyProcedure.MyContent.Number.Replace(@"\u8209?", "-").Replace(@"\u9586?", @"\");
foreach (ProcDescr pd in pdl)
{
if (pd.MatchProcNumber != null)
{
string matchStr = (pd.MatchProcNumber.StartsWith("*}")) ? pd.MatchProcNumber.Substring(2) : pd.MatchProcNumber;
if (procnum.Contains(matchStr))
{
if (pd.ProcDescr1 == "{null}") // used to override fmt file inheritance & set null/empty string
plstr = string.Empty;
else
plstr = pd.ProcDescr1;
break;
}
if (pd.MatchProcNumber == "@")
{
// 16bit code looked like it only checked for the first character, but this code looks at
// all characters. It was not working correctly for BGE. Didn't want to change it for other
// plants that have been delivered - so added special code for BGE.
if (section.ActiveFormat.PlantFormat.FormatData.PrintData.SpecialCaseCalvert)
{
if (Regex.IsMatch(procnum.Substring(0,1),"[A-Za-z]"))
plstr = pd.ProcDescr1;
else
plstr = string.Empty;
break;
}
if (Regex.IsMatch(procnum, "^[A-Za-z]+$"))
plstr = pd.ProcDescr1;
else
plstr = string.Empty;
break;
}
}
else
plstr = "UNKNOWN";
}
}
break;
case "{PROCDES2}":
ProcDescrList pdl2 = section.ActiveFormat.PlantFormat.FormatData.PrintData.ProcDescrList;
if (pdl2 != null && pdl2.Count > 0)
{
string procnum = section.MyProcedure.MyContent.Number.Replace(@"\u8209?", "-").Replace(@"\u9586?", @"\");
foreach (ProcDescr pd in pdl2)
{
if (pd.MatchProcNumber != null)
{
string matchStr = (pd.MatchProcNumber.StartsWith("*}")) ? pd.MatchProcNumber.Substring(2) : pd.MatchProcNumber;
if (procnum.Contains(matchStr))
{
plstr = pd.ProcDescr2;
break;
}
if (pd.MatchProcNumber == "@")
{
if (Regex.IsMatch(procnum, "^[A-Za-z]+$"))
plstr = pd.ProcDescr2;
else
plstr = string.Empty;
break;
}
}
else
plstr = "UNKNOWN";
}
}
break;
case "{CURDATE}":
DateTime thisDate1 = DateTime.Today;
plstr = plstr.Replace(token, thisDate1.ToString("MMMM dd, yyyy"));
break;
case "{CURTIME}":
DateTime thisDate2 = DateTime.Now;
plstr = plstr.Replace(token, thisDate2.ToString("H:mm"));
break;
case "{HLRNO}":
plstr = HLRNO==null?string.Empty:plstr.Replace(token, HLRNO);
break;
case "{HLSTAB}":
if (HLSTAB.Contains("{!Clock}")) // F2022-024 replace with the clock symbol defined in GenMac format file
{
HLSTAB = HLSTAB.Replace("{!Clock}",string.Empty).TrimStart(" ".ToCharArray());
svgGroup.Add(PageItemToSvgUse(pageItem, "Clock", supInfoMargAdj));
}
plstr = plstr.Replace(token, HLSTAB);
break;
case "{UNITALPHA}":
// copied from 16bit's pagelist.cs for BGE:
string unitnm = MySection.MyDocVersion.DocVersionConfig.Print_UnitNumberForPageList;
if (unitnm == "1")
plstr = plstr.Replace(token, "ONE");
else if (unitnm == "2")
plstr = plstr.Replace(token, "TWO");
else
plstr = plstr.Replace(token, "ONE AND TWO");
break;
case "{INITIALS}":
// For Calvert: if this section has checkoffs turned on, put out this pagelist item:
// Get SectionInfos to access specific section config items...
//SectionInfo si = SectionInfo.Get(MySection.ItemID);
//SectionInfo si = MySection.GetSectionInfo();
//SectionConfig sectCfg = si.MyConfig as SectionConfig;
//int sc = sectCfg.Section_CheckoffListSelection;
if (!MySection.HasInitials)
{
plstr = plstr.Replace(token, string.Empty);
//PIInitials = pageItem;
}
else
{
if (pageItem.Row == -MySection.MyDocStyle.Layout.TopMargin)
{
plstr = plstr.Replace(token, string.Empty);
PIInitials = pageItem;
}
else
plstr = plstr.Replace(token, "INITIALS");
}
break;
case "{REVUNIT}":
// copied from 16bit's pagelist.cs for BGE:
string revUnit = null;
string unitNum = MySection.MyDocVersion.DocVersionConfig.Print_UnitNumberForPageList;
if (Rev != null && Rev != string.Empty)
{
revUnit = Rev;
int indxs = Rev.IndexOf(MySection.ActiveFormat.PlantFormat.FormatData.PrintData.RevDateWithForwardSlash ? '\\' : '/');
if (indxs > 0) revUnit = Rev.Substring(0, indxs);
}
else
revUnit = " ";
if (unitNum == "2")
revUnit += "/Unit 2";
else if (unitNum == "1")
revUnit += "/Unit 1";
plstr = plstr.Replace(token, revUnit);
break;
case "[UNIT]":
string un = MySection.MyDocVersion.DocVersionConfig.Print_UnitNumberForPageList;
plstr = plstr.Replace(token, un);
break;
case "{MCRSERNUM}": // B2021-127: BNPPalr - Auto set of serial #
int sernum = section.MyProcedure.Ordinal - VlnSvgPageHelper.CountInApplProcs;
plstr = plstr.Replace(token, sernum.ToString());
break;
default:
if (token.Contains(@"SI-")) // procedure set specific information. (at folder or working draft levels)
{
DocVersionConfig dvConfig = new DocVersionConfig(section.MyProcedure.MyDocVersion.Config);
FolderConfig folderConfig = new FolderConfig(section.MyProcedure.MyDocVersion.MyFolder.Config);
if (dvConfig != null || folderConfig != null)
{
int indx = token.IndexOf("-");
int qindx = token.IndexOf("?", indx);
string val = null;
if (qindx == -1)
{
val = DocVersionInfo.GetInheritedSIValue(section.MyProcedure, token.Substring(4, token.Length - 5));
// C2021-051: Applicability tokens in Procedure Set and Folder Specific Information
if (val.ToUpper().Contains("<U>") || val.ToUpper().Contains("<U-")) // Replace token with the applicable unit information
{
string unbr3 = ResolveUnitApp(MySection.MyDocVersion, val);
plstr = unbr3 ?? string.Empty;
}
plstr = plstr.Replace(token, val);
break; // B2019-134 break out of switch statement after processing the <SI- token so that it can loop and handle any other tokens on the same line
}
else
{
string pstok = token.Substring(indx + 1, qindx - indx - 1);
plstr = DocVersionInfo.GetInheritedSIValue(section.MyProcedure, pstok);
// C2021-051: Applicability tokens in Procedure Set and Folder Specific Information
if (plstr.ToUpper().Contains("<U>") || val.ToUpper().Contains("<U-")) // Replace token with the applicable unit information
{
string unbr3 = ResolveUnitApp(MySection.MyDocVersion, val);
plstr = unbr3 ?? string.Empty;
}
// the first part of the string between the ? and ' ' is the other logical
// to see if it's on. If on, just use col and/or row as defined. Otherwise use
// value between = and |.
int sindx2 = token.IndexOf(" ", qindx);
string logcheck = token.Substring(qindx + 1, sindx2 - qindx - 1);
if (PgLogicals.ContainsKey(logcheck))
{
int bindx = token.IndexOf("|", indx);
string newval = token.Substring(sindx2 + 1, bindx - sindx2 - 1);
float col = pageItem.Col ?? 0;
if (newval.ToUpper().Contains("COL"))
{
col = System.Convert.ToInt32(newval.Substring(4));
}
svgGroup.Add(PageItemToSvgText(pageItem.Token, pageItem.Row ?? 0, col, pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft, pageItem.Font, plstr, MySection));
plstr = string.Empty; // clear so it doesn't get added twice, i.e. in the method that calls this.
}
}
}
}
if (token.Contains(@"RO-"))
{
plstr = token.Replace("{",string.Empty).Replace("}",string.Empty);
svgGroup.Add(PageItemToSvgText(pageItem, plstr, MySection, 0));
}
if (token.Contains(@"PS-"))
{
ProcedureConfig procConfig = new ProcedureConfig(section.MyProcedure.MyContent.Config);
if (procConfig != null)
{
int indx = token.IndexOf("-");
int qindx = token.IndexOf("?", indx);
string val = null;
if (qindx == -1)
{
val = procConfig.GetValue("PSI", token.Substring(4, token.Length - 5));
// F2021-034: Resolve applicability unit tokens (not just '<u>')
if(val.ToUpper().Contains("<U>") || val.ToUpper().Contains("<U-")) // Replace token with the applicable unit information
{
string unbr3 = ResolveUnitApp(MySection.MyDocVersion, val);
val = unbr3 ?? string.Empty;
}
// MaxWidth is used to define width that the PSI text spans x-direction on page. If it is
// defined, see if the text is too wide for a single line (SplitTextMaxWidth). The
// AdjustTopMarginForMultLinePageListItem contains the y-adjustment that must be considered
// in the TopMargin if the PSI text split onto more than one line.
if ((pageItem.MaxWidth ?? 0) > 0 || (pageItem.MaxWidthCurPage ?? 0) > 0)
{
int locwid = ((pageItem.MaxWidth??0)>0)?(int)pageItem.MaxWidth:(int)pageItem.MaxWidthCurPage;
AdjustTopMarginForMultiLinePageListItems = SplitTextMaxWidth(svgGroup, pageItem, val, locwid, token, ref plstr);
if ((pageItem.MaxWidthCurPage ?? 0) > 0) AdjustTopMarginForMultiLinePageListItems = 0;
}
else
plstr = plstr.Replace(token, val);
//svgGroup.Add(PageItemToSvgText(pageItem, plstr, MySection));
}
else
{
string pstok = token.Substring(indx + 1, qindx - indx - 1);
plstr = procConfig.GetValue("PSI", pstok);
// the first part of the string between the ? and ' ' is the other logical
// to see if it's on. If on, just use col and/or row as defined. Otherwise use
// value between = and |.
int sindx2 = token.IndexOf(" ", qindx);
string logcheck = token.Substring(qindx + 1, sindx2 - qindx - 1);
if (PgLogicals.ContainsKey(logcheck))
{
int bindx = token.IndexOf("|", indx);
string newval = token.Substring(sindx2 + 1, bindx - sindx2 - 1);
float col = pageItem.Col ?? 0;
if (newval.ToUpper().Contains("COL"))
{
col = System.Convert.ToInt32(newval.Substring(4));
}
svgGroup.Add(PageItemToSvgText(pageItem.Token, pageItem.Row ?? 0, col, pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft, pageItem.Font, plstr, MySection));
plstr = string.Empty; // clear so it doesn't get added twice, i.e. in the method that calls this.
}
}
}
}
else
{
if (plstr != string.Empty)
{
svgGroup.Add(PageItemToSvgText(pageItem, plstr, MySection, supInfoMargAdj));
plstr = string.Empty;
}
//svgGroup.Add(PageItemToSvgText(pageItem, pageItem.Token));
}
//_MyLog.InfoFormat("Token not processed {0}", token);
if (plstr == string.Empty) retval = false;
break;
}
return retval;
}
// F2021-034: Resolve applicability unit tokens (not just '<u>')
private string ResolveUnitApp(DocVersionInfo dvi, string str)
{
if (dvi == null) return str;
string tmp = str.ToUpper();
int sindx = tmp.IndexOf("<U");
int eindx = tmp.IndexOf(">", sindx + 1);
string reptmp;
while (sindx > -1 && eindx > -1) // B2022-007 added while loop to process more than one <U- RO value
{
reptmp = str.Substring(sindx, eindx - sindx + 1);
tmp = reptmp.ToUpper();
if (tmp == "<U>") str = str.Replace(reptmp, dvi.DocVersionConfig.Unit_Number);
else if (tmp == "<U-TEXT>") str = str.Replace(reptmp, dvi.DocVersionConfig.Unit_Text);
else if (tmp == "<U-NUMBER>") str = str.Replace(reptmp, dvi.DocVersionConfig.Unit_Number);
else if (tmp == "<U-NAME>") str = str.Replace(reptmp, dvi.DocVersionConfig.Unit_Name);
else if (tmp == "<U-ID>") str = str.Replace(reptmp, dvi.DocVersionConfig.Unit_ID);
// B2021-145: For applicability, the tree view & pdf file name are not getting resolved when using any of the <20>OTHER<45> tokens
else if (tmp == "<U-OTHERTEXT>") str = str.Replace(reptmp, dvi.DocVersionConfig.Other_Unit_Text);
else if (tmp == "<U-OTHERNUMBER>") str = str.Replace(reptmp, dvi.DocVersionConfig.Other_Unit_Number);
else if (tmp == "<U-OTHERNAME>") str = str.Replace(reptmp, dvi.DocVersionConfig.Other_Unit_Name);
else if (tmp == "<U-OTHERID>") str = str.Replace(reptmp, dvi.DocVersionConfig.Other_Unit_ID);
else str = str.Replace(reptmp, tmp.Replace("<", "*?").Replace(">", "?*"));
tmp = str.ToUpper();
sindx = tmp.IndexOf("<U");
eindx = tmp.IndexOf(">", sindx + 1);
}
return str;
}
// B2019-076: moved the following to DocVersionExt.cs to make it available to transitionext.cs code.
//private string GetInheritedSIValue(ProcedureInfo pi, string fieldName)
//{
// string val = null;
// DocVersionConfig dvConfig = new DocVersionConfig(pi.MyDocVersion.Config);
// if (dvConfig != null)
// {
// val = dvConfig.GetValue("SI", fieldName);
// if (val != null && val != string.Empty) return val; // the value exists within the docversion level
// }
// FolderInfo fi = pi.MyDocVersion.MyFolder;
// while (fi != null)
// {
// FolderConfig folderConfig = new FolderConfig(fi.Config);
// if (folderConfig != null)
// {
// val = folderConfig.GetValue("SI", fieldName);
// if (val != null && val != string.Empty) return val; // the value exists within this folder
// }
// fi = fi.ActiveParent as FolderInfo;
// }
// return val;
//}
private static ItemInfo ValveGetFirstStep(VEPROMS.CSLA.Library.SectionInfo section)
{
ItemInfo firstHigh = null;
if (section.Steps == null || section.Steps.Count == 0)
{
// see if there is a 1st subsection with a step. The formats must match
// if this is true, use that step. Otherwise just clear the token.
if (section.Sections != null && section.Sections.Count > 0 &&
section.Sections[0].Steps != null || section.Sections[0].Steps.Count != 0)
{
if (section.ActiveFormat.FormatID == section.Sections[0].ActiveFormat.FormatID &&
section.MyContent.Type == section.Sections[0].MyContent.Type)
firstHigh = section.Sections[0].Steps[0];
}
}
else
firstHigh = section.Steps[0];
return firstHigh;
}
private string GetAttachNum1()
{
int cnt = 0;
SectionInfo si = MySection;
while (si != null)
{
if (si.MyContent.Type == MySection.MyContent.Type) cnt++;
si = si.MyPrevious as SectionInfo;
}
return cnt.ToString();
}
private static void AddImage(SvgGroup svgGroup, float x, float y, float w, float h, string figure)
{
svgGroup.Add(new SvgImage(new System.Drawing.PointF(x, y), new System.Drawing.SizeF(w, h),
System.Windows.Forms.Application.StartupPath + @"\Resources\" + figure));
}
private float SplitTextMaxWidth(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len, string match, ref string plstr)
{
List<string> titleLines = Volian.Base.Library.RtfTools.SplitText(title, (int)len);
float yOffset = 0;
int cnt = 0;
foreach (string line in titleLines)
{
cnt++;
if (cnt == 1 && yOffset == 0)
plstr = plstr.Replace(match, line);
else
{
if (cnt == 1)
{
plstr = plstr.Replace(match, line); // include preceeding text with the first line v.c. summer
svgGroup.Add(PageItemToSvgText(pageItem, plstr, yOffset));
plstr = string.Empty;
}
else
svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset));
plstr = plstr.Replace(match, string.Empty);
}
yOffset += (float)((pageItem.Font.Size > 14) ? pageItem.Font.Size : 12);
}
return Math.Max(0, yOffset);
}
private string SplitTitle(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len, string match, string plstr,int? numAndTitleLen)
{
bool includePrecedingText = false;
if (match == "{PROCTITLE2}" || match == "[PROCTITLE2]") return plstr.Replace(match, string.Empty);
// F2017-013 - Ginna (RGESAM1) this handles when you have {SECTIONLEVELNUMBER} and {SECTIONLEVELTITLE} on the same line.
// The section number was already replaced in plstr so when determining where to split the title,
// include the section number (and anything before the title) in the calculation of where to split.
// test for the ussage of the SectionNumberAndTitleLength (numAndTitleLen parameter) format variable (use a flag for this logic)
// This logic does not handle any pagelist tokens following the section title.
// "@@" acts like a hanging indent (Calvert) so don't include stuff before the title
// For now, made this explicite with the use of SectionLevelTitle
if ((numAndTitleLen != null && numAndTitleLen > 0) && !plstr.Contains("@@") && (plstr.IndexOf("{SECTIONLEVELTITLE}") > 0))
{
int idx = plstr.IndexOf(match);
title = plstr.Replace(match, title); // include everthing on this line for splitting
plstr = plstr.Substring(idx); // since title include everthing before {SECTIONLEVELTITLE} plstr needs to be {SECTIONLEVELTITLE} and everything after it
includePrecedingText = true;
}
// check to see if the title needs to wrap
if ((len == null || len == 0 || ItemInfo.StripRtfFormatting(title).Length < len) && (!includePrecedingText || ItemInfo.StripRtfFormatting(title).Length < numAndTitleLen))
{
// B2022-061: don't print '\line' as part of procedure title in pagelist items.
if (match == "{PROCTITLE}") title = title.Replace("\\line ", string.Empty);
if (match == "{PROCTITLE2}" || match == "[PROCTITLE2]") return plstr.Replace(match, string.Empty); // this would have been done in proctitle1
plstr = plstr.Replace(match, title).Replace("@@",string.Empty);
//svgGroup.Add(PageItemToSvgText(pageItem, title));
return plstr;
}
// BGE has a '@@' in its section number/title pagelist item for eops. If the title goes onto two lines,
// the '@@' marked the starting location for the title. Process this differently than other split titles:
if (plstr.Contains("@@"))
{
DoSpecialSectNumTitle(svgGroup, pageItem, title, len, match, plstr);
return string.Empty; // all resolved pagelist items were already added to svgGroup for printing.
}
// Otherwise determine how many line to split the text into
List<string>titleLines = Volian.Base.Library.RtfTools.SplitText(title,(includePrecedingText)?(int)numAndTitleLen: (int)len);
// Adjust y location based on which pagelist token & how many lines. Proctitle1 is adjusted if
// there are more than 2 lines (proctitle1 should have it's own y location that is used if there are 1 or 2 lines.)
float yOffset = (pageItem.Token.Contains("1") && titleLines.Count <= 2) ? 0 : (-6 * (titleLines.Count - 1));
// the following was added to support the vcb format proctitles that should always start on the line defined and
// move down the page for additional lines (this was added to handle a 3 line title printing abouve the border)
if (pageItem.Token.Contains("3")) yOffset = 0;
int cnt = 0;
// if the title broke into two lines & proctitle1 & proctitle2 are on the same line, handle that
// and return the string:
if (titleLines.Count == 2 && pageItem.Token.Contains("1") && pageItem.Token.Contains("2"))
{
plstr = plstr.Replace("{PROCTITLE1}", titleLines[0]);
plstr = plstr.Replace("[PROCTITLE1]", titleLines[0]);
plstr = plstr.Replace("{PROCTITLE2}", titleLines[1]);
plstr = plstr.Replace("[PROCTITLE2]", titleLines[1]);
return plstr;
}
foreach (string line in titleLines)
{
cnt++;
if (cnt == 1 && yOffset == 0) // adj == 0 means we use PROCTITLE1/PROCTITLE2 pagelist tokens with 2 or less lines
plstr = plstr.Replace(match, line);
else
{
if (cnt == 1)
{
plstr = plstr.Replace(match, line); // include preceeding text with the first line v.c. summer
svgGroup.Add(PageItemToSvgText(pageItem, plstr, yOffset));
plstr = string.Empty;
}
else
svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset));
plstr = plstr.Replace(match, string.Empty);
}
yOffset += (float)((pageItem.Font.Size > 14) ? pageItem.Font.Size : 12);
}
return plstr;
}
private PageItem _PIInitials = null;
public PageItem PIInitials
{
get { return _PIInitials; }
set
{
if (_PIInitials != null && value == null)
_LastPIInitials = _PIInitials;
_PIInitials = value;
}
}
private PageItem _LastPIInitials = null;
public PageItem LastPIInitials
{
get { return _LastPIInitials; }
set { _LastPIInitials = value; }
}
private bool _HasInitials = false;
public bool HasInitials
{
get { return _HasInitials; }
set { _HasInitials = value; }
}
private bool _InitialsPrinted = false;
public bool InitialsPrinted
{
get { return _InitialsPrinted; }
set { _InitialsPrinted = value; }
}
public bool PrintInitials(PdfContentByte cb,float yLocation, float leftMargin)
{
if (InitialsPrinted) return false;
InitialsPrinted = true;
vlnParagraph.TextAt(cb,this, PIInitials ?? LastPIInitials, yLocation, leftMargin);
return true;
}
private void DoSpecialSectNumTitle(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len, string match, string plstr)
{
// first add anything up to the "@@" to the svgGroup:
string befAts = plstr.Substring(0, plstr.IndexOf("@@"));
svgGroup.Add(PageItemToSvgText(pageItem, befAts, 0));
// get the new xoffset. This will be the column value + the size of 'stuff' before the '@@'
float xoff = (float)pageItem.Col;
xoff += (befAts.Length * pageItem.Font.CharsToTwips);
float yoff = (float)pageItem.Row;
List<string> titleLines = Volian.Base.Library.RtfTools.SplitText(title, (int)len);
foreach (string line in titleLines)
{
svgGroup.Add(PageItemToSvgText(pageItem.Token, yoff, xoff, (E_Justify)pageItem.Justify, pageItem.Font, line, MySection));
yoff += (float)((pageItem.Font.Size > 14) ? pageItem.Font.Size : 12);
}
}
private string SplitTitleAndUnit(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len, string token, string plstr)
{
List<string> titleLines = Volian.Base.Library.RtfTools.SplitText(title, (int)len);
// Add a separate line with the Unit Number
titleLines.Add("UNIT " + MySection.MyDocVersion.DocVersionConfig.Unit_Number);
// Adjust y location based on which pagelist token & how many lines.
float yOffset = (-6 * (titleLines.Count - 1));
foreach (string line in titleLines)
{
svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset));
yOffset += (float)((pageItem.Font.Size > 14) ? pageItem.Font.Size : 12);
}
return plstr.Replace(token, string.Empty);
}
private string SplitEOPNumber(SvgGroup svgGroup, PageItem pageItem, string eopnum, string token, string plstr)
{
string[] eopnums = eopnum.Split(" ".ToCharArray());
float yOffset = (-6 * (eopnums.Length - 1));
foreach (string line in eopnums)
{
svgGroup.Add(PageItemToSvgText(pageItem, line, yOffset));
yOffset += (float)((pageItem.Font.Size > 14) ? pageItem.Font.Size : 12);
}
return plstr.Replace(token, string.Empty);
}
//private string symblsStr = "\u25CF\u0394"; // string of possible symbol character in a tab
//// add symbol characters as needed
//// "\u25CF" - solid bullet
//// \x0394 - delta
//private float GetTextWidth(VE_Font vefont, string txt, string symblFontName)
//{
// System.Drawing.Font font = new System.Drawing.Font(vefont.Family, (float)vefont.Size, GetSysFontStyle(vefont));
// System.Drawing.Font symbFont = new System.Drawing.Font(symblFontName, (float)vefont.Size);
// iTextSharp.text.Font iFont = Volian.Svg.Library.VolianPdf.GetFont(font);
// iTextSharp.text.Font iSymblFont = Volian.Svg.Library.VolianPdf.GetFont(symbFont);
// float w = 0;
// foreach (char c in txt)
// {
// int idx = symblsStr.IndexOf(c);
// if (idx >= 0) // symbol character - use symbol font to find its width
// w += iSymblFont.BaseFont.GetWidthPointKerned(symblsStr[idx].ToString(), (float)vefont.Size);
// else
// w += iFont.BaseFont.GetWidthPointKerned(c.ToString(), (float)vefont.Size);
// }
// //float w = iFont.BaseFont.GetWidthPointKerned(Text.Replace("\u25CF","@"), (float)vefont.Size);
// return w;
//}
private string SplitCoverTitle(SvgGroup svgGroup, VEPROMS.CSLA.Library.PageItem pageItem, string title, int? len, string match, string plstr)
{
if (len == null || ItemInfo.StripRtfFormatting(title).Length < len)
{
if (match == "{COVERTITLE2}" || match == "[COVERTITLE2]") return plstr; // this would have been done in COVERTITLE1
plstr = plstr.Replace(match, title);
//svgGroup.Add(PageItemToSvgText(pageItem, title));
return plstr;
}
// Otherwise determine how many line to split the text into
List<string> titleLines = Volian.Base.Library.RtfTools.SplitText(title, (int)len);
if (match == "{COVERTITLE1}" || match == "[COVERTITLE1]")
{
plstr = plstr.Replace(match, titleLines[0]);
//svgGroup.Add(PageItemToSvgText(pageItem, titleLines[0]));
return plstr;
}
// if the token was proctitle, dont' adjust. If the token was PROCTITLE1/2 then
// move down 6.
// int adj = pageItem.Token.Contains("1") || pageItem.Token.Contains("2") ? 0 : -6;
int adj = (titleLines.Count > 2) ? -6 : 0;
float yOffset = adj * (titleLines.Count - 2);
int lnCnt = 0;
foreach (string line in titleLines)
{
lnCnt++;
if (lnCnt == 1) continue;
plstr = plstr.Replace(match, line);
svgGroup.Add(PageItemToSvgText(pageItem, plstr, yOffset));
plstr = string.Empty; // clear it because it was added into the list in the line above this, i.e. don't duplicate
yOffset += 12;
}
return plstr;
}
private int FindWidth(string title, int start, int len)
{
for (int ii = start + len; ii > start; ii--)
{
if (title[ii] == ' ')
{
while (title[ii] == ' ') ii--;
if (ii > start)
return 2 + ii - start;
return len;
}
}
return len;
}
private SvgPart PageItemToSvgUse(VEPROMS.CSLA.Library.PageItem pageItem, string templateName, float supmargadj)
{
SvgUse svgUse = new SvgUse();
svgUse.UseID = templateName;
svgUse.X = new SvgMeasurement((float)(pageItem.Col ?? 0) + supmargadj, E_MeasurementUnits.PT); // F2023-035: Add in supplemental info margin adjust
svgUse.Y = new SvgMeasurement((float)(pageItem.Row ?? 0), E_MeasurementUnits.PT);
return svgUse;
}
private static SvgText PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text, VE_Font font, SectionInfo mySection, float supmargadj)
{
SvgText svgText = PageItemToSvgText(pageItem, text, mySection, supmargadj);
svgText.Font = font.WindowsFont;
return svgText;
}
private static SvgText PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text, SectionInfo mySection, float supmargadj)
{
SvgText svgText = new SvgText();
// F2021-053: Do replace words for Page List items. Send format items down to svgtext.
SvgText.CompressSuper = mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressHPSuper;
SvgText.CompressSub = mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressHPSub;
SvgText.CompressPropSubSup = mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressPropSubSup;
svgText.Text = text;
// F2023-039 logic to specify a color when printing a paglist line
if (pageItem.TextColor != null && pageItem.TextColor != "")
svgText.FillColor = System.Drawing.Color.FromName(pageItem.TextColor);// System.Drawing.Color.Red;
VEPROMS.CSLA.Library.E_Justify justify = pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft;
float colAdj16bit = 0;
if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft)
svgText.Justify = SvgJustify.Left;
else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight)
svgText.Justify = SvgJustify.Right;
else
{
svgText.Justify = SvgJustify.Center;
if (((justify & VEPROMS.CSLA.Library.E_Justify.PSTrue) != VEPROMS.CSLA.Library.E_Justify.PSTrue) &&
!mySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PicaIgnoreFiveSixths)
{
// the default CPI for Proms is 12, in 16bit 12 is the default - if a font wasn't defined
// or when doing a positioning calculation 12 was used. So we need to make an adjustment
// to handle non-12 CPI (12CPI will just cancel out in the following calculation).
// Take the difference between the width in Points of a character at 12CPI and a character
// at the defined font's CPI. Multiply that times the length of title and divide by two
// to find the half-way point.
// if the PageItem's font CPI is null, then default to 12 CPI
colAdj16bit = (1 + text.Length) * ((72 / (float)(pageItem.Font.CPI ?? 12)) - (72 / 12)) / 2;
}
}
svgText.Font = pageItem.Font.WindowsFont;
// F2021-070 & 066 - shrink font size of page list items if format has amount
string tmpText = text;
if (pageItem.FontShrinkAftLen != null && pageItem.FontShrinkAftLen > 0)
svgText.FontSize = ShrinkIt(ref tmpText, svgText, (float)pageItem.FontShrinkAftLen, pageItem.FontTooSmallMsg);
if (tmpText != text) svgText.Text = tmpText;
float row = (float)pageItem.Row < 0 ? -(float)pageItem.Row : (float)pageItem.Row;
if ((justify & VEPROMS.CSLA.Library.E_Justify.PSTop) == VEPROMS.CSLA.Library.E_Justify.PSTop) row -= ((72 / 6) / 2);
float lcol = pageItem.Col ?? 0;
// the column may need adjusted based on the document styles PageWidth. This was done in
// the 16bit code and was needed here to get the printed output to match.
if (pageItem.Font.FontIsProportional() && svgText.Justify == SvgJustify.Center)
{
int dotsPerChar = (int)(2400 / (mySection.MyDocStyle.Layout.PageWidth / 6));
lcol = (lcol * 25) / dotsPerChar;
}
// F2023-035: WCN - allow for change in left margin for supplemental information pages by
// setting a value in the DocStyle for the adjustment.
svgText.X = new SvgMeasurement((float)lcol - colAdj16bit + supmargadj, E_MeasurementUnits.PT); // F2023-035: Add in supplemental info margin adjust
svgText.Y = new SvgMeasurement(row, E_MeasurementUnits.PT);
if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine(" PL x {0} y {1} {2} {3} {4} \"{5}\"", svgText.X, svgText.Y, svgText.FontFamily, svgText.FontSize, svgText.SVGFontStyle, TextForBaseline.FixText(svgText.Text));
return svgText;
}
// F2021-070 & 066 - shrink font size of page list items if format has amount. ShrinkIt compares size (width) of text with input font and
// will decrement font size by one until the text size is less than value from format file.
// Additional work has been done for F2021-066 to allow for only shrinking to font size greater/equal to 8 and if it goes smaller than that
// to put out a message.
private static string ShrinkIt(ref string text, SvgText svgText, float fontShrinkAftLen, string reptext)
{
int tmpi = Convert.ToInt32(svgText.FontSize.Substring(0, svgText.FontSize.IndexOf("PT")));
string origFontSize = svgText.FontSize;
using (var image = new System.Drawing.Bitmap(1, 1))
{
using (var g = System.Drawing.Graphics.FromImage(image))
{
try
{
// pageitem's font size did not have a 'set'. svgtext's fontsize is in format of 12PT, so get font size from that
// and decrement until it is less than format value
System.Drawing.SizeF mySize = g.MeasureString(text, svgText.Font);
while (mySize.Width > fontShrinkAftLen && tmpi > 8)
{
tmpi = tmpi - 1;
svgText.FontSize = tmpi.ToString() + "PT";
mySize = g.MeasureString(text, svgText.Font);
}
// Additional work for F2021-066: if font size goes less than or equal to 6, use original font size & if
// there is a message in format file to use instead of text, then use it.
if (tmpi == 8 && mySize.Width > fontShrinkAftLen)
{
if (reptext != null && reptext != string.Empty)
text = reptext;
else // As per PAL (11/15/21) have default message and highlight by italics (text was already bolded)
{
text = "Text Too Long To Fit";
svgText.SVGFontStyle = "italic";
}
svgText.FontSize = origFontSize;
}
}
catch // don't reset if error occurred.
{
}
}
}
return svgText.FontSize;
}
private SvgPart PageItemToSvgText(VEPROMS.CSLA.Library.PageItem pageItem, string text, float yOffset)
{
SvgText svgText = new SvgText();
svgText.Text = text;
VEPROMS.CSLA.Library.E_Justify justify = pageItem.Justify ?? VEPROMS.CSLA.Library.E_Justify.PSLeft;
float colAdj16bit = 0;
if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft)
svgText.Justify = SvgJustify.Left;
else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight)
svgText.Justify = SvgJustify.Right;
else
{
svgText.Justify = SvgJustify.Center;
if (((justify & VEPROMS.CSLA.Library.E_Justify.PSTrue) != VEPROMS.CSLA.Library.E_Justify.PSTrue) &&
!MySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PicaIgnoreFiveSixths)
{
// the default CPI for Proms is 12, in 16bit 12 is the default - if a font wasn't defined
// or when doing a positioning calculation 12 was used. So we need to make an adjustment
// to handle non-12 CPI (12CPI will just cancel out in the following calculation).
// Take the difference between the width in Points of a character at 12CPI and a character
// at the defined font's CPI. Multiply that times the length of title and divide by two
// to find the half-way point.
colAdj16bit = (1 + text.Length) * ((72 / (float)pageItem.Font.CPI) - (72 / 12)) / 2;
}
}
float lcol = pageItem.Col ?? 0;
// the column may need adjusted based on the document styles PageWidth. This was done in
// the 16bit code and was needed here to get the printed output to match.
if (pageItem.Font.FontIsProportional() && svgText.Justify == SvgJustify.Center)
{
int dotsPerChar = (int)(2400 / (MySection.MyDocStyle.Layout.PageWidth / 6));
lcol = (lcol * 25) / dotsPerChar;
}
svgText.Font = pageItem.Font.WindowsFont;
svgText.X = new SvgMeasurement((float)lcol - colAdj16bit, E_MeasurementUnits.PT); // new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT);
svgText.Y = new SvgMeasurement((float)(yOffset + pageItem.Row ?? 0), E_MeasurementUnits.PT);
if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine(" PL x {0} y {1} {2} {3} {4} \"{5}\"", svgText.X, svgText.Y, svgText.FontFamily, svgText.FontSize, svgText.SVGFontStyle, TextForBaseline.FixText(svgText.Text));
return svgText;
}
private SvgPart PageItemToSvgText(string token, float row, float col, E_Justify just, VE_Font font, string text, SectionInfo MySection)
{
SvgText svgText = new SvgText();
svgText.Text = text;
VEPROMS.CSLA.Library.E_Justify justify = just;
float colAdj16bit = 0;
if ((justify & VEPROMS.CSLA.Library.E_Justify.PSLeft) == VEPROMS.CSLA.Library.E_Justify.PSLeft)
svgText.Justify = SvgJustify.Left;
else if ((justify & VEPROMS.CSLA.Library.E_Justify.PSRight) == VEPROMS.CSLA.Library.E_Justify.PSRight)
svgText.Justify = SvgJustify.Right;
else
{
svgText.Justify = SvgJustify.Center;
if (((justify & VEPROMS.CSLA.Library.E_Justify.PSTrue) != VEPROMS.CSLA.Library.E_Justify.PSTrue) &&
!MySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.PicaIgnoreFiveSixths)
{
// the default CPI for Proms is 12, in 16bit 12 is the default - if a font wasn't defined
// or when doing a positioning calculation 12 was used. So we need to make an adjustment
// to handle non-12 CPI (12CPI will just cancel out in the following calculation).
// Take the difference between the width in Points of a character at 12CPI and a character
// at the defined font's CPI. Multiply that times the length of title and divide by two
// to find the half-way point.
colAdj16bit = (1 + text.Length) * ((72 / (float)font.CPI) - (72 / 12)) / 2;
}
}
float lcol = col;
// the column may need adjusted based on the document styles PageWidth. This was done in
// the 16bit code and was needed here to get the printed output to match.
if (font.FontIsProportional() && svgText.Justify == SvgJustify.Center)
{
int dotsPerChar = (int)(2400 / (MySection.MyDocStyle.Layout.PageWidth / 6));
lcol = (lcol * 25) / dotsPerChar;
}
// F2021-053: Do replace words for Page List items. Send format items down to svgtext.
SvgText.CompressSuper = MySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressHPSuper;
SvgText.CompressSub = MySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressHPSub;
SvgText.CompressPropSubSup = MySection.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.CompressPropSubSup;
svgText.Font = font.WindowsFont;
svgText.X = new SvgMeasurement((float)lcol - colAdj16bit, E_MeasurementUnits.PT); // new SvgMeasurement((float)(pageItem.Col ?? 0), E_MeasurementUnits.PT);
svgText.Y = new SvgMeasurement(row, E_MeasurementUnits.PT);
if (svgText.Font.Underline && svgText.Text.EndsWith(" ")) svgText.Text = svgText.Text.Substring(0, svgText.Text.Length - 1) + "\xA0";// replace last space with a hardspace
// C2018-004 create meta file for baseline compares
Volian.Base.Library.BaselineMetaFile.WriteLine(" PL x {0} y {1} {2} {3} {4} \"{5}\"", svgText.X, svgText.Y, svgText.FontFamily, svgText.FontSize, svgText.SVGFontStyle, TextForBaseline.FixText(svgText.Text));
return svgText;
}
private static List<string> _MissingTokens = new List<string>();
protected override string ReplacePageListToken(Match match)
{
switch (match.Value)
{
case "{PAGE}": // Current Page Number
return CurrentPageNumber.ToString();
case "{OF}": // Total Page Count for this section
return CurrentPageOf.ToString();
case "{REV}": // Revision Number and/or Revision string.
case "{REV2}":
// The 16bit code has a revision number & then a revision date. This revision date
// was actually either a date OR a string. The 32bit code no longer will call this
// token or string RevDate. HLP procs & stpdif show the different types of data
// that are used.
// 16-bit had code to string preceeding blanks.
if (Rev != null && Rev != string.Empty) Rev = Rev.TrimStart(" ".ToCharArray());
// Now check the format flags to determine if/how the Rev string should be parsed.
if ((MySection.ActiveFormat.PlantFormat.FormatData.PrintData.DoRevDate && Rev.Contains("/"))
|| (MySection.ActiveFormat.PlantFormat.FormatData.PrintData.RevDateWithForwardSlash && Rev.Contains("\\")))
{
int indx = Rev.IndexOf(MySection.ActiveFormat.PlantFormat.FormatData.PrintData.RevDateWithForwardSlash ? '\\' : '/');
if (match.Value == "{REV}") return Rev.Substring(0,indx);
return Rev.Substring(indx+1);
}
if (match.Value == "{REV}")return Rev;
return System.DateTime.Today.ToShortDateString();
case "{CHKOFFHEADING}":
return PageListTopCheckOffHeader;
case "{ROMANPAGE}":
return ItemInfo.RomanNumbering(CurrentPageNumber).ToLower();
case "{SETREV}":
return MySection.MyDocVersion.DocVersionConfig.ProcedureSetRev;
case "{NULLDOCCURPAGE}":
return string.Empty;
}
if (!_MissingTokens.Contains(match.Value))
{
_MissingTokens.Add(match.Value);
_MyLog.InfoFormat("Unhandled token {0}", match.Value);
}
return string.Empty;
}
}
public class ChkListBoxesHelper : List<ChkListBoxHelper>
{
private float _yOffsetStart;
private float _yOffsetEnd;
public ChkListBoxesHelper()
: base()
{
}
public void Add(ItemInfo myHls, float yoffStart, float yoffend)
{
Add(new ChkListBoxHelper());
}
public void Draw()
{
foreach (ChkListBoxHelper cb in this)
{
}
}
}
public class ChkListBoxHelper
{
public ChkListBoxHelper()
{
}
}
public class PageBookmarks : List<PageBookmark>
{
public PageBookmarks()
: base()
{
}
public void Add(ItemInfo itemInfo, string title, PdfDestination pdfDestination)
{
foreach (PageBookmark pb in this)
if (pb.Title == title) return;
Add(new PageBookmark(itemInfo, title, pdfDestination));
}
}
public class PageBookmark
{
private ItemInfo _MyItemInfo;
public ItemInfo MyItemInfo
{
get { return _MyItemInfo; }
set { _MyItemInfo = value; }
}
private string _Title;
public string Title
{
get { return _Title; }
set { _Title = value; }
}
private PdfDestination _PdfDestination;
public PdfDestination PdfDestination
{
get { return _PdfDestination; }
set { _PdfDestination = value; }
}
public PageBookmark(ItemInfo itemInfo, string title, PdfDestination pdfDestination)
{
_MyItemInfo = itemInfo;
_Title = title;
_PdfDestination = pdfDestination;
}
internal bool IsTopLevel
{
get
{
ItemInfo parent = MyItemInfo.ActiveParent as ItemInfo;
if (parent == null || parent.IsProcedure) return true;
return false;
}
}
internal int Level
{
get
{
int level = 0;
ItemInfo parent = MyItemInfo.ActiveParent as ItemInfo;
while (parent != null && !parent.IsProcedure)
{
level++;
parent = parent.ActiveParent as ItemInfo;
}
return level;
}
}
}
public class ChangeBarDefinition // anything that is section level should go in here.
{
private PrintChangeBar _MyChangeBarType;
public PrintChangeBar MyChangeBarType
{
get { return _MyChangeBarType; }
set { _MyChangeBarType = value; }
}
private PrintChangeBarLoc _MyChangeBarLoc;
public PrintChangeBarLoc MyChangeBarLoc
{
get { return _MyChangeBarLoc; }
set { _MyChangeBarLoc = value; }
}
private PrintChangeBarText _MyChangeBarText;
public PrintChangeBarText MyChangeBarText
{
get { return _MyChangeBarText; }
set { _MyChangeBarText = value; }
}
private string _MyChangeBarMessage; // user defined change bar message from docconfig
public string MyChangeBarMessage
{
get { return _MyChangeBarMessage; }
set { _MyChangeBarMessage = value; }
}
private int _MyChangeBarColumn; // two dimensional array, if both on same side, values are =
public int MyChangeBarColumn
{
get { return _MyChangeBarColumn; }
set { _MyChangeBarColumn = value; }
}
/*
* could have line thickness (set default from 16-bit), line color (set default as black), line style
*/
public ChangeBarDefinition()
{
}
public ChangeBarDefinition(PrintChangeBar myCBT, PrintChangeBarLoc myCBL, PrintChangeBarText myCBTxt, string myCBMsg)
{
_MyChangeBarType = myCBT;
_MyChangeBarLoc = myCBL;
_MyChangeBarText = myCBTxt;
}
public ChangeBarDefinition(DocVersionConfig docverConfig, FormatInfo formatInfo)
{
// if there is not overridden data on the docversion, prompt user...
ChangeBarData changeBarData = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData;
if (docverConfig == null || docverConfig.Print_ChangeBar == PrintChangeBar.SelectBeforePrinting)
{
// use these for now, i.e. this is what user would have selected from dialog.
_MyChangeBarType = PrintChangeBar.WithDefault;
_MyChangeBarLoc = PrintChangeBarLoc.OutsideBox;
_MyChangeBarText = PrintChangeBarText.None;
}
else
{
_MyChangeBarType = docverConfig.Print_ChangeBar;
_MyChangeBarLoc = docverConfig.Print_ChangeBarLoc;
_MyChangeBarText = docverConfig.Print_ChangeBarText;
}
if (_MyChangeBarType == PrintChangeBar.WithDefault) // get data from format
{
_MyChangeBarText = changeBarData.ChangeBarMessage == "ChgID" ? PrintChangeBarText.ChgID :
changeBarData.ChangeBarMessage == "DateAndChgID" ? PrintChangeBarText.DateChgID :
changeBarData.ChangeBarMessage == "None" ? PrintChangeBarText.None :
changeBarData.ChangeBarMessage == "RevNum" ? PrintChangeBarText.RevNum : PrintChangeBarText.UserDef;
}
if (_MyChangeBarType != PrintChangeBar.Without)
{
// if the format has the absolutefixedchangecolumn format flag, then always use the fixedchangecolumn from the
// format, otherwise, use the default column based on the selected location, stored in the base format.
_MyChangeBarColumn = (changeBarData.AbsoluteFixedChangeColumn) ?
(int)changeBarData.FixedChangeColumn :
System.Convert.ToInt32(changeBarData.DefaultCBLoc.Split(",".ToCharArray())[(int)(_MyChangeBarLoc)]);
if (_MyChangeBarText == PrintChangeBarText.UserDef)
_MyChangeBarMessage = docverConfig.Print_UserCBMess1 + @"\n" + docverConfig.Print_UserCBMess2;
}
}
}
public class CheckOffHeaderHelper
{
private SvgText _SvgText;
public SvgText SvgText
{
get { return _SvgText; }
set { _SvgText = value; }
}
private VEPROMS.CSLA.Library.VE_Font _CheckOffHeaderFont;
public VEPROMS.CSLA.Library.VE_Font CheckOffHeaderFont
{
get { return _CheckOffHeaderFont; }
set { _CheckOffHeaderFont = value; }
}
public CheckOffHeaderHelper(SvgText stext, VEPROMS.CSLA.Library.VE_Font vf)
{
_SvgText = stext;
_CheckOffHeaderFont = vf;
}
}
public class Gap
{
private float _YTop;
public float YTop
{
get { return _YTop; }
set { _YTop = value; }
}
private float _YBottom;
public float YBottom
{
get { return _YBottom; }
set { _YBottom = value; }
}
public Gap(float yTop, float yBottom)
{
_YTop = yTop;
_YBottom = yBottom;
}
}
public class Gaps : List<Gap>
{
public void Add(float yTop, float yBotttom)
{
this.Add(new Gap(yTop, yBotttom));
}
}
}