Added “Final Page” logic Added “Final Page” logic, fixed PDF compare where it wasn’t finding the file in the Compare folder Added Caution and Note boxes for Turkey Point Null check and logic for PosAdjust format variable Added “Final Page” message logic Fix to get proper with of tabs containing a solid bullet
1635 lines
69 KiB
C#
1635 lines
69 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")
|
|
{
|
|
float offset = (float)itemInfo.MyDocStyle.Layout.LeftMargin;
|
|
if (formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos != null)
|
|
offset += (float)formatInfo.PlantFormat.FormatData.SectData.SectionNumber.Pos;
|
|
localXOffset = offset;
|
|
// jsj - 12Aug2011
|
|
//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;
|
|
|
|
// Set any position adjustment (defined in the format on a per type basis)
|
|
XOffset += (float)(MyItemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0);
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
}
|