KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > widgets > DirectoryDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  *******************************************************************************/

11 package org.eclipse.swt.widgets;
12
13
14 import org.eclipse.swt.internal.*;
15 import org.eclipse.swt.internal.win32.*;
16 import org.eclipse.swt.*;
17
18 /**
19  * Instances of this class allow the user to navigate
20  * the file system and select a directory.
21  * <dl>
22  * <dt><b>Styles:</b></dt>
23  * <dd>(none)</dd>
24  * <dt><b>Events:</b></dt>
25  * <dd>(none)</dd>
26  * </dl>
27  * <p>
28  * IMPORTANT: This class is intended to be subclassed <em>only</em>
29  * within the SWT implementation.
30  * </p>
31  */

32
33 public class DirectoryDialog extends Dialog {
34     String JavaDoc message = "", filterPath = ""; //$NON-NLS-1$//$NON-NLS-2$
35
String JavaDoc directoryPath;
36     
37 /**
38  * Constructs a new instance of this class given only its parent.
39  *
40  * @param parent a shell which will be the parent of the new instance
41  *
42  * @exception IllegalArgumentException <ul>
43  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
44  * </ul>
45  * @exception SWTException <ul>
46  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
47  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
48  * </ul>
49  */

50 public DirectoryDialog (Shell parent) {
51     this (parent, SWT.PRIMARY_MODAL);
52 }
53
54 /**
55  * Constructs a new instance of this class given its parent
56  * and a style value describing its behavior and appearance.
57  * <p>
58  * The style value is either one of the style constants defined in
59  * class <code>SWT</code> which is applicable to instances of this
60  * class, or must be built by <em>bitwise OR</em>'ing together
61  * (that is, using the <code>int</code> "|" operator) two or more
62  * of those <code>SWT</code> style constants. The class description
63  * lists the style constants that are applicable to the class.
64  * Style bits are also inherited from superclasses.
65  * </p>
66  *
67  * @param parent a shell which will be the parent of the new instance
68  * @param style the style of dialog to construct
69  *
70  * @exception IllegalArgumentException <ul>
71  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
72  * </ul>
73  * @exception SWTException <ul>
74  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
75  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
76  * </ul>
77  */

78 public DirectoryDialog (Shell parent, int style) {
79     super (parent, style);
80     checkSubclass ();
81 }
82
83 int BrowseCallbackProc (int hwnd, int uMsg, int lParam, int lpData) {
84     switch (uMsg) {
85         case OS.BFFM_INITIALIZED:
86             if (filterPath != null && filterPath.length () != 0) {
87                 /* Use the character encoding for the default locale */
88                 TCHAR buffer = new TCHAR (0, filterPath.replace ('/', '\\'), true);
89                 OS.SendMessage (hwnd, OS.BFFM_SETSELECTION, 1, buffer);
90             }
91             if (title != null && title.length () != 0) {
92                 /* Use the character encoding for the default locale */
93                 TCHAR buffer = new TCHAR (0, title, true);
94                 OS.SetWindowText (hwnd, buffer);
95             }
96             break;
97         case OS.BFFM_VALIDATEFAILEDA:
98         case OS.BFFM_VALIDATEFAILEDW:
99             /* Use the character encoding for the default locale */
100             int length = OS.IsUnicode ? OS.wcslen (lParam) : OS.strlen (lParam);
101             TCHAR buffer = new TCHAR (0, length);
102             int byteCount = buffer.length () * TCHAR.sizeof;
103             OS.MoveMemory (buffer, lParam, byteCount);
104             directoryPath = buffer.toString (0, length);
105             break;
106     }
107     return 0;
108 }
109
110 /**
111  * Returns the path which the dialog will use to filter
112  * the directories it shows.
113  *
114  * @return the filter path
115  *
116  * @see #setFilterPath
117  */

118 public String JavaDoc getFilterPath () {
119     return filterPath;
120 }
121
122 /**
123  * Returns the dialog's message, which is a description of
124  * the purpose for which it was opened. This message will be
125  * visible on the dialog while it is open.
126  *
127  * @return the message
128  */

129 public String JavaDoc getMessage () {
130     return message;
131 }
132
133 /**
134  * Makes the dialog visible and brings it to the front
135  * of the display.
136  *
137  * @return a string describing the absolute path of the selected directory,
138  * or null if the dialog was cancelled or an error occurred
139  *
140  * @exception SWTException <ul>
141  * <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
142  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
143  * </ul>
144  */

145 public String JavaDoc open () {
146     if (OS.IsWinCE) SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
147     
148     int hHeap = OS.GetProcessHeap ();
149     
150     /* Get the owner HWND for the dialog */
151     int hwndOwner = 0;
152     if (parent != null) hwndOwner = parent.handle;
153
154     /* Copy the message to OS memory */
155     int lpszTitle = 0;
156     if (message.length () != 0) {
157         String JavaDoc string = message;
158         if (string.indexOf ('&') != -1) {
159             int length = string.length ();
160             char [] buffer = new char [length * 2];
161             int index = 0;
162             for (int i=0; i<length; i++) {
163                 char ch = string.charAt (i);
164                 if (ch == '&') buffer [index++] = '&';
165                 buffer [index++] = ch;
166             }
167             string = new String JavaDoc (buffer, 0, index);
168         }
169         /* Use the character encoding for the default locale */
170         TCHAR buffer = new TCHAR (0, string, true);
171         int byteCount = buffer.length () * TCHAR.sizeof;
172         lpszTitle = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
173         OS.MoveMemory (lpszTitle, buffer, byteCount);
174     }
175
176     /* Create the BrowseCallbackProc */
177     Callback callback = new Callback (this, "BrowseCallbackProc", 4); //$NON-NLS-1$
178
int lpfn = callback.getAddress ();
179     if (lpfn == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
180     
181     /* Make the parent shell be temporary modal */
182     Shell oldModal = null;
183     Display display = parent.getDisplay ();
184     if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
185         oldModal = display.getModalDialogShell ();
186         display.setModalDialogShell (parent);
187     }
188     
189     directoryPath = null;
190     BROWSEINFO lpbi = new BROWSEINFO ();
191     lpbi.hwndOwner = hwndOwner;
192     lpbi.lpszTitle = lpszTitle;
193     lpbi.ulFlags = OS.BIF_NEWDIALOGSTYLE | OS.BIF_RETURNONLYFSDIRS | OS.BIF_EDITBOX | OS.BIF_VALIDATE;
194     lpbi.lpfn = lpfn;
195     /*
196     * Bug in Windows. On some hardware configurations, SHBrowseForFolder()
197     * causes warning dialogs with the message "There is no disk in the drive
198     * Please insert a disk into \Device\Harddisk0\DR0". This is possibly
199     * caused by SHBrowseForFolder() calling internally GetVolumeInformation().
200     * MSDN for GetVolumeInformation() says:
201     *
202     * "If you are attempting to obtain information about a floppy drive
203     * that does not have a floppy disk or a CD-ROM drive that does not
204     * have a compact disc, the system displays a message box asking the
205     * user to insert a floppy disk or a compact disc, respectively.
206     * To prevent the system from displaying this message box, call the
207     * SetErrorMode function with SEM_FAILCRITICALERRORS."
208     *
209     * The fix is to save and restore the error mode using SetErrorMode()
210     * with the SEM_FAILCRITICALERRORS flag around SHBrowseForFolder().
211     */

212     int oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS);
213     
214     /*
215     * Bug in Windows. When a WH_MSGFILTER hook is used to run code
216     * during the message loop for SHBrowseForFolder(), running code
217     * in the hook can cause a GP. Specifically, SetWindowText()
218     * for static controls seemed to make the problem happen.
219     * The fix is to disable async messages while the directory
220     * dialog is open.
221     *
222     * NOTE: This only happens in versions of the comctl32.dll
223     * earlier than 6.0.
224     */

225     boolean oldRunMessages = display.runMessages;
226     if (OS.COMCTL32_MAJOR < 6) display.runMessages = false;
227     int lpItemIdList = OS.SHBrowseForFolder (lpbi);
228     if (OS.COMCTL32_MAJOR < 6) display.runMessages = oldRunMessages;
229     OS.SetErrorMode (oldErrorMode);
230     
231     /* Clear the temporary dialog modal parent */
232     if ((style & (SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL)) != 0) {
233         display.setModalDialogShell (oldModal);
234     }
235     
236     boolean success = lpItemIdList != 0;
237     if (success) {
238         /* Use the character encoding for the default locale */
239         TCHAR buffer = new TCHAR (0, OS.MAX_PATH);
240         if (OS.SHGetPathFromIDList (lpItemIdList, buffer)) {
241             directoryPath = buffer.toString (0, buffer.strlen ());
242             filterPath = directoryPath;
243         }
244     }
245
246     /* Free the BrowseCallbackProc */
247     callback.dispose ();
248     
249     /* Free the OS memory */
250     if (lpszTitle != 0) OS.HeapFree (hHeap, 0, lpszTitle);
251
252     /* Free the pointer to the ITEMIDLIST */
253     int [] ppMalloc = new int [1];
254     if (OS.SHGetMalloc (ppMalloc) == OS.S_OK) {
255         /* void Free (struct IMalloc *this, void *pv); */
256         OS.VtblCall (5, ppMalloc [0], lpItemIdList);
257     }
258     
259     /*
260     * This code is intentionally commented. On some
261     * platforms, the owner window is repainted right
262     * away when a dialog window exits. This behavior
263     * is currently unspecified.
264     */

265 // if (hwndOwner != 0) OS.UpdateWindow (hwndOwner);
266

267     /* Return the directory path */
268     if (!success) return null;
269     return directoryPath;
270 }
271
272 /**
273  * Sets the path that the dialog will use to filter
274  * the directories it shows to the argument, which may
275  * be null. If the string is null, then the operating
276  * system's default filter path will be used.
277  * <p>
278  * Note that the path string is platform dependent.
279  * For convenience, either '/' or '\' can be used
280  * as a path separator.
281  * </p>
282  *
283  * @param string the filter path
284  */

285 public void setFilterPath (String JavaDoc string) {
286     filterPath = string;
287 }
288
289 /**
290  * Sets the dialog's message, which is a description of
291  * the purpose for which it was opened. This message will be
292  * visible on the dialog while it is open.
293  *
294  * @param string the message
295  *
296  * @exception IllegalArgumentException <ul>
297  * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
298  * </ul>
299  */

300 public void setMessage (String JavaDoc string) {
301     if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
302     message = string;
303 }
304
305 }
306
Popular Tags