/// /// Copyright (c) 2013-2015 Sensus Metering Systems /// using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Printing; using System.IO; using TBF.Resources; namespace TBF.BenchControl.ResultsPrinters.Basic { public class BasicPrintDocument : PrintDocument { const string FontFamilyName = "Arial"; //"Times New Roman"; const int SpacingOne = 18; const int SpacingOneAndHalf = (3 * SpacingOne) / 2; const int TitleX = 100; const int TitleY = 180; /// Depends on the size of the header const int HdrTop = 240; /// Depends on the size of the header const int BodyTop = 400; /// /// Property variable for the Font the user wishes to use /// Font font; Font boldFont; Font titleFont; /// /// Data to print /// readonly BenchControl.BenchId.Component benchId; readonly Entities.Procedure procedure; readonly IList unsortedResults; readonly bool combined; readonly DateTime dateTime; /// /// Items to print /// readonly IList resultItems; /// /// Constructor /// /// Text to be printed public BasicPrintDocument(BenchControl.BenchId.Component benchId, Entities.Procedure procedure, IList unsortedResults) { this.benchId = benchId; this.procedure = procedure; this.unsortedResults = unsortedResults; dateTime = DateTime.Now; if ((unsortedResults != null) && (unsortedResults.Count != 0) && (unsortedResults[0].MetersKind == Entities.MetersKind.Single)) { resultItems = Forms.ResultItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Printer_SingleWM); combined = false; } else { resultItems = Forms.ResultItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Printer_CombinedWM); combined = true; } } /// /// 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 (titleFont == null) { titleFont = new Font(FontFamilyName, 18, 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 (File.Exists("C:\\TBF\\header.png")) { Image img = Image.FromFile("C:\\TBF\\header.png"); e.Graphics.DrawImage(new Bitmap(img), new Rectangle(0, 0, 827, 1169)); } /// 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); ///---------- /// Header ///---------- RectangleF printArea = new RectangleF(TitleX, TitleY, 667, 40); e.Graphics.DrawString(unsortedResults[0].ProtocolTitle, titleFont, Brushes.Black, printArea); string[] leftColumn = new string[] { "Batch number: ", "Date and time: ", "Procedure:", Strings.User_, "Ambient temperature: ", "Ambient pressure: ", "Ambient humidity: ", }; string[] rightColumn = new string[] { unsortedResults[0].BatchNr.ToString(), //dateTime.ToShortDateString() + " " + dateTime.ToShortTimeString(), string.Format("{0}.{1}.{2} {3}:{4}", dateTime.Year.ToString("D4"), dateTime.Month.ToString("D2"), dateTime.Day.ToString("D2"), dateTime.Hour.ToString("D2"), dateTime.Minute.ToString("D2")), procedure.Name, Entities.User.CurrentUser.Name, unsortedResults[0].AmbientTempAve.ToString("F1") + " °C", unsortedResults[0].AmbientPressAve.ToString("F0") + " mbar", unsortedResults[0].AmbientHumiAve.ToString("F0") + " %", }; /// Determine max. left column width in characters int maxLen = 0; foreach (var s in leftColumn) if (s.Length > maxLen) maxLen = s.Length; /// Write aligned columns for (int i = 0; i < Math.Min(leftColumn.Length, rightColumn.Length); i++) { PrintAt(e, 100, HdrTop + SpacingOne* i, leftColumn[i]); PrintAt(e, 300, HdrTop + SpacingOne * i, rightColumn[i]); } ///-------- /// Body ///-------- /// This variable represents the top coordinate of the area where WM results are printed /// and it is updated (increased by) the value returned by PrintXyzWM() - the section size. int nextWmTop = BodyTop; if (combined) { for (int wmNr = 1; wmNr <= Program.WMsCount / 2; wmNr++) /// wmNr is 1-based { nextWmTop += PrintCombinedWM(e, wmNr, nextWmTop); } } else { for (int wmNr = 0; wmNr < Program.WMsCount; wmNr++) /// wmNr is 0-based { if (!unsortedResults[0].Meters[wmNr].Disabled) nextWmTop += PrintSingleWM(e, wmNr, wmNr + 1, nextWmTop); } } e.HasMorePages = false; } /// /// Print one water meter results /// /// Water meter number (0-based) /// Top coordinate of watermeter data /// The height of the printed section int PrintSingleWM(System.Drawing.Printing.PrintPageEventArgs e, int wmNr, int printedWMNr, int top) { IList results = Utils.GetSortedTestResults(procedure, unsortedResults, wmNr + 1); /// Determin column widths float[] columnPos = new float[resultItems.Count + 1]; columnPos[0] = 100.0f; for (int i = 0; i < resultItems.Count; i++) { float columnWidth = e.Graphics.MeasureString(resultItems[i].ClmnHeaderText, font).Width; foreach (var tr in results) { if (tr != null) { float width = e.Graphics.MeasureString(resultItems[i].Print(tr.Meters[wmNr]), font).Width; if (width > columnWidth) columnWidth = width; } } columnPos[i + 1] = columnPos[i] + columnWidth + 20.0f; } int tableLeftX = (int)columnPos[0]; int tableRightX = (int)columnPos[resultItems.Count] - 20; string wmText = string.Format("Water meter {0}", printedWMNr); PrintAt(e, 100, top, wmText); if (!string.IsNullOrEmpty(unsortedResults[0].Meters[wmNr].SerialNr)) { PrintAt(e, 100 + (int)e.Graphics.MeasureString(wmText, font).Width, top, string.Format(" s/n = {0}", unsortedResults[0].Meters[wmNr].SerialNr)); } /// Horizontal line int horY = top + 25; e.Graphics.DrawLine(new Pen(Color.Black, 2), new Point(tableLeftX, horY), new Point(tableRightX, horY)); for (int i = 0; i < resultItems.Count; i++) { PrintAt(e, (int)columnPos[i], top + 27, resultItems[i].ClmnHeaderText); } /// Horizontal line horY = top + 27 + SpacingOne; e.Graphics.DrawLine(new Pen(Color.Black, 2), new Point(tableLeftX, horY), new Point(tableRightX, horY)); for (int r = 0; r < results.Count; r++) { if (results[r] != null) { for (int i = 0; i < resultItems.Count; i++) { string text = resultItems[i].Print(results[r].Meters[wmNr]); string[] texts = text.Split(new char[] { '|' }); if (texts.Length == 2) { Color color = texts[1].Equals("Green") ? Color.Green : (texts[1].Equals("Red") ? Color.Red : Color.White); text = texts[0]; /// TODO: How to print colors? } PrintAt(e, (int)columnPos[i], top + 30 + SpacingOne * (r + 1), text); } } } /// Horizontal line horY = top + 30 + SpacingOne * (results.Count + 1); e.Graphics.DrawLine(new Pen(Color.Black, 2), new Point(tableLeftX, horY), new Point(tableRightX, horY)); return (results.Count + 4) * SpacingOne; } /// /// Print one combined water meter results /// /// Water meter number (1-based) /// Top coordinate of watermeter data /// The height of the printed section int PrintCombinedWM(System.Drawing.Printing.PrintPageEventArgs e, int wmNr1, int top) { IList results = Utils.GetSortedTestResults(procedure, unsortedResults, wmNr1); /// Determin column widths float[] columnPos = new float[resultItems.Count + 1]; columnPos[0] = 100.0f; for (int i = 0; i < resultItems.Count; i++) { float columnWidth = e.Graphics.MeasureString(resultItems[i].ClmnHeaderText, font).Width; foreach (var tr in results) { if (tr != null) { float width = e.Graphics.MeasureString(resultItems[i].PrintCombined(tr.Meters[2 * wmNr1 - 2], tr.Meters[2 * wmNr1 - 1], tr.CombinedMeters[wmNr1 - 1]), font).Width; if (width > columnWidth) columnWidth = width; } } columnPos[i + 1] = columnPos[i] + columnWidth + 20.0f; } int tableLeftX = (int)columnPos[0]; int tableRightX = (int)columnPos[resultItems.Count] - 20; string wmText = string.Format("Water meter {0}", wmNr1); PrintAt(e, 100, top, wmText); if (!string.IsNullOrEmpty(unsortedResults[0].Meters[2 * wmNr1 - 2].SerialNr)) { PrintAt(e, 100 + (int)e.Graphics.MeasureString(wmText, font).Width, top, string.Format(" Main s/n: {0} Aux. s/n:{1}", unsortedResults[0].Meters[2 * wmNr1 - 2].SerialNr, unsortedResults[0].Meters[2 * wmNr1 - 1].SerialNr)); } /// Horizontal line int horY = top + 25; e.Graphics.DrawLine(new Pen(Color.Black, 2), new Point(tableLeftX, horY), new Point(tableRightX, horY)); for (int i = 0; i < resultItems.Count; i++) { PrintAt(e, (int)columnPos[i], top + 27, resultItems[i].ClmnHeaderText); } /// Horizontal line horY = top + 27 + SpacingOne; e.Graphics.DrawLine(new Pen(Color.Black, 2), new Point(tableLeftX, horY), new Point(tableRightX, horY)); for (int r = 0; r < results.Count; r++) { if (results[r] != null) { for (int i = 0; i < resultItems.Count; i++) { string text = resultItems[i].PrintCombined(results[r].Meters[2 * wmNr1 - 2], results[r].Meters[2 * wmNr1 - 1], results[r].CombinedMeters[wmNr1 - 1]); string[] texts = text.Split(new char[] { '|' }); if (texts.Length == 2) { Color color = texts[1].Equals("Green") ? Color.Green : (texts[1].Equals("Red") ? Color.Red : Color.White); text = texts[0]; /// TODO: How to print colors? } PrintAt(e, (int)columnPos[i], top + 30 + SpacingOne * (r + 1), text); } } } /// Horizontal line horY = top + 30 + SpacingOne * (results.Count + 1); e.Graphics.DrawLine(new Pen(Color.Black, 2), new Point(tableLeftX, horY), new Point(tableRightX, horY)); return (results.Count + 4) * SpacingOne; } 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); } } }