diff org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/DirectoryDialog.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children 950d84783eac
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/DirectoryDialog.d	Mon Mar 02 14:44:16 2009 +0100
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module org.eclipse.swt.widgets.DirectoryDialog;
+
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.internal.win32.OS;
+import org.eclipse.swt.internal.C;
+
+import java.lang.all;
+static import tango.text.Text;
+
+/**
+ * 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 SWT implementation.
+ * </p>
+ * 
+ * @see <a href="http://www.eclipse.org/swt/snippets/#directorydialog">DirectoryDialog snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Dialog tab</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ */
+
+public class DirectoryDialog : Dialog {
+    static String message = "";
+    static String filterPath = "";  //$NON-NLS-1$//$NON-NLS-2$
+    static String directoryPath;
+
+/**
+ * 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 SWTException <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, SWT.APPLICATION_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>SWT</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>SWT</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 SWTException <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, checkStyle (parent, style));
+    checkSubclass ();
+}
+
+extern(Windows)static int BrowseCallbackProc (HWND hwnd, uint uMsg, int lParam, int lpData) {
+    DirectoryDialog pThis = cast(DirectoryDialog)cast(void*)lpData;
+    switch (uMsg) {
+        case OS.BFFM_INITIALIZED:
+            if (pThis.filterPath !is null && pThis.filterPath.length !is 0) {
+                /* Use the character encoding for the default locale */
+                TCHAR[] buffer = StrToTCHARs (0, pThis.filterPath.replace ('/', '\\'), true);
+                OS.SendMessage (hwnd, OS.BFFM_SETSELECTION, 1, buffer.ptr);
+            }
+            if (pThis.title !is null && pThis.title.length !is 0) {
+                /* Use the character encoding for the default locale */
+                TCHAR[] buffer = StrToTCHARs (0, pThis.title, true);
+                OS.SetWindowText (hwnd, buffer.ptr);
+            }
+            break;
+        case OS.BFFM_VALIDATEFAILEDA:
+        case OS.BFFM_VALIDATEFAILEDW:
+            /* Use the character encoding for the default locale */
+//            int length = OS.IsUnicode ? OS.wcslen (lParam) : OS.strlen (lParam);
+//            TCHAR buffer = new TCHAR (0, length);
+//            int byteCount = buffer.length * TCHAR.sizeof;
+//            OS.MoveMemory (buffer, lParam, byteCount);
+//            directoryPath = buffer.toString (0, length);
+            pThis.directoryPath = TCHARzToStr( cast(TCHAR*)lParam );
+            break;
+        default:
+    }
+    return 0;
+}
+
+/**
+ * Returns the path which the dialog will use to filter
+ * the directories it shows.
+ *
+ * @return the filter path
+ *
+ * @see #setFilterPath
+ */
+public String 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 String 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 SWTException <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 String open () {
+    if (OS.IsWinCE) SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+
+    auto hHeap = OS.GetProcessHeap ();
+
+    /* Get the owner HWND for the dialog */
+    HWND hwndOwner;
+    if (parent !is null) hwndOwner = parent.handle;
+
+    /* Copy the message to OS memory */
+    TCHAR* lpszTitle;
+    if (message.length !is 0) {
+        String string = message;
+        if (string.indexOf ('&') !is -1) {
+            int length = string.length;
+            char [] buffer = new char [length * 2];
+            int index = 0;
+            for (int i=0; i<length; i++) {
+                char ch = string.charAt (i);
+                if (ch is '&') buffer [index++] = '&';
+                buffer [index++] = ch;
+            }
+//            string = new String (buffer, 0, index);
+        }
+        /* Use the character encoding for the default locale */
+        TCHAR[] buffer = StrToTCHARs (0, string, true);
+        int byteCount = buffer.length * TCHAR.sizeof;
+        lpszTitle = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+        OS.MoveMemory (lpszTitle, buffer.ptr, byteCount);
+    }
+
+    /* Create the BrowseCallbackProc */
+/+    Callback callback = new Callback (this, "BrowseCallbackProc", 4); //$NON-NLS-1$
+    int lpfn = callback.getAddress ();+/
+    BFFCALLBACK lpfn = &BrowseCallbackProc;
+    if (lpfn is null) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+
+    /* Make the parent shell be temporary modal */
+    Dialog oldModal = null;
+    Display display = parent.getDisplay ();
+    if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) !is 0) {
+        oldModal = display.getModalDialog ();
+        display.setModalDialog (this);
+    }
+
+    directoryPath = null;
+    BROWSEINFO lpbi;
+    lpbi.hwndOwner = hwndOwner;
+    lpbi.lpszTitle = lpszTitle;
+    lpbi.ulFlags = OS.BIF_NEWDIALOGSTYLE | OS.BIF_RETURNONLYFSDIRS | OS.BIF_EDITBOX | OS.BIF_VALIDATE;
+    lpbi.lpfn = lpfn;
+    lpbi.lParam = cast(int)cast(void*)this;
+    /*
+    * Bug in Windows.  On some hardware configurations, SHBrowseForFolder()
+    * causes warning dialogs with the message "There is no disk in the drive
+    * Please insert a disk into \Device\Harddisk0\DR0".  This is possibly
+    * caused by SHBrowseForFolder() calling internally GetVolumeInformation().
+    * MSDN for GetVolumeInformation() says:
+    *
+    * "If you are attempting to obtain information about a floppy drive
+    * that does not have a floppy disk or a CD-ROM drive that does not
+    * have a compact disc, the system displays a message box asking the
+    * user to insert a floppy disk or a compact disc, respectively.
+    * To prevent the system from displaying this message box, call the
+    * SetErrorMode function with SEM_FAILCRITICALERRORS."
+    *
+    * The fix is to save and restore the error mode using SetErrorMode()
+    * with the SEM_FAILCRITICALERRORS flag around SHBrowseForFolder().
+    */
+    int oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS);
+
+    /*
+    * Bug in Windows.  When a WH_MSGFILTER hook is used to run code
+    * during the message loop for SHBrowseForFolder(), running code
+    * in the hook can cause a GP.  Specifically, SetWindowText()
+    * for static controls seemed to make the problem happen.
+    * The fix is to disable async messages while the directory
+    * dialog is open.
+    *
+    * NOTE:  This only happens in versions of the comctl32.dll
+    * earlier than 6.0.
+    */
+    bool oldRunMessages = display.runMessages;
+    if (OS.COMCTL32_MAJOR < 6) display.runMessages = false;
+    ITEMIDLIST* lpItemIdList = OS.SHBrowseForFolder (&lpbi);
+    if (OS.COMCTL32_MAJOR < 6) display.runMessages = oldRunMessages;
+    OS.SetErrorMode (oldErrorMode);
+
+    /* Clear the temporary dialog modal parent */
+    if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) !is 0) {
+        display.setModalDialog (oldModal);
+    }
+
+    bool success = lpItemIdList !is null;
+    if (success) {
+        /* Use the character encoding for the default locale */
+        TCHAR[OS.MAX_PATH] buffer;
+        if (OS.SHGetPathFromIDList (lpItemIdList, buffer.ptr)) {
+            directoryPath = TCHARzToStr (buffer.ptr);
+            filterPath = directoryPath;
+        }
+    }
+
+    /* Free the BrowseCallbackProc */
+//    callback.dispose ();
+
+    /* Free the OS memory */
+    if (lpszTitle !is null) OS.HeapFree (hHeap, 0, lpszTitle);
+
+    /* Free the pointer to the ITEMIDLIST */
+    LPVOID ppMalloc;
+    if (OS.SHGetMalloc (&ppMalloc) is OS.S_OK) {
+        /* void Free (struct IMalloc *this, void *pv); */
+        OS.VtblCall (5, ppMalloc , cast(int)lpItemIdList);
+    }
+
+    /*
+    * This code is intentionally commented.  On some
+    * platforms, the owner window is repainted right
+    * away when a dialog window exits.  This behavior
+    * is currently unspecified.
+    */
+//  if (hwndOwner !is 0) OS.UpdateWindow (hwndOwner);
+
+    /* Return the directory path */
+    if (!success) return null;
+    return directoryPath;
+}
+
+/**
+ * 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 (String string) {
+    filterPath = string;
+}
+
+/**
+ * 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
+ *
+ */
+public void setMessage (String string) {
+    // SWT extension: allow null string
+    //if (string is null) error (SWT.ERROR_NULL_ARGUMENT);
+    message = string;
+}
+
+}