/// /// Copyright (c) 2016-2018 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Printing; using Common; using System.IO; using Results.Resources; namespace Results.Output.Printers.Munich { public class MunichPrintDocument : PrintDocument { const string FontFamilyName = "Arial"; ///"Times New Roman"; const int SpacingOne = 18; const int SpacingOneAndHalf = 24; /// was 27 before const int TitleX = 240; const int TitleY = 180; /// Depends on the size of the header const int FirstLineNr = 14; /// Depends on the size of the header const int Tab1 = 80; /// Positions of columns above the table const int Tab2 = 240; const int Tab3 = 430; const int Tab4 = 590; const int BorderW = 1; /// Table border line width const int MarginTop = 7; /// Margins of the text from table lines const int MarginLeft = 4; /// Margins of the text from table lines /// /// Data to print /// readonly string docVersion; readonly Results.Entities.WaterMeter wm; string zaehlertyp; string pruefvorlage; readonly IList results; readonly int resultsCount; readonly bool compound; /// true when MetersKind is MetersKind.Combined int pageNr; /// Current page number int nrPages; /// Total number of pages float tableTop; /// Top coordinate of the table int[] firstTblRowsOnPage; int[] secondTblRowsOnPage; PageOrientation pageOrientation; /// /// Property variable for the Font the user wishes to use /// Font font; Font boldFont; Font fontTitle; /// /// Table style /// static TableStyle tableStyle = new TableStyle { Font = new Font(FontFamilyName, 10, FontStyle.Regular), HeaderFont = new Font(FontFamilyName, 10, FontStyle.Regular), MarginX = 7, MarginY = 5, LineWidth = 1, TopHeadersCount = 1, HorizLines = TableLines.FirstSecondAndLast, VertLines = TableLines.All, ColumnWidths = new float[] { 150, 70, 75, 75, 70, 75, 75 }, }; static Alignment[] horizontalAlignment = new Alignment[] /// Horizontal alignment of items of one row { Alignment.Left, Alignment.Left, Alignment.Left, Alignment.Left, Alignment.Left, Alignment.Left, Alignment.Left }; static VertAlignment[] verticalAlignment = new VertAlignment[] /// Vertical alignment of items of one row { VertAlignment.Middle, VertAlignment.Middle, VertAlignment.Middle, VertAlignment.Middle, VertAlignment.Middle, VertAlignment.Middle, VertAlignment.Middle }; /// /// Constructor /// /// Text to be printed public MunichPrintDocument(string docVersion, Results.Entities.WaterMeter wm, PageOrientation pageOrientation) { this.docVersion = docVersion; this.wm = wm; this.compound = wm.Compound(); this.pageOrientation = pageOrientation; string[] info = wm.ProductName().Split(new char[] { ';' }); if (info.Length >= 2) { pruefvorlage = info[0]; zaehlertyp = info[1]; } else if (info.Length == 1) { pruefvorlage = info[0]; zaehlertyp = compound ? "Verbundzähler" : "Einzelzähler"; } else { pruefvorlage = wm.ProcedureName(); zaehlertyp = compound ? "Verbundzähler" : "Einzelzähler"; } results = wm.RegularMeterTestRslts(); resultsCount = 0; foreach (var mtr in wm.RegularMeterTestRslts()) { if (mtr != null && mtr.IsPilotRslt() && mtr.Publish() == Publish.Always) resultsCount++; } pageNr = 1; if (compound) { /// Compound meter results const int MaxOnFirstPage = 23; const int MaxOnPage = 45; if (resultsCount <= 7) { nrPages = 1; firstTblRowsOnPage = new int[] { resultsCount }; secondTblRowsOnPage = new int[] { resultsCount }; } else if (resultsCount <= MaxOnFirstPage) { nrPages = 2; firstTblRowsOnPage = new int[] { resultsCount, 0 }; secondTblRowsOnPage = new int[] { 0, int.MaxValue }; } else if (resultsCount <= MaxOnPage) { nrPages = 3; firstTblRowsOnPage = new int[] { MaxOnFirstPage, (resultsCount - MaxOnFirstPage), 0 }; int secondTblRowsOn2ndPage = Math.Max(0, MaxOnFirstPage + MaxOnPage - 2 - resultsCount); secondTblRowsOnPage = new int[] { 0, secondTblRowsOn2ndPage, resultsCount - secondTblRowsOn2ndPage }; } else if (resultsCount <= MaxOnFirstPage + MaxOnPage) { nrPages = 4; firstTblRowsOnPage = new int[] { MaxOnFirstPage, MaxOnPage, 0, 0 }; secondTblRowsOnPage = new int[] { 0, 0, MaxOnPage, MaxOnFirstPage }; } else { nrPages = 5; firstTblRowsOnPage = new int[] { MaxOnFirstPage, MaxOnPage, (resultsCount - MaxOnFirstPage - MaxOnPage), 0 }; secondTblRowsOnPage = new int[] { 0, 0, Math.Max(0, MaxOnFirstPage + 2 * MaxOnPage - 2 - resultsCount), MaxOnPage, MaxOnFirstPage }; } } else { /// Regular (single) meter results const int MaxOnFirstPage = 27; const int MaxOnPage = 45; if (resultsCount <= 9) { nrPages = 1; firstTblRowsOnPage = new int[] { resultsCount }; secondTblRowsOnPage = new int[] { resultsCount }; } else if (resultsCount <= MaxOnFirstPage) { nrPages = 2; firstTblRowsOnPage = new int[] { resultsCount, 0 }; secondTblRowsOnPage = new int[] { 0, int.MaxValue }; } else if (resultsCount <= MaxOnPage) { nrPages = 3; firstTblRowsOnPage = new int[] { MaxOnFirstPage, (resultsCount - MaxOnFirstPage), 0 }; int secondTblRowsOn2ndPage = Math.Max(0, MaxOnFirstPage + MaxOnPage - 2 - resultsCount); secondTblRowsOnPage = new int[] { 0, secondTblRowsOn2ndPage, resultsCount - secondTblRowsOn2ndPage }; } else if (resultsCount <= MaxOnFirstPage + MaxOnPage) { nrPages = 4; firstTblRowsOnPage = new int[] { MaxOnFirstPage, MaxOnPage, 0, 0 }; secondTblRowsOnPage = new int[] { 0, 0, MaxOnPage, MaxOnFirstPage }; } else { nrPages = 5; firstTblRowsOnPage = new int[] { MaxOnFirstPage, MaxOnPage, (resultsCount - MaxOnFirstPage - MaxOnPage), 0 }; secondTblRowsOnPage = new int[] { 0, 0, Math.Max(0, MaxOnFirstPage + 2 * MaxOnPage - 2 - resultsCount), MaxOnPage, MaxOnFirstPage }; } } DefaultPageSettings.Landscape = (pageOrientation == PageOrientation.Landscape); } /// /// Override the default onbeginPrint method of the PrintDocument Object. /// /// /// protected override void OnBeginPrint(System.Drawing.Printing.PrintEventArgs e) { base.OnBeginPrint(e); if (font == null) { font = new Font(FontFamilyName, 10, FontStyle.Regular); } if (boldFont == null) { boldFont = new Font(FontFamilyName, 10, FontStyle.Bold); } if (fontTitle == null) { fontTitle = new Font(FontFamilyName, 24, FontStyle.Bold); } } /// /// Override the default OnPrintPage method of the PrintDocument. /// /// /// This provides the print logic for our document protected override void OnPrintPage(System.Drawing.Printing.PrintPageEventArgs e) { /// Run base code base.OnPrintPage(e); if (pageOrientation == PageOrientation.Portrait) { string[] templatePaths = new string[] { "C:\\TBF\\Templates\\MunichP.jpg", "C:\\TBF\\Templates\\MunichP.png", "C:\\TBF\\Templates\\MunichP.tif" }; foreach (var t in templatePaths) { if (File.Exists(t)) { e.Graphics.DrawImage(new Bitmap(Image.FromFile(t), 827, 1169), new Rectangle(0, 0, 827, 1169)); break; } } } else { string[] templatePaths = new string[] { "C:\\TBF\\Templates\\MunichL.jpg", "C:\\TBF\\Templates\\MunichL.png", "C:\\TBF\\Templates\\MunichL.tif" }; foreach (var t in templatePaths) { if (File.Exists(t)) { e.Graphics.DrawImage(new Bitmap(Image.FromFile(t), 1169, 827), new Rectangle(0, 0, 1169, 827)); break; } } } /// Set print area size and margins (in dots using 80 dpi) int printHeight = base.DefaultPageSettings.PaperSize.Height - base.DefaultPageSettings.Margins.Top - base.DefaultPageSettings.Margins.Bottom; int printWidth = base.DefaultPageSettings.PaperSize.Width - base.DefaultPageSettings.Margins.Left - base.DefaultPageSettings.Margins.Right; int leftMargin = base.DefaultPageSettings.Margins.Left; /// X int topMargin = base.DefaultPageSettings.Margins.Top; /// Y /// Check if the user selected to print in Landscape mode /// if they did then we need to swap height/width parameters if (base.DefaultPageSettings.Landscape) { int tmp = printHeight; printHeight = printWidth; printWidth = tmp; } int x = leftMargin; int y = topMargin; /// Use the StringFormat class for the text layout of our document StringFormat format = new StringFormat(StringFormatFlags.LineLimit); int lineNr = FirstLineNr; if (pageNr == 1) { /// This is the first page, drad the title, common part and the 1st table RectangleF printArea = new RectangleF(TitleX, TitleY, 667, 50); e.Graphics.DrawString(wm.Batch.ProtocolTitle, this.fontTitle, Brushes.Black, printArea); DrawCommonTop(e, ref lineNr, wm, pruefvorlage, docVersion); lineNr += 2; tableTop = SpacingOne * lineNr; } else { /// This appears on the top of the 2nd and every subsequent page. /// 2nd table starts from the top of the page. lineNr -= 3; if (compound) { PrintBoldAt(e, Tab1, lineNr * SpacingOne, "Hauptzahler"); PrintBoldAt(e, Tab3, lineNr * SpacingOne, "Nebenzahler"); lineNr++; } PrintAt(e, Tab1, lineNr * SpacingOne, "Hersteller :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.Producer()); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Hersteller :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.ProducerAux()); } lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Seriennummer :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.SerialNr); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Seriennummer :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.SerialNrAux); } lineNr += ((resultsCount + 2) * SpacingOneAndHalf) / SpacingOne + 2; tableTop = TitleY + (compound ? 5 : 4) * SpacingOne; } if (firstTblRowsOnPage[pageNr - 1] > 0) { int from = 0; for (int pN = 0; pN < pageNr - 1; pN++) from += firstTblRowsOnPage[pN]; Table table1 = PrepareTableOne(from, from + firstTblRowsOnPage[pageNr - 1] - 1); tableTop = table1.Draw(e, Tab1, tableTop) + SpacingOneAndHalf; } if (secondTblRowsOnPage[pageNr - 1] > 0) { int from = 0; for (int pN = 0; pN < pageNr - 1; pN++) from += secondTblRowsOnPage[pN]; Table table2 = PrepareTableTwo(from, from + secondTblRowsOnPage[pageNr - 1] - 1); tableTop = table2.Draw(e, Tab1, tableTop) + SpacingOneAndHalf; } if (pageNr == nrPages) { int top = topMargin + printHeight - 8 * SpacingOne; DrawCommonBottom(e, top, wm); } else { e.HasMorePages = true; } /// /// Draw a footer and increment the page number /// string pageNrText = string.Format("{0} {1}/{2}", Strings.Page, pageNr++, nrPages); int pageNrWidth = (int)e.Graphics.MeasureString(pageNrText, font).Width; PrintAt(e, leftMargin + (printWidth - pageNrWidth) / 2, topMargin + printHeight - SpacingOne, pageNrText); } /// /// Prepares content and style of the first table. /// /// 0-based index fo the first result to print /// 0-based index fo the last result to print /// Prepared table Table PrepareTableOne(int from = 0, int to = int.MaxValue) { Table table = new Table(7); table.Style = tableStyle; string[] tableHeader = new string[] { "Prüflauf", "Q [l/h]", "Prüf-Vol.[l]", compound ? "HZ-Vol.[l]" : "Z-Vol.[l]", compound ? "NZ-Vol.[l]" : "-", "Fehler [%]", "Ergebnis", }; table.AddRow(tableHeader, horizontalAlignment, verticalAlignment); int rowCount = 0; foreach (var mtr in wm.RegularMeterTestRslts()) { if (mtr != null && mtr.IsPilotRslt() && mtr.Publish() == Publish.Always) { if (from <= rowCount && rowCount <= to) { double flow_ctv = (mtr.TestRslt.TestTime != 0) ? (3.6 * mtr.TestRslt.VolumeCTV / mtr.TestRslt.TestTime) : 0; if (compound) { Results.Entities.MeterTestRslt mainMtr = wm.GetMeterTestRslt(mtr.Name(), CompoundMeterId.CompoundMain); Results.Entities.MeterTestRslt auxMtr = wm.GetMeterTestRslt(mtr.Name(), CompoundMeterId.CompoundAux); table.AddRow(new string[] { mtr.Name(), Units.ConvertTo(Unit.lph, flow_ctv).ToString("F1"), mtr.TestRslt.VolumeCTV.ToString("F2"), mainMtr.VolumeMeter.ToString("F2"), auxMtr.VolumeMeter.ToString("F2"), mtr.Error.ToString("F2"), mtr.Passed ? "iO" : "NiO" }, horizontalAlignment, verticalAlignment); } else { table.AddRow(new string[] { mtr.Name(), Units.ConvertTo(Unit.lph, flow_ctv).ToString("F1"), mtr.TestRslt.VolumeCTV.ToString("F2"), mtr.VolumeMeter.ToString("F2"), "-", mtr.Error.ToString("F2"), mtr.Passed ? "iO" : "NiO" }, horizontalAlignment, verticalAlignment); } } rowCount++; } } return table; } /// /// Prepares content and style of the second table. /// /// 0-based index fo the first result to print /// 0-based index fo the last result to print /// Prepared table Table PrepareTableTwo(int from = 0, int to = int.MaxValue) { Table table = new Table(7); table.Style = tableStyle; string[] tableHeader = new string[] { "", "Q [l/h]", "Temperatur", "Dichte", "Prüfzeit", "Druck Eing.", "Druck Ausg.", }; table.AddRow(tableHeader, horizontalAlignment, verticalAlignment); int rowCount = 0; foreach (var mtr in wm.RegularMeterTestRslts()) { if (mtr != null && mtr.IsPilotRslt() && mtr.Publish() == Publish.Always) { if (from <= rowCount && rowCount <= to) { double flow_ctv = (mtr.TestRslt.TestTime != 0) ? (3.6 * mtr.TestRslt.VolumeCTV / mtr.TestRslt.TestTime) : 0; table.AddRow(new string[] { mtr.Name(), Units.ConvertTo(Unit.lph, flow_ctv).ToString("F1"), mtr.TestRslt.TempDownMean.ToString("F2"), mtr.TestRslt.DensityDiv.ToString("F2"), mtr.TestTime.ToString("F1"), Units.ConvertTo(Unit.bar, mtr.TestRslt.PressUpMean).ToString("F3"), Units.ConvertTo(Unit.bar, mtr.TestRslt.PressDownMean).ToString("F3") }, horizontalAlignment, verticalAlignment); } rowCount++; } } return table; } /// /// Prints text on the top of the first page (title, common information). /// /// /// /// /// /// void DrawCommonTop(PrintPageEventArgs e, ref int lineNr, Entities.WaterMeter wm, string pruefvorlage, string docVersion) { /// /// /// PrintAt(e, Tab1, lineNr * SpacingOne, docVersion); lineNr++; PrintBoldAt(e, Tab1, lineNr * SpacingOne, "Prüfstand Nr :"); PrintBoldAt(e, Tab2, lineNr * SpacingOne, wm.BenchId().ToString()); PrintBoldAt(e, Tab3, lineNr * SpacingOne, "Datum :"); PrintBoldAt(e, Tab4, lineNr * SpacingOne, wm.Batch.EndTime.Date.ToString("d")); lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Zählertyp :"); PrintAt(e, Tab2, lineNr * SpacingOne, zaehlertyp); PrintAt(e, Tab3, lineNr * SpacingOne, "Eichjahr :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.YearOfProduction.ToString()); lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Prüfvorlage :"); PrintAt(e, Tab2, lineNr * SpacingOne, pruefvorlage); lineNr += 2; if (compound) { PrintBoldAt(e, Tab1, lineNr * SpacingOne, "Hauptzahler"); PrintBoldAt(e, Tab3, lineNr * SpacingOne, "Nebenzahler"); lineNr++; } PrintAt(e, Tab1, lineNr * SpacingOne, "Hersteller :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.Producer()); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Hersteller :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.ProducerAux()); } lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Seriennummer :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.SerialNr); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Seriennummer :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.SerialNrAux); } lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, wm.NewQnames() ? "Q3 :" : "Qn :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.Q3_Qn().ToString()); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, wm.NewQnames() ? "Q3 :" : "Qn :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.Q3_Qn_Aux().ToString()); } lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Zulassungszeichen :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.ApprovalInfo()); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Zulassungszeichen :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.ApprovalInfoAux()); } lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Metr. klasse :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.MetrologicalClass()); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Metr. klasse :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.MetrologicalClassAux()); } lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Stand :"); PrintAt(e, Tab2, lineNr * SpacingOne, wm.EndState); if (compound) { PrintAt(e, Tab3, lineNr * SpacingOne, "Stand :"); PrintAt(e, Tab4, lineNr * SpacingOne, wm.EndStateAux); lineNr += 2; PrintAt(e, Tab1, lineNr * SpacingOne, "Umschaltpunkte :"); lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Qsteig"); PrintAt(e, Tab2, lineNr * SpacingOne, (1000.0 * wm.QRise).ToString("F1") + " l/h"); lineNr++; PrintAt(e, Tab1, lineNr * SpacingOne, "Qfall"); PrintAt(e, Tab2, lineNr * SpacingOne, (1000.0 * wm.QFall).ToString("F1") + " l/h"); } } /// /// Prints text at the bottom of the last page (footer). /// /// /// /// void DrawCommonBottom(PrintPageEventArgs e, float top, Entities.WaterMeter wm) { int iTop = (int)top; PrintAt(e, Tab1, iTop, "Temperatur"); PrintAt(e, Tab2, iTop, wm.Batch.AmbTempMean().ToString("F1") + " \x00b0C"); iTop += SpacingOne; PrintAt(e, Tab1, iTop, "Feuchtigkeit"); PrintAt(e, Tab2, iTop, wm.Batch.AmbHumiMean().ToString("F0") + " %"); iTop += SpacingOne; PrintAt(e, Tab1, iTop, "Luftdruck"); PrintAt(e, Tab2, iTop, Units.ConvertTo(Unit.mbar, wm.Batch.AmbPressMean()).ToString("F0") + " mbar"); iTop += SpacingOne; PrintAt(e, Tab3, iTop, wm.Batch.EndTime.Date.ToString("d")); iTop += SpacingOne; PrintAt(e, Tab3, iTop, "Datum"); PrintAt(e, Tab4, iTop, "Unterschrift"); } void PrintAt(System.Drawing.Printing.PrintPageEventArgs e, Point p, string text) { PrintAt(e, p.X, p.Y, text); } void PrintAt(System.Drawing.Printing.PrintPageEventArgs e, int x, int y, string text) { RectangleF printArea = new RectangleF(x, y, 667, SpacingOne); e.Graphics.DrawString(text, this.font, Brushes.Black, printArea); } void PrintBoldAt(System.Drawing.Printing.PrintPageEventArgs e, Point p, string text) { PrintBoldAt(e, p.X, p.Y, text); } void PrintBoldAt(System.Drawing.Printing.PrintPageEventArgs e, int x, int y, string text) { RectangleF printArea = new RectangleF(x, y, 667, SpacingOne); e.Graphics.DrawString(text, this.boldFont, Brushes.Black, printArea); } } }