Mercurial > projects > dwt-win
annotate dwt/printing/PrintDialog.d @ 213:36f5cb12e1a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 17 May 2008 17:34:28 +0200 |
parents | ab60f3309436 |
children | fd9c62a2998e |
rev | line source |
---|---|
152 | 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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwt.printing.PrintDialog; | |
14 | |
15 | |
16 import dwt.DWT; | |
17 import dwt.DWTException; | |
18 import dwt.internal.win32.OS; | |
19 import dwt.widgets.Control; | |
20 import dwt.widgets.Dialog; | |
21 import dwt.widgets.Display; | |
22 import dwt.widgets.Shell; | |
23 import dwt.widgets.Widget; | |
24 | |
25 import dwt.printing.Printer; | |
26 import dwt.printing.PrinterData; | |
27 | |
28 import dwt.dwthelper.utils; | |
29 | |
30 /** | |
31 * Instances of this class allow the user to select | |
32 * a printer and various print-related parameters | |
33 * prior to starting a print job. | |
34 * <p> | |
35 * IMPORTANT: This class is intended to be subclassed <em>only</em> | |
36 * within the DWT implementation. | |
37 * </p> | |
38 */ | |
39 | |
40 public class PrintDialog : Dialog { | |
213 | 41 PrinterData printerData; |
152 | 42 int scope_ = PrinterData.ALL_PAGES; |
43 int startPage = 1, endPage = 1; | |
44 bool printToFile = false; | |
45 | |
46 /** | |
47 * Constructs a new instance of this class given only its parent. | |
48 * | |
49 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
50 * | |
51 * @exception IllegalArgumentException <ul> | |
52 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
53 * </ul> | |
54 * @exception DWTException <ul> | |
55 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
56 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
57 * </ul> | |
58 * | |
59 * @see DWT | |
60 * @see Widget#checkSubclass | |
61 * @see Widget#getStyle | |
62 */ | |
63 public this (Shell parent) { | |
64 this (parent, DWT.PRIMARY_MODAL); | |
65 } | |
66 | |
67 /** | |
68 * Constructs a new instance of this class given its parent | |
69 * and a style value describing its behavior and appearance. | |
70 * <p> | |
71 * The style value is either one of the style constants defined in | |
72 * class <code>DWT</code> which is applicable to instances of this | |
73 * class, or must be built by <em>bitwise OR</em>'ing together | |
74 * (that is, using the <code>int</code> "|" operator) two or more | |
75 * of those <code>DWT</code> style constants. The class description | |
76 * lists the style constants that are applicable to the class. | |
77 * Style bits are also inherited from superclasses. | |
78 * </p> | |
79 * | |
80 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
81 * @param style the style of control to construct | |
82 * | |
83 * @exception IllegalArgumentException <ul> | |
84 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
85 * </ul> | |
86 * @exception DWTException <ul> | |
87 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
88 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
89 * </ul> | |
90 * | |
91 * @see DWT | |
92 * @see Widget#checkSubclass | |
93 * @see Widget#getStyle | |
94 */ | |
95 public this (Shell parent, int style) { | |
96 super (parent, style); | |
97 checkSubclass (); | |
98 } | |
99 | |
100 /** | |
213 | 101 * Sets the printer data that will be used when the dialog |
102 * is opened. | |
103 * | |
104 * @param data the data that will be used when the dialog is opened | |
105 * | |
106 * @since 3.4 | |
107 */ | |
108 public void setPrinterData(PrinterData data) { | |
109 this.printerData = data; | |
110 } | |
111 | |
112 /** | |
113 * Returns the printer data that will be used when the dialog | |
114 * is opened. | |
115 * | |
116 * @return the data that will be used when the dialog is opened | |
117 * | |
118 * @since 3.4 | |
119 */ | |
120 public PrinterData getPrinterData() { | |
121 return printerData; | |
122 } | |
123 | |
124 /** | |
152 | 125 * Returns the print job scope that the user selected |
126 * before pressing OK in the dialog. This will be one | |
127 * of the following values: | |
128 * <dl> | |
213 | 129 * <dt><code>PrinterData.ALL_PAGES</code></dt> |
152 | 130 * <dd>Print all pages in the current document</dd> |
213 | 131 * <dt><code>PrinterData.PAGE_RANGE</code></dt> |
152 | 132 * <dd>Print the range of pages specified by startPage and endPage</dd> |
213 | 133 * <dt><code>PrinterData.SELECTION</code></dt> |
152 | 134 * <dd>Print the current selection</dd> |
135 * </dl> | |
136 * | |
137 * @return the scope setting that the user selected | |
138 */ | |
139 public int getScope() { | |
140 return scope_; | |
141 } | |
142 | |
143 /** | |
144 * Sets the scope of the print job. The user will see this | |
145 * setting when the dialog is opened. This can have one of | |
146 * the following values: | |
147 * <dl> | |
213 | 148 * <dt><code>PrinterData.ALL_PAGES</code></dt> |
152 | 149 * <dd>Print all pages in the current document</dd> |
213 | 150 * <dt><code>PrinterData.PAGE_RANGE</code></dt> |
152 | 151 * <dd>Print the range of pages specified by startPage and endPage</dd> |
213 | 152 * <dt><code>PrinterData.SELECTION</code></dt> |
152 | 153 * <dd>Print the current selection</dd> |
154 * </dl> | |
155 * | |
156 * @param scope the scope setting when the dialog is opened | |
157 */ | |
158 public void setScope(int scope_) { | |
159 this.scope_ = scope_; | |
160 } | |
161 | |
162 /** | |
163 * Returns the start page setting that the user selected | |
164 * before pressing OK in the dialog. | |
165 * <p> | |
166 * This value can be from 1 to the maximum number of pages for the platform. | |
213 | 167 * Note that it is only valid if the scope is <code>PrinterData.PAGE_RANGE</code>. |
152 | 168 * </p> |
169 * | |
170 * @return the start page setting that the user selected | |
171 */ | |
172 public int getStartPage() { | |
173 return startPage; | |
174 } | |
175 | |
176 /** | |
177 * Sets the start page that the user will see when the dialog | |
178 * is opened. | |
179 * <p> | |
180 * This value can be from 1 to the maximum number of pages for the platform. | |
213 | 181 * Note that it is only valid if the scope is <code>PrinterData.PAGE_RANGE</code>. |
152 | 182 * </p> |
183 * | |
184 * @param startPage the startPage setting when the dialog is opened | |
185 */ | |
186 public void setStartPage(int startPage) { | |
187 this.startPage = startPage; | |
188 } | |
189 | |
190 /** | |
191 * Returns the end page setting that the user selected | |
192 * before pressing OK in the dialog. | |
193 * <p> | |
194 * This value can be from 1 to the maximum number of pages for the platform. | |
213 | 195 * Note that it is only valid if the scope is <code>PrinterData.PAGE_RANGE</code>. |
152 | 196 * </p> |
197 * | |
198 * @return the end page setting that the user selected | |
199 */ | |
200 public int getEndPage() { | |
201 return endPage; | |
202 } | |
203 | |
204 /** | |
205 * Sets the end page that the user will see when the dialog | |
206 * is opened. | |
207 * <p> | |
208 * This value can be from 1 to the maximum number of pages for the platform. | |
213 | 209 * Note that it is only valid if the scope is <code>PrinterData.PAGE_RANGE</code>. |
152 | 210 * </p> |
211 * | |
212 * @param endPage the end page setting when the dialog is opened | |
213 */ | |
214 public void setEndPage(int endPage) { | |
215 this.endPage = endPage; | |
216 } | |
217 | |
218 /** | |
219 * Returns the 'Print to file' setting that the user selected | |
220 * before pressing OK in the dialog. | |
221 * | |
222 * @return the 'Print to file' setting that the user selected | |
223 */ | |
224 public bool getPrintToFile() { | |
225 return printToFile; | |
226 } | |
227 | |
228 /** | |
229 * Sets the 'Print to file' setting that the user will see | |
230 * when the dialog is opened. | |
231 * | |
232 * @param printToFile the 'Print to file' setting when the dialog is opened | |
233 */ | |
234 public void setPrintToFile(bool printToFile) { | |
235 this.printToFile = printToFile; | |
236 } | |
237 | |
238 protected void checkSubclass() { | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
239 String name = this.classinfo.name; |
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
240 String validName = PrintDialog.classinfo.name; |
152 | 241 if (validName!=/*eq*/name) { |
242 DWT.error(DWT.ERROR_INVALID_SUBCLASS); | |
243 } | |
244 } | |
245 | |
246 /** | |
247 * Makes the receiver visible and brings it to the front | |
248 * of the display. | |
249 * | |
250 * @return a printer data object describing the desired print job parameters | |
251 * | |
252 * @exception DWTException <ul> | |
253 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
254 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
255 * </ul> | |
256 */ | |
257 public PrinterData open() { | |
258 PRINTDLG pd; | |
259 pd.lStructSize = PRINTDLG.sizeof; | |
260 Control parent = getParent(); | |
261 if (parent !is null) pd.hwndOwner = parent.handle; | |
213 | 262 void* lpInitData; |
263 auto hHeap = OS.GetProcessHeap(); | |
264 if (printerData !is null) { | |
265 byte buffer [] = printerData.otherData; | |
266 if (buffer !is null && buffer.length !is 0) { | |
267 /* If user setup info from a previous print dialog was specified, restore the DEVMODE struct. */ | |
268 lpInitData = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, buffer.length); | |
269 OS.MoveMemory(lpInitData, buffer.ptr, buffer.length); | |
270 pd.hDevMode = lpInitData; | |
271 } | |
272 } | |
152 | 273 pd.Flags = OS.PD_USEDEVMODECOPIESANDCOLLATE; |
274 if (printToFile) pd.Flags |= OS.PD_PRINTTOFILE; | |
275 switch (scope_) { | |
276 case PrinterData.PAGE_RANGE: pd.Flags |= OS.PD_PAGENUMS; break; | |
277 case PrinterData.SELECTION: pd.Flags |= OS.PD_SELECTION; break; | |
278 default: pd.Flags |= OS.PD_ALLPAGES; | |
279 } | |
280 pd.nMinPage = 1; | |
281 pd.nMaxPage = cast(ushort)-1; | |
282 pd.nFromPage = cast(short) Math.min (0xFFFF, Math.max (1, startPage)); | |
283 pd.nToPage = cast(short) Math.min (0xFFFF, Math.max (1, endPage)); | |
284 | |
285 Display display = parent.getDisplay(); | |
286 Shell [] shells = display.getShells(); | |
287 if ((getStyle() & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { | |
288 for (int i=0; i<shells.length; i++) { | |
289 if (shells[i].isEnabled() && shells[i] !is parent) { | |
290 shells[i].setEnabled(false); | |
291 } else { | |
292 shells[i] = null; | |
293 } | |
294 } | |
295 } | |
296 PrinterData data = null; | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
297 String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$ |
152 | 298 Object oldValue = display.getData(key); |
299 display.setData(key, new ValueWrapperBool(true)); | |
300 bool success = cast(bool)OS.PrintDlg(&pd); | |
301 display.setData(key, oldValue); | |
302 if ((getStyle() & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { | |
303 for (int i=0; i<shells.length; i++) { | |
304 if (shells[i] !is null && !shells[i].isDisposed ()) { | |
305 shells[i].setEnabled(true); | |
306 } | |
307 } | |
308 } | |
309 | |
310 if (success) { | |
311 /* Get driver and device from the DEVNAMES struct */ | |
312 auto hMem = pd.hDevNames; | |
313 /* Ensure size is a multiple of 2 bytes on UNICODE platforms */ | |
314 int size = OS.GlobalSize(hMem) / TCHAR.sizeof * TCHAR.sizeof; | |
315 auto ptr = OS.GlobalLock(hMem); | |
316 short[4] offsets; | |
317 OS.MoveMemory(offsets.ptr, ptr, 2 * offsets.length); | |
318 TCHAR[] buffer = NewTCHARs(0, size); | |
319 OS.MoveMemory(buffer.ptr, ptr, size); | |
320 OS.GlobalUnlock(hMem); | |
321 | |
322 int driverOffset = offsets[0]; | |
323 int i = 0; | |
324 while (driverOffset + i < size) { | |
325 if (buffer[driverOffset + i] is 0) break; | |
326 i++; | |
327 } | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
328 String driver = TCHARsToStr( buffer[driverOffset .. driverOffset+i] ); |
152 | 329 |
330 int deviceOffset = offsets[1]; | |
331 i = 0; | |
332 while (deviceOffset + i < size) { | |
333 if (buffer[deviceOffset + i] is 0) break; | |
334 i++; | |
335 } | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
336 String device = TCHARsToStr( buffer[deviceOffset .. deviceOffset+i] ); |
152 | 337 |
338 int outputOffset = offsets[2]; | |
339 i = 0; | |
340 while (outputOffset + i < size) { | |
341 if (buffer[outputOffset + i] is 0) break; | |
342 i++; | |
343 } | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
344 String output = TCHARsToStr( buffer[outputOffset .. outputOffset+i] ); |
152 | 345 |
346 /* Create PrinterData object and set fields from PRINTDLG */ | |
347 data = new PrinterData(driver, device); | |
348 if ((pd.Flags & OS.PD_PAGENUMS) !is 0) { | |
349 data.scope_ = PrinterData.PAGE_RANGE; | |
350 data.startPage = pd.nFromPage & 0xFFFF; | |
351 data.endPage = pd.nToPage & 0xFFFF; | |
352 } else if ((pd.Flags & OS.PD_SELECTION) !is 0) { | |
353 data.scope_ = PrinterData.SELECTION; | |
354 } | |
355 data.printToFile = (pd.Flags & OS.PD_PRINTTOFILE) !is 0; | |
356 if (data.printToFile) data.fileName = output; | |
357 data.copyCount = pd.nCopies; | |
358 data.collate = (pd.Flags & OS.PD_COLLATE) !is 0; | |
359 | |
360 /* Bulk-save the printer-specific settings in the DEVMODE struct */ | |
361 hMem = pd.hDevMode; | |
362 size = OS.GlobalSize(hMem); | |
363 ptr = OS.GlobalLock(hMem); | |
364 data.otherData = new byte[size]; | |
365 OS.MoveMemory(data.otherData.ptr, ptr, size); | |
366 OS.GlobalUnlock(hMem); | |
213 | 367 if (lpInitData !is null) OS.HeapFree(hHeap, 0, lpInitData); |
152 | 368 |
369 endPage = data.endPage; | |
370 printToFile = data.printToFile; | |
371 scope_ = data.scope_; | |
372 startPage = data.startPage; | |
373 } | |
374 return data; | |
375 } | |
376 } |