root/dwt/widgets/FileDialog.d

Revision 263:27244095ce14, 21.6 kB (checked in by Frank Benoit <benoit@tionex.de>, 4 months ago)

Fix struct sizes, based on a comparison to the values seen by C apps.

Line 
1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 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.widgets.FileDialog;
14
15
16 import dwt.DWT;
17 import dwt.DWTException;
18 import dwt.internal.win32.OS;
19 import dwt.widgets.Dialog;
20 import dwt.widgets.Shell;
21 import dwt.widgets.Display;
22
23 import dwt.dwthelper.utils;
24
25 /**
26  * Instances of this class allow the user to navigate
27  * the file system and select or enter a file name.
28  * <dl>
29  * <dt><b>Styles:</b></dt>
30  * <dd>SAVE, OPEN, MULTI</dd>
31  * <dt><b>Events:</b></dt>
32  * <dd>(none)</dd>
33  * </dl>
34  * <p>
35  * Note: Only one of the styles SAVE and OPEN may be specified.
36  * </p><p>
37  * IMPORTANT: This class is intended to be subclassed <em>only</em>
38  * within the DWT implementation.
39  * </p>
40  *
41  * @see <a href="http://www.eclipse.org/swt/snippets/#filedialog">FileDialog snippets</a>
42  * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample, Dialog tab</a>
43  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
44  */
45 public class FileDialog : Dialog {
46     String [] filterNames;
47     String [] filterExtensions;
48     String [] fileNames;
49     String filterPath = "", fileName = "";
50     int filterIndex = 0;
51     bool overwrite = false;
52     static const String FILTER = "*.*";
53     static int BUFFER_SIZE = 1024 * 32;
54     static bool USE_HOOK = true;
55     static this() {
56         /*
57         *  Feature in Vista.  When OFN_ENABLEHOOK is set in the
58         *  save or open file dialog,  Vista uses the old XP look
59         *  and feel.  OFN_ENABLEHOOK is used to grow the file
60         *  name buffer in a multi-select file dialog.  The fix
61         *  is to only use OFN_ENABLEHOOK when the buffer has
62         *  overrun.
63         */
64         if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {
65             USE_HOOK = false;
66         }
67     }
68
69 /**
70  * Constructs a new instance of this class given only its parent.
71  *
72  * @param parent a shell which will be the parent of the new instance
73  *
74  * @exception IllegalArgumentException <ul>
75  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
76  * </ul>
77  * @exception DWTException <ul>
78  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
79  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
80  * </ul>
81  */
82 public this (Shell parent) {
83     this (parent, DWT.APPLICATION_MODAL);
84 }
85
86 /**
87  * Constructs a new instance of this class given its parent
88  * and a style value describing its behavior and appearance.
89  * <p>
90  * The style value is either one of the style constants defined in
91  * class <code>DWT</code> which is applicable to instances of this
92  * class, or must be built by <em>bitwise OR</em>'ing together
93  * (that is, using the <code>int</code> "|" operator) two or more
94  * of those <code>DWT</code> style constants. The class description
95  * lists the style constants that are applicable to the class.
96  * Style bits are also inherited from superclasses.
97  * </p>
98  *
99  * @param parent a shell which will be the parent of the new instance
100  * @param style the style of dialog to construct
101  *
102  * @exception IllegalArgumentException <ul>
103  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
104  * </ul>
105  * @exception DWTException <ul>
106  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
107  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
108  * </ul>
109  */
110 public this (Shell parent, int style) {
111     super (parent, checkStyle (parent, style));
112     checkSubclass ();
113 }
114
115 /**
116  * Returns the path of the first file that was
117  * selected in the dialog relative to the filter path, or an
118  * empty string if no such file has been selected.
119  *
120  * @return the relative path of the file
121  */
122 public String getFileName () {
123     return fileName;
124 }
125
126 /**
127  * Returns a (possibly empty) array with the paths of all files
128  * that were selected in the dialog relative to the filter path.
129  *
130  * @return the relative paths of the files
131  */
132 public String [] getFileNames () {
133     return fileNames;
134 }
135
136 /**
137  * Returns the file extensions which the dialog will
138  * use to filter the files it shows.
139  *
140  * @return the file extensions filter
141  */
142 public String [] getFilterExtensions () {
143     return filterExtensions;
144 }
145
146 /**
147  * Get the 0-based index of the file extension filter
148  * which was selected by the user, or -1 if no filter
149  * was selected.
150  * <p>
151  * This is an index into the FilterExtensions array and
152  * the FilterNames array.
153  * </p>
154  *
155  * @return index the file extension filter index
156  *
157  * @see #getFilterExtensions
158  * @see #getFilterNames
159  *
160  * @since 3.4
161  */
162 public int getFilterIndex () {
163     return filterIndex;
164 }
165
166 /**
167  * Returns the names that describe the filter extensions
168  * which the dialog will use to filter the files it shows.
169  *
170  * @return the list of filter names
171  */
172 public String [] getFilterNames () {
173     return filterNames;
174 }
175
176 /**
177  * Returns the directory path that the dialog will use, or an empty
178  * string if this is not set.  File names in this path will appear
179  * in the dialog, filtered according to the filter extensions.
180  *
181  * @return the directory path string
182  *
183  * @see #setFilterExtensions
184  */
185 public String getFilterPath () {
186     return filterPath;
187 }
188
189 /**
190  * Returns the flag that the dialog will use to
191  * determine whether to prompt the user for file
192  * overwrite if the selected file already exists.
193  *
194  * @return true if the dialog will prompt for file overwrite, false otherwise
195  *
196  * @since 3.4
197  */
198 public bool getOverwrite () {
199     return overwrite;
200 }
201
202 private static extern(Windows) uint OFNHookProc (HWND hdlg, uint uiMsg, uint wParam, int lParam) {
203     switch (uiMsg) {
204         case OS.WM_NOTIFY:
205             OFNOTIFY* ofn = cast(OFNOTIFY*)lParam;
206             //OS.MoveMemory (ofn, lParam, OFNOTIFY.sizeof);
207             if (ofn.hdr.code is OS.CDN_SELCHANGE) {
208                 int lResult = OS.SendMessage (ofn.hdr.hwndFrom, OS.CDM_GETSPEC, 0, 0);
209                 if (lResult > 0) {
210                     lResult += OS.MAX_PATH;
211                     OPENFILENAME* lpofn = ofn.lpOFN;
212                     //OS.MoveMemory (lpofn, ofn.lpOFN, OS.OPENFILENAME_sizeof);
213                     if (lpofn.nMaxFile < lResult) {
214                         auto hHeap = OS.GetProcessHeap ();
215                         auto lpstrFile = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, lResult * TCHAR.sizeof);
216                         if (lpstrFile !is null) {
217                             if (lpofn.lpstrFile !is null) OS.HeapFree (hHeap, 0, lpofn.lpstrFile);
218                             lpofn.lpstrFile = lpstrFile;
219                             lpofn.nMaxFile = lResult;
220                             //OS.MoveMemory (ofn.lpOFN, lpofn, OS.OPENFILENAME_sizeof);
221                         }
222                     }
223               }
224           }
225           break;
226         default:
227     }
228     return 0;
229 }
230
231 /**
232  * Makes the dialog visible and brings it to the front
233  * of the display.
234  *
235  * @return a string describing the absolute path of the first selected file,
236  *         or null if the dialog was cancelled or an error occurred
237  *
238  * @exception DWTException <ul>
239  *    <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
240  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
241  * </ul>
242  */
243 public String open () {
244     auto hHeap = OS.GetProcessHeap ();
245
246     /* Get the owner HWND for the dialog */
247     HWND hwndOwner;
248     auto hwndParent = parent.handle;
249
250     /*
251     * Feature in Windows.  There is no API to set the orientation of a
252     * file dialog.  It is always inherited from the parent.  The fix is
253     * to create a hidden parent and set the orientation in the hidden
254     * parent for the dialog to inherit.
255     */
256     bool enabled = false;
257     if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(4, 10)) {
258         int dialogOrientation = style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT);
259         int parentOrientation = parent.style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT);
260         if (dialogOrientation !is parentOrientation) {
261             int exStyle = OS.WS_EX_NOINHERITLAYOUT;
262             if (dialogOrientation is DWT.RIGHT_TO_LEFT) exStyle |= OS.WS_EX_LAYOUTRTL;
263             hwndOwner = OS.CreateWindowEx (
264                 exStyle,
265                 Shell.DialogClass.ptr,
266                 null,
267                 0,
268                 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0,
269                 hwndParent,
270                 null,
271                 OS.GetModuleHandle (null),
272                 null);
273             enabled = OS.IsWindowEnabled (hwndParent) !is 0;
274             if (enabled) OS.EnableWindow (hwndParent, false);
275         }
276     }
277
278     /* Convert the title and copy it into lpstrTitle */
279     if (title is null) title = "";
280     /* Use the character encoding for the default locale */
281     TCHAR[] buffer3 = StrToTCHARs (0, title, true);
282     int byteCount3 = buffer3.length * TCHAR.sizeof;
283     auto lpstrTitle = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount3);
284     OS.MoveMemory (lpstrTitle, buffer3.ptr, byteCount3);
285
286     /* Compute filters and copy into lpstrFilter */
287     String strFilter = "";
288     if (filterNames is null) filterNames = null;
289     if (filterExtensions is null) filterExtensions = null;
290     for (int i=0; i<filterExtensions.length; i++) {
291         String filterName = filterExtensions [i];
292         if (i < filterNames.length) filterName = filterNames [i];
293         strFilter = strFilter ~ filterName ~ '\0' ~ filterExtensions [i] ~ '\0';
294     }
295     if (filterExtensions.length is 0) {
296         strFilter = strFilter ~ FILTER ~ '\0' ~ FILTER ~ '\0';
297     }
298     /* Use the character encoding for the default locale */
299     TCHAR[] buffer4 = StrToTCHARs (0, strFilter, true);
300     int byteCount4 = buffer4.length * TCHAR.sizeof;
301     auto lpstrFilter = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount4);
302     OS.MoveMemory (lpstrFilter, buffer4.ptr, byteCount4);
303
304     /* Convert the fileName and filterName to C strings */
305     if (fileName is null) fileName = "";
306     /* Use the character encoding for the default locale */
307     TCHAR[] name = StrToTCHARs (0, fileName, true);
308
309     /*
310     * Copy the name into lpstrFile and ensure that the
311     * last byte is NULL and the buffer does not overrun.
312     */
313     int nMaxFile = OS.MAX_PATH;
314     if ((style & DWT.MULTI) !is 0) nMaxFile = Math.max (nMaxFile, BUFFER_SIZE);
315     int byteCount = nMaxFile * TCHAR.sizeof;
316     auto lpstrFile = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
317     int byteCountFile = Math.min (name.length * TCHAR.sizeof, byteCount - TCHAR.sizeof);
318     OS.MoveMemory (lpstrFile, name.ptr, byteCountFile);
319
320     /*
321     * Copy the path into lpstrInitialDir and ensure that
322     * the last byte is NULL and the buffer does not overrun.
323     */
324     if (filterPath is null) filterPath = "";
325     /* Use the character encoding for the default locale */
326     TCHAR[] path = StrToTCHARs (0, filterPath.replace ('/', '\\'), true);
327     int byteCount5 = OS.MAX_PATH * TCHAR.sizeof;
328     auto lpstrInitialDir = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount5);
329     int byteCountDir = Math.min (path.length * TCHAR.sizeof, byteCount5 - TCHAR.sizeof);
330     OS.MoveMemory (lpstrInitialDir, path.ptr, byteCountDir);
331
332     /* Create the file dialog struct */
333     OPENFILENAME struct_;
334     struct_.lStructSize = OS.OPENFILENAME_sizeof;
335     struct_.Flags = OS.OFN_HIDEREADONLY | OS.OFN_NOCHANGEDIR;
336     bool save = (style & DWT.SAVE) !is 0;
337     if (save && overwrite) struct_.Flags |= OS.OFN_OVERWRITEPROMPT;
338     if ((style & DWT.MULTI) !is 0) {
339         struct_.Flags |= OS.OFN_ALLOWMULTISELECT | OS.OFN_EXPLORER;
340         if (!OS.IsWinCE && USE_HOOK) {
341             //callback = new Callback (this, "OFNHookProc", 4); //$NON-NLS-1$
342             //int lpfnHook = callback.getAddress ();
343             //if (lpfnHook is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
344             struct_.lCustData = cast(uint) cast(void*) this;
345             struct_.lpfnHook = &OFNHookProc;
346             struct_.Flags |= OS.OFN_ENABLEHOOK;
347         }
348     }
349     struct_.hwndOwner = hwndOwner;
350     struct_.lpstrTitle = lpstrTitle;
351     struct_.lpstrFile = lpstrFile;
352     struct_.nMaxFile = nMaxFile;
353     struct_.lpstrInitialDir = lpstrInitialDir;
354     struct_.lpstrFilter = lpstrFilter;
355     struct_.nFilterIndex = filterIndex is 0 ? filterIndex : filterIndex + 1;
356
357     /*
358     * Set the default extension to an empty string.  If the
359     * user fails to type an extension and this extension is
360     * empty, Windows uses the current value of the filter
361     * extension at the time that the dialog is closed.
362     */
363     TCHAR* lpstrDefExt;
364     if (save) {
365         lpstrDefExt = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, TCHAR.sizeof);
366         struct_.lpstrDefExt = lpstrDefExt;
367     }
368
369     /* Make the parent shell be temporary modal */
370     Dialog oldModal = null;
371     Display display = parent.getDisplay ();
372     if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) {
373         oldModal = display.getModalDialog ();
374         display.setModalDialog (this);
375     }
376
377     /*
378     * Feature in Windows.  For some reason, the WH_MSGFILTER filter
379     * does not run for GetSaveFileName() or GetOpenFileName().  The
380     * fix is to allow async messages to run in the WH_FOREGROUNDIDLE
381     * hook instead.
382     *
383     * Bug in Windows 98.  For some reason, when certain operating
384     * system calls such as Shell_NotifyIcon(), GetOpenFileName()
385     * and GetSaveFileName() are made during the WH_FOREGROUNDIDLE
386     * hook, Windows hangs.  The fix is to disallow async messages
387     * during WH_FOREGROUNDIDLE.
388     */
389     bool oldRunMessagesInIdle = display.runMessagesInIdle;
390     display.runMessagesInIdle = !OS.IsWin95;
391     /*
392     * Open the dialog.  If the open fails due to an invalid
393     * file name, use an empty file name and open it again.
394     */
395     bool success = cast(bool)( (save) ? OS.GetSaveFileName (&struct_) : OS.GetOpenFileName (&struct_));
396     switch (OS.CommDlgExtendedError ()) {
397         case OS.FNERR_INVALIDFILENAME:
398             OS.MoveMemory (lpstrFile, StrToTCHARz ( "" ), TCHAR.sizeof);
399             success = cast(bool)((save) ? OS.GetSaveFileName (&struct_) : OS.GetOpenFileName (&struct_));
400             break;
401         case OS.FNERR_BUFFERTOOSMALL:
402             USE_HOOK = true;
403             break;
404         default:
405     }
406     display.runMessagesInIdle = oldRunMessagesInIdle;
407
408     /* Clear the temporary dialog modal parent */
409     if ((style & (DWT.APPLICATION_MODAL | DWT.SYSTEM_MODAL)) !is 0) {
410         display.setModalDialog (oldModal);
411     }
412
413     /* Dispose the callback and reassign the buffer */
414     //if (callback !is null) callback.dispose ();
415     lpstrFile = struct_.lpstrFile;
416
417     /* Set the new path, file name and filter */
418     fileNames = null;
419     String fullPath = null;
420     if (success) {
421
422         /* Use the character encoding for the default locale */
423         TCHAR[] buffer = NewTCHARs (0, struct_.nMaxFile);
424         int byteCount1 = buffer.length * TCHAR.sizeof;
425         OS.MoveMemory (buffer.ptr, lpstrFile, byteCount1);
426
427         /*
428         * Bug in WinCE.  For some reason, nFileOffset and nFileExtension
429         * are always zero on WinCE HPC. nFileOffset is always zero on
430         * WinCE PPC when using GetSaveFileName().  nFileOffset is correctly
431         * set on WinCE PPC when using OpenFileName().  The fix is to parse
432         * lpstrFile to calculate nFileOffset.
433         *
434         * Note: WinCE does not support multi-select file dialogs.
435         */
436         int nFileOffset = struct_.nFileOffset;
437         static if (OS.IsWinCE) {
438             if (nFileOffset is 0) {
439                 int index = 0;
440                 while (index < buffer.length ) {
441                     int ch = buffer[index];
442                     if (ch is 0) break;
443                     if (ch is '\\') nFileOffset = index + 1;
444                     index++;
445                 }
446             }
447         }
448         if (nFileOffset > 0) {
449
450             /* Use the character encoding for the default locale */
451             TCHAR[] prefix = NewTCHARs (0, nFileOffset - 1);
452             int byteCount2 = prefix.length * TCHAR.sizeof;
453             OS.MoveMemory (prefix.ptr, lpstrFile, byteCount2);
454             filterPath = TCHARsToStr( prefix );
455
456             /*
457             * Get each file from the buffer.  Files are delimited
458             * by a NULL character with 2 NULL characters at the end.
459             */
460             int count = 0;
461             fileNames = new String[]( (style & DWT.MULTI) !is 0 ? 4 : 1 );
462             int start = nFileOffset;
463             do {
464                 int end = start;
465                 while (end < buffer.length && buffer[end] !is 0) end++;
466                 String string = TCHARsToStr( buffer[ start .. end ] );
467                 start = end;
468                 if (count is fileNames.length) {
469                     String [] newFileNames = new String[]( fileNames.length + 4 );
470                     System.arraycopy (fileNames, 0, newFileNames, 0, fileNames.length);
471                     fileNames = newFileNames;
472                 }
473                 fileNames [count++] = string;
474                 if ((style & DWT.MULTI) is 0) break;
475                 start++;
476             } while (start < buffer.length && buffer[start] !is 0);
477
478             if (fileNames.length > 0) fileName = fileNames  [0];
479             String separator = "";
480             int length_ = filterPath.length;
481             if (length_ > 0 && filterPath[length_ - 1] !is '\\') {
482                 separator = "\\";
483             }
484             fullPath = filterPath ~ separator ~ fileName;
485             if (count < fileNames.length) {
486                 String [] newFileNames = new String[]( count );
487                 System.arraycopy (fileNames, 0, newFileNames, 0, count);
488                 fileNames = newFileNames;
489             }
490         }
491         filterIndex = struct_.nFilterIndex - 1;
492     }
493
494     /* Free the memory that was allocated. */
495     OS.HeapFree (hHeap, 0, lpstrFile);
496     OS.HeapFree (hHeap, 0, lpstrFilter);
497     OS.HeapFree (hHeap, 0, lpstrInitialDir);
498     OS.HeapFree (hHeap, 0, lpstrTitle);
499     if (lpstrDefExt !is null) OS.HeapFree (hHeap, 0, lpstrDefExt);
500
501     /* Destroy the BIDI orientation window */
502     if (hwndParent !is hwndOwner) {
503         if (enabled) OS.EnableWindow (hwndParent, true);
504         OS.SetActiveWindow (hwndParent);
505         OS.DestroyWindow (hwndOwner);
506     }
507
508     /*
509     * This code is intentionally commented.  On some
510     * platforms, the owner window is repainted right
511     * away when a dialog window exits.  This behavior
512     * is currently unspecified.
513     */
514 //  if (hwndOwner !is 0) OS.UpdateWindow (hwndOwner);
515
516     /* Answer the full path or null */
517     return fullPath;
518 }
519
520 /**
521  * Set the initial filename which the dialog will
522  * select by default when opened to the argument,
523  * which may be null.  The name will be prefixed with
524  * the filter path when one is supplied.
525  *
526  * @param string the file name
527  */
528 public void setFileName (String string) {
529     fileName = string;
530 }
531
532 /**
533  * Set the file extensions which the dialog will
534  * use to filter the files it shows to the argument,
535  * which may be null.
536  * <p>
537  * The strings are platform specific. For example, on
538  * some platforms, an extension filter string is typically
539  * of the form "*.extension", where "*.*" matches all files.
540  * For filters with multiple extensions, use semicolon as
541  * a separator, e.g. "*.jpg;*.png".
542  * </p>
543  *
544  * @param extensions the file extension filter
545  *
546  * @see #setFilterNames to specify the user-friendly
547  * names corresponding to the extensions
548  */
549 public void setFilterExtensions (String [] extensions) {
550     filterExtensions = extensions;
551 }
552
553 /**
554  * Set the 0-based index of the file extension filter
555  * which the dialog will use initially to filter the files
556  * it shows to the argument.
557  * <p>
558  * This is an index into the FilterExtensions array and
559  * the FilterNames array.
560  * </p>
561  *
562  * @param index the file extension filter index
563  *
564  * @see #setFilterExtensions
565  * @see #setFilterNames
566  *
567  * @since 3.4
568  */
569 public void setFilterIndex (int index) {
570     filterIndex = index;
571 }
572
573 /**
574  * Sets the names that describe the filter extensions
575  * which the dialog will use to filter the files it shows
576  * to the argument, which may be null.
577  * <p>
578  * Each name is a user-friendly short description shown for
579  * its corresponding filter. The <code>names</code> array must
580  * be the same length as the <code>extensions</code> array.
581  * </p>
582  *
583  * @param names the list of filter names, or null for no filter names
584  *
585  * @see #setFilterExtensions
586  */
587 public void setFilterNames (String [] names) {
588     filterNames = names;
589 }
590
591 /**
592  * Sets the directory path that the dialog will use
593  * to the argument, which may be null. File names in this
594  * path will appear in the dialog, filtered according
595  * to the filter extensions. If the string is null,
596  * then the operating system's default filter path
597  * will be used.
598  * <p>
599  * Note that the path string is platform dependent.
600  * For convenience, either '/' or '\' can be used
601  * as a path separator.
602  * </p>
603  *
604  * @param string the directory path
605  *
606  * @see #setFilterExtensions
607  */
608 public void setFilterPath (String string) {
609     filterPath = string;
610 }
611
612 /**
613  * Sets the flag that the dialog will use to
614  * determine whether to prompt the user for file
615  * overwrite if the selected file already exists.
616  *
617  * @param overwrite true if the dialog will prompt for file overwrite, false otherwise
618  *
619  * @since 3.4
620  */
621 public void setOverwrite (bool overwrite) {
622     this.overwrite = overwrite;
623 }
624 }
Note: See TracBrowser for help on using the browser.