Mercurial > projects > dwt-win
comparison dwt/widgets/FileDialog.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 |
comparison
equal
deleted
inserted
replaced
212:ab60f3309436 | 213:36f5cb12e1a2 |
---|---|
41 public class FileDialog : Dialog { | 41 public class FileDialog : Dialog { |
42 String [] filterNames; | 42 String [] filterNames; |
43 String [] filterExtensions; | 43 String [] filterExtensions; |
44 String [] fileNames; | 44 String [] fileNames; |
45 String filterPath = "", fileName = ""; | 45 String filterPath = "", fileName = ""; |
46 static final String FILTER = "*.*"; | 46 int filterIndex = 0; |
47 bool overwrite = false; | |
48 static const String FILTER = "*.*"; | |
47 static int BUFFER_SIZE = 1024 * 32; | 49 static int BUFFER_SIZE = 1024 * 32; |
48 static bool USE_HOOK; | 50 static bool USE_HOOK = true; |
51 static this() { | |
52 /* | |
53 * Feature in Vista. When OFN_ENABLEHOOK is set in the | |
54 * save or open file dialog, Vista uses the old XP look | |
55 * and feel. OFN_ENABLEHOOK is used to grow the file | |
56 * name buffer in a multi-select file dialog. The fix | |
57 * is to only use OFN_ENABLEHOOK when the buffer has | |
58 * overrun. | |
59 */ | |
60 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | |
61 USE_HOOK = false; | |
62 } | |
63 } | |
49 | 64 |
50 /** | 65 /** |
51 * Constructs a new instance of this class given only its parent. | 66 * Constructs a new instance of this class given only its parent. |
52 * | 67 * |
53 * @param parent a shell which will be the parent of the new instance | 68 * @param parent a shell which will be the parent of the new instance |
59 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | 74 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
60 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | 75 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
61 * </ul> | 76 * </ul> |
62 */ | 77 */ |
63 public this (Shell parent) { | 78 public this (Shell parent) { |
64 this (parent, DWT.PRIMARY_MODAL); | 79 this (parent, DWT.APPLICATION_MODAL); |
65 } | 80 } |
66 | 81 |
67 /** | 82 /** |
68 * Constructs a new instance of this class given its parent | 83 * Constructs a new instance of this class given its parent |
69 * and a style value describing its behavior and appearance. | 84 * and a style value describing its behavior and appearance. |
87 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | 102 * <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> | 103 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
89 * </ul> | 104 * </ul> |
90 */ | 105 */ |
91 public this (Shell parent, int style) { | 106 public this (Shell parent, int style) { |
92 super (parent, style); | 107 super (parent, checkStyle (parent, style)); |
93 checkSubclass (); | 108 checkSubclass (); |
94 } | 109 } |
95 | 110 |
96 /** | 111 /** |
97 * Returns the path of the first file that was | 112 * Returns the path of the first file that was |
123 public String [] getFilterExtensions () { | 138 public String [] getFilterExtensions () { |
124 return filterExtensions; | 139 return filterExtensions; |
125 } | 140 } |
126 | 141 |
127 /** | 142 /** |
143 * Get the 0-based index of the file extension filter | |
144 * which was selected by the user, or -1 if no filter | |
145 * was selected. | |
146 * <p> | |
147 * This is an index into the FilterExtensions array and | |
148 * the FilterNames array. | |
149 * </p> | |
150 * | |
151 * @return index the file extension filter index | |
152 * | |
153 * @see #getFilterExtensions | |
154 * @see #getFilterNames | |
155 * | |
156 * @since 3.4 | |
157 */ | |
158 public int getFilterIndex () { | |
159 return filterIndex; | |
160 } | |
161 | |
162 /** | |
128 * Returns the names that describe the filter extensions | 163 * Returns the names that describe the filter extensions |
129 * which the dialog will use to filter the files it shows. | 164 * which the dialog will use to filter the files it shows. |
130 * | 165 * |
131 * @return the list of filter names | 166 * @return the list of filter names |
132 */ | 167 */ |
143 * | 178 * |
144 * @see #setFilterExtensions | 179 * @see #setFilterExtensions |
145 */ | 180 */ |
146 public String getFilterPath () { | 181 public String getFilterPath () { |
147 return filterPath; | 182 return filterPath; |
183 } | |
184 | |
185 /** | |
186 * Returns the flag that the dialog will use to | |
187 * determine whether to prompt the user for file | |
188 * overwrite if the selected file already exists. | |
189 * | |
190 * @return true if the dialog will prompt for file overwrite, false otherwise | |
191 * | |
192 * @since 3.4 | |
193 */ | |
194 public bool getOverwrite () { | |
195 return overwrite; | |
148 } | 196 } |
149 | 197 |
150 private static extern(Windows) uint OFNHookProc (HWND hdlg, uint uiMsg, uint wParam, int lParam) { | 198 private static extern(Windows) uint OFNHookProc (HWND hdlg, uint uiMsg, uint wParam, int lParam) { |
151 switch (uiMsg) { | 199 switch (uiMsg) { |
152 case OS.WM_NOTIFY: | 200 case OS.WM_NOTIFY: |
191 public String open () { | 239 public String open () { |
192 auto hHeap = OS.GetProcessHeap (); | 240 auto hHeap = OS.GetProcessHeap (); |
193 | 241 |
194 /* Get the owner HWND for the dialog */ | 242 /* Get the owner HWND for the dialog */ |
195 HWND hwndOwner; | 243 HWND hwndOwner; |
196 if (parent !is null) hwndOwner = parent.handle; | 244 auto hwndParent = parent.handle; |
245 | |
246 /* | |
247 * Feature in Windows. There is no API to set the orientation of a | |
248 * file dialog. It is always inherited from the parent. The fix is | |
249 * to create a hidden parent and set the orientation in the hidden | |
250 * parent for the dialog to inherit. | |
251 */ | |
252 bool enabled = false; | |
253 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(4, 10)) { | |
254 int dialogOrientation = style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); | |
255 int parentOrientation = parent.style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); | |
256 if (dialogOrientation !is parentOrientation) { | |
257 int exStyle = OS.WS_EX_NOINHERITLAYOUT; | |
258 if (dialogOrientation is DWT.RIGHT_TO_LEFT) exStyle |= OS.WS_EX_LAYOUTRTL; | |
259 hwndOwner = OS.CreateWindowEx ( | |
260 exStyle, | |
261 Shell.DialogClass.ptr, | |
262 null, | |
263 0, | |
264 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0, | |
265 hwndParent, | |
266 null, | |
267 OS.GetModuleHandle (null), | |
268 null); | |
269 enabled = OS.IsWindowEnabled (hwndParent) !is 0; | |
270 if (enabled) OS.EnableWindow (hwndParent, false); | |
271 } | |
272 } | |
197 | 273 |
198 /* Convert the title and copy it into lpstrTitle */ | 274 /* Convert the title and copy it into lpstrTitle */ |
199 if (title is null) title = ""; | 275 if (title is null) title = ""; |
200 /* Use the character encoding for the default locale */ | 276 /* Use the character encoding for the default locale */ |
201 TCHAR[] buffer3 = StrToTCHARs (0, title, true); | 277 TCHAR[] buffer3 = StrToTCHARs (0, title, true); |
251 | 327 |
252 /* Create the file dialog struct */ | 328 /* Create the file dialog struct */ |
253 OPENFILENAME struct_; | 329 OPENFILENAME struct_; |
254 struct_.lStructSize = OPENFILENAME.sizeof; | 330 struct_.lStructSize = OPENFILENAME.sizeof; |
255 struct_.Flags = OS.OFN_HIDEREADONLY | OS.OFN_NOCHANGEDIR; | 331 struct_.Flags = OS.OFN_HIDEREADONLY | OS.OFN_NOCHANGEDIR; |
256 //Callback callback = null; | 332 bool save = (style & DWT.SAVE) !is 0; |
333 if (save && overwrite) struct_.Flags |= OS.OFN_OVERWRITEPROMPT; | |
257 if ((style & DWT.MULTI) !is 0) { | 334 if ((style & DWT.MULTI) !is 0) { |
258 struct_.Flags |= OS.OFN_ALLOWMULTISELECT | OS.OFN_EXPLORER; | 335 struct_.Flags |= OS.OFN_ALLOWMULTISELECT | OS.OFN_EXPLORER; |
259 if (!OS.IsWinCE && USE_HOOK) { | 336 if (!OS.IsWinCE && USE_HOOK) { |
260 //callback = new Callback (this, "OFNHookProc", 4); //$NON-NLS-1$ | 337 //callback = new Callback (this, "OFNHookProc", 4); //$NON-NLS-1$ |
261 //int lpfnHook = callback.getAddress (); | 338 //int lpfnHook = callback.getAddress (); |
269 struct_.lpstrTitle = lpstrTitle; | 346 struct_.lpstrTitle = lpstrTitle; |
270 struct_.lpstrFile = lpstrFile; | 347 struct_.lpstrFile = lpstrFile; |
271 struct_.nMaxFile = nMaxFile; | 348 struct_.nMaxFile = nMaxFile; |
272 struct_.lpstrInitialDir = lpstrInitialDir; | 349 struct_.lpstrInitialDir = lpstrInitialDir; |
273 struct_.lpstrFilter = lpstrFilter; | 350 struct_.lpstrFilter = lpstrFilter; |
274 struct_.nFilterIndex = 0; | 351 struct_.nFilterIndex = filterIndex is 0 ? filterIndex : filterIndex + 1; |
275 | 352 |
276 /* | 353 /* |
277 * Set the default extension to an empty string. If the | 354 * Set the default extension to an empty string. If the |
278 * user fails to type an extension and this extension is | 355 * user fails to type an extension and this extension is |
279 * empty, Windows uses the current value of the filter | 356 * empty, Windows uses the current value of the filter |
280 * extension at the time that the dialog is closed. | 357 * extension at the time that the dialog is closed. |
281 */ | 358 */ |
282 TCHAR* lpstrDefExt; | 359 TCHAR* lpstrDefExt; |
283 bool save = (style & DWT.SAVE) !is 0; | |
284 if (save) { | 360 if (save) { |
285 lpstrDefExt = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, TCHAR.sizeof); | 361 lpstrDefExt = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, TCHAR.sizeof); |
286 struct_.lpstrDefExt = lpstrDefExt; | 362 struct_.lpstrDefExt = lpstrDefExt; |
287 } | 363 } |
288 | 364 |
289 /* Make the parent shell be temporary modal */ | 365 /* Make the parent shell be temporary modal */ |
290 Shell oldModal = null; | 366 Dialog oldModal = null; |
291 Display display = parent.getDisplay (); | 367 Display display = parent.getDisplay (); |
292 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { | 368 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { |
293 oldModal = display.getModalDialogShell (); | 369 oldModal = display.getModalDialog (); |
294 display.setModalDialogShell (parent); | 370 display.setModalDialog (this); |
295 } | 371 } |
296 | 372 |
297 /* | 373 /* |
298 * Feature in Windows. For some reason, the WH_MSGFILTER filter | 374 * Feature in Windows. For some reason, the WH_MSGFILTER filter |
299 * does not run for GetSaveFileName() or GetOpenFileName(). The | 375 * does not run for GetSaveFileName() or GetOpenFileName(). The |
325 } | 401 } |
326 display.runMessagesInIdle = oldRunMessagesInIdle; | 402 display.runMessagesInIdle = oldRunMessagesInIdle; |
327 | 403 |
328 /* Clear the temporary dialog modal parent */ | 404 /* Clear the temporary dialog modal parent */ |
329 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { | 405 if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) { |
330 display.setModalDialogShell (oldModal); | 406 display.setModalDialog (oldModal); |
331 } | 407 } |
332 | 408 |
333 /* Dispose the callback and reassign the buffer */ | 409 /* Dispose the callback and reassign the buffer */ |
334 //if (callback !is null) callback.dispose (); | 410 //if (callback !is null) callback.dispose (); |
335 lpstrFile = struct_.lpstrFile; | 411 lpstrFile = struct_.lpstrFile; |
336 | 412 |
337 /* Set the new path, file name and filter */ | 413 /* Set the new path, file name and filter */ |
338 fileNames = new String [0]; | 414 fileNames = null; |
339 String fullPath = null; | 415 String fullPath = null; |
340 if (success) { | 416 if (success) { |
341 | 417 |
342 /* Use the character encoding for the default locale */ | 418 /* Use the character encoding for the default locale */ |
343 TCHAR[] buffer = NewTCHARs (0, struct_.nMaxFile); | 419 TCHAR[] buffer = NewTCHARs (0, struct_.nMaxFile); |
406 String [] newFileNames = new String[]( count ); | 482 String [] newFileNames = new String[]( count ); |
407 System.arraycopy (fileNames, 0, newFileNames, 0, count); | 483 System.arraycopy (fileNames, 0, newFileNames, 0, count); |
408 fileNames = newFileNames; | 484 fileNames = newFileNames; |
409 } | 485 } |
410 } | 486 } |
487 filterIndex = struct_.nFilterIndex - 1; | |
411 } | 488 } |
412 | 489 |
413 /* Free the memory that was allocated. */ | 490 /* Free the memory that was allocated. */ |
414 OS.HeapFree (hHeap, 0, lpstrFile); | 491 OS.HeapFree (hHeap, 0, lpstrFile); |
415 OS.HeapFree (hHeap, 0, lpstrFilter); | 492 OS.HeapFree (hHeap, 0, lpstrFilter); |
416 OS.HeapFree (hHeap, 0, lpstrInitialDir); | 493 OS.HeapFree (hHeap, 0, lpstrInitialDir); |
417 OS.HeapFree (hHeap, 0, lpstrTitle); | 494 OS.HeapFree (hHeap, 0, lpstrTitle); |
418 if (lpstrDefExt !is null) OS.HeapFree (hHeap, 0, lpstrDefExt); | 495 if (lpstrDefExt !is null) OS.HeapFree (hHeap, 0, lpstrDefExt); |
496 | |
497 /* Destroy the BIDI orientation window */ | |
498 if (hwndParent !is hwndOwner) { | |
499 if (enabled) OS.EnableWindow (hwndParent, true); | |
500 OS.SetActiveWindow (hwndParent); | |
501 OS.DestroyWindow (hwndOwner); | |
502 } | |
419 | 503 |
420 /* | 504 /* |
421 * This code is intentionally commented. On some | 505 * This code is intentionally commented. On some |
422 * platforms, the owner window is repainted right | 506 * platforms, the owner window is repainted right |
423 * away when a dialog window exits. This behavior | 507 * away when a dialog window exits. This behavior |
459 public void setFilterExtensions (String [] extensions) { | 543 public void setFilterExtensions (String [] extensions) { |
460 filterExtensions = extensions; | 544 filterExtensions = extensions; |
461 } | 545 } |
462 | 546 |
463 /** | 547 /** |
464 * Sets the the names that describe the filter extensions | 548 * Set the 0-based index of the file extension filter |
549 * which the dialog will use initially to filter the files | |
550 * it shows to the argument. | |
551 * <p> | |
552 * This is an index into the FilterExtensions array and | |
553 * the FilterNames array. | |
554 * </p> | |
555 * | |
556 * @param index the file extension filter index | |
557 * | |
558 * @see #setFilterExtensions | |
559 * @see #setFilterNames | |
560 * | |
561 * @since 3.4 | |
562 */ | |
563 public void setFilterIndex (int index) { | |
564 filterIndex = index; | |
565 } | |
566 | |
567 /** | |
568 * Sets the names that describe the filter extensions | |
465 * which the dialog will use to filter the files it shows | 569 * which the dialog will use to filter the files it shows |
466 * to the argument, which may be null. | 570 * to the argument, which may be null. |
467 * <p> | 571 * <p> |
468 * Each name is a user-friendly short description shown for | 572 * Each name is a user-friendly short description shown for |
469 * its corresponding filter. The <code>names</code> array must | 573 * its corresponding filter. The <code>names</code> array must |
497 */ | 601 */ |
498 public void setFilterPath (String string) { | 602 public void setFilterPath (String string) { |
499 filterPath = string; | 603 filterPath = string; |
500 } | 604 } |
501 | 605 |
502 } | 606 /** |
503 | 607 * Sets the flag that the dialog will use to |
608 * determine whether to prompt the user for file | |
609 * overwrite if the selected file already exists. | |
610 * | |
611 * @param overwrite true if the dialog will prompt for file overwrite, false otherwise | |
612 * | |
613 * @since 3.4 | |
614 */ | |
615 public void setOverwrite (bool overwrite) { | |
616 this.overwrite = overwrite; | |
617 } | |
618 } | |
619 |