// // ORIGINAL CODE BASE IS Copyright (C) 2006-2010 by Alphons van der Heijden. // The code was donated on 2010-04-28 by Alphons van der Heijden to Brandon 'Dimentox Travanti' Husbands & // Malcolm J. Kudra, who in turn License under the GPLv2 in agreement with Alphons van der Heijden's wishes. // // The community would like to thank Alphons for all of his hard work, blood sweat and tears. Without his work // the community would be stuck with crappy editors. // // The source code in this file ("Source Code") is provided by The LSLEditor Group to you under the terms of the GNU // General Public License, version 2.0 ("GPL"), unless you have obtained a separate licensing agreement ("Other // License"), formally executed by you and The LSLEditor Group. // Terms of the GPL can be found in the gplv2.txt document. // // GPLv2 Header // ************ // LSLEditor, a External editor for the LSL Language. // Copyright (C) 2010 The LSLEditor Group. // // This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public // License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any // later version. // // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with this program; if not, write to the Free // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // ******************************************************************************************************************** // The above copyright notice and this permission notice shall be included in copies or substantial portions of the // Software. // ******************************************************************************************************************** // // // // // // using System; using System.Text; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Printing; using System.Globalization; using System.Windows.Forms; namespace LSLEditor.Helpers { /// /// Data Grid View Printer. Print functions for a datagridview, since MS /// didn't see fit to do it. /// class PrinterHelper { //--------------------------------------------------------------------- // global variables //--------------------------------------------------------------------- #region global variables // the data grid view we're printing EditForm editForm = null; int intCharFrom; int intCharTo; int intCharPrint; // print document PrintDocument docToPrint = null; // print dialogue PrintDialog pd = null; // print status items int fromPage = 0; int toPage = -1; // page formatting options int pageHeight = 0; int pageWidth = 0; int printWidth = 0; int CurrentPage = 0; PrintRange printRange; // calculated values private float footerHeight = 0; private float pagenumberHeight = 0; #endregion //--------------------------------------------------------------------- // properties - settable by user //--------------------------------------------------------------------- #region properties // Title #region title properties /// /// Title for this report. Default is empty. /// private String title; public String Title { get { return title; } set { title = value; docToPrint.DocumentName = title; } } /// /// Font for the title. Default is Tahoma, 18pt. /// private Font titlefont; public Font TitleFont { get { return titlefont; } set { titlefont = value; } } /// /// Foreground color for the title. Default is Black /// private Color titlecolor; public Color TitleColor { get { return titlecolor; } set { titlecolor = value; } } /// /// Allow the user to override the title string alignment. Default value is /// Alignment - Near; /// private StringAlignment titlealignment; public StringAlignment TitleAlignment { get { return titlealignment; } set { titlealignment = value; } } /// /// Allow the user to override the title string format flags. Default values /// are: FormatFlags - NoWrap, LineLimit, NoClip /// private StringFormatFlags titleformatflags; public StringFormatFlags TitleFormatFlags { get { return titleformatflags; } set { titleformatflags = value; } } #endregion // SubTitle #region subtitle properties /// /// SubTitle for this report. Default is empty. /// private String subtitle; public String SubTitle { get { return subtitle; } set { subtitle = value; } } /// /// Font for the subtitle. Default is Tahoma, 12pt. /// private Font subtitlefont; public Font SubTitleFont { get { return subtitlefont; } set { subtitlefont = value; } } /// /// Foreground color for the subtitle. Default is Black /// private Color subtitlecolor; public Color SubTitleColor { get { return subtitlecolor; } set { subtitlecolor = value; } } /// /// Allow the user to override the subtitle string alignment. Default value is /// Alignment - Near; /// private StringAlignment subtitlealignment; public StringAlignment SubTitleAlignment { get { return subtitlealignment; } set { subtitlealignment = value; } } /// /// Allow the user to override the subtitle string format flags. Default values /// are: FormatFlags - NoWrap, LineLimit, NoClip /// private StringFormatFlags subtitleformatflags; public StringFormatFlags SubTitleFormatFlags { get { return subtitleformatflags; } set { subtitleformatflags = value; } } #endregion // Footer #region footer properties /// /// footer for this report. Default is empty. /// private String footer; public String Footer { get { return footer; } set { footer = value; } } /// /// Font for the footer. Default is Tahoma, 10pt. /// private Font footerfont; public Font FooterFont { get { return footerfont; } set { footerfont = value; } } /// /// Foreground color for the footer. Default is Black /// private Color footercolor; public Color FooterColor { get { return footercolor; } set { footercolor = value; } } /// /// Allow the user to override the footer string alignment. Default value is /// Alignment - Center; /// private StringAlignment footeralignment; public StringAlignment FooterAlignment { get { return footeralignment; } set { footeralignment = value; } } /// /// Allow the user to override the footer string format flags. Default values /// are: FormatFlags - NoWrap, LineLimit, NoClip /// private StringFormatFlags footerformatflags; public StringFormatFlags FooterFormatFlags { get { return footerformatflags; } set { footerformatflags = value; } } private float footerspacing; public float FooterSpacing { get { return footerspacing; } set { footerspacing = value; } } #endregion // Page Numbering #region page number properties /// /// Include page number in the printout. Default is true. /// private bool pageno = true; public bool PageNumbers { get { return pageno; } set { pageno = value; } } /// /// Font for the page number, Default is Tahoma, 8pt. /// private Font pagenofont; public Font PageNumberFont { get { return pagenofont; } set { pagenofont = value; } } /// /// Text color (foreground) for the page number. Default is Black /// private Color pagenocolor; public Color PageNumberColor { get { return pagenocolor; } set { pagenocolor = value; } } /// /// Allow the user to override the page number string alignment. Default value is /// Alignment - Near; /// private StringAlignment pagenumberalignment; public StringAlignment PaageNumberAlignment { get { return pagenumberalignment; } set { pagenumberalignment = value; } } /// /// Allow the user to override the pagenumber string format flags. Default values /// are: FormatFlags - NoWrap, LineLimit, NoClip /// private StringFormatFlags pagenumberformatflags; public StringFormatFlags PageNumberFormatFlags { get { return pagenumberformatflags; } set { pagenumberformatflags = value; } } /// /// Allow the user to select whether to have the page number at the top or bottom /// of the page. Default is false: page numbers on the bottom of the page /// private bool pagenumberontop = false; public bool PageNumberInHeader { get { return pagenumberontop; } set { pagenumberontop = value; } } /// /// Should the page number be printed on a separate line, or printed on the /// same line as the header / footer? Default is false; /// private bool pagenumberonseparateline = false; public bool PaageNumberOnSeparateLine { get { return pagenumberonseparateline; } set { pagenumberonseparateline = value; } } #endregion // Page Level Properties #region page level properties /// /// Page margins override. Default is (60, 60, 60, 60) /// private Margins printmargins; public Margins PrintMargins { get { return printmargins; } set { printmargins = value; } } #endregion #endregion /// /// Constructor for PrinterHelper /// public PrinterHelper(PageSetupDialog pageSetupDialog) { // create print document docToPrint = new PrintDocument(); docToPrint.PrintPage += new PrintPageEventHandler(printDoc_PrintPage); if (pageSetupDialog.PrinterSettings != null) docToPrint.PrinterSettings = pageSetupDialog.PrinterSettings; if (pageSetupDialog.PageSettings != null) docToPrint.DefaultPageSettings = pageSetupDialog.PageSettings; else docToPrint.DefaultPageSettings.Margins = new Margins(60, 80, 40, 40); printmargins = docToPrint.DefaultPageSettings.Margins; // set default fonts pagenofont = new Font("Tahoma", 10, FontStyle.Regular, GraphicsUnit.Point); pagenocolor = Color.Black; titlefont = new Font("Tahoma", 10, FontStyle.Bold, GraphicsUnit.Point); titlecolor = Color.Black; subtitlefont = new Font("Tahoma", 10, FontStyle.Regular, GraphicsUnit.Point); subtitlecolor = Color.Black; footerfont = new Font("Tahoma", 10, FontStyle.Regular, GraphicsUnit.Point); footercolor = Color.Black; // set default string formats titlealignment = StringAlignment.Near; titleformatflags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; subtitlealignment = StringAlignment.Near; subtitleformatflags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; footeralignment = StringAlignment.Near; footerformatflags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; pagenumberalignment = StringAlignment.Center; pagenumberformatflags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; } /// /// Start the printing process, print to a printer. /// /// The EditForm to print /// NOTE: Any changes to this method also need to be done in PrintPreviewEditForm public void PrintEditForm(EditForm editForm) { saveFormData(editForm); setupPrintDialogue(); // show print dialog if (pd.ShowDialog() == DialogResult.OK) { SetupPrint(pd); docToPrint.Print(); } } /// /// Start the printing process, print to a print preview dialog /// /// The EditForm to print /// NOTE: Any changes to this method also need to be done in PrintDataGridView public void PrintPreviewEditForm(EditForm editForm) { saveFormData(editForm); setupPrintDialogue(); // show print dialog if (pd.ShowDialog() == DialogResult.OK) { SetupPrint(pd); PrintPreviewDialog ppdialog = new PrintPreviewDialog(); ppdialog.Document = docToPrint; ppdialog.ShowDialog(); } } /// /// Set up the print job. Save information from print dialog /// and print document for easy access. Also sets up the rows /// and columns that will be printed. /// /// The print dialog the user just filled out void SetupPrint(PrintDialog pd) { //----------------------------------------------------------------- // save data from print dialog and document //----------------------------------------------------------------- // check to see if we're doing landscape printing if (docToPrint.DefaultPageSettings.Landscape) { // landscape: switch width and height pageHeight = docToPrint.DefaultPageSettings.PaperSize.Width; pageWidth = docToPrint.DefaultPageSettings.PaperSize.Height; } else { // portrait: keep width and height as expected pageHeight = docToPrint.DefaultPageSettings.PaperSize.Height; pageWidth = docToPrint.DefaultPageSettings.PaperSize.Width; } // save printer margins and calc print width printmargins = docToPrint.DefaultPageSettings.Margins; printWidth = pageWidth - printmargins.Left - printmargins.Right; // save print range printRange = pd.PrinterSettings.PrintRange; // pages to print handles "some pages" option if (PrintRange.SomePages == printRange) { // set limits to only print some pages fromPage = pd.PrinterSettings.FromPage; toPage = pd.PrinterSettings.ToPage; } else { // set extremes so that we'll print all pages fromPage = 0; toPage = 2147483647; } //----------------------------------------------------------------- // set up the pages to print //----------------------------------------------------------------- // pages (handles "selection" and "current page" options if (PrintRange.Selection == printRange) { intCharPrint = this.editForm.TextBox.SelectionStart; intCharFrom = intCharPrint; intCharTo = intCharFrom + this.editForm.TextBox.SelectionLength; } else if (PrintRange.CurrentPage == printRange) { } // this is the default for print all else { intCharPrint = 0; intCharFrom = intCharPrint; intCharTo = this.editForm.TextBox.Text.Length; } } /// /// Centralize the string format settings. Does the work of checking for user /// overrides, and if they're not present, setting the cell alignment to match /// (somewhat) the source control's string alignment. /// /// String alignment /// String format flags /// DataGridView style to apply (if available) /// True if user overrode alignment or flags /// private static StringFormat managestringformat(StringAlignment alignment, StringFormatFlags flags) { // start with the provided StringFormat format = new StringFormat(); format.Trimming = StringTrimming.Word; format.Alignment = alignment; format.FormatFlags = flags; return format; } /// /// PrintPage event handler. This routine prints one page. It will /// skip non-printable pages if the user selected the "some pages" option /// on the print dialog. /// /// default object from windows /// Event info from Windows about the printing private void printDoc_PrintPage(object sender, PrintPageEventArgs e) { // adjust printing region, make space for headers and footers Rectangle rect = new Rectangle( e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height - e.MarginBounds.Top - e.MarginBounds.Top); PrintPageEventArgs ee = new PrintPageEventArgs(e.Graphics, rect, e.PageBounds, e.PageSettings); // Print the content of RichTextBox. Store the last character printed. intCharFrom = editForm.TextBox.Print(intCharFrom, intCharTo, ee); // increment page number & check page range CurrentPage++; //----------------------------------------------------------------- // print headers //----------------------------------------------------------------- // reset printpos as it may have changed during the 'skip pages' routine just above. float printpos = printmargins.Top; // print page number if user selected it if (pagenumberontop) { // if we have a page number to print if (pageno) { // ... then print it printsection(e.Graphics, ref printpos, "Page " + CurrentPage.ToString(CultureInfo.CurrentCulture), pagenofont, pagenocolor, pagenumberalignment, pagenumberformatflags); // if the page number is not on a separate line, don't "use up" it's vertical space if (!pagenumberonseparateline) printpos -= pagenumberHeight; } } // print title if provided if (!String.IsNullOrEmpty(title)) printsection(e.Graphics, ref printpos, title, titlefont, titlecolor, titlealignment, titleformatflags); // print subtitle if provided if (!String.IsNullOrEmpty(subtitle)) printsection(e.Graphics, ref printpos, subtitle, subtitlefont, subtitlecolor, subtitlealignment, subtitleformatflags); //----------------------------------------------------------------- // print footer //----------------------------------------------------------------- printfooter(e.Graphics, ref printpos); // Check for more pages if (intCharFrom < intCharTo) e.HasMorePages = true; else { intCharFrom = intCharPrint; // reset CurrentPage = 0; e.HasMorePages = false; } } /// /// Print a header or footer section. Used for page numbers and titles /// /// Graphic context to print in /// Track vertical space used; 'y' location /// String to print /// Font to use for printing /// Color to print in /// Alignment - print to left, center or right /// String format flags /// True if the user overrode the alignment or flags private void printsection(Graphics g, ref float pos, string text, Font font, Color color, StringAlignment alignment, StringFormatFlags flags) { // string formatting setup StringFormat printformat = managestringformat(alignment, flags); // measure string SizeF printsize = g.MeasureString(text, font, printWidth, printformat); // build area to print within RectangleF printarea = new RectangleF((float)printmargins.Left, pos, (float)printWidth, printsize.Height); // do the actual print g.DrawString(text, font, new SolidBrush(color), printarea, printformat); // track "used" vertical space pos += printsize.Height; } /// /// Print the footer. This handles the footer spacing, and printing the page number /// at the bottom of the page (if the page number is not in the header). /// /// Graphic context to print in /// Track vertical space used; 'y' location private void printfooter(Graphics g, ref float pos) { // print last footer. Note: need to force printpos to the bottom of the page // as we may have run out of data anywhere on the page pos = pageHeight - footerHeight - printmargins.Top - printmargins.Bottom; // add spacing pos += footerspacing; // print the footer printsection(g, ref pos, footer, footerfont, footercolor, footeralignment, footerformatflags); // print the page number if it's on the bottom. if (!pagenumberontop) { if (pageno) { pagenumberHeight = g.MeasureString("M", pagenofont).Height; // if the pageno is not on a separate line, push the print location up by its height. if (!pagenumberonseparateline) pos = pos - pagenumberHeight; // print the page number printsection(g, ref pos, "Page " + CurrentPage.ToString(CultureInfo.CurrentCulture), pagenofont, pagenocolor, pagenumberalignment, pagenumberformatflags); } } } private void saveFormData(EditForm editForm) { // save the datagridview we're printing this.editForm = editForm; this.intCharFrom = 0; this.intCharPrint = 0; this.intCharTo = editForm.TextBox.Text.Length; } private void setupPrintDialogue() { // create new print dialog pd = new PrintDialog(); pd.Document = docToPrint; pd.AllowSelection = true; pd.AllowSomePages = false; pd.AllowCurrentPage = false; pd.AllowPrintToFile = false; pd.UseEXDialog = true; } } }