Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/widgets/FileDialog.d @ 50:d5075f5226e5
[swt lin]
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 27 Mar 2009 15:30:20 +0100 |
parents | 7a2dd761a8b2 |
children | c01d033c633a |
rev | line source |
---|---|
25 | 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 org.eclipse.swt.widgets.FileDialog; | |
14 | |
15 | |
16 | |
17 import org.eclipse.swt.SWT; | |
18 import org.eclipse.swt.SWTException; | |
19 import org.eclipse.swt.internal.gtk.OS; | |
20 import org.eclipse.swt.widgets.Dialog; | |
21 import org.eclipse.swt.widgets.Shell; | |
22 import org.eclipse.swt.widgets.Display; | |
23 import java.lang.all; | |
24 | |
48 | 25 version(Tango){ |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
26 static import tango.io.model.IFile; |
48 | 27 } else { // Phobos |
28 } | |
25 | 29 |
30 /** | |
31 * Instances of this class allow the user to navigate | |
32 * the file system and select or enter a file name. | |
33 * <dl> | |
34 * <dt><b>Styles:</b></dt> | |
35 * <dd>SAVE, OPEN, MULTI</dd> | |
36 * <dt><b>Events:</b></dt> | |
37 * <dd>(none)</dd> | |
38 * </dl> | |
39 * <p> | |
40 * Note: Only one of the styles SAVE and OPEN may be specified. | |
41 * </p><p> | |
42 * IMPORTANT: This class is intended to be subclassed <em>only</em> | |
43 * within the SWT implementation. | |
44 * </p> | |
45 * | |
46 * @see <a href="http://www.eclipse.org/swt/snippets/#filedialog">FileDialog snippets</a> | |
47 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Dialog tab</a> | |
48 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
49 */ | |
50 public class FileDialog : Dialog { | |
51 String [] filterNames; | |
52 String [] filterExtensions; | |
53 String filterPath = ""; | |
54 String fileName = ""; | |
55 String[] fileNames; | |
56 String fullPath = ""; | |
57 int filterIndex = -1; | |
58 bool overwrite = false; | |
59 GtkWidget* handle; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
60 version(Tango){ |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
61 static const char SEPARATOR = tango.io.model.IFile.FileConst.PathSeparatorChar; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
62 } else { // Phobos |
50 | 63 static const char SEPARATOR = std.path.sep[0]; |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
64 } |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
65 static const char EXTENSION_SEPARATOR = ';'; |
25 | 66 |
67 /** | |
68 * Constructs a new instance of this class given only its parent. | |
69 * | |
70 * @param parent a shell which will be the parent of the new instance | |
71 * | |
72 * @exception IllegalArgumentException <ul> | |
73 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
74 * </ul> | |
75 * @exception SWTException <ul> | |
76 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
77 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
78 * </ul> | |
79 */ | |
80 public this (Shell parent) { | |
81 this (parent, SWT.APPLICATION_MODAL); | |
82 } | |
83 /** | |
84 * Constructs a new instance of this class given its parent | |
85 * and a style value describing its behavior and appearance. | |
86 * <p> | |
87 * The style value is either one of the style constants defined in | |
88 * class <code>SWT</code> which is applicable to instances of this | |
89 * class, or must be built by <em>bitwise OR</em>'ing together | |
90 * (that is, using the <code>int</code> "|" operator) two or more | |
91 * of those <code>SWT</code> style constants. The class description | |
92 * lists the style constants that are applicable to the class. | |
93 * Style bits are also inherited from superclasses. | |
94 * </p> | |
95 * | |
96 * @param parent a shell which will be the parent of the new instance | |
97 * @param style the style of dialog to construct | |
98 * | |
99 * @exception IllegalArgumentException <ul> | |
100 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
101 * </ul> | |
102 * @exception SWTException <ul> | |
103 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
104 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
105 * </ul> | |
106 */ | |
107 public this (Shell parent, int style) { | |
108 super (parent, checkStyle (parent, style)); | |
109 checkSubclass (); | |
110 } | |
111 String computeResultChooserDialog () { | |
112 /* MULTI is only valid if the native dialog's action is Open */ | |
113 fullPath = null; | |
114 if ((style & (SWT.SAVE | SWT.MULTI)) is SWT.MULTI) { | |
115 auto list = OS.gtk_file_chooser_get_filenames (handle); | |
116 int listLength = OS.g_slist_length (list); | |
117 fileNames = new String [listLength]; | |
118 auto current = list; | |
119 int writePos = 0; | |
120 for (int i = 0; i < listLength; i++) { | |
121 auto name = cast(char*)OS.g_slist_data (current); | |
122 uint items_written; | |
123 char* utf8Ptr = OS.g_filename_to_utf8 (name, -1, null, &items_written, null); | |
124 OS.g_free (name); | |
125 if (utf8Ptr !is null) { | |
126 fullPath = utf8Ptr[ 0 .. items_written ].dup; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
127 int start = fullPath.lastIndexOf( SEPARATOR); |
25 | 128 fileNames [writePos++] = fullPath[ start + 1 .. $ ].dup; |
129 OS.g_free (utf8Ptr); | |
130 } | |
131 current = OS.g_slist_next (current); | |
132 } | |
133 if (writePos !is 0 && writePos !is listLength) { | |
134 String [] validFileNames = new String [writePos]; | |
135 System.arraycopy (fileNames, 0, validFileNames, 0, writePos); | |
136 fileNames = validFileNames; | |
137 } | |
138 OS.g_slist_free (list); | |
139 } else { | |
140 auto path = OS.gtk_file_chooser_get_filename (handle); | |
141 if (path !is null) { | |
142 uint items_written; | |
143 auto utf8Ptr = OS.g_filename_to_utf8 (path, -1, null, &items_written, null); | |
144 OS.g_free (path); | |
145 if (utf8Ptr !is null) { | |
146 fullPath = utf8Ptr[ 0 .. items_written ].dup; | |
147 fileNames = new String [1]; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
148 int start = fullPath.lastIndexOf( SEPARATOR); |
25 | 149 fileNames[0] = fullPath[ start + 1 .. $ ]; |
150 OS.g_free (utf8Ptr); | |
151 } | |
152 } | |
153 } | |
154 filterIndex = -1; | |
155 auto filter = OS.gtk_file_chooser_get_filter (handle); | |
156 if (filter !is null) { | |
157 auto filterNamePtr = OS.gtk_file_filter_get_name (filter); | |
158 if (filterNamePtr !is null) { | |
159 String filterName = fromStringz(filterNamePtr).dup; | |
160 //OS.g_free (filterNamePtr); //GTK owns this pointer - do not free | |
161 for (int i = 0; i < filterExtensions.length; i++) { | |
162 if (filterNames.length > 0) { | |
163 if (filterNames[i].equals(filterName)) { | |
164 filterIndex = i; | |
165 break; | |
166 } | |
167 } else { | |
168 if (filterExtensions[i].equals(filterName)) { | |
169 filterIndex = i; | |
170 break; | |
171 } | |
172 } | |
173 } | |
174 } | |
175 } | |
176 if (fullPath !is null) { | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
177 int separatorIndex = fullPath.lastIndexOf( SEPARATOR); |
25 | 178 fileName = fullPath[separatorIndex + 1 .. $ ]; |
179 filterPath = fullPath[0 .. separatorIndex ]; | |
180 } | |
181 return fullPath; | |
182 } | |
183 String computeResultClassicDialog () { | |
184 filterIndex = -1; | |
185 GtkFileSelection* selection = cast(GtkFileSelection*)handle; | |
186 auto entry = selection.selection_entry; | |
187 auto entryText = OS.gtk_entry_get_text (entry); | |
188 String txt = fromStringz( entryText ); | |
189 if (txt.length is 0) { | |
190 auto fileList = selection.file_list; | |
191 auto listSelection = OS.gtk_tree_view_get_selection (fileList); | |
192 void* model; | |
193 auto selectedList = OS.gtk_tree_selection_get_selected_rows (listSelection, &model); | |
194 if (selectedList is null) return null; | |
195 int listLength = OS.g_list_length (selectedList); | |
196 if (listLength is 0) { | |
197 OS.g_list_free (selectedList); | |
198 return null; | |
199 } | |
200 auto path = OS.g_list_nth_data (selectedList, 0); | |
201 char* ptr; | |
202 GtkTreeIter iter; | |
203 if (OS.gtk_tree_model_get_iter (&model, &iter, path)) { | |
204 OS.gtk_tree_model_get1 (&model, &iter, 0, cast(void**)&ptr); | |
205 } | |
206 for (int i = 0; i < listLength; i++) { | |
207 OS.gtk_tree_path_free (OS.g_list_nth_data (selectedList, i)); | |
208 } | |
209 OS.g_list_free (selectedList); | |
210 if (ptr is null) return null; | |
211 OS.gtk_entry_set_text (entry, ptr); | |
212 OS.g_free (ptr); | |
213 } | |
214 | |
215 auto fileNamePtr = OS.gtk_file_selection_get_filename (handle); | |
216 uint items_written; | |
217 auto utf8Ptr = OS.g_filename_to_utf8 (fileNamePtr, -1, null, &items_written, null); | |
218 String osAnswer = utf8Ptr[ 0 .. items_written ].dup; | |
219 OS.g_free (utf8Ptr); | |
220 | |
221 if (osAnswer.length is 0) return null; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
222 int separatorIndex = osAnswer.lastIndexOf( SEPARATOR); |
25 | 223 if (separatorIndex+1 is osAnswer.length ) return null; |
224 | |
225 String answer = fullPath = osAnswer; | |
226 fileName = fullPath[ separatorIndex+1 .. $ ]; | |
227 filterPath = fullPath[ 0 .. separatorIndex ]; | |
228 if ((style & SWT.MULTI) is 0) { | |
229 fileNames = [ fileName ]; | |
230 } else { | |
231 auto namesPtr = OS.gtk_file_selection_get_selections (handle); | |
232 auto namesPtr1 = namesPtr; | |
233 char* namePtr = namesPtr1[0]; | |
234 int length_ = 0; | |
235 while (namePtr !is null) { | |
236 length_++; | |
237 namePtr = namesPtr1[length_]; | |
238 } | |
239 fileNames = new String[](length_); | |
240 for (int i = 0; i < length_; i++) { | |
241 utf8Ptr = OS.g_filename_to_utf8 (namesPtr [i], -1, null, &items_written, null); | |
242 String name = utf8Ptr[ 0 .. items_written ].dup; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
243 int start = name.lastIndexOf( SEPARATOR); |
25 | 244 fileNames [i] = name[ start + 1 .. $ ].dup; |
245 OS.g_free (utf8Ptr); | |
246 } | |
247 OS.g_strfreev (namesPtr); | |
248 } | |
249 return answer; | |
250 } | |
251 /** | |
252 * Returns the path of the first file that was | |
253 * selected in the dialog relative to the filter path, or an | |
254 * empty string if no such file has been selected. | |
255 * | |
256 * @return the relative path of the file | |
257 */ | |
258 public String getFileName () { | |
259 return fileName; | |
260 } | |
261 /** | |
262 * Returns a (possibly empty) array with the paths of all files | |
263 * that were selected in the dialog relative to the filter path. | |
264 * | |
265 * @return the relative paths of the files | |
266 */ | |
267 public String [] getFileNames () { | |
268 return fileNames; | |
269 } | |
270 /** | |
271 * Returns the file extensions which the dialog will | |
272 * use to filter the files it shows. | |
273 * | |
274 * @return the file extensions filter | |
275 */ | |
276 public String [] getFilterExtensions () { | |
277 return filterExtensions; | |
278 } | |
279 /** | |
280 * Get the 0-based index of the file extension filter | |
281 * which was selected by the user, or -1 if no filter | |
282 * was selected. | |
283 * <p> | |
284 * This is an index into the FilterExtensions array and | |
285 * the FilterNames array. | |
286 * </p> | |
287 * | |
288 * @return index the file extension filter index | |
289 * | |
290 * @see #getFilterExtensions | |
291 * @see #getFilterNames | |
292 * | |
293 * @since 3.4 | |
294 */ | |
295 public int getFilterIndex () { | |
296 return filterIndex; | |
297 } | |
298 /** | |
299 * Returns the names that describe the filter extensions | |
300 * which the dialog will use to filter the files it shows. | |
301 * | |
302 * @return the list of filter names | |
303 */ | |
304 public String [] getFilterNames () { | |
305 return filterNames; | |
306 } | |
307 /** | |
308 * Returns the directory path that the dialog will use, or an empty | |
309 * string if this is not set. File names in this path will appear | |
310 * in the dialog, filtered according to the filter extensions. | |
311 * | |
312 * @return the directory path string | |
313 * | |
314 * @see #setFilterExtensions | |
315 */ | |
316 public String getFilterPath () { | |
317 return filterPath; | |
318 } | |
319 /** | |
320 * Returns the flag that the dialog will use to | |
321 * determine whether to prompt the user for file | |
322 * overwrite if the selected file already exists. | |
323 * | |
324 * @return true if the dialog will prompt for file overwrite, false otherwise | |
325 * | |
326 * @since 3.4 | |
327 */ | |
328 public bool getOverwrite () { | |
329 return overwrite; | |
330 } | |
331 /** | |
332 * Makes the dialog visible and brings it to the front | |
333 * of the display. | |
334 * | |
335 * @return a string describing the absolute path of the first selected file, | |
336 * or null if the dialog was cancelled or an error occurred | |
337 * | |
338 * @exception SWTException <ul> | |
339 * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li> | |
340 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li> | |
341 * </ul> | |
342 */ | |
343 public String open () { | |
344 bool useChooserDialog = OS.GTK_VERSION >= OS.buildVERSION (2, 4, 10); | |
345 if (useChooserDialog) { | |
346 return openChooserDialog (); | |
347 } else { | |
348 return openClassicDialog (); | |
349 } | |
350 } | |
351 String openChooserDialog () { | |
352 char* titleBytes = toStringz( title ); | |
353 int action = (style & SWT.SAVE) !is 0 ? | |
354 OS.GTK_FILE_CHOOSER_ACTION_SAVE : | |
355 OS.GTK_FILE_CHOOSER_ACTION_OPEN; | |
356 auto shellHandle = parent.topHandle (); | |
357 handle = OS.gtk_file_chooser_dialog_new2 ( | |
358 titleBytes, | |
359 shellHandle, | |
360 action, | |
361 OS.GTK_STOCK_CANCEL (), OS.GTK_RESPONSE_CANCEL, | |
362 OS.GTK_STOCK_OK (), OS.GTK_RESPONSE_OK); | |
363 auto pixbufs = OS.gtk_window_get_icon_list (shellHandle); | |
364 if (pixbufs !is null) { | |
365 OS.gtk_window_set_icon_list (handle, pixbufs); | |
366 OS.g_list_free (pixbufs); | |
367 } | |
368 presetChooserDialog (); | |
369 Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); | |
370 display.addIdleProc (); | |
371 String answer = null; | |
372 Dialog oldModal = null; | |
373 if (OS.gtk_window_get_modal (handle)) { | |
374 oldModal = display.getModalDialog (); | |
375 display.setModalDialog (this); | |
376 } | |
377 uint signalId = 0; | |
378 uint /*long*/ hookId = 0; | |
379 CallbackData emissionData; | |
380 emissionData.display = display; | |
381 if ((style & SWT.RIGHT_TO_LEFT) !is 0) { | |
382 signalId = OS.g_signal_lookup (OS.map.ptr, OS.GTK_TYPE_WIDGET()); | |
383 emissionData.data = handle; | |
384 hookId = OS.g_signal_add_emission_hook (signalId, 0, &Display.emissionFunc, &emissionData, null); | |
385 } | |
386 int response = OS.gtk_dialog_run (handle); | |
387 if ((style & SWT.RIGHT_TO_LEFT) !is 0) { | |
388 OS.g_signal_remove_emission_hook (signalId, hookId); | |
389 } | |
390 if (OS.gtk_window_get_modal (handle)) { | |
391 display.setModalDialog (oldModal); | |
392 } | |
393 if (response is OS.GTK_RESPONSE_OK) { | |
394 answer = computeResultChooserDialog (); | |
395 } | |
396 display.removeIdleProc (); | |
397 OS.gtk_widget_destroy (handle); | |
398 return answer; | |
399 } | |
400 String openClassicDialog () { | |
401 char* titleBytes = toStringz( title ); | |
402 handle = OS.gtk_file_selection_new (titleBytes); | |
403 if (parent !is null) { | |
404 auto shellHandle = parent.topHandle (); | |
405 OS.gtk_window_set_transient_for (handle, shellHandle); | |
406 auto pixbufs = OS.gtk_window_get_icon_list (shellHandle); | |
407 if (pixbufs !is null) { | |
408 OS.gtk_window_set_icon_list (handle, pixbufs); | |
409 OS.g_list_free (pixbufs); | |
410 } | |
411 } | |
412 presetClassicDialog (); | |
413 Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); | |
414 display.addIdleProc (); | |
415 String answer = null; | |
416 Dialog oldModal = null; | |
417 if (OS.gtk_window_get_modal (handle)) { | |
418 oldModal = display.getModalDialog (); | |
419 display.setModalDialog (this); | |
420 } | |
421 int signalId = 0; | |
422 int /*long*/ hookId = 0; | |
423 CallbackData emissionData; | |
424 emissionData.display = display; | |
425 if ((style & SWT.RIGHT_TO_LEFT) !is 0) { | |
426 signalId = OS.g_signal_lookup (OS.map.ptr, OS.GTK_TYPE_WIDGET()); | |
427 emissionData.data = handle; | |
428 hookId = OS.g_signal_add_emission_hook (signalId, 0, &Display.emissionFunc, &emissionData, null); | |
429 } | |
430 int response = OS.gtk_dialog_run (handle); | |
431 if ((style & SWT.RIGHT_TO_LEFT) !is 0) { | |
432 OS.g_signal_remove_emission_hook (signalId, hookId); | |
433 } | |
434 if (OS.gtk_window_get_modal (handle)) { | |
435 display.setModalDialog (oldModal); | |
436 } | |
437 if (response is OS.GTK_RESPONSE_OK) { | |
438 answer = computeResultClassicDialog (); | |
439 } | |
440 display.removeIdleProc (); | |
441 OS.gtk_widget_destroy (handle); | |
442 return answer; | |
443 } | |
444 void presetChooserDialog () { | |
445 /* MULTI is only valid if the native dialog's action is Open */ | |
446 if ((style & (SWT.SAVE | SWT.MULTI)) is SWT.MULTI) { | |
447 OS.gtk_file_chooser_set_select_multiple (handle, true); | |
448 } | |
449 if (filterPath is null) filterPath = ""; | |
450 if (fileName is null) fileName = ""; | |
451 if (filterPath.length > 0) { | |
452 StringBuffer stringBuffer = new StringBuffer(); | |
453 /* filename must be a full path */ | |
454 if (filterPath[0] !is SEPARATOR) { | |
455 stringBuffer.append (SEPARATOR); | |
456 } | |
457 stringBuffer.append (filterPath); | |
458 if (fileName.length > 0 && (style & SWT.SAVE) is 0) { | |
459 if (filterPath[filterPath.length - 1 ] !is SEPARATOR) { | |
460 stringBuffer.append (SEPARATOR); | |
461 } | |
462 stringBuffer.append (fileName); | |
463 char* buffer = toStringz( stringBuffer.toString ()); | |
464 /* | |
465 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 | |
466 * when setting a file name that is not a true canonical path. | |
467 * The fix is to use the canonical path. | |
468 */ | |
469 auto ptr = OS.realpath (buffer, null); | |
470 if (ptr !is null) { | |
471 OS.gtk_file_chooser_set_filename (handle, ptr); | |
472 OS.g_free (ptr); | |
473 } | |
474 } else { | |
475 char* buffer = toStringz( stringBuffer.toString () ); | |
476 /* | |
477 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 | |
478 * when setting a file name that is not a true canonical path. | |
479 * The fix is to use the canonical path. | |
480 */ | |
481 auto ptr = OS.realpath (buffer, null); | |
482 if (ptr !is null) { | |
483 OS.gtk_file_chooser_set_current_folder (handle, ptr); | |
484 OS.g_free (ptr); | |
485 } | |
486 } | |
487 } else { | |
488 if (fileName.length > 0) { | |
489 if (fileName[0] is SEPARATOR) { | |
490 char* buffer = toStringz(fileName); | |
491 | |
492 /* | |
493 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 | |
494 * when setting a file name that is not a true canonical path. | |
495 * The fix is to use the canonical path. | |
496 */ | |
497 auto ptr = OS.realpath (buffer, null); | |
498 if (ptr !is null) { | |
499 OS.gtk_file_chooser_set_filename (handle, ptr); | |
500 OS.g_free (ptr); | |
501 } | |
502 } | |
503 } | |
504 } | |
505 if ((style & SWT.SAVE) !is 0 && fileName.length > 0) { | |
506 char* buffer = toStringz(fileName); | |
507 OS.gtk_file_chooser_set_current_name (handle, buffer); | |
508 } | |
509 if ((style & SWT.SAVE) !is 0) { | |
510 if (OS.GTK_VERSION >= OS.buildVERSION (2, 8, 0)) { | |
511 OS.gtk_file_chooser_set_do_overwrite_confirmation (handle, overwrite); | |
512 } | |
513 } | |
514 | |
515 /* Set the extension filters */ | |
516 if (filterNames is null) filterNames = null; | |
517 if (filterExtensions is null) filterExtensions = null; | |
518 GtkFileFilter* initialFilter = null; | |
519 for (int i = 0; i < filterExtensions.length; i++) { | |
520 if (filterExtensions [i] !is null) { | |
521 auto filter = OS.gtk_file_filter_new (); | |
522 if (filterNames.length > i && filterNames [i] !is null) { | |
523 char* name = toStringz(filterNames [i]); | |
524 OS.gtk_file_filter_set_name (filter, name); | |
525 } else { | |
526 char* name = toStringz(filterExtensions [i]); | |
527 OS.gtk_file_filter_set_name (filter, name); | |
528 } | |
529 int start = 0; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
530 int index = filterExtensions [i].indexOf( EXTENSION_SEPARATOR ); |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
531 while (index !is -1 ) { |
25 | 532 String current = filterExtensions [i][ start .. index ]; |
533 char* filterString = toStringz(current); | |
534 OS.gtk_file_filter_add_pattern (filter, filterString); | |
535 start = index + 1; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
536 index = filterExtensions [i].indexOf( EXTENSION_SEPARATOR, start); |
25 | 537 } |
538 String current = filterExtensions [i][ start .. $ ]; | |
539 char* filterString = toStringz(current); | |
540 OS.gtk_file_filter_add_pattern (filter, filterString); | |
541 OS.gtk_file_chooser_add_filter (handle, filter); | |
542 if (i is filterIndex) { | |
543 initialFilter = filter; | |
544 } | |
545 } | |
546 } | |
547 if (initialFilter !is null) { | |
548 OS.gtk_file_chooser_set_filter(handle, initialFilter); | |
549 } | |
550 fullPath = null; | |
551 fileNames = null; | |
552 } | |
553 void presetClassicDialog () { | |
554 OS.gtk_file_selection_set_select_multiple(handle, (style & SWT.MULTI) !is 0); | |
555 | |
556 /* Calculate the fully-specified file name and convert to bytes */ | |
557 StringBuffer stringBuffer = new StringBuffer(); | |
558 if (filterPath is null) { | |
559 filterPath = ""; | |
560 } else { | |
561 if (filterPath.length > 0) { | |
562 stringBuffer.append (filterPath); | |
563 if (filterPath[filterPath.length - 1] !is SEPARATOR) { | |
564 stringBuffer.append (SEPARATOR); | |
565 } | |
566 } | |
567 } | |
568 if (fileName is null) { | |
569 fileName = ""; | |
570 } else { | |
571 stringBuffer.append (fileName); | |
572 } | |
573 fullPath = stringBuffer.toString (); | |
574 auto fileNamePtr = OS.g_filename_from_utf8 (toStringz( fullPath ), -1, null, null, null); | |
575 OS.gtk_file_selection_set_filename (handle, fileNamePtr); | |
576 OS.g_free (fileNamePtr); | |
577 | |
578 if (filterNames is null) filterNames = null; | |
579 if (filterExtensions is null) filterExtensions = null; | |
580 fullPath = null; | |
581 fileNames = null; | |
582 } | |
583 /** | |
584 * Set the initial filename which the dialog will | |
585 * select by default when opened to the argument, | |
586 * which may be null. The name will be prefixed with | |
587 * the filter path when one is supplied. | |
588 * | |
589 * @param string the file name | |
590 */ | |
591 public void setFileName (String string) { | |
592 fileName = string; | |
593 } | |
594 /** | |
595 * Set the file extensions which the dialog will | |
596 * use to filter the files it shows to the argument, | |
597 * which may be null. | |
598 * <p> | |
599 * The strings are platform specific. For example, on | |
600 * some platforms, an extension filter string is typically | |
601 * of the form "*.extension", where "*.*" matches all files. | |
602 * For filters with multiple extensions, use semicolon as | |
603 * a separator, e.g. "*.jpg;*.png". | |
604 * </p> | |
605 * | |
606 * @param extensions the file extension filter | |
607 * | |
608 * @see #setFilterNames to specify the user-friendly | |
609 * names corresponding to the extensions | |
610 */ | |
611 public void setFilterExtensions (String [] extensions) { | |
612 filterExtensions = extensions; | |
613 } | |
614 /** | |
615 * Set the 0-based index of the file extension filter | |
616 * which the dialog will use initially to filter the files | |
617 * it shows to the argument. | |
618 * <p> | |
619 * This is an index into the FilterExtensions array and | |
620 * the FilterNames array. | |
621 * </p> | |
622 * | |
623 * @param index the file extension filter index | |
624 * | |
625 * @see #setFilterExtensions | |
626 * @see #setFilterNames | |
627 * | |
628 * @since 3.4 | |
629 */ | |
630 public void setFilterIndex (int index) { | |
631 filterIndex = index; | |
632 } | |
633 /** | |
634 * Sets the names that describe the filter extensions | |
635 * which the dialog will use to filter the files it shows | |
636 * to the argument, which may be null. | |
637 * <p> | |
638 * Each name is a user-friendly short description shown for | |
639 * its corresponding filter. The <code>names</code> array must | |
640 * be the same length as the <code>extensions</code> array. | |
641 * </p> | |
642 * | |
643 * @param names the list of filter names, or null for no filter names | |
644 * | |
645 * @see #setFilterExtensions | |
646 */ | |
647 public void setFilterNames (String [] names) { | |
648 filterNames = names; | |
649 } | |
650 /** | |
651 * Sets the directory path that the dialog will use | |
652 * to the argument, which may be null. File names in this | |
653 * path will appear in the dialog, filtered according | |
654 * to the filter extensions. If the string is null, | |
655 * then the operating system's default filter path | |
656 * will be used. | |
657 * <p> | |
658 * Note that the path string is platform dependent. | |
659 * For convenience, either '/' or '\' can be used | |
660 * as a path separator. | |
661 * </p> | |
662 * | |
663 * @param string the directory path | |
664 * | |
665 * @see #setFilterExtensions | |
666 */ | |
667 public void setFilterPath (String string) { | |
668 filterPath = string; | |
669 } | |
670 | |
671 /** | |
672 * Sets the flag that the dialog will use to | |
673 * determine whether to prompt the user for file | |
674 * overwrite if the selected file already exists. | |
675 * | |
676 * @param overwrite true if the dialog will prompt for file overwrite, false otherwise | |
677 * | |
678 * @since 3.4 | |
679 */ | |
680 public void setOverwrite (bool overwrite) { | |
681 this.overwrite = overwrite; | |
682 } | |
683 } |