Mercurial > projects > dwt-linux
comparison dwt/widgets/FileDialog.d @ 240:ce446666f5a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 19:13:01 +0200 |
parents | 380bad9f6852 |
children | 5a30aa9820f3 |
comparison
equal
deleted
inserted
replaced
239:06a1f6829310 | 240:ce446666f5a2 |
---|---|
47 String [] filterExtensions; | 47 String [] filterExtensions; |
48 String filterPath = ""; | 48 String filterPath = ""; |
49 String fileName = ""; | 49 String fileName = ""; |
50 String[] fileNames; | 50 String[] fileNames; |
51 String fullPath = ""; | 51 String fullPath = ""; |
52 int filterIndex = -1; | |
53 bool overwrite = false; | |
52 GtkWidget* handle; | 54 GtkWidget* handle; |
53 static final char SEPARATOR = tango.io.FileConst.FileConst.PathSeparatorChar; | 55 static final char SEPARATOR = tango.io.FileConst.FileConst.PathSeparatorChar; |
54 static final char EXTENSION_SEPARATOR = ';'; | 56 static final char EXTENSION_SEPARATOR = ';'; |
55 | 57 |
56 /** | 58 /** |
65 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | 67 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
66 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | 68 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
67 * </ul> | 69 * </ul> |
68 */ | 70 */ |
69 public this (Shell parent) { | 71 public this (Shell parent) { |
70 this (parent, DWT.PRIMARY_MODAL); | 72 this (parent, DWT.APPLICATION_MODAL); |
71 } | 73 } |
72 /** | 74 /** |
73 * Constructs a new instance of this class given its parent | 75 * Constructs a new instance of this class given its parent |
74 * and a style value describing its behavior and appearance. | 76 * and a style value describing its behavior and appearance. |
75 * <p> | 77 * <p> |
92 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | 94 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
93 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | 95 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> |
94 * </ul> | 96 * </ul> |
95 */ | 97 */ |
96 public this (Shell parent, int style) { | 98 public this (Shell parent, int style) { |
97 super (parent, style); | 99 super (parent, checkStyle (parent, style)); |
98 checkSubclass (); | 100 checkSubclass (); |
99 } | 101 } |
100 String computeResultChooserDialog () { | 102 String computeResultChooserDialog () { |
101 /* MULTI is only valid if the native dialog's action is Open */ | 103 /* MULTI is only valid if the native dialog's action is Open */ |
102 fullPath = null; | 104 fullPath = null; |
140 fileNames[0] = fullPath[ start + 1 .. $ ]; | 142 fileNames[0] = fullPath[ start + 1 .. $ ]; |
141 OS.g_free (utf8Ptr); | 143 OS.g_free (utf8Ptr); |
142 } | 144 } |
143 } | 145 } |
144 } | 146 } |
147 filterIndex = -1; | |
148 auto filter = OS.gtk_file_chooser_get_filter (handle); | |
149 if (filter !is null) { | |
150 auto filterNamePtr = OS.gtk_file_filter_get_name (filter); | |
151 if (filterNamePtr !is null) { | |
152 String filterName = tango.stdc.stringz.fromStringz(filterNamePtr).dup; | |
153 //OS.g_free (filterNamePtr); //GTK owns this pointer - do not free | |
154 for (int i = 0; i < filterExtensions.length; i++) { | |
155 if (filterNames.length > 0) { | |
156 if (filterNames[i].equals(filterName)) { | |
157 filterIndex = i; | |
158 break; | |
159 } | |
160 } else { | |
161 if (filterExtensions[i].equals(filterName)) { | |
162 filterIndex = i; | |
163 break; | |
164 } | |
165 } | |
166 } | |
167 } | |
168 } | |
145 if (fullPath !is null) { | 169 if (fullPath !is null) { |
146 int separatorIndex = tango.text.Util.locatePrior( fullPath, SEPARATOR); | 170 int separatorIndex = tango.text.Util.locatePrior( fullPath, SEPARATOR); |
147 if( separatorIndex is fullPath.length ) separatorIndex = -1; | 171 if( separatorIndex is fullPath.length ) separatorIndex = -1; |
148 fileName = fullPath[separatorIndex + 1 .. $ ]; | 172 fileName = fullPath[separatorIndex + 1 .. $ ]; |
149 filterPath = fullPath[0 .. separatorIndex ]; | 173 filterPath = fullPath[0 .. separatorIndex ]; |
150 } | 174 } |
151 return fullPath; | 175 return fullPath; |
152 } | 176 } |
153 String computeResultClassicDialog () { | 177 String computeResultClassicDialog () { |
178 filterIndex = -1; | |
154 GtkFileSelection* selection = cast(GtkFileSelection*)handle; | 179 GtkFileSelection* selection = cast(GtkFileSelection*)handle; |
155 auto entry = selection.selection_entry; | 180 auto entry = selection.selection_entry; |
156 auto entryText = OS.gtk_entry_get_text (entry); | 181 auto entryText = OS.gtk_entry_get_text (entry); |
157 String txt = tango.stdc.stringz.fromStringz( entryText ); | 182 String txt = tango.stdc.stringz.fromStringz( entryText ); |
158 if (txt.length is 0) { | 183 if (txt.length is 0) { |
246 */ | 271 */ |
247 public String [] getFilterExtensions () { | 272 public String [] getFilterExtensions () { |
248 return filterExtensions; | 273 return filterExtensions; |
249 } | 274 } |
250 /** | 275 /** |
276 * Get the 0-based index of the file extension filter | |
277 * which was selected by the user, or -1 if no filter | |
278 * was selected. | |
279 * <p> | |
280 * This is an index into the FilterExtensions array and | |
281 * the FilterNames array. | |
282 * </p> | |
283 * | |
284 * @return index the file extension filter index | |
285 * | |
286 * @see #getFilterExtensions | |
287 * @see #getFilterNames | |
288 * | |
289 * @since 3.4 | |
290 */ | |
291 public int getFilterIndex () { | |
292 return filterIndex; | |
293 } | |
294 /** | |
251 * Returns the names that describe the filter extensions | 295 * Returns the names that describe the filter extensions |
252 * which the dialog will use to filter the files it shows. | 296 * which the dialog will use to filter the files it shows. |
253 * | 297 * |
254 * @return the list of filter names | 298 * @return the list of filter names |
255 */ | 299 */ |
265 * | 309 * |
266 * @see #setFilterExtensions | 310 * @see #setFilterExtensions |
267 */ | 311 */ |
268 public String getFilterPath () { | 312 public String getFilterPath () { |
269 return filterPath; | 313 return filterPath; |
314 } | |
315 /** | |
316 * Returns the flag that the dialog will use to | |
317 * determine whether to prompt the user for file | |
318 * overwrite if the selected file already exists. | |
319 * | |
320 * @return true if the dialog will prompt for file overwrite, false otherwise | |
321 * | |
322 * @since 3.4 | |
323 */ | |
324 public bool getOverwrite () { | |
325 return overwrite; | |
270 } | 326 } |
271 /** | 327 /** |
272 * Makes the dialog visible and brings it to the front | 328 * Makes the dialog visible and brings it to the front |
273 * of the display. | 329 * of the display. |
274 * | 330 * |
307 } | 363 } |
308 presetChooserDialog (); | 364 presetChooserDialog (); |
309 Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); | 365 Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); |
310 display.addIdleProc (); | 366 display.addIdleProc (); |
311 String answer = null; | 367 String answer = null; |
312 if (OS.gtk_dialog_run (handle) is OS.GTK_RESPONSE_OK) { | 368 Dialog oldModal = null; |
369 if (OS.gtk_window_get_modal (handle)) { | |
370 oldModal = display.getModalDialog (); | |
371 display.setModalDialog (this); | |
372 } | |
373 uint signalId = 0; | |
374 uint /*long*/ hookId = 0; | |
375 CallbackData emissionData; | |
376 emissionData.display = display; | |
377 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
378 signalId = OS.g_signal_lookup (OS.map.ptr, OS.GTK_TYPE_WIDGET()); | |
379 emissionData.data = handle; | |
380 hookId = OS.g_signal_add_emission_hook (signalId, 0, &Display.emissionFunc, &emissionData, null); | |
381 } | |
382 int response = OS.gtk_dialog_run (handle); | |
383 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
384 OS.g_signal_remove_emission_hook (signalId, hookId); | |
385 } | |
386 if (OS.gtk_window_get_modal (handle)) { | |
387 display.setModalDialog (oldModal); | |
388 } | |
389 if (response is OS.GTK_RESPONSE_OK) { | |
313 answer = computeResultChooserDialog (); | 390 answer = computeResultChooserDialog (); |
314 } | 391 } |
315 display.removeIdleProc (); | 392 display.removeIdleProc (); |
316 OS.gtk_widget_destroy (handle); | 393 OS.gtk_widget_destroy (handle); |
317 return answer; | 394 return answer; |
330 } | 407 } |
331 presetClassicDialog (); | 408 presetClassicDialog (); |
332 Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); | 409 Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); |
333 display.addIdleProc (); | 410 display.addIdleProc (); |
334 String answer = null; | 411 String answer = null; |
335 if (OS.gtk_dialog_run (handle) is OS.GTK_RESPONSE_OK) { | 412 Dialog oldModal = null; |
413 if (OS.gtk_window_get_modal (handle)) { | |
414 oldModal = display.getModalDialog (); | |
415 display.setModalDialog (this); | |
416 } | |
417 int signalId = 0; | |
418 int /*long*/ hookId = 0; | |
419 CallbackData emissionData; | |
420 emissionData.display = display; | |
421 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
422 signalId = OS.g_signal_lookup (OS.map.ptr, OS.GTK_TYPE_WIDGET()); | |
423 emissionData.data = handle; | |
424 hookId = OS.g_signal_add_emission_hook (signalId, 0, &Display.emissionFunc, &emissionData, null); | |
425 } | |
426 int response = OS.gtk_dialog_run (handle); | |
427 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
428 OS.g_signal_remove_emission_hook (signalId, hookId); | |
429 } | |
430 if (OS.gtk_window_get_modal (handle)) { | |
431 display.setModalDialog (oldModal); | |
432 } | |
433 if (response is OS.GTK_RESPONSE_OK) { | |
336 answer = computeResultClassicDialog (); | 434 answer = computeResultClassicDialog (); |
337 } | 435 } |
338 display.removeIdleProc (); | 436 display.removeIdleProc (); |
339 OS.gtk_widget_destroy (handle); | 437 OS.gtk_widget_destroy (handle); |
340 return answer; | 438 return answer; |
351 /* filename must be a full path */ | 449 /* filename must be a full path */ |
352 if (filterPath[0] !is SEPARATOR) { | 450 if (filterPath[0] !is SEPARATOR) { |
353 stringBuffer.append (SEPARATOR); | 451 stringBuffer.append (SEPARATOR); |
354 } | 452 } |
355 stringBuffer.append (filterPath); | 453 stringBuffer.append (filterPath); |
356 if (filterPath[filterPath.length - 1 ] !is SEPARATOR) { | 454 if (fileName.length > 0 && (style & DWT.SAVE) is 0) { |
357 stringBuffer.append (SEPARATOR); | 455 if (filterPath[filterPath.length - 1 ] !is SEPARATOR) { |
358 } | 456 stringBuffer.append (SEPARATOR); |
359 if (fileName.length > 0) { | 457 } |
360 stringBuffer.append (fileName); | 458 stringBuffer.append (fileName); |
361 } else { | |
362 /* go into the specified directory */ | |
363 stringBuffer.append ('.'); | |
364 } | |
365 char* buffer = tango.stdc.stringz.toStringz( stringBuffer.toString ()); | 459 char* buffer = tango.stdc.stringz.toStringz( stringBuffer.toString ()); |
366 /* | 460 /* |
367 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 | 461 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 |
368 * when setting a file name that is not a true canonical path. | 462 * when setting a file name that is not a true canonical path. |
369 * The fix is to use the canonical path. | 463 * The fix is to use the canonical path. |
370 */ | 464 */ |
371 auto ptr = OS.realpath (buffer, null); | 465 auto ptr = OS.realpath (buffer, null); |
372 if (ptr !is null) { | 466 if (ptr !is null) { |
373 OS.gtk_file_chooser_set_filename (handle, ptr); | 467 OS.gtk_file_chooser_set_filename (handle, ptr); |
374 OS.g_free (ptr); | 468 OS.g_free (ptr); |
469 } | |
470 } else { | |
471 char* buffer = tango.stdc.stringz.toStringz( stringBuffer.toString () ); | |
472 /* | |
473 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 | |
474 * when setting a file name that is not a true canonical path. | |
475 * The fix is to use the canonical path. | |
476 */ | |
477 auto ptr = OS.realpath (buffer, null); | |
478 if (ptr !is null) { | |
479 OS.gtk_file_chooser_set_current_folder (handle, ptr); | |
480 OS.g_free (ptr); | |
481 } | |
375 } | 482 } |
376 } else { | 483 } else { |
377 if (fileName.length > 0) { | 484 if (fileName.length > 0) { |
378 if (fileName[0] is SEPARATOR) { | 485 if (fileName[0] is SEPARATOR) { |
379 char* buffer = tango.stdc.stringz.toStringz(fileName); | 486 char* buffer = tango.stdc.stringz.toStringz(fileName); |
487 | |
380 /* | 488 /* |
381 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 | 489 * Bug in GTK. GtkFileChooser may crash on GTK versions 2.4.10 to 2.6 |
382 * when setting a file name that is not a true canonical path. | 490 * when setting a file name that is not a true canonical path. |
383 * The fix is to use the canonical path. | 491 * The fix is to use the canonical path. |
384 */ | 492 */ |
392 } | 500 } |
393 if ((style & DWT.SAVE) !is 0 && fileName.length > 0) { | 501 if ((style & DWT.SAVE) !is 0 && fileName.length > 0) { |
394 char* buffer = tango.stdc.stringz.toStringz(fileName); | 502 char* buffer = tango.stdc.stringz.toStringz(fileName); |
395 OS.gtk_file_chooser_set_current_name (handle, buffer); | 503 OS.gtk_file_chooser_set_current_name (handle, buffer); |
396 } | 504 } |
505 if ((style & DWT.SAVE) !is 0) { | |
506 if (OS.GTK_VERSION >= OS.buildVERSION (2, 8, 0)) { | |
507 OS.gtk_file_chooser_set_do_overwrite_confirmation (handle, overwrite); | |
508 } | |
509 } | |
397 | 510 |
398 /* Set the extension filters */ | 511 /* Set the extension filters */ |
399 if (filterNames is null) filterNames = null; | 512 if (filterNames is null) filterNames = null; |
400 if (filterExtensions is null) filterExtensions = null; | 513 if (filterExtensions is null) filterExtensions = null; |
514 GtkFileFilter* initialFilter = null; | |
401 for (int i = 0; i < filterExtensions.length; i++) { | 515 for (int i = 0; i < filterExtensions.length; i++) { |
402 if (filterExtensions [i] !is null) { | 516 if (filterExtensions [i] !is null) { |
403 auto filter = OS.gtk_file_filter_new (); | 517 auto filter = OS.gtk_file_filter_new (); |
404 if (filterNames.length > i && filterNames [i] !is null) { | 518 if (filterNames.length > i && filterNames [i] !is null) { |
405 char* name = tango.stdc.stringz.toStringz(filterNames [i]); | 519 char* name = tango.stdc.stringz.toStringz(filterNames [i]); |
419 } | 533 } |
420 String current = filterExtensions [i][ start .. $ ]; | 534 String current = filterExtensions [i][ start .. $ ]; |
421 char* filterString = tango.stdc.stringz.toStringz(current); | 535 char* filterString = tango.stdc.stringz.toStringz(current); |
422 OS.gtk_file_filter_add_pattern (filter, filterString); | 536 OS.gtk_file_filter_add_pattern (filter, filterString); |
423 OS.gtk_file_chooser_add_filter (handle, filter); | 537 OS.gtk_file_chooser_add_filter (handle, filter); |
424 } | 538 if (i is filterIndex) { |
539 initialFilter = filter; | |
540 } | |
541 } | |
542 } | |
543 if (initialFilter !is null) { | |
544 OS.gtk_file_chooser_set_filter(handle, initialFilter); | |
425 } | 545 } |
426 fullPath = null; | 546 fullPath = null; |
427 fileNames = null; | 547 fileNames = null; |
428 } | 548 } |
429 void presetClassicDialog () { | 549 void presetClassicDialog () { |
482 * @see #setFilterNames to specify the user-friendly | 602 * @see #setFilterNames to specify the user-friendly |
483 * names corresponding to the extensions | 603 * names corresponding to the extensions |
484 */ | 604 */ |
485 public void setFilterExtensions (String [] extensions) { | 605 public void setFilterExtensions (String [] extensions) { |
486 filterExtensions = extensions; | 606 filterExtensions = extensions; |
607 } | |
608 /** | |
609 * Set the 0-based index of the file extension filter | |
610 * which the dialog will use initially to filter the files | |
611 * it shows to the argument. | |
612 * <p> | |
613 * This is an index into the FilterExtensions array and | |
614 * the FilterNames array. | |
615 * </p> | |
616 * | |
617 * @param index the file extension filter index | |
618 * | |
619 * @see #setFilterExtensions | |
620 * @see #setFilterNames | |
621 * | |
622 * @since 3.4 | |
623 */ | |
624 public void setFilterIndex (int index) { | |
625 filterIndex = index; | |
487 } | 626 } |
488 /** | 627 /** |
489 * Sets the the names that describe the filter extensions | 628 * Sets the the names that describe the filter extensions |
490 * which the dialog will use to filter the files it shows | 629 * which the dialog will use to filter the files it shows |
491 * to the argument, which may be null. | 630 * to the argument, which may be null. |
520 * @see #setFilterExtensions | 659 * @see #setFilterExtensions |
521 */ | 660 */ |
522 public void setFilterPath (String string) { | 661 public void setFilterPath (String string) { |
523 filterPath = string; | 662 filterPath = string; |
524 } | 663 } |
525 } | 664 |
665 /** | |
666 * Sets the flag that the dialog will use to | |
667 * determine whether to prompt the user for file | |
668 * overwrite if the selected file already exists. | |
669 * | |
670 * @param overwrite true if the dialog will prompt for file overwrite, false otherwise | |
671 * | |
672 * @since 3.4 | |
673 */ | |
674 public void setOverwrite (bool overwrite) { | |
675 this.overwrite = overwrite; | |
676 } | |
677 } |