KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > printing > Printer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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
10  *******************************************************************************/

11 package org.eclipse.swt.printing;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.graphics.*;
16 import org.eclipse.swt.internal.win32.*;
17
18 /**
19  * Instances of this class are used to print to a printer.
20  * Applications create a GC on a printer using <code>new GC(printer)</code>
21  * and then draw on the printer GC using the usual graphics calls.
22  * <p>
23  * A <code>Printer</code> object may be constructed by providing
24  * a <code>PrinterData</code> object which identifies the printer.
25  * A <code>PrintDialog</code> presents a print dialog to the user
26  * and returns an initialized instance of <code>PrinterData</code>.
27  * Alternatively, calling <code>new Printer()</code> will construct a
28  * printer object for the user's default printer.
29  * </p><p>
30  * Application code must explicitly invoke the <code>Printer.dispose()</code>
31  * method to release the operating system resources managed by each instance
32  * when those instances are no longer required.
33  * </p>
34  *
35  * @see PrinterData
36  * @see PrintDialog
37  */

38 public final class Printer extends Device {
39     /**
40      * the handle to the printer DC
41      * (Warning: This field is platform dependent)
42      * <p>
43      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
44      * public API. It is marked public only so that it can be shared
45      * within the packages provided by SWT. It is not available on all
46      * platforms and should never be accessed from application code.
47      * </p>
48      */

49     public int handle;
50
51     /**
52      * the printer data describing this printer
53      */

54     PrinterData data;
55
56     /**
57      * whether or not a GC was created for this printer
58      */

59     boolean isGCCreated = false;
60
61     /**
62      * strings used to access the Windows registry
63      */

64     static TCHAR profile;
65     static TCHAR appName;
66     static TCHAR keyName;
67     static {
68         profile = new TCHAR(0, "PrinterPorts", true); //$NON-NLS-1$
69
appName = new TCHAR(0, "windows", true); //$NON-NLS-1$
70
keyName = new TCHAR(0, "device", true); //$NON-NLS-1$
71
}
72     
73 /**
74  * Returns an array of <code>PrinterData</code> objects
75  * representing all available printers.
76  *
77  * @return the list of available printers
78  */

79 public static PrinterData[] getPrinterList() {
80     int length = 1024;
81     /* Use the character encoding for the default locale */
82     TCHAR buf = new TCHAR(0, length);
83     TCHAR nullBuf = new TCHAR(0, 1);
84     int n = OS.GetProfileString(profile, null, nullBuf, buf, length);
85     if (n == 0) return new PrinterData[0];
86     String JavaDoc[] deviceNames = new String JavaDoc[5];
87     int nameCount = 0;
88     int index = 0;
89     for (int i = 0; i < n; i++) {
90         if (buf.tcharAt(i) == 0) {
91             if (nameCount == deviceNames.length) {
92                 String JavaDoc[] newNames = new String JavaDoc[deviceNames.length + 5];
93                 System.arraycopy(deviceNames, 0, newNames, 0, deviceNames.length);
94                 deviceNames = newNames;
95             }
96             deviceNames[nameCount] = buf.toString(index, i - index);
97             nameCount++;
98             index = i + 1;
99         }
100     }
101     PrinterData printerList[] = new PrinterData[nameCount];
102     for (int p = 0; p < nameCount; p++) {
103         String JavaDoc device = deviceNames[p];
104         String JavaDoc driver = ""; //$NON-NLS-1$
105
if (OS.GetProfileString(profile, new TCHAR(0, device, true), nullBuf, buf, length) > 0) {
106             int commaIndex = 0;
107             while (buf.tcharAt(commaIndex) != ',' && commaIndex < length) commaIndex++;
108             if (commaIndex < length) {
109                 driver = buf.toString(0, commaIndex);
110             }
111         }
112         printerList[p] = new PrinterData(driver, device);
113     }
114     return printerList;
115 }
116
117 /**
118  * Returns a <code>PrinterData</code> object representing
119  * the default printer or <code>null</code> if there is no
120  * printer available on the System.
121  *
122  * @return the default printer data or null
123  *
124  * @since 2.1
125  */

126 public static PrinterData getDefaultPrinterData() {
127     String JavaDoc deviceName = null;
128     int length = 1024;
129     /* Use the character encoding for the default locale */
130     TCHAR buf = new TCHAR(0, length);
131     TCHAR nullBuf = new TCHAR(0, 1);
132     int n = OS.GetProfileString(appName, keyName, nullBuf, buf, length);
133     if (n == 0) return null;
134     int commaIndex = 0;
135     while(buf.tcharAt(commaIndex) != ',' && commaIndex < length) commaIndex++;
136     if (commaIndex < length) {
137         deviceName = buf.toString(0, commaIndex);
138     }
139     String JavaDoc driver = ""; //$NON-NLS-1$
140
if (OS.GetProfileString(profile, new TCHAR(0, deviceName, true), nullBuf, buf, length) > 0) {
141         commaIndex = 0;
142         while (buf.tcharAt(commaIndex) != ',' && commaIndex < length) commaIndex++;
143         if (commaIndex < length) {
144             driver = buf.toString(0, commaIndex);
145         }
146     }
147     return new PrinterData(driver, deviceName);
148 }
149
150 static DeviceData checkNull (PrinterData data) {
151     if (data == null) data = new PrinterData();
152     if (data.driver == null || data.name == null) {
153         PrinterData defaultPrinter = getDefaultPrinterData();
154         if (defaultPrinter == null) SWT.error(SWT.ERROR_NO_HANDLES);
155         data.driver = defaultPrinter.driver;
156         data.name = defaultPrinter.name;
157     }
158     return data;
159 }
160
161 /**
162  * Constructs a new printer representing the default printer.
163  * <p>
164  * You must dispose the printer when it is no longer required.
165  * </p>
166  *
167  * @exception SWTError <ul>
168  * <li>ERROR_NO_HANDLES - if there are no valid printers
169  * </ul>
170  *
171  * @see Device#dispose
172  */

173 public Printer() {
174     this(null);
175 }
176
177 /**
178  * Constructs a new printer given a <code>PrinterData</code>
179  * object representing the desired printer.
180  * <p>
181  * You must dispose the printer when it is no longer required.
182  * </p>
183  *
184  * @param data the printer data for the specified printer
185  *
186  * @exception IllegalArgumentException <ul>
187  * <li>ERROR_INVALID_ARGUMENT - if the specified printer data does not represent a valid printer
188  * </ul>
189  * @exception SWTError <ul>
190  * <li>ERROR_NO_HANDLES - if there are no valid printers
191  * </ul>
192  *
193  * @see Device#dispose
194  */

195 public Printer(PrinterData data) {
196     super(checkNull(data));
197 }
198
199 /**
200  * Creates the printer handle.
201  * This method is called internally by the instance creation
202  * mechanism of the <code>Device</code> class.
203  * @param deviceData the device data
204  */

205 protected void create(DeviceData deviceData) {
206     data = (PrinterData)deviceData;
207     /* Use the character encoding for the default locale */
208     TCHAR driver = new TCHAR(0, data.driver, true);
209     TCHAR device = new TCHAR(0, data.name, true);
210     int lpInitData = 0;
211     byte buffer [] = data.otherData;
212     int hHeap = OS.GetProcessHeap();
213     if (buffer != null && buffer.length != 0) {
214         /* If user setup info from a print dialog was specified, restore the DEVMODE struct. */
215         lpInitData = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, buffer.length);
216         OS.MoveMemory(lpInitData, buffer, buffer.length);
217     }
218     handle = OS.CreateDC(driver, device, 0, lpInitData);
219     if (lpInitData != 0) OS.HeapFree(hHeap, 0, lpInitData);
220     if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
221 }
222
223 /**
224  * Invokes platform specific functionality to allocate a new GC handle.
225  * <p>
226  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
227  * API for <code>Printer</code>. It is marked public only so that it
228  * can be shared within the packages provided by SWT. It is not
229  * available on all platforms, and should never be called from
230  * application code.
231  * </p>
232  *
233  * @param data the platform specific GC data
234  * @return the platform specific GC handle
235  */

236 public int internal_new_GC(GCData data) {
237     if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
238     if (data != null) {
239         if (isGCCreated) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
240         int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
241         if ((data.style & mask) != 0) {
242             data.layout = (data.style & SWT.RIGHT_TO_LEFT) != 0 ? OS.LAYOUT_RTL : 0;
243         } else {
244             data.style |= SWT.LEFT_TO_RIGHT;
245         }
246         data.device = this;
247         data.hFont = OS.GetCurrentObject(handle, OS.OBJ_FONT);
248         isGCCreated = true;
249     }
250     return handle;
251 }
252
253 /**
254  * Invokes platform specific functionality to dispose a GC handle.
255  * <p>
256  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
257  * API for <code>Printer</code>. It is marked public only so that it
258  * can be shared within the packages provided by SWT. It is not
259  * available on all platforms, and should never be called from
260  * application code.
261  * </p>
262  *
263  * @param hDC the platform specific GC handle
264  * @param data the platform specific GC data
265  */

266 public void internal_dispose_GC(int hDC, GCData data) {
267     if (data != null) isGCCreated = false;
268 }
269
270 /**
271  * Starts a print job and returns true if the job started successfully
272  * and false otherwise.
273  * <p>
274  * This must be the first method called to initiate a print job,
275  * followed by any number of startPage/endPage calls, followed by
276  * endJob. Calling startPage, endPage, or endJob before startJob
277  * will result in undefined behavior.
278  * </p>
279  *
280  * @param jobName the name of the print job to start
281  * @return true if the job started successfully and false otherwise.
282  *
283  * @exception SWTException <ul>
284  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
285  * </ul>
286  *
287  * @see #startPage
288  * @see #endPage
289  * @see #endJob
290  */

291 public boolean startJob(String JavaDoc jobName) {
292     checkDevice();
293     DOCINFO di = new DOCINFO();
294     di.cbSize = DOCINFO.sizeof;
295     int hHeap = OS.GetProcessHeap();
296     int lpszDocName = 0;
297     if (jobName != null && jobName.length() != 0) {
298         /* Use the character encoding for the default locale */
299         TCHAR buffer = new TCHAR(0, jobName, true);
300         int byteCount = buffer.length() * TCHAR.sizeof;
301         lpszDocName = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
302         OS.MoveMemory(lpszDocName, buffer, byteCount);
303         di.lpszDocName = lpszDocName;
304     }
305     int lpszOutput = 0;
306     if (data.printToFile && data.fileName != null) {
307         /* Use the character encoding for the default locale */
308         TCHAR buffer = new TCHAR(0, data.fileName, true);
309         int byteCount = buffer.length() * TCHAR.sizeof;
310         lpszOutput = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
311         OS.MoveMemory(lpszOutput, buffer, byteCount);
312         di.lpszOutput = lpszOutput;
313     }
314     int rc = OS.StartDoc(handle, di);
315     if (lpszDocName != 0) OS.HeapFree(hHeap, 0, lpszDocName);
316     if (lpszOutput != 0) OS.HeapFree(hHeap, 0, lpszOutput);
317     return rc > 0;
318 }
319
320 /**
321  * Ends the current print job.
322  *
323  * @exception SWTException <ul>
324  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
325  * </ul>
326  *
327  * @see #startJob
328  * @see #startPage
329  * @see #endPage
330  */

331 public void endJob() {
332     checkDevice();
333     OS.EndDoc(handle);
334 }
335
336 /**
337  * Cancels a print job in progress.
338  *
339  * @exception SWTException <ul>
340  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
341  * </ul>
342  */

343 public void cancelJob() {
344     checkDevice();
345     OS.AbortDoc(handle);
346 }
347
348 /**
349  * Starts a page and returns true if the page started successfully
350  * and false otherwise.
351  * <p>
352  * After calling startJob, this method may be called any number of times
353  * along with a matching endPage.
354  * </p>
355  *
356  * @return true if the page started successfully and false otherwise.
357  *
358  * @exception SWTException <ul>
359  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
360  * </ul>
361  *
362  * @see #endPage
363  * @see #startJob
364  * @see #endJob
365  */

366 public boolean startPage() {
367     checkDevice();
368     int rc = OS.StartPage(handle);
369     if (rc <= 0) OS.AbortDoc(handle);
370     return rc > 0;
371 }
372
373 /**
374  * Ends the current page.
375  *
376  * @exception SWTException <ul>
377  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
378  * </ul>
379  *
380  * @see #startPage
381  * @see #startJob
382  * @see #endJob
383  */

384 public void endPage() {
385     checkDevice();
386     OS.EndPage(handle);
387 }
388
389 /**
390  * Returns a point whose x coordinate is the horizontal
391  * dots per inch of the printer, and whose y coordinate
392  * is the vertical dots per inch of the printer.
393  *
394  * @return the horizontal and vertical DPI
395  *
396  * @exception SWTException <ul>
397  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
398  * </ul>
399  */

400 public Point getDPI() {
401     checkDevice();
402     int dpiX = OS.GetDeviceCaps(handle, OS.LOGPIXELSX);
403     int dpiY = OS.GetDeviceCaps(handle, OS.LOGPIXELSY);
404     return new Point(dpiX, dpiY);
405 }
406
407 /**
408  * Returns a rectangle describing the receiver's size and location.
409  * For a printer, this is the size of a physical page, in pixels.
410  *
411  * @return the bounding rectangle
412  *
413  * @exception SWTException <ul>
414  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
415  * </ul>
416  *
417  * @see #getClientArea
418  * @see #computeTrim
419  */

420 public Rectangle getBounds() {
421     checkDevice();
422     int width = OS.GetDeviceCaps(handle, OS.PHYSICALWIDTH);
423     int height = OS.GetDeviceCaps(handle, OS.PHYSICALHEIGHT);
424     return new Rectangle(0, 0, width, height);
425 }
426
427 /**
428  * Returns a rectangle which describes the area of the
429  * receiver which is capable of displaying data.
430  * For a printer, this is the size of the printable area
431  * of a page, in pixels.
432  *
433  * @return the client area
434  *
435  * @exception SWTException <ul>
436  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
437  * </ul>
438  *
439  * @see #getBounds
440  * @see #computeTrim
441  */

442 public Rectangle getClientArea() {
443     checkDevice();
444     int width = OS.GetDeviceCaps(handle, OS.HORZRES);
445     int height = OS.GetDeviceCaps(handle, OS.VERTRES);
446     return new Rectangle(0, 0, width, height);
447 }
448
449 /**
450  * Given a desired <em>client area</em> for the receiver
451  * (as described by the arguments), returns the bounding
452  * rectangle which would be required to produce that client
453  * area.
454  * <p>
455  * In other words, it returns a rectangle such that, if the
456  * receiver's bounds were set to that rectangle, the area
457  * of the receiver which is capable of displaying data
458  * (that is, not covered by the "trimmings") would be the
459  * rectangle described by the arguments (relative to the
460  * receiver's parent).
461  * </p><p>
462  * Note that there is no setBounds for a printer. This method
463  * is usually used by passing in the client area (the 'printable
464  * area') of the printer. It can also be useful to pass in 0, 0, 0, 0.
465  * </p>
466  *
467  * @param x the desired x coordinate of the client area
468  * @param y the desired y coordinate of the client area
469  * @param width the desired width of the client area
470  * @param height the desired height of the client area
471  * @return the required bounds to produce the given client area
472  *
473  * @exception SWTException <ul>
474  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
475  * </ul>
476  *
477  * @see #getBounds
478  * @see #getClientArea
479  */

480 public Rectangle computeTrim(int x, int y, int width, int height) {
481     checkDevice();
482     int printX = -OS.GetDeviceCaps(handle, OS.PHYSICALOFFSETX);
483     int printY = -OS.GetDeviceCaps(handle, OS.PHYSICALOFFSETY);
484     int printWidth = OS.GetDeviceCaps(handle, OS.HORZRES);
485     int printHeight = OS.GetDeviceCaps(handle, OS.VERTRES);
486     int paperWidth = OS.GetDeviceCaps(handle, OS.PHYSICALWIDTH);
487     int paperHeight = OS.GetDeviceCaps(handle, OS.PHYSICALHEIGHT);
488     int hTrim = paperWidth - printWidth;
489     int vTrim = paperHeight - printHeight;
490     return new Rectangle(x + printX, y + printY, width + hTrim, height + vTrim);
491 }
492
493 /**
494  * Returns a <code>PrinterData</code> object representing the
495  * target printer for this print job.
496  *
497  * @return a PrinterData object describing the receiver
498  */

499 public PrinterData getPrinterData() {
500     return data;
501 }
502
503 /**
504  * Checks the validity of this device.
505  *
506  * @exception SWTException <ul>
507  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
508  * </ul>
509  */

510 protected void checkDevice() {
511     if (handle == 0) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
512 }
513
514 /**
515  * Releases any internal state prior to destroying this printer.
516  * This method is called internally by the dispose
517  * mechanism of the <code>Device</code> class.
518  */

519 protected void release() {
520     super.release();
521     data = null;
522 }
523
524 /**
525  * Destroys the printer handle.
526  * This method is called internally by the dispose
527  * mechanism of the <code>Device</code> class.
528  */

529 protected void destroy() {
530     if (handle != 0) OS.DeleteDC(handle);
531     handle = 0;
532 }
533
534 }
535
Popular Tags