
Show how long it takes to print all procedures For Null values use Arial as a default font. Added Try/Catch to PDFDocument.Close (In case page is empty) Only output End Message if it exists Pagination Fixes
1625 lines
68 KiB
C#
1625 lines
68 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using System.Text.RegularExpressions;
|
|
using System.IO;
|
|
using iTextSharp.text.pdf;
|
|
using iTextSharp.text;
|
|
using Itenso.Rtf;
|
|
using Itenso.Rtf.Parser;
|
|
using Itenso.Rtf.Interpreter;
|
|
using Itenso.Rtf.Support;
|
|
using Volian.Controls.Library;
|
|
using VEPROMS.CSLA.Library;
|
|
using Volian.Base.Library;
|
|
|
|
namespace Volian.Print.Library
|
|
{
|
|
public partial class vlnParagraphs : List<vlnParagraph>
|
|
{
|
|
private vlnParagraph _Parent;
|
|
public vlnParagraph Parent
|
|
{
|
|
get { return _Parent; }
|
|
set { _Parent = value; }
|
|
}
|
|
public vlnParagraphs(vlnParagraph parent)
|
|
{
|
|
_Parent = parent;
|
|
}
|
|
public float Add(PdfContentByte cb, ItemInfoList itemInfoList, float xoff, float yoff, float yoffRight, int rnoLevel, int maxRNO, FormatInfo formatInfo)
|
|
{
|
|
int? bxIndex = null;
|
|
vlnBox box = null;
|
|
float yTop = yoff;
|
|
foreach (ItemInfo childItemInfo in itemInfoList)
|
|
{
|
|
int? bxIndx = childItemInfo.FormatStepData==null?-1:childItemInfo.FormatStepData.StepLayoutData.STBoxindex;
|
|
if (bxIndx != -1 && (bxIndex != bxIndx || childItemInfo.FormatStepData.BoxIt))
|
|
{
|
|
if (childItemInfo.FormatStepData.BoxIt) // this is a boxed HLS
|
|
{
|
|
box = new vlnBox();
|
|
box.MyBox = new Box();
|
|
box.DefBox = vlnBox.BoxThin;
|
|
StepSectionLayoutData ssld = formatInfo.MyStepSectionLayoutData;
|
|
int colR = int.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[childItemInfo.ColumnMode]);
|
|
int widS = vlnPrintObject.ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
|
|
box.DefEnd = (float)(ssld.ColS + colR + widS + (60/4.8));
|
|
box.YOffset = yoff - .75F * vlnPrintObject.SixLinesPerInch;
|
|
}
|
|
else if (bxIndex == null) // First boxed step
|
|
{
|
|
box = new vlnBox();
|
|
box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
|
|
box.YOffset = yoff;
|
|
int ln = 1; // a format flag determines whether there is a space before the note/caution.
|
|
if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
|
|
yoff += ln * vlnPrintObject.SixLinesPerInch;
|
|
}
|
|
else // Change Box Style
|
|
{
|
|
if (box != null) box.Height = yoff - box.YOffset; // new height, with children
|
|
box = new vlnBox();
|
|
box.MyBox = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
|
|
box.YOffset = yoff;
|
|
int ln = 1; // a format flag determines whether there is a space before the note/caution.
|
|
if (childItemInfo.FormatStepData.OneLineBeforeTab) ln++;
|
|
yoff += ln * vlnPrintObject.SixLinesPerInch;
|
|
}
|
|
bxIndex = bxIndx;
|
|
}
|
|
if (childItemInfo is SectionInfo) formatInfo = (childItemInfo as SectionInfo).LocalFormat ?? formatInfo;
|
|
if (rnoLevel < maxRNO && childItemInfo.RNOs != null) yoff = Math.Max(yoff, yoffRight);
|
|
vlnParagraph para = new vlnParagraph(Parent, cb, childItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo);
|
|
if (box != null && box.MyParent == null)
|
|
{
|
|
box.MyParent = para;
|
|
para.PartsContainer.Add(box);
|
|
}
|
|
Add(para);
|
|
// para.YBottomMost will have y for bottom of any substeps that are also enclosed in the box.
|
|
yoff = para.YBottomMost;
|
|
if (childItemInfo.FormatStepData != null && childItemInfo.FormatStepData.BoxIt)
|
|
{
|
|
box.Height = yoff - box.YOffset - (1.1F * vlnPrintObject.SixLinesPerInch);
|
|
box = null; // if doing boxed steps, only do single sibling at a time.
|
|
}
|
|
}
|
|
if (box != null)
|
|
{
|
|
if (box != null) box.Height = yoff - box.YOffset; // new height, with children
|
|
yoff += 2 * vlnPrintObject.SixLinesPerInch;
|
|
}
|
|
return yoff;
|
|
}
|
|
public float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
|
|
{
|
|
foreach (vlnParagraph child in this)
|
|
{
|
|
yPageStart = child.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
}
|
|
return yPageStart;
|
|
}
|
|
}
|
|
public partial class vlnParagraph : vlnPrintObject
|
|
{
|
|
private vlnTable _MyGrid;
|
|
public vlnTable MyGrid
|
|
{
|
|
get { return _MyGrid; }
|
|
set { _MyGrid = value; }
|
|
}
|
|
public float SectYPageStart = 0;
|
|
/// <summary>
|
|
/// This variable is used to match 16 bit pagination
|
|
/// </summary>
|
|
private bool _Match16BitPagination = false;
|
|
public float ParagraphToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
|
|
{
|
|
if (Processed) return yPageStart;
|
|
//float localYPageStart = yPageStart;
|
|
Processed = true;
|
|
if (_PartsAbove != null && _PartsAbove.Count > 0) yPageStart = PartsAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
if (MyItemInfo.IsHigh && MyItemInfo.MyDocStyle.SpecialStepsFoldout) yPageStart -= SixLinesPerInch;
|
|
float yLocation = CalculateYOffset(yPageStart, yTopMargin);
|
|
if (MyItemInfo.HasChangeBar && MyPageHelper.ChangeBarDefinition.MyChangeBarType != PrintChangeBar.Without) MyPageHelper.AddChangeBar(DoChangeBar(cb, MyItemInfo, MyPageHelper, XOffset, yLocation, MyPageHelper.MaxRNO, MyItemInfo.ActiveFormat), cbMess);
|
|
float retval = yLocation;
|
|
if (MyItemInfo.IsFigure)
|
|
{
|
|
yLocation -= (SixLinesPerInch * MyPageHelper.YMultiplier);
|
|
if (ImageText != null)
|
|
retval = DrawFigure(cb, yBottomMargin, yLocation);
|
|
else
|
|
retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
|
|
|
|
}
|
|
else if (!MyItemInfo.IsStepSection
|
|
|| (MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
|
|
&& !MyItemInfo.MyDocStyle.CancelSectTitle
|
|
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)) // Don't ouput the Step Section title
|
|
{
|
|
if (MyItemInfo.MyContent.MyGrid != null)
|
|
retval = DrawGrid(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
|
|
else
|
|
retval = DrawText(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation);
|
|
if (MyItemInfo.IsHigh)
|
|
{
|
|
MyPageHelper.PageBookmarks.Add(MyItemInfo, MyItemInfo.MyTab.CleanText + " " + MyItemInfo.DisplayText,
|
|
new PdfDestination(PdfDestination.FITBH, yLocation + YVeryTop - YTopMost + SixLinesPerInch));
|
|
}
|
|
}
|
|
//Height = yLocation - retval;
|
|
if (_PartsLeft != null && _PartsLeft.Count > 0) yPageStart = PartsLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
if (_PartsRight != null && _PartsRight.Count > 0) yPageStart = PartsRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
if (_PartsBelow != null && _PartsBelow.Count > 0) yPageStart = PartsBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
if (_PartsContainer != null && _PartsContainer.Count > 0) yPageStart = PartsContainer.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
|
|
//if (localYPageStart != yPageStart) DebugText.WriteLine("ParToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, localYPageStart, yPageStart);
|
|
return yPageStart;
|
|
}
|
|
|
|
private float DrawGrid(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
|
|
{
|
|
//DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.ShortPath, FormattedText);
|
|
DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.ShortPath,MyItemInfo.MyContent.Text);
|
|
float retval = Rtf2Pdf.GridAt(cb, MyGrid, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
|
|
return retval;
|
|
}
|
|
|
|
private float DrawText(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation)
|
|
{
|
|
DebugText.WriteLine("{0},'{1}','{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, FormattedText);
|
|
//Console.WriteLine("{0},{1},'{2}','<<END>>'", MyItemInfo.ItemID, MyItemInfo.DBSequence, IParagraph.Content);
|
|
float retval = yLocation;
|
|
// Check if only one line, i.e. "Height < (1.2F * IParagraph.Leading". The Leading can be for six or seven lines per inch, so the 1.2
|
|
// multiplier accounts for both.
|
|
if (!MyItemInfo.IsStepSection && MyItemInfo.FormatStepData.CenterOneLineOnly && MyItemInfo.MyPrevious == null && MyItemInfo.NextItem == null && Height < (1.2F * IParagraph.Leading))
|
|
IParagraph.Alignment = Element.ALIGN_CENTER;
|
|
retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin);
|
|
if (retval == 0) // problem occurred - paragraph was not able to be printed on page
|
|
{ // pagination logic needs to be fixed.
|
|
cb.PdfDocument.NewPage(); // pagination issue
|
|
DebugText.WriteLine("*****PaginateError");
|
|
yPageStart = yTopMargin + YVeryTop;
|
|
yLocation = yPageStart - YOffset;
|
|
//MyItemInfo.ItemID, YSize, yPageSize, yLocation
|
|
DebugPagination.WriteLine("-1,'Yes','Forced Pagination',{0},{1},,{3},{4}", MyItemInfo.ItemID, YSize, 0, yLocation, MyItemInfo.DBSequence);
|
|
retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin);
|
|
}
|
|
return retval;
|
|
}
|
|
private static List<string> myAttributes =new List<string>();
|
|
private static void AddAttribute(string attr)
|
|
{
|
|
if (myAttributes.Contains(attr))
|
|
return;
|
|
//Console.WriteLine("Attribute = \"{0}\"", attr);
|
|
myAttributes.Add(attr);
|
|
}
|
|
private void CheckAttributes(System.Collections.Hashtable attributes)
|
|
{
|
|
foreach (string attr in attributes.Keys)
|
|
{
|
|
AddAttribute(attr);
|
|
}
|
|
}
|
|
private string FormattedText
|
|
{
|
|
get
|
|
{
|
|
bool subscript = false;
|
|
//if (_MyItemInfo.ItemID == 467)
|
|
// Console.Write("");
|
|
StringBuilder sb = new StringBuilder();
|
|
//if (IParagraph.Chunks.Count > 1)
|
|
// Console.WriteLine("{0} Chunks", IParagraph.Chunks.Count);
|
|
foreach (Chunk chk in IParagraph.Chunks)
|
|
{
|
|
string prefix = "";
|
|
string suffix = "";
|
|
CheckAttributes(chk.Attributes);
|
|
if (chk.Font.BaseFont != null && chk.Font.BaseFont.PostscriptFontName.ToUpper().Contains("BOLD"))
|
|
{
|
|
prefix += "\xD5";
|
|
suffix = "\xD6" + suffix;
|
|
}
|
|
if (chk.Attributes.ContainsKey("SUBSUPSCRIPT"))
|
|
{
|
|
float sup = (float)(chk.Attributes["SUBSUPSCRIPT"]);
|
|
if (sup > 0)
|
|
{
|
|
prefix += "\xA6";
|
|
suffix = "\xD1" + suffix;
|
|
}
|
|
else if (sup < 0)
|
|
{
|
|
prefix += "\xD1";
|
|
suffix = "\xA6" + suffix;
|
|
}
|
|
|
|
}
|
|
if (chk.Attributes.ContainsKey("UNDERLINE"))
|
|
{
|
|
prefix += "\x16";
|
|
suffix = "\x16" + suffix; ;
|
|
}
|
|
sb.Append(prefix + chk.Content + suffix);
|
|
}
|
|
string retval = sb.ToString();
|
|
retval = retval.Replace("\xD1\xA6", "");// Remove Multiple Superscript commands in a row
|
|
retval = retval.Replace("\xA6\xD1", "");// Remove Multiple Superscript commands in a row
|
|
retval = retval.Replace("\xD6\xD5", "");
|
|
retval = retval.Replace("\xD6\x16\xD5", "\x16");
|
|
return retval;
|
|
}
|
|
}
|
|
//private bool _TextDebug = false; //true; this will turn on a writeline with debug in DrawText()
|
|
private float DrawFigure(PdfContentByte cb, float yBottomMargin, float yLocation)
|
|
{
|
|
float retval = yLocation;
|
|
if (ImageText != null)
|
|
{
|
|
string[] vals = ImageText.Split("\n".ToCharArray());
|
|
ProcedureInfo proc = MyItemInfo.MyProcedure;
|
|
DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo;
|
|
ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst;
|
|
ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]);
|
|
if (roImage != null)
|
|
{
|
|
iTextSharp.text.Image it_image = iTextSharp.text.Image.GetInstance(roImage.Content);
|
|
retval = Rtf2Pdf.FigureAt(cb, it_image, XOffset + MyItemInfo.FormatStepData.Font.CharsToTwips, yLocation, Width * MyPageHelper.YMultiplier, Height * MyPageHelper.YMultiplier, DebugInfo, yBottomMargin, !MyItemInfo.FormatStepData.Type.Contains("Borderless"));
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
private string DebugInfo
|
|
{
|
|
get
|
|
{
|
|
return string.Format("DebugID = {0}, ID={1} Type={2} TypeName='{3}' StepLevel={4} DBSequence={5}", DebugId, MyItemInfo.ItemID, MyItemInfo.FormatStepType, MyItemInfo.FormatStepData==null?"NoStepData":MyItemInfo.FormatStepData.Type, MyItemInfo.StepLevel, MyItemInfo.DBSequence);
|
|
}
|
|
}
|
|
public override float ToPdf(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin)
|
|
{
|
|
float yLocalypagestart = yPageStart;
|
|
// yPageStart is offset into roll; YTopMost is offset of topmost of this paragraph.
|
|
float yLocation = yPageStart - YTopMost;
|
|
DebugText.WriteLine("ToPdf1:{0},'{1}',{2},{3},{4}", MyItemInfo.ItemID, MyItemInfo.ShortSearchPath, yLocation, yPageStart, YTopMost);
|
|
int paginate = Paginate(yLocation, yTopMargin, yBottomMargin);
|
|
bool firstHighLevelStep = MyItemInfo.IsHigh && (MyItemInfo.MyPrevious == null);
|
|
switch (paginate)
|
|
{
|
|
case 0:
|
|
if (MyItemInfo.IsSection)
|
|
{
|
|
SectionInfo si = MyItemInfo as SectionInfo;
|
|
MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
|
|
}
|
|
break;
|
|
case 1: // Break on High Level Step
|
|
OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
|
|
cb.PdfDocument.NewPage();
|
|
DebugText.WriteLine("Paginate1");
|
|
if (MyItemInfo.IsSection)
|
|
{
|
|
SectionInfo si = MyItemInfo as SectionInfo;
|
|
MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
|
|
}
|
|
|
|
if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
|
|
PromsPrinter.DoFoldoutPage(cb, "HLS", MyPageHelper.TextLayer, MyPageHelper);
|
|
yPageStart = yTopMargin + YTopMost;
|
|
MyPageHelper.YMultiplier = 1;
|
|
break;
|
|
case 2: // Break within a Step
|
|
OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
|
|
DocStyle docstyle = MyItemInfo.MyDocStyle;
|
|
string myMsg = docstyle.Continue.Bottom.Message;
|
|
if (myMsg != null && myMsg != "")
|
|
{
|
|
if (myMsg.IndexOf(@"%d") > -1)
|
|
myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanText.Trim());
|
|
if (myMsg.IndexOf(@"%2d") > -1)
|
|
myMsg = myMsg.Replace(@"%2d", MyItemInfo.MyHLS.MyTab.CleanText.Trim(" .".ToCharArray()).PadLeft(2));
|
|
float msg_yLocation = 0;
|
|
switch (docstyle.Continue.Bottom.Location)
|
|
{
|
|
case E_ContBottomLoc.EndOfText: // place continue string at end of text
|
|
case E_ContBottomLoc.BtwnTextAndBottom: // place continue string between end of text & bottom of page
|
|
Console.WriteLine("Not done yet");
|
|
break;
|
|
case E_ContBottomLoc.BottomOfPage: // place continue message at bottom of page
|
|
//msg_yLocation = yBottomMargin + 2 * SixLinesPerInch + (float)docstyle.Layout.FooterLength; // 2 lines above bottom margin
|
|
msg_yLocation = yBottomMargin + (float)docstyle.Layout.FooterLength;
|
|
break;
|
|
default:
|
|
Console.WriteLine("**** BOTTOM CONTINUE MESSAGE NOT CODED*****");
|
|
break;
|
|
}
|
|
MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Bottom.Margin ?? 0, msg_yLocation, MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
|
|
}
|
|
cb.PdfDocument.NewPage();
|
|
DebugText.WriteLine("Paginate2");
|
|
if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
|
|
PromsPrinter.DoFoldoutPage(cb, "Break within Step", MyPageHelper.TextLayer, MyPageHelper); // temporary foldout
|
|
|
|
// If there is a box, adjust the yTopMost to include it.
|
|
float yTopMost = YTopMost;
|
|
//if (YVeryTop < yTopMost) Console.WriteLine("{0},{1},{2}", MyItemInfo.DBSequence, yTopMost, YVeryTop);
|
|
yTopMost = Math.Min(yTopMost,YVeryTop);
|
|
yPageStart = yTopMargin + yTopMost;// -2 * SixLinesPerInch;
|
|
if (EmptyTopMostPart) yPageStart += SixLinesPerInch;
|
|
myMsg = docstyle.Continue.Top.Message;
|
|
if (myMsg != null && myMsg != "")
|
|
{
|
|
yPageStart -= 2 * SixLinesPerInch;// Allow two lines for top continue message
|
|
if (myMsg.IndexOf(@"%d") > -1)
|
|
myMsg = myMsg.Replace(@"%d", MyItemInfo.MyHLS.MyTab.CleanText.Trim(" .".ToCharArray()));
|
|
MyPageHelper.TopMessage = new vlnText(cb, this, myMsg, myMsg, docstyle.Layout.LeftMargin + XOffsetBox + docstyle.Continue.Top.Margin ?? 0, yTopMargin + 0.1F, MyItemInfo.ActiveFormat.PlantFormat.FormatData.Font);
|
|
}
|
|
MyPageHelper.YMultiplier = 1;
|
|
break;
|
|
case 3: // Break on High Level Step (SevenLinesPerInch)
|
|
if (!firstHighLevelStep)
|
|
{
|
|
OutputOtherPageSteps(cb, YTopMost, yPageStart, yTopMargin, yBottomMargin);
|
|
cb.PdfDocument.NewPage(); // HLS (7 lpi) breakif (MyItemInfo.IsSection)
|
|
DebugText.WriteLine("Paginate3");
|
|
if (MyItemInfo.IsSection)
|
|
{
|
|
SectionInfo si = MyItemInfo as SectionInfo;
|
|
MyPageHelper.PageBookmarks.Add(MyItemInfo, ((si.DisplayNumber ?? "") == "" ? "" : si.DisplayNumber + " - ") + si.DisplayText, null);
|
|
}
|
|
if ((MyItemInfo.ActiveSection.MyDocStyle.StructureStyle.Style ?? 0 & E_DocStructStyle.UseSectionFoldout) != 0)
|
|
PromsPrinter.DoFoldoutPage(cb, "HLS (7 lpi) break", MyPageHelper.TextLayer, MyPageHelper);
|
|
}
|
|
if (MyItemInfo.MyParent != null && MyItemInfo.MyParent.IsStepSection &&
|
|
MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
|
|
&& !MyItemInfo.MyDocStyle.CancelSectTitle
|
|
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout)
|
|
yPageStart = yPageStart; // if printing the section title, we already have the y location
|
|
else
|
|
yPageStart = yTopMargin + YTopMost;
|
|
MyPageHelper.YMultiplier = _SevenLinesPerInch / SixLinesPerInch;
|
|
break;
|
|
}
|
|
yPageStart = ChildrenAbove.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
yPageStart = ChildrenLeft.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
DebugText.WriteLine("Left:{0},{1},{2},{3},{4}", MyItemInfo.ItemID, yLocalypagestart, yPageStart, yTopMargin, yBottomMargin);
|
|
yPageStart = ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
DebugText.WriteLine("Self:{0},{1},{2},{3},{4}", MyItemInfo.ItemID, yLocalypagestart, yPageStart, yTopMargin, yBottomMargin);
|
|
|
|
yPageStart = ChildrenRight.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
DebugText.WriteLine("Right:{0},{1},{2},{3},{4}", MyItemInfo.ItemID, yLocalypagestart, yPageStart, yTopMargin, yBottomMargin);
|
|
|
|
yPageStart = ChildrenBelow.ToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
DebugText.WriteLine("Below:{0},{1},{2},{3},{4}", MyItemInfo.ItemID, yLocalypagestart, yPageStart, yTopMargin, yBottomMargin);
|
|
|
|
if (MyItemInfo.IsHigh && MyItemInfo.NextItem == null) // last hls, add the 'end' message, if there is one
|
|
{
|
|
DocStyle docstyle = MyItemInfo.MyDocStyle;
|
|
string myMsg = (docstyle.End == null) ? null : docstyle.End.Message;
|
|
if (myMsg != null)
|
|
{
|
|
// If the flag is 0 or 1, just put the end message out right below this vlnParagraph:
|
|
float msg_yLocation = CalculateYLocation(yPageStart - YBottomMost, yTopMargin);
|
|
|
|
// use the 'flag' to position the message.
|
|
if (docstyle.End.Flag > 2) // >2 position at an absolute location defined by docstyle.End.Flag.
|
|
{
|
|
msg_yLocation = yTopMargin - (float)(docstyle.End.Flag * SixLinesPerInch);
|
|
}
|
|
// center the message.
|
|
float wtpm = (float)docstyle.Layout.PageWidth - (float)docstyle.Layout.LeftMargin;
|
|
float centerpos = XOffsetBox + (float)docstyle.Layout.LeftMargin + (wtpm - (myMsg.Length * MyItemInfo.FormatStepData.Font.CharsToTwips)) / 2;
|
|
MyPageHelper.BottomMessage = new vlnText(cb, this, myMsg, myMsg, centerpos, msg_yLocation, docstyle.End.Font);
|
|
}
|
|
}
|
|
if (yLocalypagestart != yPageStart) DebugText.WriteLine("ToPdf-yPagestartDiff:{0},{1},{2}", MyItemInfo.ItemID, yLocalypagestart, yPageStart);
|
|
return yPageStart;
|
|
}
|
|
private vlnParagraph TopMostChild
|
|
{
|
|
get
|
|
{
|
|
if (ChildrenAbove.Count>0) return ChildrenAbove[0].TopMostChild;
|
|
return this;
|
|
}
|
|
}
|
|
private bool EmptyTopMostPart
|
|
{
|
|
get
|
|
{
|
|
if (TopMostChild.PartsAbove.Count == 0) return false;
|
|
foreach (vlnPrintObject po in TopMostChild.PartsAbove)
|
|
{
|
|
vlnHeader hd = po as vlnHeader;
|
|
if (hd == null) return false;
|
|
if (hd.Text != "") return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
private void OutputOtherPageSteps(PdfContentByte cb, float YTopMost, float yPageStart, float yTopMargin, float yBottomMargin)
|
|
{
|
|
// Find any items remaining in MyPageHelper.MyParagraphs that should be printed on this page.
|
|
vlnParagraphs process = new vlnParagraphs(null);
|
|
foreach (vlnParagraph vPara in MyPageHelper.MyParagraphs.Values)
|
|
{
|
|
//if (!vPara.Processed && ((vPara.YOffset + vPara.Height) < YTopMost))
|
|
if (!vPara.Processed && ((vPara.YOffset) < YTopMost))
|
|
process.Add(vPara);
|
|
}
|
|
foreach (vlnParagraph vPara in process)
|
|
{
|
|
vPara.ParagraphToPdf(cb, yPageStart, yTopMargin, yBottomMargin);
|
|
}
|
|
}
|
|
private void WalkStepLevel(float yTopMost)
|
|
{
|
|
foreach (vlnParagraph child in ChildrenAbove)
|
|
child.WalkStepLevel(yTopMost);
|
|
foreach (vlnParagraph child in ChildrenLeft)
|
|
child.WalkStepLevel(yTopMost);
|
|
ShowStepLevel(yTopMost);
|
|
foreach (vlnParagraph child in ChildrenRight)
|
|
child.WalkStepLevel(yTopMost);
|
|
foreach (vlnParagraph child in ChildrenBelow)
|
|
child.WalkStepLevel(yTopMost);
|
|
}
|
|
private void ShowStepLevel(float yTopMost)
|
|
{
|
|
ItemInfo item = MyItemInfo;
|
|
ItemInfo parent = item.ActiveParent as ItemInfo;
|
|
//if (para.MyItemInfo.ItemID == 205)
|
|
// Console.Write("");
|
|
DebugPagination.WriteLine("'StepLevel',{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", YVeryTop - yTopMost, YSize, YBottomMost - yTopMost, item.ItemID, item.DBSequence, item.StepLevel, item.MyContent.Type % 10000,
|
|
parent.MyContent.Type % 10000, item.HasCautionOrNote ? 1 : 0, parent.Cautions == null ? 0 : 1);
|
|
}
|
|
private float _YVeryTop = -1;
|
|
public float YVeryTop
|
|
{
|
|
get
|
|
{
|
|
if (_YVeryTop == -1)
|
|
{
|
|
_YVeryTop = YTop;
|
|
_YVeryTop = VeryTop(PartsAbove,_YVeryTop);
|
|
_YVeryTop = VeryTop(PartsContainer,_YVeryTop);
|
|
}
|
|
return _YVeryTop;
|
|
}
|
|
}
|
|
|
|
private float VeryTop(vlnPrintObjects parts, float yVeryTop)
|
|
{
|
|
if (parts != null)
|
|
foreach (vlnPrintObject part in parts)
|
|
if (part.YOffset < yVeryTop)
|
|
yVeryTop = part.YOffset;
|
|
return yVeryTop;
|
|
}
|
|
private int Paginate(float yLocation, float yTopMargin, float yBottomMargin)
|
|
{
|
|
float yPageSize = yTopMargin - yBottomMargin;
|
|
// TODO: This does not account for a long step as the last step that would exceed more than one page and
|
|
// that has an end message that needs to be accounted for in determining pagination. To do that the last
|
|
// child should be the only paragraph that accounts for the End message.
|
|
//
|
|
// If last step & there should be an end message, pagination tests need to account for the 3 lines the end
|
|
// message uses. The 3 is for a line above, the end message line & the line below (in case there is a border/box line).
|
|
|
|
// The 3 was changed to 2 for the end line & the line below. The blank line below the step gives the blank
|
|
// line above the end message, thus 2 not 3. This change was made on July 20, 2011 by RHM & KBR. The
|
|
// procedure in questions was VEWCNEMG\EMGAPP.PRC, ES-01, Step 8.
|
|
float yEndMsg = !MyItemInfo.IsSection && MyItemInfo.MyHLS.NextItem == null && (MyItemInfo.MyDocStyle.End.Message ?? "") != "" ? 2 * SixLinesPerInch : 0;
|
|
float yWithinMargins = CalculateYLocation(yLocation, yTopMargin) - yBottomMargin; // -SixLinesPerInch;
|
|
// if step is breaking over a number of pages, determine if the current step is the
|
|
// location of a pagebreak.
|
|
if (MyPageHelper.ParaBreaks.Count > 0)
|
|
{
|
|
if (this == MyPageHelper.ParaBreaks[0] || this.YTopMost > MyPageHelper.ParaBreaks[0].YTopMost)
|
|
{
|
|
MyPageHelper.ParaBreaks.RemoveAt(0);
|
|
//Console.WriteLine("'PageBreak',6,'Yes','Page Break within Step',{0},{1},{2},{3}, {4},'{5}'", MyItemInfo.ItemID, YSize, 0, 0, 0, MyItemInfo.ShortPath);
|
|
//Console.WriteLine("Prev = {0}", MyItemInfo.MyPrevious==null ? "''" : MyItemInfo.DBSequence);
|
|
ShowPageBreak(100,"Page Break within Step","Yes",YSize, yPageSize, yWithinMargins);
|
|
return 2; // break on this item within a step
|
|
}
|
|
return 0; // this is not an item with a break
|
|
}
|
|
float mySize = YSize * MyPageHelper.YMultiplier;
|
|
bool ManualPageBreak = false;
|
|
if (MyItemInfo.IsStepSection)
|
|
{
|
|
if (yLocation < yTopMargin) // continuous section
|
|
{
|
|
if (ChildrenBelow == null) return 0;
|
|
vlnParagraph firstChild = ChildrenBelow[0];
|
|
|
|
// This is a continuous section. There may be cases where the user put a manual page
|
|
// break on the first step (child) in the section. if so, break on the section. The
|
|
// flag SectionPageBreak is set to true to flag that a pagebreak should not be done
|
|
// on that first step.
|
|
ManualPageBreak = (firstChild.MyItemInfo.MyConfig as StepConfig).Step_ManualPagebreak;
|
|
if (ManualPageBreak)
|
|
{
|
|
SectionPageBreak = true;
|
|
return 1;
|
|
}
|
|
|
|
// can the title and the first step fit?
|
|
// add the first child's size + (the section title's size)
|
|
float ySizeIncludingFirst = firstChild.YSize + (firstChild.YTop - YTop);
|
|
//if (ySizeIncludingFirst > (yLocation - yBottomMargin - SixLinesPerInch)) return 1;
|
|
if (ySizeIncludingFirst > (yLocation - yBottomMargin))
|
|
{
|
|
ShowPageBreak(100, "Page Break Before Step Section", "Yes", YSize, yPageSize, yWithinMargins);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0; // Don't Paginate (page break) on a Step Section if it's first thing on page
|
|
}
|
|
if (!MyItemInfo.IsHigh) return 0; // Don't Paginate on a Substep level
|
|
ManualPageBreak = (MyItemInfo.MyConfig as StepConfig).Step_ManualPagebreak;
|
|
if (MyItemInfo.FirstSibling == MyItemInfo && ManualPageBreak)
|
|
{
|
|
// if parent/section used this pagebreak, skip it.
|
|
if (MyParent.SectionPageBreak)
|
|
{
|
|
ManualPageBreak = false;
|
|
MyParent.SectionPageBreak = false;
|
|
}
|
|
}
|
|
if (_Match16BitPagination) mySize = YSize;
|
|
float ySize7LPI = YSize; // +SixLinesPerInch;
|
|
if (_Match16BitPagination) ySize7LPI += SixLinesPerInch;
|
|
string firstStep = "No";
|
|
if (MyItemInfo.IsHigh && MyItemInfo.MyPrevious == null)
|
|
firstStep = "Yes";
|
|
if (!ManualPageBreak && mySize + yEndMsg <= yWithinMargins) // Don't Paginate if there is enough room, will fit on page
|
|
//if (!ManualPageBreak && mySize + yEndMsg <= yWithinMargins + SixLinesPerInch) // Don't Paginate if there is enough room, will fit on page
|
|
{
|
|
//Console.WriteLine("'PageBreak',1,'No','HLS will fit on page',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
ShowPageBreak(-1, "HLS will fit on page", firstStep, YSize, yPageSize, yWithinMargins);
|
|
return 0;
|
|
}
|
|
// !MyItemInfo.IsHigh - if (MyItemInfo.IsRNOPart && MyParent.XOffset < XOffset) return 0; // Don't paginate on an RNO to the right
|
|
|
|
// YSize includes a blank line after the step which we don't want to include in the page break test, thus the
|
|
// YSize - SixLinesPerInch:
|
|
if (YSize - SixLinesPerInch + yEndMsg <= yPageSize) // if the entire step can fit on one page, do a page break
|
|
{
|
|
// Don't want extra line before step
|
|
//Console.WriteLine("'PageBreak',2,'Yes','HLS will fit on 1 Page',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
ShowPageBreak(5, "HLS will fit on 1 Page at 6 LPI", "Yes", YSize, yPageSize, yWithinMargins);
|
|
return 1;
|
|
}
|
|
// TODO - yEndMsg - compressed size?
|
|
|
|
// ySize7LPI includes a blank line after the step which we don't want to include in the page break test.
|
|
else if (MyItemInfo.ActiveFormat.MyStepSectionLayoutData.CompressSteps && (ySize7LPI - SixLinesPerInch) < (yPageSize * SixLinesPerInch / _SevenLinesPerInch))
|
|
{
|
|
//Console.WriteLine("'PageBreak',3,'Yes','HLS will fit on 1 Page at 7 LPI',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
ShowPageBreak(7, "HLS will fit on 1 Page at 7 LPI", "Yes", YSize, yPageSize, yWithinMargins);
|
|
//Console.WriteLine("'7LPI',{0},{1}", MyItemInfo.DBSequence, YSize);
|
|
return 3; // High Level Step can fit at SevenLinesPerInch
|
|
}
|
|
else // The entire step cannot fit on a blank page.
|
|
{
|
|
// if there is more than half a page left, then start to print on the current page
|
|
float myFirstPieceSize = GetFirstPieceSize(); //Case 0
|
|
if (_Match16BitPagination) myFirstPieceSize += 2 * SixLinesPerInch;
|
|
// TODO: Put this line back to case 0, i.e. previous line. This fixes a 16-bit vs 32-bit pagination diff in EO30 Step 20.
|
|
//float myFirstPieceSize = GetFirstPieceSize() + 2 * SixLinesPerInch; //Case 10 - this is to match 16bit
|
|
if (!ManualPageBreak && MyItemInfo.ActiveFormat.MyStepSectionLayoutData.SpecialPageBreakFlag && yWithinMargins > yPageSize / 2 &&
|
|
myFirstPieceSize < yWithinMargins )
|
|
{
|
|
//Console.WriteLine("'PageBreak',4,'No','HLS will have to split anyway',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
ShowPageBreak(-4, "HLS will have to split anyway", firstStep , YSize, yPageSize, yWithinMargins);
|
|
//BuildPageBreakList(yWithinMargins+SixLinesPerInch,yPageSize-2*SixLinesPerInch); // Determine items where page break(s) occur
|
|
BuildPageBreakList(yWithinMargins + SixLinesPerInch, yPageSize); // Case 5 - Determine items where page break(s) occur
|
|
return 0; // Stay on this page
|
|
}
|
|
|
|
// Less than half a page left, start printing on a new page.
|
|
//Console.WriteLine("'PageBreak',5,'Yes','HLS will have to split',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
ShowPageBreak(3, "HLS will have to split", "Yes", YSize, yPageSize, yWithinMargins);
|
|
// Determine items where page break(s) occur
|
|
//BuildPageBreakList(yPageSize, yPageSize - 2 * SixLinesPerInch); // Case Base
|
|
BuildPageBreakList(yPageSize, yPageSize); // Case 1 :Works for ES05 Step 15 SubStep 7
|
|
return 1; // Paginate on High Level Steps
|
|
}
|
|
//if (yWithinMargins > yPageSize / 2)
|
|
//{
|
|
// Console.WriteLine("'PageBreak',4,'No','Not Half way down the page',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
// return 0; // More than half way down the page
|
|
//}
|
|
//if (ChildrenBelow.Count > 0 && ChildrenBelow[0].YSize < yWithinMargins)
|
|
// return 0;
|
|
//Console.WriteLine("'PageBreak',5,'Yes','At least half the page is filled',{0},{1},{2},{3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
|
|
//return 2;
|
|
throw new Exception("PageBreak Logic Missing, vlnParagraph.cs");
|
|
}
|
|
/// <summary>
|
|
/// This gets the height of the step with it's Caution's, Notes and potentially any First Substeps
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private float GetFirstPieceSize()
|
|
{
|
|
vlnParagraph paraLast = GetFirstPieceLastPart();
|
|
float retval = (paraLast.YBottom) - YTopMost;
|
|
//Console.WriteLine(MyItemInfo.DBSequence);
|
|
return retval;
|
|
}
|
|
public override float YBottom
|
|
{
|
|
get
|
|
{
|
|
float bottom = YOffset + Height;
|
|
if (PartsBelow != null)
|
|
{
|
|
foreach (vlnPrintObject part in PartsBelow)
|
|
{
|
|
float partBottom = part.YBottom;
|
|
bottom = Math.Max(partBottom, bottom);
|
|
}
|
|
}
|
|
return bottom;
|
|
}
|
|
}
|
|
public float YBottomText
|
|
{
|
|
get
|
|
{
|
|
return YOffset + Height;
|
|
}
|
|
}
|
|
private vlnParagraph GetFirstPieceLastPart()
|
|
{
|
|
vlnParagraph para = this;
|
|
if (!MyItemInfo.ActiveFormat.MyStepSectionLayoutData.PaginateOnFirstSubstep && ChildrenBelow != null && ChildrenBelow.Count > 0)
|
|
{
|
|
para = ChildrenBelow[0].GetFirstPieceLastPart();
|
|
}
|
|
if (ChildrenRight != null && ChildrenRight.Count > 0)
|
|
{
|
|
foreach(vlnParagraph paraRight in ChildrenRight)
|
|
{
|
|
vlnParagraph paraRightLast = paraRight.GetFirstPieceLastPart();
|
|
if (paraRightLast.YBottom > para.YBottom)
|
|
para = paraRightLast;
|
|
}
|
|
}
|
|
return para;
|
|
}
|
|
private void ShowPageBreak(int instance, string message, string breakOrNot, float YSize, float yPageSize, float yWithinMargins)
|
|
{
|
|
if (breakOrNot == "Yes")
|
|
{
|
|
// DebugPagination.WriteLine("{0}", MyItemInfo.DBSequence); //,instance);
|
|
DebugPagination.WriteLine("{0},'{1}',{2},'{3}','{4}',{5},{6},{7},{8},{9}",MyPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber, MyItemInfo.ShortPath, instance, message, breakOrNot,
|
|
MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize));
|
|
}
|
|
// Console.WriteLine("{0},{1}", MyItemInfo.DBSequence, IsFirstSubStep(MyItemInfo)); //,instance);
|
|
}
|
|
private void BuildPageBreakList(float ySpaceOnCurPage, float yPageSize)
|
|
{
|
|
ParagraphLocations myLocations = new ParagraphLocations();
|
|
BuildLocationList(YTopMost, myLocations);
|
|
StepLevelList myList = myLocations.BuildStepLevelList();
|
|
// Find Break Locations in the list based upon StepLevel and yLocation
|
|
float yTop = 0;
|
|
float yLowerLimit = (yPageSize - 2 * SixLinesPerInch) / 2;
|
|
float yStart = Math.Max(0,(yPageSize - 2 * SixLinesPerInch) - ySpaceOnCurPage);
|
|
//Console.WriteLine("'yStart',{0},{1}", MyItemInfo.DBSequence, yStart);
|
|
|
|
// The following three lines make page breaking match 16-bit:
|
|
if (_Match16BitPagination)
|
|
{
|
|
yLowerLimit = yStart - SixLinesPerInch + ySpaceOnCurPage / 2;
|
|
if ((yStart + MyItemInfo.MyDocStyle.Layout.TopMargin + 2 * SixLinesPerInch) > ((MyItemInfo.MyDocStyle.Layout.TopMargin + yPageSize - 2 * SixLinesPerInch) / 2))
|
|
yLowerLimit = yStart + 2 * SixLinesPerInch;
|
|
}
|
|
// Make sure that the FirstPiece (Caution Note HLS and First Substeps) fit
|
|
float myFirstPieceSize = GetFirstPieceSize(); //Case 0
|
|
if (myFirstPieceSize < ySpaceOnCurPage) yLowerLimit = Math.Max(myFirstPieceSize + yStart, yLowerLimit);
|
|
while ((YSize - yTop) >= ySpaceOnCurPage)
|
|
{
|
|
vlnParagraph paraBreak = FindPageBreak(yStart, ySpaceOnCurPage, yLowerLimit, myList);
|
|
if (paraBreak == null) break;
|
|
// yTopNew is y Location of this page break. YTopMost is top of HLS, including any Cautions/Notes/Boxes/etc
|
|
float yTopNew = paraBreak.YVeryTop - YTopMost;
|
|
RemoveProcessedParagraphs(myList, yTopNew-yTop);
|
|
yTop = yTopNew;
|
|
MyPageHelper.ParaBreaks.Add(paraBreak);
|
|
ySpaceOnCurPage = yPageSize - 2 * SixLinesPerInch; // Allow for continue message and blank line.
|
|
//ySpaceOnCurPage = yPageSize; // Allow for continue message and blank line.
|
|
//DocStyle docstyle = MyItemInfo.MyDocStyle;
|
|
//string myMsg = docstyle.Continue.Bottom.Message;
|
|
//if ((myMsg ?? "") != "") ySpaceOnCurPage -= 2 * SixLinesPerInch; // Allow for continue message and blank line.
|
|
yLowerLimit = ySpaceOnCurPage / 2;
|
|
if(_Match16BitPagination)yLowerLimit -= 1.5F * SixLinesPerInch; // 276 for HLP
|
|
yStart = 0;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Find items from previous page (yLocation less than yTop) and remove them from the list.
|
|
/// yTop is the new starting location on the next page for this step.
|
|
/// </summary>
|
|
/// <param name="myList"></param>
|
|
/// <param name="yTop"></param>
|
|
private void RemoveProcessedParagraphs(StepLevelList myList, float yTop)
|
|
{
|
|
// the two CleanUpLists are used to remove items from
|
|
// the original list because list items cannot be removed in a
|
|
// 'foreach'.
|
|
List<int> CleanupListStepLevel = new List<int>();
|
|
foreach(int stepLevel in myList.Keys)
|
|
{
|
|
List<float> CleanupListYLocation = new List<float>();
|
|
SortedList<float, float> AdjustYLocation = new SortedList<float,float>();
|
|
foreach (float yLocation in myList[stepLevel].Keys)
|
|
{
|
|
if (-yLocation <= yTop)
|
|
CleanupListYLocation.Add(yLocation);
|
|
else
|
|
AdjustYLocation.Add(-yLocation, yLocation); // order in ascending order
|
|
}
|
|
foreach (float yLocation in CleanupListYLocation)
|
|
myList[stepLevel].Remove(yLocation);
|
|
foreach (float yLocation in AdjustYLocation.Keys)
|
|
{
|
|
vlnParagraph para = myList[stepLevel][-yLocation];
|
|
myList[stepLevel].Remove(-yLocation);
|
|
// shift yLocation by yTop to work with items whose locations
|
|
// are defined from the top of the new page rather than
|
|
// from the beginning of the step.
|
|
// Note that yLocation is negative to have items in descending
|
|
// order so that adding yTop decrements their values.
|
|
myList[stepLevel].Add(yTop-yLocation, para);
|
|
}
|
|
if (myList[stepLevel].Count == 0)
|
|
CleanupListStepLevel.Add(stepLevel);
|
|
}
|
|
foreach (int stepLevel in CleanupListStepLevel)
|
|
myList.Remove(stepLevel);
|
|
}
|
|
/// <summary>
|
|
/// Finds the highest StepLevel (lowest StepLevel number, 0 = HLS, 1 = first substep) that
|
|
/// fills the page sufficiently (more than half-full)
|
|
/// </summary>
|
|
/// <param name="yWithinMargins"></param>
|
|
/// <param name="yTop"></param>
|
|
/// <param name="myList"></param>
|
|
/// <returns></returns>
|
|
private static vlnParagraph FindPageBreak(float yStart, float yUpperLimit, float yLowerLimit, StepLevelList myList)
|
|
{
|
|
foreach (int stepLevel in myList.Keys) // loop thru StepLevels, starting with lowest.
|
|
{
|
|
foreach (float yLocation in myList[stepLevel].Keys) // loop thru yLocation
|
|
{
|
|
// The top of this step will fit onto page (-yLocation < yWithinMargins)
|
|
if (-yLocation <= yUpperLimit) // Fix for OFN-RJ-23
|
|
//if (-yLocation < yUpperLimit) // Before
|
|
//if (-yLocation < yWithinMargins && myList[stepLevel][yLocation].MyItemInfo.MyPrevious != null)
|
|
{
|
|
//ItemInfo prev = myList[stepLevel][yLocation].MyItemInfo.MyPrevious;
|
|
//if (myList[stepLevel][yLocation].MyItemInfo.ItemID == 5609) Console.WriteLine("aer");
|
|
//if (myList[stepLevel][yLocation].MyItemInfo.ItemID == 4312) Console.WriteLine("rno");
|
|
// The top of this step is more than 1/2 way down the page
|
|
if ((-yLocation + yStart) >= yLowerLimit)
|
|
{
|
|
return myList[stepLevel][yLocation];
|
|
}
|
|
// if is a caution or note & parent is a substep and entire substep doesn't fit, break.
|
|
if ((myList[stepLevel][yLocation].MyItemInfo.IsNote || myList[stepLevel][yLocation].MyItemInfo.IsCaution) &&
|
|
!myList[stepLevel][yLocation].MyParent.MyItemInfo.IsHigh &&
|
|
myList[stepLevel][yLocation].MyParent.YSize > (yUpperLimit + yLocation))
|
|
{
|
|
return myList[stepLevel][yLocation];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
/// <summary>
|
|
/// Builds a list of paragraphs by StepLevel and yLocation in descending order.
|
|
/// </summary>
|
|
/// <param name="yTopMost"></param>
|
|
/// <param name="myList"></param>
|
|
private void BuildLocationList(float yTopMost, ParagraphLocations myLocations)
|
|
{
|
|
foreach (vlnParagraph child in ChildrenAbove)
|
|
child.BuildLocationList(yTopMost, myLocations);
|
|
foreach (vlnParagraph child in ChildrenLeft)
|
|
child.BuildLocationList(yTopMost, myLocations);
|
|
|
|
// Add a list entry consisting of StepLevel, yoffset from the beginning of this step, paragraph itself
|
|
myLocations.Add(this, yTopMost);
|
|
|
|
foreach (vlnParagraph child in ChildrenRight)
|
|
child.BuildLocationList(yTopMost, myLocations);
|
|
foreach (vlnParagraph child in ChildrenBelow)
|
|
child.BuildLocationList(yTopMost, myLocations);
|
|
}
|
|
private int COL_WID_ADJ = 6; // adjusts for incorrect use of WidSTable when breaking a line (it breaks 6 chars too short)
|
|
public vlnParagraph(vlnParagraph parent, PdfContentByte cb, ItemInfo itemInfo, float xoff, float yoff, int rnoLevel, int maxRNO, FormatInfo formatInfo)
|
|
{
|
|
//int[] problemIDs = { 889 };
|
|
//List<int> lProblemIDs = new List<int>(problemIDs);
|
|
//if (lProblemIDs.Contains(itemInfo.ItemID))
|
|
// Console.WriteLine("Found Item {0}", itemInfo.ItemID);
|
|
MyParent = parent;
|
|
// The following code determines the last paragraph for an RNO
|
|
// MyTopRNO finds the Top paragraph for an RNO
|
|
if (itemInfo.IsInRNO)
|
|
{
|
|
if (rnoLevel <= maxRNO && itemInfo.IsRNOPart) // Not top level RNO
|
|
MyTopRNO = this;
|
|
else
|
|
MyTopRNO = MyParent.MyTopRNO;
|
|
if(MyTopRNO != null) MyTopRNO.LastRNO = this;
|
|
}
|
|
MyContentByte = cb;
|
|
MyPageHelper.MyParagraphs.Add(itemInfo.ItemID, this);
|
|
MyItemInfo = itemInfo;
|
|
XOffset = xoff;
|
|
YTopMost = YOffset = yoff;
|
|
vlnTab mytab = null;
|
|
bool doSectTab = false;
|
|
if (itemInfo.MyTab != null && itemInfo.MyTab.Text != null && itemInfo.MyTab.Text != "")
|
|
{
|
|
float localXOffset = XOffset;
|
|
if (itemInfo.IsSection && !itemInfo.MyDocStyle.CancelSectTitle && itemInfo.MyTab.Text.ToUpper() != "FOLDOUT")
|
|
{
|
|
doSectTab = true;
|
|
if (itemInfo.IsStepSection && formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Just == "PSLeft")
|
|
localXOffset = (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos + (float)itemInfo.MyDocStyle.Layout.LeftMargin;
|
|
}
|
|
if (!itemInfo.IsSection || doSectTab)
|
|
{
|
|
mytab = new vlnTab(cb, this, itemInfo.MyTab.Text, itemInfo.MyTab.CleanText, localXOffset, yoff, itemInfo.MyTab.MyFont, doSectTab);
|
|
PartsLeft.Add(mytab);
|
|
if (mytab.MyMacro != null) PartsLeft.Add(mytab.MyMacro);
|
|
}
|
|
}
|
|
AdjustWidth(itemInfo, maxRNO, formatInfo, mytab);
|
|
AdjustXOffsetForTab(itemInfo, maxRNO, formatInfo, mytab);
|
|
if (itemInfo.Cautions != null)
|
|
yoff = ChildrenAbove.Add(cb, itemInfo.Cautions, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
|
|
if (itemInfo.Notes != null)
|
|
yoff = ChildrenAbove.Add(cb, itemInfo.Notes, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
|
|
YTop = yoff;
|
|
if (itemInfo.MyHeader != null && itemInfo.MyHeader.Text != null && !doSectTab)
|
|
yoff += SetHeader(this, cb, itemInfo, formatInfo);
|
|
YOffset = yoff;
|
|
if (itemInfo.IsRNOPart)
|
|
{
|
|
// there may be other places that double space, but this supports it for RNOs (the DoubleRNOspace flag)
|
|
if (rnoLevel > 1 && itemInfo.FormatStepData.DoubleSpace) yoff = YOffset = yoff + SixLinesPerInch;
|
|
}
|
|
AddMacros(itemInfo, mytab);
|
|
if (mytab != null)
|
|
{
|
|
mytab.YOffset = yoff;
|
|
if (mytab.MyMacro != null) mytab.MyMacro.YOffset = yoff;
|
|
}
|
|
if (itemInfo.MyContent.MyGrid != null)
|
|
{
|
|
VlnFlexGrid myFlexGrid = new VlnFlexGrid(1,1);
|
|
myFlexGrid.LoadGrid(itemInfo);
|
|
MyGrid = new vlnTable(myFlexGrid, cb);
|
|
Height = MyGrid.Height;
|
|
Width = MyGrid.Width;
|
|
yoff += (Height + (2 * SixLinesPerInch));
|
|
CalculateXOffset(itemInfo, maxRNO, formatInfo);
|
|
}
|
|
else if (itemInfo.IsFigure) // if a figure we've got to determine the size:
|
|
{
|
|
if (itemInfo.MyContent.Text != null)
|
|
{
|
|
ProcedureInfo proc = itemInfo.MyProcedure;
|
|
DocVersionInfo dvi = proc.ActiveParent as DocVersionInfo;
|
|
ROFstInfo rofst = dvi.DocVersionAssociations[0].MyROFst;
|
|
ROFSTLookup lookup = rofst.ROFSTLookup;
|
|
string linkInfoText = itemInfo.MyContent.Text.Replace(@"\v ", "");
|
|
Match m = Regex.Match(linkInfoText, @"(.*)[#]Link:([A-Za-z]*):(.*)");
|
|
string[] subs = m.Groups[3].Value.Split(" ".ToCharArray());
|
|
string roid = subs[1];
|
|
string val = lookup.GetRoValue(subs[1]);
|
|
if (val == null) val = lookup.GetRoValue(subs[1].Substring(0, 12));
|
|
if (val != null)
|
|
{
|
|
string[] vals = val.Split("\n".ToCharArray());
|
|
Width = Int32.Parse(vals[3], System.Globalization.NumberStyles.AllowHexSpecifier) * MyItemInfo.FormatStepData.Font.CharsToTwips;
|
|
int lines = Int32.Parse(vals[2], System.Globalization.NumberStyles.AllowHexSpecifier);
|
|
Height = lines * SixLinesPerInch;
|
|
yoff += (Height + (2 * SixLinesPerInch));
|
|
string erMsg = null;
|
|
try
|
|
{
|
|
ROImageInfo roImage = ROImageInfo.GetByROFstID_FileName(rofst.ROFstID, vals[0]);
|
|
if (roImage != null)
|
|
ImageText = val;
|
|
else
|
|
erMsg = string.Format("Image {0} does not exist.", vals[0]);
|
|
}
|
|
|
|
catch (Exception ex)
|
|
{
|
|
erMsg = string.Format("Image {0} does not exist, error = {1}.", vals[0], ex.Message);
|
|
}
|
|
if (erMsg != null) Rtf = GetRtf(erMsg, itemInfo.ActiveFormat.PlantFormat.FormatData.Font);
|
|
}
|
|
CalculateXOffset(itemInfo, maxRNO, formatInfo);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Rtf = GetRtf(itemInfo);
|
|
if (itemInfo.IsTablePart) // Not for grid, this is for old-style tables.
|
|
{
|
|
Width = GetTableWidth(cb, IParagraph, MyItemInfo.MyDocStyle.Layout.PageWidth);
|
|
CalculateXOffset(itemInfo, maxRNO, formatInfo);
|
|
}
|
|
// Determine if section title is output
|
|
if (!itemInfo.IsStepSection
|
|
|| (formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ShowSectionTitles
|
|
&& !MyItemInfo.MyDocStyle.CancelSectTitle
|
|
&& !MyItemInfo.MyDocStyle.SpecialStepsFoldout))
|
|
{
|
|
yoff += Height;
|
|
yoff += AdjustForBlankLines();
|
|
}
|
|
}
|
|
float yOffRight = yoff;
|
|
float RnoOffset = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
|
|
if (rnoLevel < maxRNO && itemInfo.RNOs != null) yOffRight = ChildrenRight.Add(cb, itemInfo.RNOs, XOffset + RnoOffset, YTop, YTop, rnoLevel + 1, maxRNO, formatInfo);
|
|
// Need code to determine if the table will overlap the Right Column if it does then
|
|
// use YOffRight rather than yoff
|
|
if (itemInfo.Tables != null)
|
|
{
|
|
bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
|
|
if(!aerTableOrFigure && itemInfo.RNOLevel == 0) // Centered Table
|
|
yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yOffRight, yOffRight, rnoLevel, maxRNO, formatInfo);
|
|
else // AER or RNO Table
|
|
yoff = ChildrenBelow.Add(cb, itemInfo.Tables, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
|
|
}
|
|
if (itemInfo.Steps != null) yoff = ChildrenBelow.Add(cb, itemInfo.Steps, XOffset, yoff, yOffRight, rnoLevel, maxRNO, formatInfo);
|
|
if (itemInfo.Sections != null) yoff = ChildrenBelow.Add(cb, itemInfo.Sections, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
|
|
if (itemInfo.Procedures != null) yoff = ChildrenBelow.Add(cb, itemInfo.Procedures, xoff, yoff, yoff, rnoLevel, maxRNO, formatInfo);
|
|
if (rnoLevel >= maxRNO && itemInfo.RNOs != null) yoff = ChildrenBelow.Add(cb, itemInfo.RNOs, XOffset, yoff, yoff, rnoLevel + 1, maxRNO, formatInfo);
|
|
yoff = Math.Max(yoff, yOffRight);
|
|
// TODO - use RNOSepAfterAER flag too:
|
|
string tmpRnoSepStr = formatInfo.MyStepSectionPrintData.RNOSepString;
|
|
if (rnoLevel < maxRNO && itemInfo.RNOs != null && tmpRnoSepStr != null)
|
|
{
|
|
vlnParagraph rno = ChildrenRight[0];
|
|
vlnParagraph bottomChild = BottomChild;
|
|
float xsep = MyHighLevelParagraph.XOffset + RnoOffset;
|
|
vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff, formatInfo, bottomChild==null?true:bottomChild.MyItemInfo.HasChangeBar);
|
|
// TODO: May need to handle more than one RNO column for RNO Separator
|
|
if (rno.LastRNO.MyItemInfo.HasChangeBar == false && bottomChild != null && bottomChild.MyItemInfo.HasChangeBar)
|
|
bottomChild.PartsBelow.Add(myRnoSep);
|
|
else
|
|
rno.LastRNO.PartsBelow.Add(myRnoSep);
|
|
yoff += myRnoSep.Height + SixLinesPerInch;
|
|
}
|
|
YBottomMost = yoff;
|
|
}
|
|
internal vlnParagraph BottomChild
|
|
{
|
|
get
|
|
{
|
|
float bottomChildYBottomText = YBottomText;
|
|
vlnParagraph bottomChild = this;
|
|
foreach (vlnParagraph child in ChildrenRight)
|
|
{
|
|
vlnParagraph grandChild = child.BottomChild;
|
|
if (grandChild != null && grandChild.YBottomText > bottomChildYBottomText) bottomChild = grandChild;
|
|
if (grandChild != null && grandChild.YBottomText == bottomChildYBottomText && grandChild.MyItemInfo.HasChangeBar) bottomChild = grandChild;
|
|
bottomChildYBottomText = bottomChild.YBottomText;
|
|
}
|
|
foreach (vlnParagraph child in ChildrenBelow)
|
|
{
|
|
vlnParagraph grandChild = child.BottomChild;
|
|
if (grandChild != null && grandChild.YBottomText > bottomChildYBottomText) bottomChild = grandChild;
|
|
if (grandChild != null && grandChild.YBottomText == bottomChildYBottomText && grandChild.MyItemInfo.HasChangeBar) bottomChild = grandChild;
|
|
bottomChildYBottomText = bottomChild.YBottomText;
|
|
}
|
|
return bottomChild;
|
|
}
|
|
}
|
|
private void CalculateXOffset(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo)
|
|
{
|
|
bool aerTableOrFigure = itemInfo.FormatStepData.Type.Contains("AER");
|
|
vlnParagraph hls1 = MyParent;
|
|
while (hls1.MyParent != null && !hls1.MyItemInfo.IsHigh) hls1 = hls1.MyParent;
|
|
// Determine center of hls
|
|
XOffset = hls1.XOffset + hls1.Width / 2;
|
|
// Determine left edge of the table by subtracting 1/2 of its width.
|
|
XOffset -= Width / 2;
|
|
float colR = float.Parse(formatInfo.MyStepSectionLayoutData.ColRTable.Split(",".ToCharArray())[itemInfo.ColumnMode]);
|
|
float xLowerLimit = hls1.XOffset; // 6; // Adjusted for HLP VE-PROMS
|
|
float xUpperLimit = hls1.XOffset + hls1.Width + colR * itemInfo.ColumnMode; // 20110429 RHM Adjusted for RNO Tables Removed +18; // Adjusted for HLP VE-PROMS
|
|
if (!aerTableOrFigure && itemInfo.RNOLevel == 0) // Centered Table or Figure
|
|
{
|
|
// Add in 1/2 of the width of all RNO columns
|
|
XOffset += (colR * itemInfo.ColumnMode) / 2;
|
|
XOffset -= 12;
|
|
}
|
|
else // AER or RNO
|
|
XOffset = MyParent.XOffset + MyParent.Width / 2 - Width / 2;
|
|
|
|
// if the XOffset < High Level Step Text's XOffset, then align with the High Level Step Text
|
|
if (XOffset < xLowerLimit)
|
|
XOffset = xLowerLimit;
|
|
|
|
// if the right margin exceeds the right edge of the rightmost RNO, then adjust right edge to match.
|
|
if (XOffset + Width > xUpperLimit)
|
|
XOffset = xUpperLimit - Width;
|
|
|
|
// because of the above, if it pushes beyond the left margin, use the left margin.
|
|
if (XOffset < (float)itemInfo.MyDocStyle.Layout.LeftMargin)
|
|
XOffset = XOffsetBox = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
|
|
}
|
|
private float AdjustForBlankLines()
|
|
{
|
|
if (MyItemInfo.MyDocStyle.SpecialStepsFoldout) return 0;
|
|
int everyNLines = MyItemInfo.FormatStepData == null ? 1 : MyItemInfo.FormatStepData.StepLayoutData.EveryNLines ?? 1;
|
|
if (MyItemInfo.Ordinal % everyNLines == 0 || MyItemInfo.NextItem == null) return SixLinesPerInch;
|
|
return 0;
|
|
}
|
|
private void AddMacros(ItemInfo itemInfo, vlnTab mytab)
|
|
{
|
|
float y = YOffset;
|
|
float x = mytab == null ? XOffset : mytab.XOffset + mytab.TabOffset;
|
|
List<Macro> myMacros = itemInfo.MyMacros;
|
|
if (myMacros != null)
|
|
{
|
|
foreach (Macro myMacro in myMacros)
|
|
{
|
|
PartsLeft.Add(new vlnMacro(x, y, myMacro.MacroDef));
|
|
}
|
|
}
|
|
}
|
|
// HLP Change bar flags in format file:
|
|
// Locations: With Text, Outside Box, AER on Left RNO on Right, To The Left of Text
|
|
// Text: Date & Change ID, Revision Number, Change ID, None, Custom (use input data)
|
|
// Flag AERChgBarMsgRNOChgBarNoMsg and AERMsgRNONoMsg are NOT Used in 16-bit.
|
|
private string cbMess = null;
|
|
private vlnChangeBar DoChangeBar(PdfContentByte cb, ItemInfo itemInfo, VlnSvgPageHelper myPageHelper, float xoff, float yoff, int maxRNO, FormatInfo formatInfo) //, vlnChangeBar myCB)
|
|
{
|
|
// find column for the change bar based on format flags - this is code from 16-bit
|
|
// if AbsoluteFixedChangeColumn
|
|
// if FixedAERChangeColumn
|
|
// if col>ColsS+ColR+COL_WID+ADJ
|
|
// FixedChangeColumn
|
|
// else
|
|
// AERLeftChangeBarLocation()
|
|
// else
|
|
// FixedChangeColumn
|
|
// else
|
|
// ChangeBarLocation()
|
|
ChangeBarData cbd = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData;
|
|
float cols = formatInfo.MyStepSectionLayoutData.ColS ?? 0;
|
|
float colr = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
|
|
float col = (cbd.AbsoluteFixedChangeColumn) ?
|
|
((cbd.FixedAERChangeColumn ?? 0) > 0) ?
|
|
(xoff > (cols + colr + COL_WID_ADJ)) ?
|
|
cbd.FixedChangeColumn ?? 0 : AERLeftChangeBarLocation(formatInfo) :
|
|
cbd.FixedChangeColumn ?? 0 : ChangeBarLocation(xoff, this, formatInfo, maxRNO);
|
|
|
|
if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.ChgID)
|
|
cbMess = itemInfo.MyContent.UserID;
|
|
else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.DateChgID)
|
|
{
|
|
string fmtDate = itemInfo.MyContent.DTS.ToShortDateString();
|
|
if (fmtDate.Length != 10) // need to add zeros
|
|
{
|
|
if (fmtDate.IndexOf("/") == 1)
|
|
fmtDate = "0" + fmtDate;
|
|
if (fmtDate.IndexOf("/", 3) == 1)
|
|
fmtDate = fmtDate.Substring(0, 3) + "0" + fmtDate.Substring(3, fmtDate.Length - 3);
|
|
}
|
|
cbMess = itemInfo.MyContent.UserID + @"\n" + fmtDate;
|
|
}
|
|
else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.RevNum)
|
|
cbMess = myPageHelper.Rev;
|
|
else if (myPageHelper.ChangeBarDefinition.MyChangeBarText == PrintChangeBarText.UserDef)
|
|
cbMess = myPageHelper.ChangeBarDefinition.MyChangeBarMessage;
|
|
|
|
int msgAlign = Element.ALIGN_LEFT;
|
|
if (myPageHelper.ChangeBarDefinition.MyChangeBarLoc == PrintChangeBarLoc.LeftOfText ||
|
|
(myPageHelper.ChangeBarDefinition.MyChangeBarLoc == PrintChangeBarLoc.AERleftRNOright &&
|
|
!itemInfo.IsInRNO)) msgAlign = Element.ALIGN_RIGHT;
|
|
return new vlnChangeBar(cb, this, (float)itemInfo.MyDocStyle.Layout.LeftMargin + (col * itemInfo.FormatStepData.Font.CharsToTwips), yoff, msgAlign);
|
|
}
|
|
|
|
private int ChangeBarLocation(float c, vlnParagraph paragraph, FormatInfo formatInfo, int maxRNO)
|
|
{
|
|
int fixedChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedChangeColumn ?? 0;
|
|
float cols = formatInfo.MyStepSectionLayoutData.ColS ?? 0;
|
|
int colr = ToInt(formatInfo.MyStepSectionLayoutData.ColRTable, maxRNO);
|
|
// if this is a caution or note, put the change bar to the right of the text:
|
|
if (paragraph.MyItemInfo.IsCaution || paragraph.MyItemInfo.IsNote && fixedChgCol < -10) return -fixedChgCol;
|
|
if (fixedChgCol < -10 || fixedChgCol >= 0)
|
|
return ((fixedChgCol > 0) ? fixedChgCol :
|
|
(fixedChgCol == 0) ? (int)c + 1 :
|
|
(c > cols + colr + COL_WID_ADJ) ? -fixedChgCol :
|
|
AERLeftChangeBarLocation(formatInfo));
|
|
else
|
|
return (int)(fixedChgCol + (((c < cols + Width + colr) || TableTest()
|
|
|| MyItemInfo.IsCaution || MyItemInfo.IsNote) ? 0 : cols + colr)); // || (GetColumnMode() == 0)) ? 0 : cols + colr));
|
|
/* Change bars to left of text -- ColS+WidS+ColR is the end of RNO col*/
|
|
}
|
|
/*
|
|
** Centered tables whose width exceeds the end of the RNO column should
|
|
** still have their change bars printed on the left. This procedure checks
|
|
** to make sure the step is a table and that it is not an RNO.
|
|
*/
|
|
private bool TableTest()
|
|
{
|
|
return false;
|
|
//return ((s->Type == TABLE || s->Type == BORDERLESSTABLE) &&
|
|
//!(strchr((char *)&s->dbseq[2],RNO_MARKER)));
|
|
}
|
|
private float GetBottomYoff(float bottomY)
|
|
{
|
|
foreach (vlnParagraph child in ChildrenBelow)
|
|
{
|
|
if (child.YOffset > bottomY) bottomY = child.YOffset;
|
|
bottomY = child.GetBottomYoff(bottomY);
|
|
}
|
|
return bottomY;
|
|
}
|
|
private int AERLeftChangeBarLocation(FormatInfo formatInfo)
|
|
{
|
|
// use -5 default unless it is format specified
|
|
int fixedAERChgCol = formatInfo.PlantFormat.FormatData.ProcData.ChangeBarData.FixedAERChangeColumn ?? 0;
|
|
return (fixedAERChgCol != 0) ?
|
|
(fixedAERChgCol > 100) ?
|
|
(fixedAERChgCol % 100) : -fixedAERChgCol : -5;
|
|
}
|
|
private StringBuilder _RtfSB = null;
|
|
|
|
// return rtf and use for tab and other text
|
|
public string GetRtf(ItemInfo itemInfo)
|
|
{
|
|
_RtfSB = new StringBuilder();
|
|
DisplayText vlntxt = new DisplayText(itemInfo, E_EditPrintMode.Print, E_ViewMode.View, true, E_FieldToEdit.StepText, false);
|
|
System.Drawing.Font myFont = vlntxt.TextFont.WindowsFont;
|
|
if (!itemInfo.IsTable && StepRTB.MyFontFamily != null)
|
|
myFont = new System.Drawing.Font(StepRTB.MyFontFamily, myFont.Size, myFont.Style);
|
|
if (itemInfo.IsHigh && itemInfo.MyDocStyle.UndSpecialStepsFoldout) myFont = new System.Drawing.Font(myFont.FontFamily, myFont.Size, myFont.Style | FontStyle.Underline);
|
|
_RtfSB.Append(AddFontTable(myFont));
|
|
_RtfSB.Append(vlntxt.StartText);
|
|
_RtfSB.Append("}");
|
|
return _RtfSB.ToString();
|
|
}
|
|
private float _XOffsetBox = 0;
|
|
public float XOffsetBox
|
|
{
|
|
get { return _XOffsetBox; }
|
|
set { _XOffsetBox = value; }
|
|
}
|
|
private float SetHeader(vlnParagraph para, PdfContentByte cb, ItemInfo itemInfo, FormatInfo formatInfo)
|
|
{
|
|
float xoff = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
|
|
// The '6' below is really converting from characters to Twips. But instead of considering the CPI, 16bit assumed
|
|
// it was 12 to center the header. That's where the 6 comes from.
|
|
float hdrWidth = (itemInfo.MyHeader.CleanText == null) ? 0 : itemInfo.MyHeader.CleanText.Length * 6;
|
|
int typ = ((int)itemInfo.MyContent.Type) % 10000;
|
|
int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
|
|
|
|
if (itemInfo.MyHeader.Justify == System.Drawing.ContentAlignment.MiddleCenter)
|
|
{
|
|
if (bxIndx != null)
|
|
{
|
|
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
|
|
if (bx.TabPos > 0)
|
|
xoff += (float)bx.TabPos; // xoff starts as left margin
|
|
else
|
|
xoff += (float)((bx.TxtStart + XOffsetBox + (bx.TxtWidth / 2)) - (hdrWidth / 2)); // xoff starts as left margin
|
|
}
|
|
else if (formatInfo.MyStepSectionLayoutData.Separator.Location > 0)
|
|
xoff = XOffset + AdjustToCharPosition((float)((para.Width - hdrWidth) / formatInfo.MyStepSectionLayoutData.Separator.Location), itemInfo.MyHeader.MyFont.CPI);
|
|
else
|
|
xoff = XOffset + (para.Width / 2) + (hdrWidth / 2); // XOffset has left margin included
|
|
}
|
|
else
|
|
xoff = XOffset; // XOffset has left margin included
|
|
vlnHeader myHeader = new vlnHeader(this, cb, itemInfo.MyHeader.Text, itemInfo.MyHeader.CleanText.TrimStart(" ".ToCharArray()), xoff, YOffset, itemInfo.MyHeader.MyFont);
|
|
PartsAbove.Add(myHeader);
|
|
return myHeader.Height + (!MyItemInfo.MyDocStyle.SpecialStepsFoldout ? SixLinesPerInch : 0);
|
|
}
|
|
private float AdjustToCharPosition(float position, float? CPI)
|
|
{
|
|
int iPosition = (int)position;
|
|
int charsToTwips = (int)(72 / (CPI ?? 12));
|
|
iPosition = (iPosition / charsToTwips) * charsToTwips;
|
|
position = (position / 7.2F) * 7.2F;
|
|
return (float)iPosition;
|
|
}
|
|
private bool _SectionPageBreak = false;
|
|
public bool SectionPageBreak
|
|
{
|
|
get { return _SectionPageBreak; }
|
|
set { _SectionPageBreak = value; }
|
|
}
|
|
private bool _Processed = false;
|
|
public bool Processed
|
|
{
|
|
get { return _Processed; }
|
|
set { _Processed = value; }
|
|
}
|
|
private vlnParagraph _LastRNO;
|
|
public vlnParagraph LastRNO
|
|
{
|
|
get { return _LastRNO; }
|
|
set { _LastRNO = value; }
|
|
}
|
|
private vlnParagraph _MyTopRNO;
|
|
public vlnParagraph MyTopRNO
|
|
{
|
|
get { return _MyTopRNO; }
|
|
set { _MyTopRNO = value; }
|
|
}
|
|
private static string _Prefix = "";
|
|
public static string Prefix
|
|
{
|
|
get { return vlnParagraph._Prefix; }
|
|
set { vlnParagraph._Prefix = value; }
|
|
}
|
|
protected float _YBottomMost; // Bottom of the paragraph including the children
|
|
public float YBottomMost
|
|
{
|
|
get { return _YBottomMost; }
|
|
set { _YBottomMost = value; }
|
|
}
|
|
protected float _YTopMost; // Top of the paragraph including the children
|
|
public float YTopMost
|
|
{
|
|
get { return _YTopMost; }
|
|
set { _YTopMost = value; }
|
|
}
|
|
protected float _YTop; // Top of the paragraph including parts
|
|
public float YTop
|
|
{
|
|
get { return _YTop; }
|
|
set
|
|
{
|
|
vlnParagraph vp = this as vlnParagraph;
|
|
_YTop = value;
|
|
|
|
}
|
|
}
|
|
public float YSize // How big this paragraph is with all of its children
|
|
{
|
|
get { return _YBottomMost - _YTopMost; }
|
|
}
|
|
private ItemInfo _MyItemInfo;
|
|
public ItemInfo MyItemInfo
|
|
{
|
|
get { return _MyItemInfo; }
|
|
set { _MyItemInfo = value; }
|
|
}
|
|
private vlnParagraph _MyHighLevelParagraph;
|
|
|
|
public vlnParagraph MyHighLevelParagraph
|
|
{
|
|
get
|
|
{
|
|
if (_MyHighLevelParagraph == null)
|
|
{
|
|
_MyHighLevelParagraph = GetHighLevelParagraph();
|
|
}
|
|
return _MyHighLevelParagraph;
|
|
}
|
|
}
|
|
private vlnParagraph GetHighLevelParagraph()
|
|
{
|
|
if (MyItemInfo.IsHigh) return this;
|
|
return MyParent.GetHighLevelParagraph();
|
|
}
|
|
// Tab, Separator, ChangeBar, Box, Circle, Checkoff
|
|
private vlnPrintObjects _PartsAbove;
|
|
public vlnPrintObjects PartsAbove
|
|
{
|
|
get
|
|
{
|
|
if (_PartsAbove == null) _PartsAbove = new vlnPrintObjects();
|
|
return _PartsAbove;
|
|
}
|
|
}
|
|
private vlnPrintObjects _PartsBelow;
|
|
public vlnPrintObjects PartsBelow
|
|
{
|
|
get
|
|
{
|
|
if (_PartsBelow == null) _PartsBelow = new vlnPrintObjects();
|
|
return _PartsBelow;
|
|
}
|
|
}
|
|
private vlnPrintObjects _PartsRight;
|
|
public vlnPrintObjects PartsRight
|
|
{
|
|
get
|
|
{
|
|
if (_PartsRight == null) _PartsRight = new vlnPrintObjects();
|
|
return _PartsRight;
|
|
}
|
|
}
|
|
private vlnPrintObjects _PartsLeft;
|
|
public vlnPrintObjects PartsLeft
|
|
{
|
|
get
|
|
{
|
|
if (_PartsLeft == null) _PartsLeft = new vlnPrintObjects();
|
|
return _PartsLeft;
|
|
}
|
|
}
|
|
private vlnPrintObjects _PartsContainer;
|
|
public vlnPrintObjects PartsContainer
|
|
{
|
|
get
|
|
{
|
|
if (_PartsContainer == null) _PartsContainer = new vlnPrintObjects();
|
|
return _PartsContainer;
|
|
}
|
|
}
|
|
private vlnParagraphs _ChildrenAbove;
|
|
public vlnParagraphs ChildrenAbove
|
|
{
|
|
get
|
|
{
|
|
if (_ChildrenAbove == null) _ChildrenAbove = new vlnParagraphs(this);
|
|
return _ChildrenAbove;
|
|
}
|
|
}
|
|
private vlnParagraphs _ChildrenBelow;
|
|
public vlnParagraphs ChildrenBelow
|
|
{
|
|
get
|
|
{
|
|
if (_ChildrenBelow == null) _ChildrenBelow = new vlnParagraphs(this);
|
|
return _ChildrenBelow;
|
|
}
|
|
}
|
|
private vlnParagraphs _ChildrenRight;
|
|
public vlnParagraphs ChildrenRight
|
|
{
|
|
get
|
|
{
|
|
if (_ChildrenRight == null) _ChildrenRight = new vlnParagraphs(this);
|
|
return _ChildrenRight;
|
|
}
|
|
}
|
|
private vlnParagraphs _ChildrenLeft;
|
|
public vlnParagraphs ChildrenLeft
|
|
{
|
|
get
|
|
{
|
|
if (_ChildrenLeft == null) _ChildrenLeft = new vlnParagraphs(this);
|
|
return _ChildrenLeft;
|
|
}
|
|
}
|
|
public void AdjustXOffsetForTab(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab)
|
|
{
|
|
float tabWidth = (myTab == null) ? 0 : myTab.Width;
|
|
if (itemInfo.IsStepSection)
|
|
{
|
|
if (formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Just == "PSLeft")
|
|
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.SectionHeader.Pos;
|
|
return;
|
|
}
|
|
int typ = ((int)itemInfo.MyContent.Type) % 10000;
|
|
int? bxIndx = formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex;
|
|
if (bxIndx != null)
|
|
{
|
|
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
|
|
XOffset = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)bx.TxtStart + tabWidth + XOffsetBox;
|
|
if (myTab != null) myTab.XOffset = XOffset - tabWidth;
|
|
}
|
|
else if (itemInfo.IsHigh)
|
|
{
|
|
float x = (float)itemInfo.MyDocStyle.Layout.LeftMargin + (float)formatInfo.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData.ColS;
|
|
float xoff = x - XOffset;
|
|
XOffset += xoff;
|
|
if (myTab != null) myTab.XOffset += xoff;
|
|
}
|
|
else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh)
|
|
{
|
|
// don't adjust for rno
|
|
}
|
|
else if (MyParent != null)
|
|
{
|
|
XOffset += tabWidth - (myTab == null ? 0 : myTab.TabAlign);
|
|
if (myTab != null) myTab.XOffset += tabWidth - myTab.TabAlign;
|
|
}
|
|
}
|
|
public void AdjustWidth(ItemInfo itemInfo, int maxRNO, FormatInfo formatInfo, vlnTab myTab)
|
|
{
|
|
float tabWidth = (myTab == null) ? 0 : myTab.Width;
|
|
int typ = ((int)itemInfo.MyContent.Type) % 10000;
|
|
int? bxIndx = itemInfo.IsStep ? formatInfo.PlantFormat.FormatData.StepDataList[typ].StepLayoutData.STBoxindex : null;
|
|
if (bxIndx != null)
|
|
{
|
|
Box bx = formatInfo.PlantFormat.FormatData.BoxList[(int)bxIndx];
|
|
Width = _WidthAdjustBox + (float)bx.TxtWidth - tabWidth; // add 1 to get it to wrap like 16Bit
|
|
}
|
|
else if (itemInfo.IsHigh)
|
|
{
|
|
Width = _WidthAdjust + ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
|
|
}
|
|
else if (itemInfo.IsCaution || itemInfo.IsNote)
|
|
{
|
|
float mycolT = (float)formatInfo.MyStepSectionLayoutData.ColT;
|
|
Width = (float)formatInfo.MyStepSectionLayoutData.WidT - 6 - mycolT;
|
|
XOffset += mycolT; // adjust caution/note text position
|
|
if (PartsLeft != null)// adjust tab position
|
|
foreach(vlnPrintObject vpo in PartsLeft)
|
|
vpo.XOffset += mycolT;
|
|
}
|
|
else if (itemInfo.IsSection)
|
|
{
|
|
Width = _WidthAdjust + ToInt(formatInfo.MyStepSectionLayoutData.WidSTablePrint, maxRNO);
|
|
}
|
|
else if (MyParent == null)
|
|
{
|
|
// 72 points / inch - 7 inches (about width of page)
|
|
Width = 72 * 7;
|
|
}
|
|
else if (itemInfo.IsRNOPart && !((ItemInfo)itemInfo.ActiveParent).IsHigh)
|
|
{
|
|
Width = MyParent.Width;
|
|
}
|
|
else if (itemInfo.IsTablePart)
|
|
{
|
|
Width = 72 * 7; // TODO: Need to determine the Width of the Table based upon the contents
|
|
}
|
|
else
|
|
{
|
|
Width = MyParent.Width - tabWidth + (myTab == null ? 0 : myTab.TabAlign);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// First order by stepLevel, then within a stepLevel, order by descending yLocation on page.
|
|
/// Want to find maximum y value that fits on page, i.e. put the most on page that can
|
|
/// fit which is defined by the largest yLocation
|
|
/// </summary>
|
|
public class StepLevelList : SortedDictionary<int, SortedDictionary<float, vlnParagraph>>
|
|
{
|
|
public StepLevelList() : base()
|
|
{
|
|
}
|
|
public void Add(int stepLevel, float yLocation, vlnParagraph para)
|
|
{
|
|
if (stepLevel == 0) return;
|
|
if (!this.ContainsKey(stepLevel))
|
|
this.Add(stepLevel, new SortedDictionary<float, vlnParagraph>());
|
|
// using a negative for yLocation so that its in descending order:
|
|
if (!this[stepLevel].ContainsKey(-yLocation))
|
|
this[stepLevel].Add(-yLocation, para);
|
|
}
|
|
}
|
|
public class ParagraphLocations : List<ParagraphLocation>
|
|
{
|
|
public ParagraphLocations()
|
|
: base()
|
|
{
|
|
}
|
|
public void Add(vlnParagraph myParagraph, float yTopMost)
|
|
{
|
|
ParagraphLocation foundOverlap = FindOverlap(myParagraph);
|
|
if (foundOverlap == null)
|
|
{
|
|
this.Add(new ParagraphLocation(yTopMost,myParagraph));
|
|
return;
|
|
}
|
|
ParagraphLocation doubleOverlap = FindOverlap(foundOverlap);
|
|
while (doubleOverlap != null)
|
|
{
|
|
doubleOverlap.Merge(foundOverlap);
|
|
this.Remove(foundOverlap);
|
|
foundOverlap = doubleOverlap;
|
|
doubleOverlap = FindOverlap(foundOverlap);
|
|
}
|
|
}
|
|
|
|
private ParagraphLocation FindOverlap(vlnParagraph myParagraph)
|
|
{
|
|
foreach (ParagraphLocation paraLoc in this)
|
|
if (paraLoc.Overlap(myParagraph))
|
|
return paraLoc;
|
|
return null;
|
|
}
|
|
private ParagraphLocation FindOverlap(ParagraphLocation myParaLoc)
|
|
{
|
|
foreach (ParagraphLocation paraLoc in this)
|
|
if (paraLoc != myParaLoc && paraLoc.Overlap(myParaLoc))
|
|
return paraLoc;
|
|
return null;
|
|
}
|
|
internal StepLevelList BuildStepLevelList()
|
|
{
|
|
StepLevelList myList = new StepLevelList();
|
|
foreach (ParagraphLocation paraLoc in this)
|
|
myList.Add(paraLoc.StepLevel, paraLoc.YTop, paraLoc.MyParagraph);
|
|
return myList;
|
|
}
|
|
}
|
|
public class ParagraphLocation
|
|
{
|
|
private float _YTop;
|
|
public float YTop
|
|
{
|
|
get { return _YTop; }
|
|
set { _YTop = value; }
|
|
}
|
|
private float _YBottom;
|
|
public float YBottom
|
|
{
|
|
get { return _YBottom; }
|
|
set { _YBottom = value; }
|
|
}
|
|
private int _StepLevel;
|
|
public int StepLevel
|
|
{
|
|
get { return _StepLevel; }
|
|
set { _StepLevel = value; }
|
|
}
|
|
private vlnParagraph _MyParagraph;
|
|
public vlnParagraph MyParagraph
|
|
{
|
|
get { return _MyParagraph; }
|
|
set { _MyParagraph = value; }
|
|
}
|
|
public ParagraphLocation(float yTopMost,vlnParagraph myParagraph)
|
|
{
|
|
MyParagraph =myParagraph;
|
|
YTop = myParagraph.YVeryTop - yTopMost;
|
|
YBottom = myParagraph.YBottom - yTopMost;
|
|
StepLevel = myParagraph.MyItemInfo.StepLevel;
|
|
}
|
|
public bool Overlap(vlnParagraph otherParagraph)
|
|
{
|
|
if (Between(otherParagraph.YTop, YTop, YBottom)) return true;
|
|
if (Between(otherParagraph.YBottom, YTop, YBottom)) return true;
|
|
if(Between(YTop,otherParagraph.YVeryTop,otherParagraph.YBottom)) return true;
|
|
if(Between(YBottom,otherParagraph.YVeryTop,otherParagraph.YBottom)) return true;
|
|
return false;
|
|
}
|
|
public static bool Between(float x, float lower, float higher)
|
|
{ return x >= lower && x <= higher; }
|
|
public bool Overlap(ParagraphLocation otherParagraphLocation)
|
|
{
|
|
if (Between(otherParagraphLocation.YTop, YTop, YBottom)) return true; // The top is within the other
|
|
if (Between(otherParagraphLocation.YBottom, YTop, YBottom)) return true; // The bottom is within the other
|
|
if(Between(YTop,otherParagraphLocation.YTop,otherParagraphLocation.YBottom)) return true; // the other top is within this one
|
|
if(Between(YBottom,otherParagraphLocation.YTop,otherParagraphLocation.YBottom)) return true;// I believe this is unnecessary
|
|
return false;
|
|
}
|
|
public void Merge(vlnParagraph otherParagraph)
|
|
{
|
|
if (StepLevel < otherParagraph.MyItemInfo.StepLevel) MyParagraph = otherParagraph;
|
|
YTop = Math.Min(YTop, otherParagraph.YVeryTop);
|
|
YBottom = Math.Max(YBottom, otherParagraph.YBottom);
|
|
StepLevel = Math.Max(StepLevel, otherParagraph.MyItemInfo.StepLevel);
|
|
}
|
|
public void Merge(ParagraphLocation otherParagraphLocation)
|
|
{
|
|
if (StepLevel < otherParagraphLocation.StepLevel) MyParagraph = otherParagraphLocation.MyParagraph;
|
|
YTop = Math.Min(YTop, otherParagraphLocation.YTop);
|
|
YBottom = Math.Max(YBottom, otherParagraphLocation.YBottom);
|
|
StepLevel = Math.Max(StepLevel, otherParagraphLocation.StepLevel);
|
|
}
|
|
}
|
|
}
|