Mercurial > projects > dwt-linux
changeset 78:3acb1029ed5c
DirectoryDialog
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 15 Jan 2008 16:35:35 +0100 |
parents | 5f2f175327bc |
children | eb0144eddf0f |
files | dwt/internal/gtk/OS.d dwt/widgets/DirectoryDialog.d |
diffstat | 2 files changed, 280 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/dwt/internal/gtk/OS.d Tue Jan 15 15:59:30 2008 +0100 +++ b/dwt/internal/gtk/OS.d Tue Jan 15 16:35:35 2008 +0100 @@ -547,7 +547,9 @@ private void gtk_cell_layout_set_attributes1( void *cell_layout, void* cell, void* key, void* value ){ gtk_cell_layout_set_attributes( cast(GtkCellLayout *)cell_layout, cast(GtkCellRenderer*)cell, key, value, null ); } - +GtkWidget * gtk_file_chooser_dialog_new2(char * title, aGtkWindow * parent, int action, char * btn0_text, int btn0_id, char * btn1_text, int btn1_id ){ + return gtk_file_chooser_dialog_new( title, parent, action, btn0_text, btn0_id, btn1_text, btn1_id, null ); +} // for linux always true, the other possibility would be GDK_WINDOWING_WIN32 private bool GDK_WINDOWING_X11(){ return true; @@ -1267,7 +1269,6 @@ mixin ForwardGtkOsCFunc!(.g_utf8_pointer_to_offset); mixin ForwardGtkOsCFunc!(.g_utf8_strlen); mixin ForwardGtkOsCFunc!(.g_utf8_to_utf16); - mixin ForwardGtkOsCFunc!(.g_utf8_to_utf16); mixin ForwardGtkOsCFunc!(.gdk_atom_intern); // mixin ForwardGtkOsCFunc!(.gdk_atom_name); mixin ForwardGtkOsCFunc!(.gdk_beep); @@ -1544,7 +1545,7 @@ mixin ForwardGtkOsCFunc!(.gtk_expander_set_label); mixin ForwardGtkOsCFunc!(.gtk_expander_set_label_widget); mixin ForwardGtkOsCFunc!(.gtk_file_chooser_add_filter); - mixin ForwardGtkOsCFunc!(.gtk_file_chooser_dialog_new); + mixin ForwardGtkOsCFunc!(.gtk_file_chooser_dialog_new2); mixin ForwardGtkOsCFunc!(.gtk_file_chooser_get_current_folder); mixin ForwardGtkOsCFunc!(.gtk_file_chooser_get_filename); mixin ForwardGtkOsCFunc!(.gtk_file_chooser_get_filenames);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/widgets/DirectoryDialog.d Tue Jan 15 16:35:35 2008 +0100 @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.widgets.DirectoryDialog; + + + +import dwt.DWT; +import dwt.DWTException; +import dwt.internal.gtk.OS; +import dwt.widgets.Dialog; +import dwt.widgets.Shell; +import dwt.widgets.Display; + +static import tango.io.FileConst; +static import tango.stdc.stringz; +static import tango.text.Util; + +/** + * Instances of this class allow the user to navigate + * the file system and select a directory. + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>(none)</dd> + * <dt><b>Events:</b></dt> + * <dd>(none)</dd> + * </dl> + * <p> + * IMPORTANT: This class is intended to be subclassed <em>only</em> + * within the DWT implementation. + * </p> + */ +public class DirectoryDialog : Dialog { + char[] message = "", filterPath = ""; + static const char[] SEPARATOR = tango.io.FileConst.FileConst.PathSeparatorString;; + +/** + * Constructs a new instance of this class given only its parent. + * + * @param parent a shell which will be the parent of the new instance + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + */ +public this (Shell parent) { + this (parent, DWT.PRIMARY_MODAL); +} +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * <p> + * The style value is either one of the style constants defined in + * class <code>DWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>DWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a shell which will be the parent of the new instance + * @param style the style of dialog to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + */ +public this (Shell parent, int style) { + super (parent, style); + checkSubclass (); +} +/** + * Returns the path which the dialog will use to filter + * the directories it shows. + * + * @return the filter path + * + * @see #setFilterPath + */ +public char[] getFilterPath () { + return filterPath; +} +/** + * Returns the dialog's message, which is a description of + * the purpose for which it was opened. This message will be + * visible on the dialog while it is open. + * + * @return the message + */ +public char[] getMessage () { + return message; +} +/** + * Makes the dialog visible and brings it to the front + * of the display. + * + * @return a string describing the absolute path of the selected directory, + * or null if the dialog was cancelled or an error occurred + * + * @exception DWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li> + * </ul> + */ +public char[] open () { + bool useChooserDialog = OS.GTK_VERSION >= OS.buildVERSION (2, 4, 10); + if (useChooserDialog) { + return openChooserDialog (); + } else { + return openClassicDialog (); + } +} +char[] openChooserDialog () { + char* titleBytes = tango.stdc.stringz.toStringz(title); + auto shellHandle = parent.topHandle (); + auto handle = OS.gtk_file_chooser_dialog_new2 ( + titleBytes, + shellHandle, + OS.GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + OS.GTK_STOCK_CANCEL (), OS.GTK_RESPONSE_CANCEL, + OS.GTK_STOCK_OK (), OS.GTK_RESPONSE_OK ); + auto pixbufs = OS.gtk_window_get_icon_list (shellHandle); + if (pixbufs !is null) { + OS.gtk_window_set_icon_list (handle, pixbufs); + OS.g_list_free (pixbufs); + } + if (filterPath !is null && filterPath.length > 0) { + char[] p; + /* filename must be a full path */ + if ( filterPath[ 0 .. SEPARATOR.length ] != SEPARATOR ) { + p ~= SEPARATOR; + p ~= filterPath; + } + else{ + p = filterPath; + } + OS.gtk_file_chooser_set_current_folder (handle, tango.stdc.stringz.toStringz(p)); + } + if (message.length > 0) { + char* buffer = tango.stdc.stringz.toStringz(message); + auto box = OS.gtk_hbox_new (false, 0); + if (box is null) error (DWT.ERROR_NO_HANDLES); + auto label = OS.gtk_label_new (buffer); + if (label is null) error (DWT.ERROR_NO_HANDLES); + OS.gtk_container_add (box, label); + OS.gtk_widget_show (label); + OS.gtk_label_set_line_wrap (label, true); + OS.gtk_label_set_justify (label, OS.GTK_JUSTIFY_CENTER); + OS.gtk_file_chooser_set_extra_widget (handle, box); + } + char[] answer = null; + Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); + display.addIdleProc (); + int response = OS.gtk_dialog_run (handle); + if (response is OS.GTK_RESPONSE_OK) { + auto path = OS.gtk_file_chooser_get_filename (handle); + if (path !is null) { + auto utf8Ptr = OS.g_filename_to_utf8 (path, -1, null, null, null); + OS.g_free (path); + if (utf8Ptr !is null) { + answer = tango.stdc.stringz.fromUtf8z( utf8Ptr ).dup; + filterPath = answer[ tango.text.Util.locatePatternPrior( answer, SEPARATOR ) + 1 .. $ ]; + OS.g_free (utf8Ptr); + } + } + } + display.removeIdleProc (); + OS.gtk_widget_destroy (handle); + return answer; +} +char[] openClassicDialog () { + char* titleBytes = tango.stdc.stringz.toStringz(title); + auto handle = OS.gtk_file_selection_new (titleBytes); + if (parent !is null) { + auto shellHandle = parent.topHandle (); + OS.gtk_window_set_transient_for (handle, shellHandle); + auto pixbufs = OS.gtk_window_get_icon_list (shellHandle); + if (pixbufs !is null) { + OS.gtk_window_set_icon_list (handle, pixbufs); + OS.g_list_free (pixbufs); + } + } + char[] answer = null; + if (filterPath !is null) { + char[] path = filterPath; + if (path.length > 0 && path[ $-1 .. $ ] != SEPARATOR ) { + path ~= SEPARATOR; + } + char* fileNamePtr = OS.g_filename_from_utf8 (tango.stdc.stringz.toStringz(path), -1, null, null, null); + OS.gtk_file_selection_set_filename (handle, fileNamePtr); + OS.g_free (fileNamePtr); + } + GtkFileSelection* selection = cast(GtkFileSelection*)handle; + OS.gtk_file_selection_hide_fileop_buttons (handle); + auto fileListParent = OS.gtk_widget_get_parent (selection.file_list); + OS.gtk_widget_hide (selection.file_list); + OS.gtk_widget_hide (fileListParent); + if (message.length > 0) { + auto labelHandle = OS.gtk_label_new (tango.stdc.stringz.toStringz(message)); + OS.gtk_label_set_line_wrap (labelHandle, true); + OS.gtk_misc_set_alignment (labelHandle, 0.0f, 0.0f); + OS.gtk_container_add (selection.main_vbox, labelHandle); + OS.gtk_box_set_child_packing ( + selection.main_vbox, labelHandle, false, false, 0, OS.GTK_PACK_START); + OS.gtk_widget_show (labelHandle); + } + Display display = parent !is null ? parent.getDisplay (): Display.getCurrent (); + display.addIdleProc (); + int response = OS.gtk_dialog_run (handle); + if (response is OS.GTK_RESPONSE_OK) { + char* fileNamePtr = OS.gtk_file_selection_get_filename (handle); + char* utf8Ptr = OS.g_filename_to_utf8 (fileNamePtr, -1, null, null, null); + if (utf8Ptr !is null) { + char[] osAnswer = tango.stdc.stringz.fromUtf8z(utf8Ptr); + if (osAnswer.length !is 0) { + /* remove trailing separator, unless root directory */ + if ( osAnswer != SEPARATOR && osAnswer[ $-1 .. $ ] == SEPARATOR ) { + osAnswer = osAnswer[ 0 .. $ - 1 ]; + } + answer = filterPath = osAnswer.dup; + } + OS.g_free (utf8Ptr); + } + } + display.removeIdleProc (); + OS.gtk_widget_destroy (handle); + return answer; +} +/** + * Sets the path that the dialog will use to filter + * the directories it shows to the argument, which may + * be null. If the string is null, then the operating + * system's default filter path will be used. + * <p> + * Note that the path string is platform dependent. + * For convenience, either '/' or '\' can be used + * as a path separator. + * </p> + * + * @param string the filter path + */ +public void setFilterPath (char[] string) { + filterPath = string.dup; +} +/** + * Sets the dialog's message, which is a description of + * the purpose for which it was opened. This message will be + * visible on the dialog while it is open. + * + * @param string the message + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the string is null</li> + * </ul> + */ +public void setMessage (char[] string) { + if (string is null) error (DWT.ERROR_NULL_ARGUMENT); + message = string.dup; +} +}