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;
+}
+}