Mercurial > projects > dwt-linux
annotate dwt/printing/Printer.d @ 200:08789b28bdf3
import dwt.dwthelper.utils now explicit
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 07 Mar 2008 03:12:23 +0100 |
parents | e0ffca35fe59 |
children | 00180515eb65 |
rev | line source |
---|---|
115
52b32f5cb1e0
many file checked for switch default
Frank Benoit <benoit@tionex.de>
parents:
108
diff
changeset
|
1 /******************************************************************************* |
91 | 2 * Copyright (c) 2000, 2007 IBM Corporation and others. |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
108 | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | |
91 | 12 *******************************************************************************/ |
13 module dwt.printing.Printer; | |
14 | |
15 | |
16 | |
17 import dwt.DWT; | |
18 import dwt.DWTError; | |
19 import dwt.DWTException; | |
20 import dwt.graphics.Device; | |
21 import dwt.graphics.DeviceData; | |
22 import dwt.graphics.Font; | |
23 import dwt.graphics.GCData; | |
24 import dwt.graphics.Point; | |
25 import dwt.graphics.Rectangle; | |
26 import dwt.internal.cairo.Cairo; | |
27 import dwt.internal.gtk.OS; | |
28 import dwt.printing.PrinterData; | |
200
08789b28bdf3
import dwt.dwthelper.utils now explicit
Frank Benoit <benoit@tionex.de>
parents:
195
diff
changeset
|
29 import dwt.dwthelper.utils; |
91 | 30 |
31 static import tango.stdc.stringz; | |
32 static import tango.io.Stdout; | |
33 import tango.util.Convert; | |
34 | |
35 | |
36 /** | |
37 * Instances of this class are used to print to a printer. | |
38 * Applications create a GC on a printer using <code>new GC(printer)</code> | |
39 * and then draw on the printer GC using the usual graphics calls. | |
40 * <p> | |
41 * A <code>Printer</code> object may be constructed by providing | |
42 * a <code>PrinterData</code> object which identifies the printer. | |
43 * A <code>PrintDialog</code> presents a print dialog to the user | |
44 * and returns an initialized instance of <code>PrinterData</code>. | |
45 * Alternatively, calling <code>new Printer()</code> will construct a | |
46 * printer object for the user's default printer. | |
47 * </p><p> | |
48 * Application code must explicitly invoke the <code>Printer.dispose()</code> | |
49 * method to release the operating system resources managed by each instance | |
50 * when those instances are no longer required. | |
51 * </p> | |
52 * | |
53 * @see PrinterData | |
54 * @see PrintDialog | |
55 */ | |
56 public final class Printer : Device { | |
57 static PrinterData [] printerList; | |
58 | |
59 PrinterData data; | |
60 GtkPrinter* printer; | |
61 GtkPrintJob* printJob; | |
62 GtkPrintSettings* settings; | |
63 void* pageSetup; | |
64 cairo_surface_t* surface; | |
65 cairo_t* cairo; | |
66 | |
67 /** | |
68 * whether or not a GC was created for this printer | |
69 */ | |
70 bool isGCCreated = false; | |
71 Font systemFont; | |
72 | |
73 char[] settingsData; | |
74 int start, end; | |
75 | |
76 static const char[] GTK_LPR_BACKEND = "GtkPrintBackendLpr"; //$NON-NLS-1$ | |
77 | |
78 /** | |
79 * Returns an array of <code>PrinterData</code> objects | |
80 * representing all available printers. | |
81 * | |
82 * @return the list of available printers | |
83 */ | |
84 public static PrinterData[] getPrinterList() { | |
85 printerList = new PrinterData [0]; | |
86 if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) { | |
87 return printerList; | |
88 } | |
89 OS.gtk_enumerate_printers(&GtkPrinterFunc_List, null, null, true); | |
90 return printerList; | |
91 } | |
92 | |
93 private static extern(C) int GtkPrinterFunc_List (GtkPrinter* printer, void* user_data) { | |
94 int length_ = printerList.length; | |
95 PrinterData [] newList = new PrinterData [length_ + 1]; | |
96 System.arraycopy (printerList, 0, newList, 0, length_); | |
97 printerList = newList; | |
98 printerList [length_] = printerDataFromGtkPrinter(printer); | |
99 /* | |
100 * Bug in GTK. While performing a gtk_enumerate_printers(), GTK finds all of the | |
101 * available printers from each backend and can hang. If a backend requires more | |
102 * time to gather printer info, GTK will start an event loop waiting for a done | |
103 * signal before continuing. For the Lpr backend, GTK does not send a done signal | |
104 * which means the event loop never ends. The fix is to check to see if the driver | |
105 * is of type Lpr, and stop the enumeration, which exits the event loop. | |
106 */ | |
195 | 107 if (printerList[length_].driver.equals(GTK_LPR_BACKEND)) return 1; |
91 | 108 return 0; |
109 } | |
110 | |
111 /** | |
112 * Returns a <code>PrinterData</code> object representing | |
113 * the default printer or <code>null</code> if there is no | |
114 * printer available on the System. | |
115 * | |
116 * @return the default printer data or null | |
117 * | |
118 * @since 2.1 | |
119 */ | |
120 public static PrinterData getDefaultPrinterData() { | |
121 printerList = new PrinterData [1]; | |
122 if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) { | |
123 return null; | |
124 } | |
125 OS.gtk_enumerate_printers(&GtkPrinterFunc_Default, null, null, true); | |
126 return printerList[0]; | |
127 } | |
128 | |
129 private static extern(C) int GtkPrinterFunc_Default (GtkPrinter* printer, void* user_data) { | |
130 if (OS.gtk_printer_is_default(printer)) { | |
131 printerList[0] = printerDataFromGtkPrinter(printer); | |
132 return 1; | |
133 } | |
134 return 0; | |
135 } | |
136 | |
137 GtkPrinter* gtkPrinterFromPrinterData() { | |
138 printer = null; | |
139 OS.gtk_enumerate_printers(&GtkPrinterFunc_FindNamedPrinterFunc, cast(void*)this, null, true); | |
140 return printer; | |
141 } | |
142 | |
143 private static extern(C) int GtkPrinterFunc_FindNamedPrinterFunc (GtkPrinter* printer, void* user_data) { | |
144 return (cast(Printer)user_data).GtkPrinterFunc_FindNamedPrinter( printer, null ); | |
145 } | |
146 int GtkPrinterFunc_FindNamedPrinter (GtkPrinter* printer, void* user_data) { | |
147 PrinterData pd = printerDataFromGtkPrinter(printer); | |
195 | 148 if (pd.driver.equals(data.driver) && pd.name.equals(data.name)) { |
91 | 149 this.printer = printer; |
150 OS.g_object_ref(printer); | |
151 return 1; | |
152 } | |
153 return 0; | |
154 } | |
155 | |
156 static PrinterData printerDataFromGtkPrinter(GtkPrinter* printer) { | |
157 auto backend = OS.gtk_printer_get_backend(printer); | |
158 auto address = OS.G_OBJECT_TYPE_NAME(backend); | |
158
de2578a843a7
Tango update to rev 3158, TracedException>Exception, fromUtf8z>fromStringz,Fix Bug in MenuItem Thanx to nascent for the report.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
159 char[] backendType =tango.stdc.stringz.fromStringz( address ).dup; |
91 | 160 |
161 address = OS.gtk_printer_get_name (printer); | |
158
de2578a843a7
Tango update to rev 3158, TracedException>Exception, fromUtf8z>fromStringz,Fix Bug in MenuItem Thanx to nascent for the report.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
162 char[] name =tango.stdc.stringz.fromStringz( address ).dup; |
91 | 163 |
164 return new PrinterData (backendType, name); | |
165 } | |
166 | |
167 static void setScope(GtkPrintSettings* settings, int scope_, int startPage, int endPage) { | |
168 switch (scope_) { | |
169 case PrinterData.ALL_PAGES: | |
170 OS.gtk_print_settings_set_print_pages(settings, OS.GTK_PRINT_PAGES_ALL); | |
171 break; | |
172 case PrinterData.PAGE_RANGE: | |
173 OS.gtk_print_settings_set_print_pages(settings, OS.GTK_PRINT_PAGES_RANGES); | |
174 GtkPageRange pageRange; | |
175 pageRange.start = startPage - 1; | |
176 pageRange.end = endPage - 1; | |
177 OS.gtk_print_settings_set_page_ranges(settings, &pageRange, 1); | |
178 break; | |
179 case PrinterData.SELECTION: | |
180 //TODO: Not correctly implemented. May need new API. For now, set to ALL. (see gtk bug 344519) | |
181 OS.gtk_print_settings_set_print_pages(settings, OS.GTK_PRINT_PAGES_ALL); | |
182 break; | |
183 default: | |
184 } | |
185 } | |
186 | |
187 static DeviceData checkNull (PrinterData data) { | |
188 if (data is null) data = new PrinterData(); | |
189 if (data.driver is null || data.name is null) { | |
190 PrinterData defaultPrinter = getDefaultPrinterData(); | |
191 if (defaultPrinter is null) DWT.error(DWT.ERROR_NO_HANDLES); | |
192 data.driver = defaultPrinter.driver; | |
193 data.name = defaultPrinter.name; | |
194 } | |
195 return data; | |
196 } | |
197 | |
198 /** | |
199 * Constructs a new printer representing the default printer. | |
200 * <p> | |
201 * You must dispose the printer when it is no longer required. | |
202 * </p> | |
203 * | |
204 * @exception DWTError <ul> | |
205 * <li>ERROR_NO_HANDLES - if there are no valid printers | |
206 * </ul> | |
207 * | |
208 * @see Device#dispose | |
209 */ | |
210 public this() { | |
211 this(null); | |
212 } | |
213 | |
214 /** | |
215 * Constructs a new printer given a <code>PrinterData</code> | |
216 * object representing the desired printer. | |
217 * <p> | |
218 * You must dispose the printer when it is no longer required. | |
219 * </p> | |
220 * | |
221 * @param data the printer data for the specified printer | |
222 * | |
223 * @exception IllegalArgumentException <ul> | |
224 * <li>ERROR_INVALID_ARGUMENT - if the specified printer data does not represent a valid printer | |
225 * </ul> | |
226 * @exception DWTError <ul> | |
227 * <li>ERROR_NO_HANDLES - if there are no valid printers | |
228 * </ul> | |
229 * | |
230 * @see Device#dispose | |
231 */ | |
232 public this(PrinterData data) { | |
233 super(checkNull(data)); | |
234 } | |
235 | |
236 int restoreInt(char[] key) { | |
237 char [] value = restoreBytes(key, false); | |
238 return to!(int)( value ); | |
239 } | |
240 | |
241 double restoreDouble(char[] key) { | |
242 char [] value = restoreBytes(key, false); | |
243 return to!(double)( value ); | |
244 } | |
245 | |
246 bool restoreBoolean(char[] key) { | |
247 char [] value = restoreBytes(key, false); | |
248 return to!(bool)( value ); | |
249 } | |
250 | |
251 char[] restoreBytes(char[] key, bool nullTerminate) { | |
252 //get key | |
253 start = end; | |
254 while (end < settingsData.length && settingsData[end] !is 0) end++; | |
255 end++; | |
256 char [] keyBuffer = new char [end - start]; | |
257 System.arraycopy (settingsData, start, keyBuffer, 0, keyBuffer.length); | |
258 | |
259 //get value | |
260 start = end; | |
261 while (end < settingsData.length && settingsData[end] !is 0) end++; | |
262 int length_ = end - start; | |
263 end++; | |
264 if (nullTerminate) length_++; | |
265 char [] valueBuffer = new char [length_]; | |
266 System.arraycopy (settingsData, start, valueBuffer, 0, length_); | |
267 | |
268 if (DEBUG) tango.io.Stdout.Stdout.formatln( "{}: {}", keyBuffer, valueBuffer ); | |
269 | |
270 return valueBuffer; | |
271 } | |
272 | |
273 /** | |
274 * Returns a reasonable font for applications to use. | |
275 * On some platforms, this will match the "default font" | |
276 * or "system font" if such can be found. This font | |
277 * should not be free'd because it was allocated by the | |
278 * system, not the application. | |
279 * <p> | |
280 * Typically, applications which want the default look | |
281 * should simply not set the font on the widgets they | |
282 * create. Widgets are always created with the correct | |
283 * default font for the class of user-interface component | |
284 * they represent. | |
285 * </p> | |
286 * | |
287 * @return a font | |
288 * | |
289 * @exception DWTException <ul> | |
290 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
291 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
292 * </ul> | |
293 */ | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
115
diff
changeset
|
294 public override Font getSystemFont () { |
91 | 295 checkDevice (); |
296 if (systemFont !is null) return systemFont; | |
297 auto style = OS.gtk_widget_get_default_style(); | |
298 auto defaultFont = OS.pango_font_description_copy (OS.gtk_style_get_font_desc (style)); | |
299 return systemFont = Font.gtk_new (this, defaultFont); | |
300 } | |
301 | |
302 /** | |
303 * Invokes platform specific functionality to allocate a new GC handle. | |
304 * <p> | |
305 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
306 * API for <code>Printer</code>. It is marked public only so that it | |
307 * can be shared within the packages provided by DWT. It is not | |
308 * available on all platforms, and should never be called from | |
309 * application code. | |
310 * </p> | |
311 * | |
312 * @param data the platform specific GC data | |
313 * @return the platform specific GC handle | |
314 */ | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
115
diff
changeset
|
315 public override GdkGC* internal_new_GC(GCData data) { |
91 | 316 auto drawable = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), 1, 1, 1); |
317 auto gdkGC = OS.gdk_gc_new (drawable); | |
318 if (gdkGC is null) DWT.error (DWT.ERROR_NO_HANDLES); | |
319 if (data !is null) { | |
320 if (isGCCreated) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
321 int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; | |
322 if ((data.style & mask) is 0) { | |
323 data.style |= DWT.LEFT_TO_RIGHT; | |
324 } | |
325 data.device = this; | |
326 data.drawable = drawable; | |
327 data.background = getSystemColor (DWT.COLOR_WHITE).handle; | |
328 data.foreground = getSystemColor (DWT.COLOR_BLACK).handle; | |
329 data.font = getSystemFont ().handle; | |
330 if (cairo is null) DWT.error(DWT.ERROR_NO_HANDLES); | |
331 data.cairo = cairo; | |
332 isGCCreated = true; | |
333 } | |
334 return gdkGC; | |
335 } | |
336 | |
337 /** | |
338 * Invokes platform specific functionality to dispose a GC handle. | |
339 * <p> | |
340 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
341 * API for <code>Printer</code>. It is marked public only so that it | |
342 * can be shared within the packages provided by DWT. It is not | |
343 * available on all platforms, and should never be called from | |
344 * application code. | |
345 * </p> | |
346 * | |
347 * @param hDC the platform specific GC handle | |
348 * @param data the platform specific GC data | |
349 */ | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
115
diff
changeset
|
350 public override void internal_dispose_GC(GdkGC* gdkGC, GCData data) { |
91 | 351 if (data !is null) isGCCreated = false; |
352 OS.g_object_unref (gdkGC); | |
353 if (data !is null) { | |
354 if (data.drawable !is null) OS.g_object_unref (data.drawable); | |
355 data.drawable = null; | |
356 data.cairo = null; | |
357 } | |
358 } | |
359 | |
360 /** | |
361 * Releases any internal state prior to destroying this printer. | |
362 * This method is called internally by the dispose | |
363 * mechanism of the <code>Device</code> class. | |
364 */ | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
365 protected override void release () { |
91 | 366 super.release(); |
367 | |
368 /* Dispose the default font */ | |
369 if (systemFont !is null) systemFont.dispose (); | |
370 systemFont = null; | |
371 } | |
372 | |
373 /** | |
374 * Starts a print job and returns true if the job started successfully | |
375 * and false otherwise. | |
376 * <p> | |
377 * This must be the first method called to initiate a print job, | |
378 * followed by any number of startPage/endPage calls, followed by | |
379 * endJob. Calling startPage, endPage, or endJob before startJob | |
380 * will result in undefined behavior. | |
381 * </p> | |
382 * | |
383 * @param jobName the name of the print job to start | |
384 * @return true if the job started successfully and false otherwise. | |
385 * | |
386 * @exception DWTException <ul> | |
387 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
388 * </ul> | |
389 * | |
390 * @see #startPage | |
391 * @see #endPage | |
392 * @see #endJob | |
393 */ | |
394 public bool startJob(char[] jobName) { | |
395 checkDevice(); | |
396 char* buffer = tango.stdc.stringz.toStringz(jobName); | |
397 printJob = OS.gtk_print_job_new (buffer, printer, settings, pageSetup); | |
398 if (printJob is null) return false; | |
399 surface = OS.gtk_print_job_get_surface(printJob, null); | |
400 if (surface is null) { | |
401 OS.g_object_unref(printJob); | |
402 printJob = null; | |
403 return false; | |
404 } | |
405 cairo = Cairo.cairo_create(surface); | |
406 if (cairo is null) { | |
407 OS.g_object_unref(printJob); | |
408 printJob = null; | |
409 return false; | |
410 } | |
411 return true; | |
412 } | |
413 | |
414 /** | |
415 * Destroys the printer handle. | |
416 * This method is called internally by the dispose | |
417 * mechanism of the <code>Device</code> class. | |
418 */ | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
419 protected override void destroy () { |
91 | 420 if (printer !is null) OS.g_object_unref (printer); |
421 if (settings !is null) OS.g_object_unref (settings); | |
422 if (pageSetup !is null) OS.g_object_unref (pageSetup); | |
423 if (cairo !is null) Cairo.cairo_destroy (cairo); | |
424 if (printJob !is null) OS.g_object_unref (printJob); | |
425 printer = null; | |
426 settings = null; | |
427 pageSetup = null; | |
428 cairo = null; | |
429 printJob = null; | |
430 } | |
431 | |
432 /** | |
433 * Ends the current print job. | |
434 * | |
435 * @exception DWTException <ul> | |
436 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
437 * </ul> | |
438 * | |
439 * @see #startJob | |
440 * @see #startPage | |
441 * @see #endPage | |
442 */ | |
443 public void endJob() { | |
444 checkDevice(); | |
445 if (printJob is null) return; | |
446 Cairo.cairo_surface_finish(surface); | |
447 OS.gtk_print_job_send(printJob, null, null, null ); | |
448 } | |
449 | |
450 /** | |
451 * Cancels a print job in progress. | |
452 * | |
453 * @exception DWTException <ul> | |
454 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
455 * </ul> | |
456 */ | |
457 public void cancelJob() { | |
458 checkDevice(); | |
459 if (printJob is null) return; | |
460 //TODO: Need to implement (waiting on gtk bug 339323) | |
461 //OS.g_object_unref(printJob); | |
462 //printJob = 0; | |
463 } | |
464 | |
465 /** | |
466 * Starts a page and returns true if the page started successfully | |
467 * and false otherwise. | |
468 * <p> | |
469 * After calling startJob, this method may be called any number of times | |
470 * along with a matching endPage. | |
471 * </p> | |
472 * | |
473 * @return true if the page started successfully and false otherwise. | |
474 * | |
475 * @exception DWTException <ul> | |
476 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
477 * </ul> | |
478 * | |
479 * @see #endPage | |
480 * @see #startJob | |
481 * @see #endJob | |
482 */ | |
483 public bool startPage() { | |
484 checkDevice(); | |
485 if (printJob is null) return false; | |
486 double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS); | |
487 double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS); | |
488 int type = Cairo.cairo_surface_get_type (surface); | |
489 switch (type) { | |
490 case Cairo.CAIRO_SURFACE_TYPE_PS: | |
491 Cairo.cairo_ps_surface_set_size (surface, width, height); | |
492 break; | |
493 case Cairo.CAIRO_SURFACE_TYPE_PDF: | |
494 Cairo.cairo_pdf_surface_set_size (surface, width, height); | |
495 break; | |
115
52b32f5cb1e0
many file checked for switch default
Frank Benoit <benoit@tionex.de>
parents:
108
diff
changeset
|
496 default: |
91 | 497 } |
498 return true; | |
499 } | |
500 | |
501 /** | |
502 * Ends the current page. | |
503 * | |
504 * @exception DWTException <ul> | |
505 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
506 * </ul> | |
507 * | |
508 * @see #startPage | |
509 * @see #startJob | |
510 * @see #endJob | |
511 */ | |
512 public void endPage() { | |
513 checkDevice(); | |
514 if (cairo !is null) Cairo.cairo_show_page(cairo); | |
515 } | |
516 | |
517 /** | |
518 * Returns a point whose x coordinate is the horizontal | |
519 * dots per inch of the printer, and whose y coordinate | |
520 * is the vertical dots per inch of the printer. | |
521 * | |
522 * @return the horizontal and vertical DPI | |
523 * | |
524 * @exception DWTException <ul> | |
525 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
526 * </ul> | |
527 */ | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
115
diff
changeset
|
528 public override Point getDPI() { |
91 | 529 checkDevice(); |
530 int resolution = OS.gtk_print_settings_get_resolution(settings); | |
531 if (DEBUG) tango.io.Stdout.Stdout.formatln("print_settings.resolution={}", resolution); | |
532 //TODO: Return 72 (1/72 inch = 1 point) until gtk bug 346245 is fixed | |
533 //TODO: Fix this: gtk_print_settings_get_resolution returns 0? (see gtk bug 346252) | |
534 if (true || resolution is 0) return new Point(72, 72); | |
535 return new Point(resolution, resolution); | |
536 } | |
537 | |
538 /** | |
539 * Returns a rectangle describing the receiver's size and location. | |
540 * For a printer, this is the size of a physical page, in pixels. | |
541 * | |
542 * @return the bounding rectangle | |
543 * | |
544 * @exception DWTException <ul> | |
545 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
546 * </ul> | |
547 * | |
548 * @see #getClientArea | |
549 * @see #computeTrim | |
550 */ | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
115
diff
changeset
|
551 public override Rectangle getBounds() { |
91 | 552 checkDevice(); |
553 //TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245) | |
554 double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS); | |
555 double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS); | |
556 return new Rectangle(0, 0, cast(int) width, cast(int) height); | |
557 } | |
558 | |
559 /** | |
560 * Returns a rectangle which describes the area of the | |
561 * receiver which is capable of displaying data. | |
562 * For a printer, this is the size of the printable area | |
563 * of a page, in pixels. | |
564 * | |
565 * @return the client area | |
566 * | |
567 * @exception DWTException <ul> | |
568 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
569 * </ul> | |
570 * | |
571 * @see #getBounds | |
572 * @see #computeTrim | |
573 */ | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
115
diff
changeset
|
574 public override Rectangle getClientArea() { |
91 | 575 checkDevice(); |
576 //TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245) | |
577 double width = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS); | |
578 double height = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS); | |
579 return new Rectangle(0, 0, cast(int) width, cast(int) height); | |
580 } | |
581 | |
582 /** | |
583 * Given a desired <em>client area</em> for the receiver | |
584 * (as described by the arguments), returns the bounding | |
585 * rectangle which would be required to produce that client | |
586 * area. | |
587 * <p> | |
588 * In other words, it returns a rectangle such that, if the | |
589 * receiver's bounds were set to that rectangle, the area | |
590 * of the receiver which is capable of displaying data | |
591 * (that is, not covered by the "trimmings") would be the | |
592 * rectangle described by the arguments (relative to the | |
593 * receiver's parent). | |
594 * </p><p> | |
595 * Note that there is no setBounds for a printer. This method | |
596 * is usually used by passing in the client area (the 'printable | |
597 * area') of the printer. It can also be useful to pass in 0, 0, 0, 0. | |
598 * </p> | |
599 * | |
600 * @param x the desired x coordinate of the client area | |
601 * @param y the desired y coordinate of the client area | |
602 * @param width the desired width of the client area | |
603 * @param height the desired height of the client area | |
604 * @return the required bounds to produce the given client area | |
605 * | |
606 * @exception DWTException <ul> | |
607 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
608 * </ul> | |
609 * | |
610 * @see #getBounds | |
611 * @see #getClientArea | |
612 */ | |
613 public Rectangle computeTrim(int x, int y, int width, int height) { | |
614 checkDevice(); | |
615 //TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245) | |
616 double printWidth = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS); | |
617 double printHeight = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS); | |
618 double paperWidth = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS); | |
619 double paperHeight = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS); | |
620 double printX = -OS.gtk_page_setup_get_left_margin(pageSetup, OS.GTK_UNIT_POINTS); | |
621 double printY = -OS.gtk_page_setup_get_top_margin(pageSetup, OS.GTK_UNIT_POINTS); | |
622 double hTrim = paperWidth - printWidth; | |
623 double vTrim = paperHeight - printHeight; | |
624 return new Rectangle(x + cast(int)printX, y + cast(int)printY, width + cast(int)hTrim, height + cast(int)vTrim); | |
625 } | |
626 | |
627 /** | |
628 * Creates the printer handle. | |
629 * This method is called internally by the instance creation | |
630 * mechanism of the <code>Device</code> class. | |
631 * @param deviceData the device data | |
632 */ | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
633 protected override void create(DeviceData deviceData) { |
91 | 634 this.data = cast(PrinterData)deviceData; |
635 if (OS.GTK_VERSION < OS.buildVERSION (2, 10, 0)) DWT.error(DWT.ERROR_NO_HANDLES); | |
636 printer = gtkPrinterFromPrinterData(); | |
637 if (printer is null) DWT.error(DWT.ERROR_NO_HANDLES); | |
638 } | |
639 | |
640 /** | |
641 * Initializes any internal resources needed by the | |
642 * device. | |
643 * <p> | |
644 * This method is called after <code>create</code>. | |
645 * </p><p> | |
646 * If subclasses reimplement this method, they must | |
647 * call the <code>super</code> implementation. | |
648 * </p> | |
649 * | |
650 * @see #create | |
651 */ | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
652 protected override void init() { |
91 | 653 super.init (); |
654 settings = OS.gtk_print_settings_new(); | |
655 pageSetup = OS.gtk_page_setup_new(); | |
656 if (data.otherData !is null) { | |
657 /* Retreive stored printer_settings data. */ | |
658 settingsData = data.otherData; | |
659 start = end = 0; | |
660 while (end < settingsData.length && settingsData[end] !is 0) { | |
661 start = end; | |
662 while (end < settingsData.length && settingsData[end] !is 0) end++; | |
663 end++; | |
664 char [] keyBuffer = new char [end - start]; | |
665 System.arraycopy (settingsData, start, keyBuffer, 0, keyBuffer.length); | |
666 start = end; | |
667 while (end < settingsData.length && settingsData[end] !is 0) end++; | |
668 end++; | |
669 char [] valueBuffer = new char [end - start]; | |
670 System.arraycopy (settingsData, start, valueBuffer, 0, valueBuffer.length); | |
671 OS.gtk_print_settings_set(settings, keyBuffer.ptr, valueBuffer.ptr); | |
672 if (DEBUG) tango.io.Stdout.Stdout.formatln("{}: {}", keyBuffer, valueBuffer); | |
673 } | |
674 end++; // skip extra null terminator | |
675 | |
676 /* Retreive stored page_setup data. | |
677 * Note that page_setup properties must be stored (in PrintDialog) and restored (here) in the same order. | |
678 */ | |
679 OS.gtk_page_setup_set_orientation(pageSetup, restoreInt("orientation")); //$NON-NLS-1$ | |
680 OS.gtk_page_setup_set_top_margin(pageSetup, restoreDouble("top_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ | |
681 OS.gtk_page_setup_set_bottom_margin(pageSetup, restoreDouble("bottom_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ | |
682 OS.gtk_page_setup_set_left_margin(pageSetup, restoreDouble("left_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ | |
683 OS.gtk_page_setup_set_right_margin(pageSetup, restoreDouble("right_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$ | |
684 char [] name = restoreBytes("paper_size_name", true); //$NON-NLS-1$ | |
685 char [] display_name = restoreBytes("paper_size_display_name", true); //$NON-NLS-1$ | |
686 char [] ppd_name = restoreBytes("paper_size_ppd_name", true); //$NON-NLS-1$ | |
687 double width = restoreDouble("paper_size_width"); //$NON-NLS-1$ | |
688 double height = restoreDouble("paper_size_height"); //$NON-NLS-1$ | |
689 bool custom = restoreBoolean("paper_size_is_custom"); //$NON-NLS-1$ | |
690 GtkPaperSize* paper_size; | |
691 if (custom) { | |
692 if (ppd_name.length > 0) { | |
693 paper_size = OS.gtk_paper_size_new_from_ppd(ppd_name.ptr, display_name.ptr, width, height); | |
694 } else { | |
695 paper_size = OS.gtk_paper_size_new_custom(name.ptr, display_name.ptr, width, height, OS.GTK_UNIT_MM); | |
696 } | |
697 } else { | |
698 paper_size = OS.gtk_paper_size_new(name.ptr); | |
699 } | |
700 OS.gtk_page_setup_set_paper_size(pageSetup, paper_size); | |
701 OS.g_free(paper_size); | |
702 } | |
703 | |
704 /* Set values of settings from PrinterData. */ | |
705 setScope(settings, data.scope_, data.startPage, data.endPage); | |
706 //TODO: Should we look at printToFile, or driver/name for "Print to File", or both? (see gtk bug 345590) | |
707 if (data.printToFile) { | |
708 char* buffer = tango.stdc.stringz.toStringz( data.fileName ); | |
709 OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI.ptr, buffer); | |
710 } | |
195 | 711 if (data.driver.equals("GtkPrintBackendFile") && data.name.equals("Print to File")) { //$NON-NLS-1$ //$NON-NLS-2$ |
91 | 712 char* buffer = tango.stdc.stringz.toStringz( data.fileName ); |
713 OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI.ptr, buffer); | |
714 } | |
715 OS.gtk_print_settings_set_n_copies(settings, data.copyCount); | |
716 OS.gtk_print_settings_set_collate(settings, data.collate); | |
717 } | |
718 | |
719 /** | |
720 * Returns a <code>PrinterData</code> object representing the | |
721 * target printer for this print job. | |
722 * | |
723 * @return a PrinterData object describing the receiver | |
724 */ | |
725 public PrinterData getPrinterData() { | |
726 checkDevice(); | |
727 return data; | |
728 } | |
729 | |
730 } |