diff --git a/PROMS/Volian.Controls.Library/StepTabRibbon.cs b/PROMS/Volian.Controls.Library/StepTabRibbon.cs index 5f9736e2..d6951ed0 100644 --- a/PROMS/Volian.Controls.Library/StepTabRibbon.cs +++ b/PROMS/Volian.Controls.Library/StepTabRibbon.cs @@ -177,6 +177,7 @@ namespace Volian.Controls.Library void _MyStepRTB_TextChanged(object sender, EventArgs e) { + if (_MyStepRTB == null) return; // if we are in view mode or the edit window is empty, then don't allow inserting steps/substeps, // page breaks, copy step, nor creating a pdf bool allow = (_MyStepRTB.TextLength > 0); diff --git a/PROMS/Volian.Print.Library/Pagination.cs b/PROMS/Volian.Print.Library/Pagination.cs new file mode 100644 index 00000000..31c230d7 --- /dev/null +++ b/PROMS/Volian.Print.Library/Pagination.cs @@ -0,0 +1,315 @@ +using System; +using System.Collections.Generic; +using System.Text; +using VEPROMS.CSLA.Library; +using Volian.Base.Library; +using iTextSharp.text.pdf; +using Volian.Svg.Library; + +namespace Volian.Print.Library +{ + public partial class vlnParagraph + { + /// + /// This variable is used to match 16 bit pagination + /// + private bool _Match16BitPagination = false; + /// + /// Dtermines if the current step is preceded by a Page Break + /// + /// + /// + /// + /// + /// 0 - No page break + /// 1 - Break on High Level Step + /// 2 - Break within a Step + /// 3 - Break on High Level Step (SevenLinesPerInch) + /// + 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(1, "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 || ChildrenBelow.Count == 0) 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. + StepConfig sc = firstChild.MyItemInfo.MyConfig as StepConfig; + ManualPageBreak = MyPageHelper.OriginalPageBreak ? (sc == null ? false : sc.Step_ManualPagebreak) : + sc == null ? false : sc.Step_NewManualPagebreak; + if (ManualPageBreak) + { + SectionPageBreak = true; + ShowPageBreak(2, "Manual Page Break", "Yes", YSize, yPageSize, yWithinMargins); + 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) && ySizeIncludingFirst < yPageSize) + if (ySizeIncludingFirst > (yLocation - yBottomMargin)) + { + ShowPageBreak(4, "Page Break Before Continuous 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 + StepConfig sc1 = MyItemInfo.MyConfig as StepConfig; + ManualPageBreak = MyPageHelper.OriginalPageBreak ? (sc1 == null ? false : sc1.Step_ManualPagebreak) : + sc1 == null ? false : sc1.Step_NewManualPagebreak; + 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"); + } + private void ForcePagination(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation, ref float retval) + { + 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); + } + 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; + } + } + /// + /// Finds the highest StepLevel (lowest StepLevel number, 0 = HLS, 1 = first substep) that + /// fills the page sufficiently (more than half-full) + /// + /// + /// + /// + /// + 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; + } + + //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); + //} + } + public partial class VlnSvgPageHelper : SvgPageHelper + { + private bool _OriginalPageBreak; // use 16bit page breaks. + public bool OriginalPageBreak + { + get { return _OriginalPageBreak; } + set { _OriginalPageBreak = value; } + } + // This handles Page Breaks within a Step + private List _ParaBreaks = new List(); + public List ParaBreaks + { + get { return _ParaBreaks; } + set { _ParaBreaks = value; } + } + } +} diff --git a/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs b/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs index 3d23958b..b126b3ea 100644 --- a/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs +++ b/PROMS/Volian.Print.Library/VlnSvgPageHelper.cs @@ -11,16 +11,9 @@ using VEPROMS.CSLA.Library; namespace Volian.Print.Library { - public class VlnSvgPageHelper:SvgPageHelper + public partial class VlnSvgPageHelper:SvgPageHelper { private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - // This handles Page Breaks within a Step - private List _ParaBreaks = new List(); - public List ParaBreaks - { - get { return _ParaBreaks; } - set { _ParaBreaks = value; } - } private PageBookmarks _PageBookmarks = new PageBookmarks(); public PageBookmarks PageBookmarks { @@ -305,12 +298,6 @@ namespace Volian.Print.Library get { return _MyChangeBars; } set { _MyChangeBars = value; } } - private bool _OriginalPageBreak; // use 16bit page breaks. - public bool OriginalPageBreak - { - get { return _OriginalPageBreak; } - set { _OriginalPageBreak = value; } - } public void AddChangeBar(vlnChangeBar vcb, string cbmess) { if (vcb == null) return; diff --git a/PROMS/Volian.Print.Library/vlnParagraph.cs b/PROMS/Volian.Print.Library/vlnParagraph.cs index a9a10d8d..9505419a 100644 --- a/PROMS/Volian.Print.Library/vlnParagraph.cs +++ b/PROMS/Volian.Print.Library/vlnParagraph.cs @@ -41,7 +41,7 @@ namespace Volian.Print.Library yoff = Add(cb, childItemInfo.Cautions, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo); if (childItemInfo.Notes != null && (childItemInfo.IsCaution || childItemInfo.IsNote)) yoff = Add(cb, childItemInfo.Notes, xoff, yoff, yoffRight, rnoLevel, maxRNO, formatInfo); - int? bxIndx = childItemInfo.FormatStepData == null ? -1 : childItemInfo.FormatStepData.StepLayoutData.STBoxindex; + 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 @@ -52,7 +52,7 @@ namespace Volian.Print.Library 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.DefEnd = (float)(ssld.ColS + colR + widS + (60/4.8)); box.YOffset = yoff - .75F * vlnPrintObject.SixLinesPerInch; } else if (bxIndex == null) // First boxed step @@ -81,8 +81,8 @@ namespace Volian.Print.Library } 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) { @@ -103,7 +103,6 @@ namespace Volian.Print.Library 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) @@ -124,10 +123,6 @@ namespace Volian.Print.Library set { _MyGrid = value; } } public float SectYPageStart = 0; - /// - /// This variable is used to match 16 bit pagination - /// - private bool _Match16BitPagination = false; private bool _IsWordDocPara = false; public bool IsWordDocPara { @@ -226,13 +221,7 @@ namespace Volian.Print.Library 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); + ForcePagination(cb, ref yPageStart, yTopMargin, yBottomMargin, ref yLocation, ref retval); } return retval; } @@ -347,7 +336,7 @@ namespace Volian.Print.Library bool firstHighLevelStep = MyItemInfo.IsHigh && (MyItemInfo.MyPrevious == null); switch (paginate) { - case 0: + case 0: // No page break if (MyItemInfo.IsSection) { SectionInfo si = MyItemInfo as SectionInfo; @@ -526,27 +515,6 @@ namespace Volian.Print.Library 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 { @@ -570,152 +538,6 @@ namespace Volian.Print.Library 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 || ChildrenBelow.Count==0) 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. - StepConfig sc = firstChild.MyItemInfo.MyConfig as StepConfig; - ManualPageBreak = MyPageHelper.OriginalPageBreak ? (sc == null?false: sc.Step_ManualPagebreak): - sc == null? false: sc.Step_NewManualPagebreak; - 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 - StepConfig sc1 = MyItemInfo.MyConfig as StepConfig; - ManualPageBreak = MyPageHelper.OriginalPageBreak ? (sc1 == null ? false : sc1.Step_ManualPagebreak) : - sc1 == null ? false : sc1.Step_NewManualPagebreak; - 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"); - } /// /// This gets the height of the step with it's Caution's, Notes and potentially any First Substeps /// @@ -768,56 +590,6 @@ namespace Volian.Print.Library } 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; - } - } /// /// 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. @@ -861,45 +633,6 @@ namespace Volian.Print.Library myList.Remove(stepLevel); } /// - /// Finds the highest StepLevel (lowest StepLevel number, 0 = HLS, 1 = first substep) that - /// fills the page sufficiently (more than half-full) - /// - /// - /// - /// - /// - 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; - } - /// /// Builds a list of paragraphs by StepLevel and yLocation in descending order. /// /// @@ -1109,7 +842,6 @@ namespace Volian.Print.Library else if (itemInfo.FormatStepData != null && itemInfo.FormatStepData.StepPrintData != null) XOffset += (float)(itemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0); - bool printMetaHdr = false; if (itemInfo.Steps != null && itemInfo.IsSection && itemInfo.Sections != null && itemInfo.Sections.Count > 0) {