Mercurial > projects > dwt-linux
changeset 91:b58ec55ce70d
package printing
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 17 Jan 2008 15:44:59 +0100 |
parents | 9ba02d7fb226 |
children | ddb19cb18d2e |
files | dwt/internal/c/atk.d dwt/internal/c/cairo.d dwt/internal/c/cairo_pdf.d dwt/internal/c/cairo_ps.d dwt/internal/cairo/Cairo.d dwt/internal/gtk/OS.d dwt/printing/PrintDialog.d dwt/printing/Printer.d dwt/printing/PrinterData.d |
diffstat | 9 files changed, 1368 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/dwt/internal/c/atk.d Thu Jan 17 09:03:45 2008 +0100 +++ b/dwt/internal/c/atk.d Thu Jan 17 15:44:59 2008 +0100 @@ -1,6 +1,6 @@ /****************************************************************************** Based on the generated files from the BCD tool - modified by: Frank Benoit <keinfarbton@googlemail.com> + modified by: Frank Benoit <benoit@tionex.de> ******************************************************************************/ module dwt.internal.c.atk;
--- a/dwt/internal/c/cairo.d Thu Jan 17 09:03:45 2008 +0100 +++ b/dwt/internal/c/cairo.d Thu Jan 17 15:44:59 2008 +0100 @@ -1,6 +1,6 @@ /****************************************************************************** Based on the generated files from the BCD tool - modified by: Frank Benoit <keinfarbton@googlemail.com> + modified by: Frank Benoit <benoit@tionex.de> ******************************************************************************/ module dwt.internal.c.cairo;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/internal/c/cairo_pdf.d Thu Jan 17 15:44:59 2008 +0100 @@ -0,0 +1,30 @@ +/****************************************************************************** + Based on the generated files from the BCD tool + modified by: Frank Benoit <benoit@tionex.de> +******************************************************************************/ +module dwt.internal.c.cairo_pdf; +public import dwt.internal.c.glib_object; +public import dwt.internal.c.cairo; + +align(4): + +alias int function(void *, char *, uint) _BCD_func__480; +alias int function(void *, char *, uint) _BCD_func__479; +alias void function(void *) _BCD_func__484; +version(DYNLINK){ +extern (C) void function(void *, double, double)cairo_pdf_surface_set_size; +extern (C) void * function(_BCD_func__480, void *, double, double)cairo_pdf_surface_create_for_stream; +extern (C) void * function(char *, double, double)cairo_pdf_surface_create; + + +Symbol[] symbols = [ + { "cairo_pdf_surface_set_size", cast(void**)& cairo_pdf_surface_set_size}, + { "cairo_pdf_surface_create_for_stream", cast(void**)& cairo_pdf_surface_create_for_stream}, + { "cairo_pdf_surface_create", cast(void**)& cairo_pdf_surface_create}, +]; + +} else { // version(DYNLINK) +extern (C) void cairo_pdf_surface_set_size(void *, double, double); +extern (C) void * cairo_pdf_surface_create_for_stream(_BCD_func__480, void *, double, double); +extern (C) void * cairo_pdf_surface_create(char *, double, double); +} // version(DYNLINK)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/internal/c/cairo_ps.d Thu Jan 17 15:44:59 2008 +0100 @@ -0,0 +1,51 @@ +/****************************************************************************** + Based on the generated files from the BCD tool + modified by: Frank Benoit <benoit@tionex.de> +******************************************************************************/ +module dwt.internal.c.cairo_ps; +public import dwt.internal.c.glib_object; +public import dwt.internal.c.cairo; + +align(4): + +alias int function(void *, char *, uint) _BCD_func__879; +alias int function(void *) _BCD_func__133; +alias int function(void *, long *, int) _BCD_func__135; +alias int function(void *, char *, uint) _BCD_func__137; +alias int function(void *, char *, uint) _BCD_func__139; +alias void function(void *) _BCD_func__734; +alias int function(void * *, char *) _BCD_func__735; +alias int function(char *, char * * *, uint *) _BCD_func__736; +alias int function(void *, char *, char *, char *, char *) _BCD_func__737; +alias int function(__gconv_step *, __gconv_step_data *, void *, char *, char * *, char *, char * *, uint *) _BCD_func__738; +alias void function(__gconv_step *) _BCD_func__739; +alias int function(__gconv_step *) _BCD_func__740; +alias uint function(__gconv_step *, char) _BCD_func__741; +alias int function(__gconv_step *, __gconv_step_data *, char * *, char *, char * *, uint *, int, int) _BCD_func__742; +alias int function(void *, char *, uint) _BCD_func__878; +version(DYNLINK){ +extern (C) void function(void *)cairo_ps_surface_dsc_begin_page_setup; +extern (C) void function(void *)cairo_ps_surface_dsc_begin_setup; +extern (C) void function(void *, char *)cairo_ps_surface_dsc_comment; +extern (C) void function(void *, double, double)cairo_ps_surface_set_size; +extern (C) void * function(_BCD_func__879, void *, double, double)cairo_ps_surface_create_for_stream; +extern (C) void * function(char *, double, double)cairo_ps_surface_create; + + +Symbol[] symbols = [ + { "cairo_ps_surface_dsc_begin_page_setup", cast(void**)& cairo_ps_surface_dsc_begin_page_setup}, + { "cairo_ps_surface_dsc_begin_setup", cast(void**)& cairo_ps_surface_dsc_begin_setup}, + { "cairo_ps_surface_dsc_comment", cast(void**)& cairo_ps_surface_dsc_comment}, + { "cairo_ps_surface_set_size", cast(void**)& cairo_ps_surface_set_size}, + { "cairo_ps_surface_create_for_stream", cast(void**)& cairo_ps_surface_create_for_stream}, + { "cairo_ps_surface_create", cast(void**)& cairo_ps_surface_create}, +]; + +} else { // version(DYNLINK) +extern (C) void cairo_ps_surface_dsc_begin_page_setup(void *); +extern (C) void cairo_ps_surface_dsc_begin_setup(void *); +extern (C) void cairo_ps_surface_dsc_comment(void *, char *); +extern (C) void cairo_ps_surface_set_size(void *, double, double); +extern (C) void * cairo_ps_surface_create_for_stream(_BCD_func__879, void *, double, double); +extern (C) void * cairo_ps_surface_create(char *, double, double); +} // version(DYNLINK)
--- a/dwt/internal/cairo/Cairo.d Thu Jan 17 09:03:45 2008 +0100 +++ b/dwt/internal/cairo/Cairo.d Thu Jan 17 15:44:59 2008 +0100 @@ -1,4 +1,4 @@ -/* ***** BEGIN LICENSE BLOCK ***** +/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version @@ -22,6 +22,8 @@ import dwt.internal.c.cairo; import dwt.internal.c.cairo_xlib; +import dwt.internal.c.cairo_ps; +import dwt.internal.c.cairo_pdf; import dwt.internal.c.Xlib; import dwt.internal.Platform; @@ -221,8 +223,8 @@ mixin ForwardGtkCairoCFunc!(.cairo_pattern_set_extend); mixin ForwardGtkCairoCFunc!(.cairo_pattern_set_filter); mixin ForwardGtkCairoCFunc!(.cairo_pattern_set_matrix); - //mixin ForwardGtkCairoCFunc!(.cairo_pdf_surface_set_size); - //mixin ForwardGtkCairoCFunc!(.cairo_ps_surface_set_size); + mixin ForwardGtkCairoCFunc!(.cairo_pdf_surface_set_size); + mixin ForwardGtkCairoCFunc!(.cairo_ps_surface_set_size); mixin ForwardGtkCairoCFunc!(.cairo_rectangle); mixin ForwardGtkCairoCFunc!(.cairo_reference); mixin ForwardGtkCairoCFunc!(.cairo_rel_curve_to);
--- a/dwt/internal/gtk/OS.d Thu Jan 17 09:03:45 2008 +0100 +++ b/dwt/internal/gtk/OS.d Thu Jan 17 15:44:59 2008 +0100 @@ -493,6 +493,11 @@ public alias dwt.internal.c.gtk.GtkAllocation GtkAllocation; +public alias dwt.internal.c.gtk_unix_print_2_0.GtkPrinter GtkPrinter; +public alias dwt.internal.c.gtk_unix_print_2_0.GtkPrintUnixDialog GtkPrintUnixDialog; +public alias dwt.internal.c.gtk_unix_print_2_0.GtkPrintJob GtkPrintJob; +public alias dwt.internal.c.gtk_unix_print_2_0.GtkPrintSettings GtkPrintSettings; +public alias dwt.internal.c.gtk_unix_print_2_0.GtkPaperSize GtkPaperSize; public alias dwt.internal.c.Xlib.XErrorEvent XErrorEvent; public alias dwt.internal.c.Xlib.XExposeEvent XExposeEvent;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/printing/PrintDialog.d Thu Jan 17 15:44:59 2008 +0100 @@ -0,0 +1,381 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.printing.PrintDialog; + + + +import dwt.DWT; +import dwt.DWTException; +import dwt.internal.gtk.OS; +import dwt.widgets.Dialog; +import dwt.widgets.Display; +import dwt.widgets.Shell; +import dwt.widgets.Widget; +import dwt.printing.Printer; +import dwt.printing.PrinterData; + +import tango.util.Convert; +import Math = tango.math.Math; +static import tango.stdc.stringz; + +/** + * Instances of this class allow the user to select + * a printer and various print-related parameters + * prior to starting a print job. + * <p> + * IMPORTANT: This class is intended to be subclassed <em>only</em> + * within the DWT implementation. + * </p> + */ +public class PrintDialog : Dialog { + int scope_ = PrinterData.ALL_PAGES; + int startPage = 1, endPage = 1; + bool printToFile = false; + + GtkPrintUnixDialog* handle; + int index; + char [] settingsData; + + static const char[] ADD_IDLE_PROC_KEY = "org.eclipse.swt.internal.gtk2.addIdleProc"; + static const char[] REMOVE_IDLE_PROC_KEY = "org.eclipse.swt.internal.gtk2.removeIdleProc"; + +/** + * Constructs a new instance of this class given only its parent. + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + * + * @see DWT + * @see Widget#checkSubclass + * @see Widget#getStyle + */ +public this (Shell parent) { + this (parent, DWT.PRIMARY_MODAL); +} + +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * <p> + * The style value is either one of the style constants defined in + * class <code>DWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>DWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + * + * @see DWT + * @see Widget#checkSubclass + * @see Widget#getStyle + */ +public this (Shell parent, int style) { + super (parent, style); + checkSubclass (); +} + +protected void checkSubclass() { +} + +/** + * Returns the print job scope that the user selected + * before pressing OK in the dialog. This will be one + * of the following values: + * <dl> + * <dt><code>ALL_PAGES</code></dt> + * <dd>Print all pages in the current document</dd> + * <dt><code>PAGE_RANGE</code></dt> + * <dd>Print the range of pages specified by startPage and endPage</dd> + * <dt><code>SELECTION</code></dt> + * <dd>Print the current selection</dd> + * </dl> + * + * @return the scope setting that the user selected + */ +public int getScope() { + return scope_; +} + +/** + * Sets the scope of the print job. The user will see this + * setting when the dialog is opened. This can have one of + * the following values: + * <dl> + * <dt><code>ALL_PAGES</code></dt> + * <dd>Print all pages in the current document</dd> + * <dt><code>PAGE_RANGE</code></dt> + * <dd>Print the range of pages specified by startPage and endPage</dd> + * <dt><code>SELECTION</code></dt> + * <dd>Print the current selection</dd> + * </dl> + * + * @param scope the scope setting when the dialog is opened + */ +public void setScope(int scope_) { + this.scope_ = scope_; +} + +/** + * Returns the start page setting that the user selected + * before pressing OK in the dialog. + * <p> + * This value can be from 1 to the maximum number of pages for the platform. + * Note that it is only valid if the scope is <code>PAGE_RANGE</code>. + * </p> + * + * @return the start page setting that the user selected + */ +public int getStartPage() { + return startPage; +} + +/** + * Sets the start page that the user will see when the dialog + * is opened. + * <p> + * This value can be from 1 to the maximum number of pages for the platform. + * Note that it is only valid if the scope is <code>PAGE_RANGE</code>. + * </p> + * + * @param startPage the startPage setting when the dialog is opened + */ +public void setStartPage(int startPage) { + this.startPage = startPage; +} + +/** + * Returns the end page setting that the user selected + * before pressing OK in the dialog. + * <p> + * This value can be from 1 to the maximum number of pages for the platform. + * Note that it is only valid if the scope is <code>PAGE_RANGE</code>. + * </p> + * + * @return the end page setting that the user selected + */ +public int getEndPage() { + return endPage; +} + +/** + * Sets the end page that the user will see when the dialog + * is opened. + * <p> + * This value can be from 1 to the maximum number of pages for the platform. + * Note that it is only valid if the scope is <code>PAGE_RANGE</code>. + * </p> + * + * @param endPage the end page setting when the dialog is opened + */ +public void setEndPage(int endPage) { + this.endPage = endPage; +} + +/** + * Returns the 'Print to file' setting that the user selected + * before pressing OK in the dialog. + * + * @return the 'Print to file' setting that the user selected + */ +public bool getPrintToFile() { + return printToFile; +} + +/** + * Sets the 'Print to file' setting that the user will see + * when the dialog is opened. + * + * @param printToFile the 'Print to file' setting when the dialog is opened + */ +public void setPrintToFile(bool printToFile) { + this.printToFile = printToFile; +} + +/** + * Makes the receiver visible and brings it to the front + * of the display. + * + * @return a printer data object describing the desired print job parameters + * + * @exception DWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public PrinterData open() { + if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) { + return Printer.getDefaultPrinterData(); + } else { + char* titleBytes = tango.stdc.stringz.toStringz( getText() ); + auto topHandle = getParent().handle; + while (topHandle !is null && !OS.GTK_IS_WINDOW(topHandle)) { + topHandle = OS.gtk_widget_get_parent(topHandle); + } + handle = cast(GtkPrintUnixDialog*)OS.gtk_print_unix_dialog_new(titleBytes, cast(GtkWindow*)topHandle); + + //TODO: Not currently implemented. May need new API. For now, disable 'Current' in the dialog. (see gtk bug 344519) + OS.gtk_print_unix_dialog_set_current_page(handle, -1); + + OS.gtk_print_unix_dialog_set_manual_capabilities(handle, + OS.GTK_PRINT_CAPABILITY_COLLATE | OS.GTK_PRINT_CAPABILITY_COPIES | OS.GTK_PRINT_CAPABILITY_PAGE_SET); + + /* Set state into print dialog settings. */ + auto settings = OS.gtk_print_settings_new(); + auto page_setup = OS.gtk_page_setup_new(); + Printer.setScope(settings, scope_, startPage, endPage); + if (printToFile) { + char* buffer = tango.stdc.stringz.toStringz( "Print to File" ); //$NON-NLS-1$ + OS.gtk_print_settings_set_printer(settings, buffer); + } + OS.gtk_print_unix_dialog_set_settings(handle, settings); + OS.gtk_print_unix_dialog_set_page_setup(handle, page_setup); + OS.g_object_unref(settings); + OS.g_object_unref(page_setup); + + PrinterData data = null; + //TODO: Handle 'Print Preview' (GTK_RESPONSE_APPLY). + Display display = getParent() !is null ? getParent().getDisplay (): Display.getCurrent (); + display.setData (ADD_IDLE_PROC_KEY, null); + if (OS.gtk_dialog_run (handle) is OS.GTK_RESPONSE_OK) { + auto printer = OS.gtk_print_unix_dialog_get_selected_printer(handle); + if (printer !is null) { + /* Get state from print dialog. */ + settings = OS.gtk_print_unix_dialog_get_settings(handle); // must unref + page_setup = OS.gtk_print_unix_dialog_get_page_setup(handle); // do not unref + data = Printer.printerDataFromGtkPrinter(printer); + int print_pages = OS.gtk_print_settings_get_print_pages(settings); + switch (print_pages) { + case OS.GTK_PRINT_PAGES_ALL: + scope_ = PrinterData.ALL_PAGES; + break; + case OS.GTK_PRINT_PAGES_RANGES: + scope_ = PrinterData.PAGE_RANGE; + int num_ranges; + auto page_ranges = OS.gtk_print_settings_get_page_ranges(settings, &num_ranges); + int length = num_ranges; + int min = int.max, max = 0; + for (int i = 0; i < length; i++) { + min = Math.min(min, page_ranges[i].start + 1); + max = Math.max(max, page_ranges[i].end + 1); + } + OS.g_free(page_ranges); + startPage = min is int.max ? 1 : min; + endPage = max is 0 ? 1 : max; + break; + case OS.GTK_PRINT_PAGES_CURRENT: + //TODO: Disabled in dialog (see above). This code will not run. (see gtk bug 344519) + scope_ = PrinterData.SELECTION; + startPage = endPage = OS.gtk_print_unix_dialog_get_current_page(handle); + break; + } + + printToFile = ( data.name ==/*eq*/ "Print to File" ); //$NON-NLS-1$ + if (printToFile) { + auto address = OS.gtk_print_settings_get(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI.ptr); + data.fileName = tango.stdc.stringz.fromUtf8z( address).dup; + } + + data.scope_ = scope_; + data.startPage = startPage; + data.endPage = endPage; + data.printToFile = printToFile; + data.copyCount = OS.gtk_print_settings_get_n_copies(settings); + data.collate = cast(bool)OS.gtk_print_settings_get_collate(settings); + + /* Save other print_settings data as key/value pairs in otherData. */ + index = 0; + settingsData = new char[1024]; + settingsData[] = '\0'; + OS.gtk_print_settings_foreach (settings, &GtkPrintSettingsFunc, cast(void*)this ); + index++; // extra null terminator after print_settings and before page_setup + + /* Save page_setup data as key/value pairs in otherData. + * Note that page_setup properties must be stored and restored in the same order. + */ + store("orientation", OS.gtk_page_setup_get_orientation(page_setup)); //$NON-NLS-1$ + store("top_margin", OS.gtk_page_setup_get_top_margin(page_setup, OS.GTK_UNIT_MM)); //$NON-NLS-1$ + store("bottom_margin", OS.gtk_page_setup_get_bottom_margin(page_setup, OS.GTK_UNIT_MM)); //$NON-NLS-1$ + store("left_margin", OS.gtk_page_setup_get_left_margin(page_setup, OS.GTK_UNIT_MM)); //$NON-NLS-1$ + store("right_margin", OS.gtk_page_setup_get_right_margin(page_setup, OS.GTK_UNIT_MM)); //$NON-NLS-1$ + auto paper_size = OS.gtk_page_setup_get_paper_size(page_setup); //$NON-NLS-1$ + storeBytes("paper_size_name", OS.gtk_paper_size_get_name(paper_size)); //$NON-NLS-1$ + storeBytes("paper_size_display_name", OS.gtk_paper_size_get_display_name(paper_size)); //$NON-NLS-1$ + storeBytes("paper_size_ppd_name", OS.gtk_paper_size_get_ppd_name(paper_size)); //$NON-NLS-1$ + store("paper_size_width", OS.gtk_paper_size_get_width(paper_size, OS.GTK_UNIT_MM)); //$NON-NLS-1$ + store("paper_size_height", OS.gtk_paper_size_get_height(paper_size, OS.GTK_UNIT_MM)); //$NON-NLS-1$ + store("paper_size_is_custom", OS.gtk_paper_size_is_custom(paper_size)); //$NON-NLS-1$ + data.otherData = settingsData; + OS.g_object_unref(settings); + } + } + display.setData (REMOVE_IDLE_PROC_KEY, null); + OS.gtk_widget_destroy (handle); + return data; + } +} + +private static extern(C) void GtkPrintSettingsFunc (char* key, char* value, void* data) { + (cast(PrintDialog)data).GtkPrintSettingsMeth(key, value ); +} + +void GtkPrintSettingsMeth (char* key, char* value) { + store( tango.stdc.stringz.fromUtf8z(key).dup, tango.stdc.stringz.fromUtf8z(value).dup ); +} + +void store(char[] key, int value) { + store(key, to!(char[])(value)); +} + +void store(char[] key, double value) { + store(key, to!(char[])(value)); +} + +void store(char[] key, bool value) { + store(key, to!(char[])(value)); +} + +void storeBytes(char[] key, char* value) { + store(key, tango.stdc.stringz.fromUtf8z(value).dup ); +} + +void store(char [] key, char[] value) { + int length = key.length + 1 + value.length + 1; + if (index + length + 1 > settingsData.length) { + char [] newData = new char[settingsData.length + Math.max(length + 1, 1024)]; + newData[] = '\0'; + System.arraycopy (settingsData, 0, newData, 0, settingsData.length); + settingsData = newData; + } + System.arraycopy (key, 0, settingsData, index, key.length); + index += key.length + 1; // null terminated + System.arraycopy (value, 0, settingsData, index, value.length); + index += value.length + 1; // null terminated +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/printing/Printer.d Thu Jan 17 15:44:59 2008 +0100 @@ -0,0 +1,726 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.printing.Printer; + + + +import dwt.DWT; +import dwt.DWTError; +import dwt.DWTException; +import dwt.graphics.Device; +import dwt.graphics.DeviceData; +import dwt.graphics.Font; +import dwt.graphics.GCData; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.internal.cairo.Cairo; +import dwt.internal.gtk.OS; +import dwt.printing.PrinterData; + +static import tango.stdc.stringz; +static import tango.io.Stdout; +import tango.util.Convert; + + +/** + * Instances of this class are used to print to a printer. + * Applications create a GC on a printer using <code>new GC(printer)</code> + * and then draw on the printer GC using the usual graphics calls. + * <p> + * A <code>Printer</code> object may be constructed by providing + * a <code>PrinterData</code> object which identifies the printer. + * A <code>PrintDialog</code> presents a print dialog to the user + * and returns an initialized instance of <code>PrinterData</code>. + * Alternatively, calling <code>new Printer()</code> will construct a + * printer object for the user's default printer. + * </p><p> + * Application code must explicitly invoke the <code>Printer.dispose()</code> + * method to release the operating system resources managed by each instance + * when those instances are no longer required. + * </p> + * + * @see PrinterData + * @see PrintDialog + */ +public final class Printer : Device { + static PrinterData [] printerList; + + PrinterData data; + GtkPrinter* printer; + GtkPrintJob* printJob; + GtkPrintSettings* settings; + void* pageSetup; + cairo_surface_t* surface; + cairo_t* cairo; + + /** + * whether or not a GC was created for this printer + */ + bool isGCCreated = false; + Font systemFont; + + char[] settingsData; + int start, end; + + static const char[] GTK_LPR_BACKEND = "GtkPrintBackendLpr"; //$NON-NLS-1$ + +/** + * Returns an array of <code>PrinterData</code> objects + * representing all available printers. + * + * @return the list of available printers + */ +public static PrinterData[] getPrinterList() { + printerList = new PrinterData [0]; + if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) { + return printerList; + } + OS.gtk_enumerate_printers(&GtkPrinterFunc_List, null, null, true); + return printerList; +} + +private static extern(C) int GtkPrinterFunc_List (GtkPrinter* printer, void* user_data) { + int length_ = printerList.length; + PrinterData [] newList = new PrinterData [length_ + 1]; + System.arraycopy (printerList, 0, newList, 0, length_); + printerList = newList; + printerList [length_] = printerDataFromGtkPrinter(printer); + /* + * Bug in GTK. While performing a gtk_enumerate_printers(), GTK finds all of the + * available printers from each backend and can hang. If a backend requires more + * time to gather printer info, GTK will start an event loop waiting for a done + * signal before continuing. For the Lpr backend, GTK does not send a done signal + * which means the event loop never ends. The fix is to check to see if the driver + * is of type Lpr, and stop the enumeration, which exits the event loop. + */ + if (printerList[length_].driver ==/*eq*/ GTK_LPR_BACKEND) return 1; + return 0; +} + +/** + * Returns a <code>PrinterData</code> object representing + * the default printer or <code>null</code> if there is no + * printer available on the System. + * + * @return the default printer data or null + * + * @since 2.1 + */ +public static PrinterData getDefaultPrinterData() { + printerList = new PrinterData [1]; + if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) { + return null; + } + OS.gtk_enumerate_printers(&GtkPrinterFunc_Default, null, null, true); + return printerList[0]; +} + +private static extern(C) int GtkPrinterFunc_Default (GtkPrinter* printer, void* user_data) { + if (OS.gtk_printer_is_default(printer)) { + printerList[0] = printerDataFromGtkPrinter(printer); + return 1; + } + return 0; +} + +GtkPrinter* gtkPrinterFromPrinterData() { + printer = null; + OS.gtk_enumerate_printers(&GtkPrinterFunc_FindNamedPrinterFunc, cast(void*)this, null, true); + return printer; +} + +private static extern(C) int GtkPrinterFunc_FindNamedPrinterFunc (GtkPrinter* printer, void* user_data) { + return (cast(Printer)user_data).GtkPrinterFunc_FindNamedPrinter( printer, null ); +} +int GtkPrinterFunc_FindNamedPrinter (GtkPrinter* printer, void* user_data) { + PrinterData pd = printerDataFromGtkPrinter(printer); + if (pd.driver ==/*eq*/data.driver && pd.name ==/*eq*/ data.name ) { + this.printer = printer; + OS.g_object_ref(printer); + return 1; + } + return 0; +} + +static PrinterData printerDataFromGtkPrinter(GtkPrinter* printer) { + auto backend = OS.gtk_printer_get_backend(printer); + auto address = OS.G_OBJECT_TYPE_NAME(backend); + char[] backendType =tango.stdc.stringz.fromUtf8z( address ).dup; + + address = OS.gtk_printer_get_name (printer); + char[] name =tango.stdc.stringz.fromUtf8z( address ).dup; + + return new PrinterData (backendType, name); +} + +static void setScope(GtkPrintSettings* settings, int scope_, int startPage, int endPage) { + switch (scope_) { + case PrinterData.ALL_PAGES: + OS.gtk_print_settings_set_print_pages(settings, OS.GTK_PRINT_PAGES_ALL); + break; + case PrinterData.PAGE_RANGE: + OS.gtk_print_settings_set_print_pages(settings, OS.GTK_PRINT_PAGES_RANGES); + GtkPageRange pageRange; + pageRange.start = startPage - 1; + pageRange.end = endPage - 1; + OS.gtk_print_settings_set_page_ranges(settings, &pageRange, 1); + break; + case PrinterData.SELECTION: + //TODO: Not correctly implemented. May need new API. For now, set to ALL. (see gtk bug 344519) + OS.gtk_print_settings_set_print_pages(settings, OS.GTK_PRINT_PAGES_ALL); + break; + default: + } +} + +static DeviceData checkNull (PrinterData data) { + if (data is null) data = new PrinterData(); + if (data.driver is null || data.name is null) { + PrinterData defaultPrinter = getDefaultPrinterData(); + if (defaultPrinter is null) DWT.error(DWT.ERROR_NO_HANDLES); + data.driver = defaultPrinter.driver; + data.name = defaultPrinter.name; + } + return data; +} + +/** + * Constructs a new printer representing the default printer. + * <p> + * You must dispose the printer when it is no longer required. + * </p> + * + * @exception DWTError <ul> + * <li>ERROR_NO_HANDLES - if there are no valid printers + * </ul> + * + * @see Device#dispose + */ +public this() { + this(null); +} + +/** + * Constructs a new printer given a <code>PrinterData</code> + * object representing the desired printer. + * <p> + * You must dispose the printer when it is no longer required. + * </p> + * + * @param data the printer data for the specified printer + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the specified printer data does not represent a valid printer + * </ul> + * @exception DWTError <ul> + * <li>ERROR_NO_HANDLES - if there are no valid printers + * </ul> + * + * @see Device#dispose + */ +public this(PrinterData data) { + super(checkNull(data)); +} + +int restoreInt(char[] key) { + char [] value = restoreBytes(key, false); + return to!(int)( value ); +} + +double restoreDouble(char[] key) { + char [] value = restoreBytes(key, false); + return to!(double)( value ); +} + +bool restoreBoolean(char[] key) { + char [] value = restoreBytes(key, false); + return to!(bool)( value ); +} + +char[] restoreBytes(char[] key, bool nullTerminate) { + //get key + start = end; + while (end < settingsData.length && settingsData[end] !is 0) end++; + end++; + char [] keyBuffer = new char [end - start]; + System.arraycopy (settingsData, start, keyBuffer, 0, keyBuffer.length); + + //get value + start = end; + while (end < settingsData.length && settingsData[end] !is 0) end++; + int length_ = end - start; + end++; + if (nullTerminate) length_++; + char [] valueBuffer = new char [length_]; + System.arraycopy (settingsData, start, valueBuffer, 0, length_); + + if (DEBUG) tango.io.Stdout.Stdout.formatln( "{}: {}", keyBuffer, valueBuffer ); + + return valueBuffer; +} + +/** + * Returns a reasonable font for applications to use. + * On some platforms, this will match the "default font" + * or "system font" if such can be found. This font + * should not be free'd because it was allocated by the + * system, not the application. + * <p> + * Typically, applications which want the default look + * should simply not set the font on the widgets they + * create. Widgets are always created with the correct + * default font for the class of user-interface component + * they represent. + * </p> + * + * @return a font + * + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + */ +public Font getSystemFont () { + checkDevice (); + if (systemFont !is null) return systemFont; + auto style = OS.gtk_widget_get_default_style(); + auto defaultFont = OS.pango_font_description_copy (OS.gtk_style_get_font_desc (style)); + return systemFont = Font.gtk_new (this, defaultFont); +} + +/** + * Invokes platform specific functionality to allocate a new GC handle. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the public + * API for <code>Printer</code>. It is marked public only so that it + * can be shared within the packages provided by DWT. It is not + * available on all platforms, and should never be called from + * application code. + * </p> + * + * @param data the platform specific GC data + * @return the platform specific GC handle + */ +public GdkGC* internal_new_GC(GCData data) { + auto drawable = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), 1, 1, 1); + auto gdkGC = OS.gdk_gc_new (drawable); + if (gdkGC is null) DWT.error (DWT.ERROR_NO_HANDLES); + if (data !is null) { + if (isGCCreated) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; + if ((data.style & mask) is 0) { + data.style |= DWT.LEFT_TO_RIGHT; + } + data.device = this; + data.drawable = drawable; + data.background = getSystemColor (DWT.COLOR_WHITE).handle; + data.foreground = getSystemColor (DWT.COLOR_BLACK).handle; + data.font = getSystemFont ().handle; + if (cairo is null) DWT.error(DWT.ERROR_NO_HANDLES); + data.cairo = cairo; + isGCCreated = true; + } + return gdkGC; +} + +/** + * Invokes platform specific functionality to dispose a GC handle. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the public + * API for <code>Printer</code>. It is marked public only so that it + * can be shared within the packages provided by DWT. It is not + * available on all platforms, and should never be called from + * application code. + * </p> + * + * @param hDC the platform specific GC handle + * @param data the platform specific GC data + */ +public void internal_dispose_GC(GdkGC* gdkGC, GCData data) { + if (data !is null) isGCCreated = false; + OS.g_object_unref (gdkGC); + if (data !is null) { + if (data.drawable !is null) OS.g_object_unref (data.drawable); + data.drawable = null; + data.cairo = null; + } +} + +/** + * Releases any internal state prior to destroying this printer. + * This method is called internally by the dispose + * mechanism of the <code>Device</code> class. + */ +protected void release () { + super.release(); + + /* Dispose the default font */ + if (systemFont !is null) systemFont.dispose (); + systemFont = null; +} + +/** + * Starts a print job and returns true if the job started successfully + * and false otherwise. + * <p> + * This must be the first method called to initiate a print job, + * followed by any number of startPage/endPage calls, followed by + * endJob. Calling startPage, endPage, or endJob before startJob + * will result in undefined behavior. + * </p> + * + * @param jobName the name of the print job to start + * @return true if the job started successfully and false otherwise. + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #startPage + * @see #endPage + * @see #endJob + */ +public bool startJob(char[] jobName) { + checkDevice(); + char* buffer = tango.stdc.stringz.toStringz(jobName); + printJob = OS.gtk_print_job_new (buffer, printer, settings, pageSetup); + if (printJob is null) return false; + surface = OS.gtk_print_job_get_surface(printJob, null); + if (surface is null) { + OS.g_object_unref(printJob); + printJob = null; + return false; + } + cairo = Cairo.cairo_create(surface); + if (cairo is null) { + OS.g_object_unref(printJob); + printJob = null; + return false; + } + return true; +} + +/** + * Destroys the printer handle. + * This method is called internally by the dispose + * mechanism of the <code>Device</code> class. + */ +protected void destroy () { + if (printer !is null) OS.g_object_unref (printer); + if (settings !is null) OS.g_object_unref (settings); + if (pageSetup !is null) OS.g_object_unref (pageSetup); + if (cairo !is null) Cairo.cairo_destroy (cairo); + if (printJob !is null) OS.g_object_unref (printJob); + printer = null; + settings = null; + pageSetup = null; + cairo = null; + printJob = null; +} + +/** + * Ends the current print job. + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #startJob + * @see #startPage + * @see #endPage + */ +public void endJob() { + checkDevice(); + if (printJob is null) return; + Cairo.cairo_surface_finish(surface); + OS.gtk_print_job_send(printJob, null, null, null ); +} + +/** + * Cancels a print job in progress. + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + */ +public void cancelJob() { + checkDevice(); + if (printJob is null) return; + //TODO: Need to implement (waiting on gtk bug 339323) + //OS.g_object_unref(printJob); + //printJob = 0; +} + +/** + * Starts a page and returns true if the page started successfully + * and false otherwise. + * <p> + * After calling startJob, this method may be called any number of times + * along with a matching endPage. + * </p> + * + * @return true if the page started successfully and false otherwise. + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #endPage + * @see #startJob + * @see #endJob + */ +public bool startPage() { + checkDevice(); + if (printJob is null) return false; + double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS); + double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS); + int type = Cairo.cairo_surface_get_type (surface); + switch (type) { + case Cairo.CAIRO_SURFACE_TYPE_PS: + Cairo.cairo_ps_surface_set_size (surface, width, height); + break; + case Cairo.CAIRO_SURFACE_TYPE_PDF: + Cairo.cairo_pdf_surface_set_size (surface, width, height); + break; + } + return true; +} + +/** + * Ends the current page. + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #startPage + * @see #startJob + * @see #endJob + */ +public void endPage() { + checkDevice(); + if (cairo !is null) Cairo.cairo_show_page(cairo); +} + +/** + * Returns a point whose x coordinate is the horizontal + * dots per inch of the printer, and whose y coordinate + * is the vertical dots per inch of the printer. + * + * @return the horizontal and vertical DPI + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + */ +public Point getDPI() { + checkDevice(); + int resolution = OS.gtk_print_settings_get_resolution(settings); + if (DEBUG) tango.io.Stdout.Stdout.formatln("print_settings.resolution={}", resolution); + //TODO: Return 72 (1/72 inch = 1 point) until gtk bug 346245 is fixed + //TODO: Fix this: gtk_print_settings_get_resolution returns 0? (see gtk bug 346252) + if (true || resolution is 0) return new Point(72, 72); + return new Point(resolution, resolution); +} + +/** + * Returns a rectangle describing the receiver's size and location. + * For a printer, this is the size of a physical page, in pixels. + * + * @return the bounding rectangle + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #getClientArea + * @see #computeTrim + */ +public Rectangle getBounds() { + checkDevice(); + //TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245) + double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS); + double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS); + return new Rectangle(0, 0, cast(int) width, cast(int) height); +} + +/** + * Returns a rectangle which describes the area of the + * receiver which is capable of displaying data. + * For a printer, this is the size of the printable area + * of a page, in pixels. + * + * @return the client area + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #getBounds + * @see #computeTrim + */ +public Rectangle getClientArea() { + checkDevice(); + //TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245) + double width = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS); + double height = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS); + return new Rectangle(0, 0, cast(int) width, cast(int) height); +} + +/** + * Given a desired <em>client area</em> for the receiver + * (as described by the arguments), returns the bounding + * rectangle which would be required to produce that client + * area. + * <p> + * In other words, it returns a rectangle such that, if the + * receiver's bounds were set to that rectangle, the area + * of the receiver which is capable of displaying data + * (that is, not covered by the "trimmings") would be the + * rectangle described by the arguments (relative to the + * receiver's parent). + * </p><p> + * Note that there is no setBounds for a printer. This method + * is usually used by passing in the client area (the 'printable + * area') of the printer. It can also be useful to pass in 0, 0, 0, 0. + * </p> + * + * @param x the desired x coordinate of the client area + * @param y the desired y coordinate of the client area + * @param width the desired width of the client area + * @param height the desired height of the client area + * @return the required bounds to produce the given client area + * + * @exception DWTException <ul> + * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> + * </ul> + * + * @see #getBounds + * @see #getClientArea + */ +public Rectangle computeTrim(int x, int y, int width, int height) { + checkDevice(); + //TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245) + double printWidth = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS); + double printHeight = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS); + double paperWidth = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS); + double paperHeight = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS); + double printX = -OS.gtk_page_setup_get_left_margin(pageSetup, OS.GTK_UNIT_POINTS); + double printY = -OS.gtk_page_setup_get_top_margin(pageSetup, OS.GTK_UNIT_POINTS); + double hTrim = paperWidth - printWidth; + double vTrim = paperHeight - printHeight; + return new Rectangle(x + cast(int)printX, y + cast(int)printY, width + cast(int)hTrim, height + cast(int)vTrim); +} + +/** + * Creates the printer handle. + * This method is called internally by the instance creation + * mechanism of the <code>Device</code> class. + * @param deviceData the device data + */ +protected void create(DeviceData deviceData) { + this.data = cast(PrinterData)deviceData; + if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) DWT.error(DWT.ERROR_NO_HANDLES); + printer = gtkPrinterFromPrinterData(); + if (printer is null) DWT.error(DWT.ERROR_NO_HANDLES); +} + +/** + * Initializes any internal resources needed by the + * device. + * <p> + * This method is called after <code>create</code>. + * </p><p> + * If subclasses reimplement this method, they must + * call the <code>super</code> implementation. + * </p> + * + * @see #create + */ +protected void init() { + super.init (); + settings = OS.gtk_print_settings_new(); + pageSetup = OS.gtk_page_setup_new(); + if (data.otherData !is null) { + /* Retreive stored printer_settings data. */ + settingsData = data.otherData; + start = end = 0; + while (end < settingsData.length && settingsData[end] !is 0) { + start = end; + while (end < settingsData.length && settingsData[end] !is 0) end++; + end++; + char [] keyBuffer = new char [end - start]; + System.arraycopy (settingsData, start, keyBuffer, 0, keyBuffer.length); + start = end; + while (end < settingsData.length && settingsData[end] !is 0) end++; + end++; + char [] valueBuffer = new char [end - start]; + System.arraycopy (settingsData, start, valueBuffer, 0, valueBuffer.length); + OS.gtk_print_settings_set(settings, keyBuffer.ptr, valueBuffer.ptr); + if (DEBUG) tango.io.Stdout.Stdout.formatln("{}: {}", keyBuffer, valueBuffer); + } + end++; // skip extra null terminator + + /* Retreive stored page_setup data. + * Note that page_setup properties must be stored (in PrintDialog) and restored (here) in the same order. + */ + OS.gtk_page_setup_set_orientation(pageSetup, restoreInt("orientation")); //$NON-NLS-1$ + OS.gtk_page_setup_set_top_margin(pageSetup, restoreDouble("top_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ + OS.gtk_page_setup_set_bottom_margin(pageSetup, restoreDouble("bottom_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ + OS.gtk_page_setup_set_left_margin(pageSetup, restoreDouble("left_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ + OS.gtk_page_setup_set_right_margin(pageSetup, restoreDouble("right_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ + char [] name = restoreBytes("paper_size_name", true); //$NON-NLS-1$ + char [] display_name = restoreBytes("paper_size_display_name", true); //$NON-NLS-1$ + char [] ppd_name = restoreBytes("paper_size_ppd_name", true); //$NON-NLS-1$ + double width = restoreDouble("paper_size_width"); //$NON-NLS-1$ + double height = restoreDouble("paper_size_height"); //$NON-NLS-1$ + bool custom = restoreBoolean("paper_size_is_custom"); //$NON-NLS-1$ + GtkPaperSize* paper_size; + if (custom) { + if (ppd_name.length > 0) { + paper_size = OS.gtk_paper_size_new_from_ppd(ppd_name.ptr, display_name.ptr, width, height); + } else { + paper_size = OS.gtk_paper_size_new_custom(name.ptr, display_name.ptr, width, height, OS.GTK_UNIT_MM); + } + } else { + paper_size = OS.gtk_paper_size_new(name.ptr); + } + OS.gtk_page_setup_set_paper_size(pageSetup, paper_size); + OS.g_free(paper_size); + } + + /* Set values of settings from PrinterData. */ + setScope(settings, data.scope_, data.startPage, data.endPage); + //TODO: Should we look at printToFile, or driver/name for "Print to File", or both? (see gtk bug 345590) + if (data.printToFile) { + char* buffer = tango.stdc.stringz.toStringz( data.fileName ); + OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI.ptr, buffer); + } + if (data.driver ==/*eq*/ "GtkPrintBackendFile" && data.name ==/*eq*/ "Print to File" ) { //$NON-NLS-1$ //$NON-NLS-2$ + char* buffer = tango.stdc.stringz.toStringz( data.fileName ); + OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI.ptr, buffer); + } + OS.gtk_print_settings_set_n_copies(settings, data.copyCount); + OS.gtk_print_settings_set_collate(settings, data.collate); +} + +/** + * Returns a <code>PrinterData</code> object representing the + * target printer for this print job. + * + * @return a PrinterData object describing the receiver + */ +public PrinterData getPrinterData() { + checkDevice(); + return data; +} + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/printing/PrinterData.d Thu Jan 17 15:44:59 2008 +0100 @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.printing.PrinterData; + + +import dwt.graphics.DeviceData; + +import tango.text.convert.Format; + + +/** + * Instances of this class are descriptions of a print job + * in terms of the printer, and the scope and type of printing + * that is desired. For example, the number of pages and copies + * can be specified, as well as whether or not the print job + * should go to a file. + * <p> + * Application code does <em>not</em> need to explicitly release the + * resources managed by each instance when those instances are no longer + * required, and thus no <code>dispose()</code> method is provided. + * </p> + * + * @see Printer + * @see Printer#getPrinterList + * @see PrintDialog#open + */ + +public final class PrinterData : DeviceData { + + /** + * the printer driver + * On Windows systems, this is the name of the driver (often "winspool"). + * On Mac OSX, this is the destination type ("Printer", "Fax", "File", or "Preview"). + * On X/Window systems, this is the name of a display connection to the + * Xprt server (the default is ":1"). + * On GTK+, this is the backend type name (eg. GtkPrintBackendCups). + */ + // TODO: note that this api is not finalized for GTK+ + public char[] driver; + + /** + * the name of the printer + * On Windows systems, this is the name of the 'device'. + * On Mac OSX, X/Window systems, and GTK+, this is the printer's 'name'. + */ + public char[] name; + + /** + * the scope of the print job, expressed as one of the following values: + * <dl> + * <dt><code>ALL_PAGES</code></dt> + * <dd>Print all pages in the current document</dd> + * <dt><code>PAGE_RANGE</code></dt> + * <dd>Print the range of pages specified by startPage and endPage</dd> + * <dt><code>SELECTION</code></dt> + * <dd>Print the current selection</dd> + * </dl> + */ + public int scope_ = ALL_PAGES; + + /** + * the start page of a page range, used when scope is PAGE_RANGE. + * This value can be from 1 to the maximum number of pages for the platform. + */ + public int startPage = 0; + + /** + * the end page of a page range, used when scope is PAGE_RANGE. + * This value can be from 1 to the maximum number of pages for the platform. + */ + public int endPage = 0; + + /** + * whether or not the print job should go to a file + */ + public bool printToFile = false; + + /** + * the name of the file to print to if printToFile is true. + * Note that this field is ignored if printToFile is false. + */ + public char[] fileName; + + /** + * the number of copies to print. + * Note that this field may be controlled by the printer driver + * In other words, the printer itself may be capable of printing + * multiple copies, and if so, the value of this field will always be 1. + */ + public int copyCount = 1; + + /** + * whether or not the printer should collate the printed paper + * Note that this field may be controlled by the printer driver. + * In other words, the printer itself may be capable of doing the + * collation, and if so, the value of this field will always be false. + */ + public bool collate = false; + + /** + * <code>scope</code> field value indicating that + * all pages should be printed + */ + public static const int ALL_PAGES = 0; + + /** + * <code>scope</code> field value indicating that + * the range of pages specified by startPage and endPage + * should be printed + */ + public static const int PAGE_RANGE = 1; + + /** + * <code>scope</code> field value indicating that + * the current selection should be printed + */ + public static const int SELECTION = 2; + + /** + * private, platform-specific data + * On Windows, this contains a copy of the DEVMODE struct + * returned from the <code>PrintDialog</code>. + * This field is not currently used on the X/Window System. + */ + char [] otherData; + + /** + * Constructs an instance of this class that can be + * used to print to the default printer. + * + * @see Printer#getDefaultPrinterData + */ + public this() { + } + + /** + * Constructs an instance of this class with the given + * printer driver and printer name. + * + * @param driver the printer driver for the printer + * @param name the name of the printer + * + * @see #driver + * @see #name + */ + public this(char[] driver, char[] name) { + this.driver = driver; + this.name = name; + } + + /** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the receiver + */ + public char[] toString() { + return Format( "PrinterData {{driver = {}, name = {}}", driver, name ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } +}