diff --git a/PROMS/Volian.Base.Library/DebugPrint.cs b/PROMS/Volian.Base.Library/DebugPrint.cs index 72163e84..2a89687f 100644 --- a/PROMS/Volian.Base.Library/DebugPrint.cs +++ b/PROMS/Volian.Base.Library/DebugPrint.cs @@ -5,8 +5,12 @@ using System.IO; namespace Volian.Base.Library { - public class DebugPrint + public class DebugPrint:IDisposable { + public void Dispose() + { + Close(); + } private StreamWriter _MyStreamWriter = null; public StreamWriter MyStreamWriter { @@ -14,7 +18,10 @@ namespace Volian.Base.Library set { if (_MyStreamWriter != null) + { + _MyStreamWriter.Flush(); _MyStreamWriter.Close(); + } _MyStreamWriter = value; } } @@ -66,11 +73,20 @@ namespace Volian.Base.Library } public static class DebugPagination { + private static int _TotalPages = 0; + public static int TotalPages + { + get { return _TotalPages; } + set { _TotalPages = value; } + } private static DebugPrint _MyDebugPrint = new DebugPrint(); public static void Open(string fileName) { _MyDebugPrint.Open(fileName); } public static void Close() - { _MyDebugPrint.Close(); } + { + WriteLine("{0} Total Pages", TotalPages); + _MyDebugPrint.Close(); + } public static void Write(string format, params object[] args) { _MyDebugPrint.Write(format, args); } public static void WriteLine(string format, params object[] args) diff --git a/PROMS/Volian.Print.Library/Pagination.cs b/PROMS/Volian.Print.Library/Pagination.cs index 7873f305..a4fc981d 100644 --- a/PROMS/Volian.Print.Library/Pagination.cs +++ b/PROMS/Volian.Print.Library/Pagination.cs @@ -39,10 +39,12 @@ namespace Volian.Print.Library // 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. + bool ManualPageBreak = false; 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 (MyItemInfo.ItemID == 54 || MyItemInfo.ItemID == 54) Console.WriteLine("here"); if (MyPageHelper.ParaBreaks.Count > 0) { if (this == MyPageHelper.ParaBreaks[0] || this.YTopMost > MyPageHelper.ParaBreaks[0].YTopMost) @@ -50,13 +52,15 @@ namespace Volian.Print.Library 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); + ShowPageBreak(1, "Page Break within Step", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); 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; + vlnParagraph firstChild = ChildrenBelow.Count > 0 ? ChildrenBelow[0] : null; + float ySizeIncludingFirst = firstChild == null ? YSize : firstChild.YSize + (firstChild.YTopMost - YTopMost); + bool KeepStepsOnPage = MyItemInfo.ActiveFormat.MyStepSectionLayoutData.KeepStepsOnPage; if (MyItemInfo.IsStepSection) { if (yLocation < yTopMargin) // continuous section @@ -71,7 +75,6 @@ namespace Volian.Print.Library } 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 @@ -83,18 +86,25 @@ namespace Volian.Print.Library if (ManualPageBreak) { SectionPageBreak = true; - ShowPageBreak(2, "Manual Page Break", "Yes", YSize, yPageSize, yWithinMargins); + ShowPageBreak(2, "Section Page Break", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); 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)) + vlnParagraph firstStepChild = firstChild; + //while (firstStepChild.MyItemInfo.IsSection && firstStepChild.ChildrenBelow.Count > 0) firstStepChild = firstStepChild.ChildrenBelow[0]; + while (firstStepChild.ChildrenBelow.Count > 0 && (firstStepChild.MyItemInfo.IsSection || firstStepChild.MyItemInfo.IsHigh)) firstStepChild = firstStepChild.ChildrenBelow[0]; + float ySizeIncludingFirstStep = firstStepChild.YSize + (firstStepChild.YTopMost - YTopMost); + bool isFirstSection = MyItemInfo.MyPrevious == null; + bool nearTheTop = yWithinMargins > (yPageSize - 5 * SixLinesPerInch); + bool firstSubstepExceedsSpaceAvailable = ySizeIncludingFirstStep > yWithinMargins; + if (KeepStepsOnPage && firstSubstepExceedsSpaceAvailable && !isFirstSection) + KeepStepsOnPage = false; + if (!KeepStepsOnPage && ySizeIncludingFirst > (yLocation - yBottomMargin)) { - ShowPageBreak(4, "Page Break Before Continuous Step Section", "Yes", YSize, yPageSize, yWithinMargins); + ShowPageBreak(4, "Page Break Before Continuous Step Section", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); return 1; } } @@ -117,33 +127,40 @@ namespace Volian.Print.Library 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) // Don't Paginate if there is enough room, will fit on page + // Pagination Fix - Break1LineShort1 + float yExtra = (yWithinMargins == yPageSize ? 0 : SixLinesPerInch - MyItemInfo.MyDocStyle.Layout.FooterLength) ?? 0; + float yExtra2 = (SixLinesPerInch - MyItemInfo.MyDocStyle.Layout.FooterLength) ?? 0; + if (KeepStepsOnPage && ySizeIncludingFirst > yWithinMargins) + KeepStepsOnPage = false; + if (!ManualPageBreak && mySize + yEndMsg <= yWithinMargins + yExtra) // 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); + ShowPageBreak(-1, "HLS will fit on page", firstStep, YSize, yPageSize, yWithinMargins,ManualPageBreak); 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 + if (!KeepStepsOnPage && 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); + ShowPageBreak(5, "HLS will fit on 1 Page at 6 LPI", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); 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)) + else if (!KeepStepsOnPage && 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); + ShowPageBreak(7, "HLS will fit on 1 Page at 7 LPI", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); //Console.WriteLine("'7LPI',{0},{1}", MyItemInfo.DBSequence, YSize); return 3; // High Level Step can fit at SevenLinesPerInch } @@ -154,22 +171,34 @@ namespace Volian.Print.Library 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) + if (!ManualPageBreak && ((MyItemInfo.ActiveFormat.MyStepSectionLayoutData.SpecialPageBreakFlag && yWithinMargins > yPageSize / 2 && + myFirstPieceSize < yWithinMargins) || KeepStepsOnPage)) { //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); + if(firstStep == "Yes") + ShowPageBreak(8, "First HLS has to split on current page", firstStep, YSize, yPageSize, yWithinMargins, ManualPageBreak); + else + ShowPageBreak(6, "HLS will have to split on current page", "Special", YSize, yPageSize, yWithinMargins, ManualPageBreak); //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 + //BuildPageBreakList(yWithinMargins + SixLinesPerInch, yPageSize); // Case 5 - Determine items where page break(s) occur + // Pagination Fix Break1LineShort3a + BuildPageBreakList(yWithinMargins + SixLinesPerInch, yPageSize + yExtra2,KeepStepsOnPage); // 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); + if (firstStep == "Yes") + ShowPageBreak(9, "First HLS will have to split on new page", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); + else + ShowPageBreak(3, "HLS will have to split on new page", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak); // 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 + //BuildPageBreakList(yPageSize, yPageSize - 2 * SixLinesPerInch); // Case Base + //BuildPageBreakList(yPageSize, yPageSize); // Case 1 :Works for ES05 Step 15 SubStep 7 + // Pagination Fix Break1LineShort2 + //BuildPageBreakList(yPageSize + yExtra, yPageSize); // Case 1 :Works for ES05 Step 15 SubStep 7 + // Pagination Fix Break1LineShort4 + BuildPageBreakList(yPageSize + yExtra, yPageSize + yExtra2,KeepStepsOnPage); // Case 1 :Works for ES05 Step 15 SubStep 7 return 1; // Paginate on High Level Steps } //if (yWithinMargins > yPageSize / 2) @@ -193,21 +222,24 @@ namespace Volian.Print.Library 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) + private void ShowPageBreak(int instance, string message, string breakOrNot, float YSize, float yPageSize, float yWithinMargins, bool manualPageBreak) { - if (breakOrNot == "Yes") + if (breakOrNot != "No") { // 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, + DebugPagination.WriteLine("{0},'{1}',{2},'{3}','{4}',{5},{6},{7},{8},{9}", + MyPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber - (breakOrNot == "Yes" ? 0 : 1), + MyItemInfo.ShortPath, instance, + (manualPageBreak ? "Manual " : "") + 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) + private void BuildPageBreakList(float ySpaceOnCurPage, float yPageSize, bool KeepStepsOnPage) { ParagraphLocations myLocations = new ParagraphLocations(); BuildLocationList(YTopMost, myLocations); - StepLevelList myList = myLocations.BuildStepLevelList(); + StepLevelList myList = myLocations.BuildStepLevelList(KeepStepsOnPage); // Find Break Locations in the list based upon StepLevel and yLocation float yTop = 0; float yLowerLimit = (yPageSize - 2 * SixLinesPerInch) / 2; @@ -224,7 +256,9 @@ namespace Volian.Print.Library // 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) + //while ((YSize - yTop) >= ySpaceOnCurPage) + // Pagination Fix Break1LineShort3b + while ((YSize - yTop) > ySpaceOnCurPage) { vlnParagraph paraBreak = FindPageBreak(yStart, ySpaceOnCurPage, yLowerLimit, myList); if (paraBreak == null) break; diff --git a/PROMS/Volian.Print.Library/PromsPrinter.cs b/PROMS/Volian.Print.Library/PromsPrinter.cs index d9c7d314..cf1637e7 100644 --- a/PROMS/Volian.Print.Library/PromsPrinter.cs +++ b/PROMS/Volian.Print.Library/PromsPrinter.cs @@ -432,6 +432,7 @@ namespace Volian.Print.Library } } OnStatusChanged(myProcedure.DisplayNumber + " PDF Creation Completed", PromsPrinterStatusType.Progress, progress); + DebugPagination.TotalPages += cb.PdfWriter.CurrentPageNumber; CloseDocument(cb, outputFileName); _MyHelper = null; return outputFileName; diff --git a/PROMS/Volian.Print.Library/Rtf2Pdf.cs b/PROMS/Volian.Print.Library/Rtf2Pdf.cs index 2d6c892b..efa8e950 100644 --- a/PROMS/Volian.Print.Library/Rtf2Pdf.cs +++ b/PROMS/Volian.Print.Library/Rtf2Pdf.cs @@ -166,7 +166,7 @@ namespace Volian.Print.Library ColumnText ct = new ColumnText(cb); ct.SetSimpleColumn(left, 4 + top - yDescent, right, top - yDescent - 50); iTextSharp.text.Font font = FontFactory.GetFont("Arial", 2); - Chunk chk = new Chunk(debugText, font); + Chunk chk = new Chunk(debugText + string.Format(" Top = {0}",top), font); Phrase ph = new Phrase(chk); ct.AddElement(ph); cb.SetColorFill(new Color(sysColor)); diff --git a/PROMS/Volian.Print.Library/vlnParagraph.cs b/PROMS/Volian.Print.Library/vlnParagraph.cs index 64691b1a..ae93dca3 100644 --- a/PROMS/Volian.Print.Library/vlnParagraph.cs +++ b/PROMS/Volian.Print.Library/vlnParagraph.cs @@ -2124,11 +2124,21 @@ namespace Volian.Print.Library return paraLoc; return null; } - internal StepLevelList BuildStepLevelList() + internal StepLevelList BuildStepLevelList(bool KeepStepsOnPage) { StepLevelList myList = new StepLevelList(); foreach (ParagraphLocation paraLoc in this) - myList.Add(paraLoc.StepLevel, paraLoc.YTop, paraLoc.MyParagraph); + { + int level = paraLoc.StepLevel; + if (KeepStepsOnPage && paraLoc.MyParagraph.MyItemInfo.MyContent.Type == 20001) + { + if (paraLoc.MyParagraph.MyItemInfo.MyPrevious == null) + level = 0; + else + level = 1; + } + myList.Add(level , paraLoc.YTop, paraLoc.MyParagraph); + } return myList; } } diff --git a/PROMS/Volian.Print.Library/vlnPrintObject.cs b/PROMS/Volian.Print.Library/vlnPrintObject.cs index 2d246705..d37f5032 100644 --- a/PROMS/Volian.Print.Library/vlnPrintObject.cs +++ b/PROMS/Volian.Print.Library/vlnPrintObject.cs @@ -149,11 +149,22 @@ namespace Volian.Print.Library if (chk == null) return null; string s = chk.Content; - if (s.Length > 1) // don't remove last character if it's the only one + if (s.Length > 1 || iParagraph.Count > 1) // don't remove last character if it's the only one { iParagraph.RemoveAt(iParagraph.Count - 1); + if (s.Length > 0) + { + if (s == "\xA0") // If this is a space at the end put it back + { + iParagraph.Add(chk); + return null; + } + else + { s = s.Substring(0, s.Length - 1); iParagraph.Add(new Chunk(s, chk.Font)); + } + } } return chk; }