diff options
| author | Jason Rumney | 2002-06-22 19:52:29 +0000 |
|---|---|---|
| committer | Jason Rumney | 2002-06-22 19:52:29 +0000 |
| commit | 1030b26bcc03cc968021979b9754a93f91921e8d (patch) | |
| tree | fa000a88815a14e096dc8704749e74e2bd52cee3 /src | |
| parent | 29c3cbf0f36fe92cb2be88b7e7daa03d67124399 (diff) | |
| download | emacs-1030b26bcc03cc968021979b9754a93f91921e8d.tar.gz emacs-1030b26bcc03cc968021979b9754a93f91921e8d.zip | |
(file_dialog_callback): New function.
(Fx_file_dialog): Allow selecting directories as well as files.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/w32fns.c | 132 |
2 files changed, 92 insertions, 45 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 222f06329cc..7651e9701f0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2002-06-22 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32fns.c (file_dialog_callback): New function. | ||
| 4 | (Fx_file_dialog): Allow selecting directories as well as files. | ||
| 5 | |||
| 1 | 2002-06-21 Pavel Jan,Bm(Bk <Pavel@Janik.cz> | 6 | 2002-06-21 Pavel Jan,Bm(Bk <Pavel@Janik.cz> |
| 2 | 7 | ||
| 3 | * m/pmax.h (START_FILES): Define START_FILES for NetBSD and | 8 | * m/pmax.h (START_FILES): Define START_FILES for NetBSD and |
diff --git a/src/w32fns.c b/src/w32fns.c index 95ecc1b401c..09824ccbd6f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -52,6 +52,9 @@ Boston, MA 02111-1307, USA. */ | |||
| 52 | #include <shellapi.h> | 52 | #include <shellapi.h> |
| 53 | #include <ctype.h> | 53 | #include <ctype.h> |
| 54 | 54 | ||
| 55 | #include <dlgs.h> | ||
| 56 | #define FILE_NAME_TEXT_FIELD edt1 | ||
| 57 | |||
| 55 | extern void free_frame_menubar (); | 58 | extern void free_frame_menubar (); |
| 56 | extern void x_compute_fringe_widths P_ ((struct frame *, int)); | 59 | extern void x_compute_fringe_widths P_ ((struct frame *, int)); |
| 57 | extern double atof (); | 60 | extern double atof (); |
| @@ -14244,9 +14247,47 @@ Value is t if tooltip was open, nil otherwise. */) | |||
| 14244 | /*********************************************************************** | 14247 | /*********************************************************************** |
| 14245 | File selection dialog | 14248 | File selection dialog |
| 14246 | ***********************************************************************/ | 14249 | ***********************************************************************/ |
| 14247 | |||
| 14248 | extern Lisp_Object Qfile_name_history; | 14250 | extern Lisp_Object Qfile_name_history; |
| 14249 | 14251 | ||
| 14252 | /* Callback for altering the behaviour of the Open File dialog. | ||
| 14253 | Makes the Filename text field contain "Current Directory" and be | ||
| 14254 | read-only when "Directories" is selected in the filter. This | ||
| 14255 | allows us to work around the fact that the standard Open File | ||
| 14256 | dialog does not support directories. */ | ||
| 14257 | UINT CALLBACK | ||
| 14258 | file_dialog_callback (hwnd, msg, wParam, lParam) | ||
| 14259 | HWND hwnd; | ||
| 14260 | UINT msg; | ||
| 14261 | WPARAM wParam; | ||
| 14262 | LPARAM lParam; | ||
| 14263 | { | ||
| 14264 | if (msg == WM_NOTIFY) | ||
| 14265 | { | ||
| 14266 | OFNOTIFY * notify = (OFNOTIFY *)lParam; | ||
| 14267 | /* Detect when the Filter dropdown is changed. */ | ||
| 14268 | if (notify->hdr.code == CDN_TYPECHANGE) | ||
| 14269 | { | ||
| 14270 | HWND dialog = GetParent (hwnd); | ||
| 14271 | HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); | ||
| 14272 | |||
| 14273 | /* Directories is in index 2. */ | ||
| 14274 | if (notify->lpOFN->nFilterIndex == 2) | ||
| 14275 | { | ||
| 14276 | CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, | ||
| 14277 | "Current Directory"); | ||
| 14278 | EnableWindow (edit_control, FALSE); | ||
| 14279 | } | ||
| 14280 | else | ||
| 14281 | { | ||
| 14282 | CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, | ||
| 14283 | ""); | ||
| 14284 | EnableWindow (edit_control, TRUE); | ||
| 14285 | } | ||
| 14286 | } | ||
| 14287 | } | ||
| 14288 | return 0; | ||
| 14289 | } | ||
| 14290 | |||
| 14250 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, | 14291 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, |
| 14251 | doc: /* Read file name, prompting with PROMPT in directory DIR. | 14292 | doc: /* Read file name, prompting with PROMPT in directory DIR. |
| 14252 | Use a file selection dialog. | 14293 | Use a file selection dialog. |
| @@ -14261,7 +14302,6 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) | |||
| 14261 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 14302 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 14262 | char filename[MAX_PATH + 1]; | 14303 | char filename[MAX_PATH + 1]; |
| 14263 | char init_dir[MAX_PATH + 1]; | 14304 | char init_dir[MAX_PATH + 1]; |
| 14264 | int use_dialog_p = 1; | ||
| 14265 | 14305 | ||
| 14266 | GCPRO5 (prompt, dir, default_filename, mustmatch, file); | 14306 | GCPRO5 (prompt, dir, default_filename, mustmatch, file); |
| 14267 | CHECK_STRING (prompt); | 14307 | CHECK_STRING (prompt); |
| @@ -14287,12 +14327,6 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) | |||
| 14287 | else | 14327 | else |
| 14288 | { | 14328 | { |
| 14289 | file_name_only++; | 14329 | file_name_only++; |
| 14290 | |||
| 14291 | /* If default_file_name is a directory, don't use the open | ||
| 14292 | file dialog, as it does not support selecting | ||
| 14293 | directories. */ | ||
| 14294 | if (!(*file_name_only)) | ||
| 14295 | use_dialog_p = 0; | ||
| 14296 | } | 14330 | } |
| 14297 | 14331 | ||
| 14298 | strncpy (filename, file_name_only, MAX_PATH); | 14332 | strncpy (filename, file_name_only, MAX_PATH); |
| @@ -14301,46 +14335,54 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) | |||
| 14301 | else | 14335 | else |
| 14302 | filename[0] = '\0'; | 14336 | filename[0] = '\0'; |
| 14303 | 14337 | ||
| 14304 | if (use_dialog_p) | 14338 | { |
| 14305 | { | 14339 | OPENFILENAME file_details; |
| 14306 | OPENFILENAME file_details; | ||
| 14307 | 14340 | ||
| 14308 | /* Prevent redisplay. */ | 14341 | /* Prevent redisplay. */ |
| 14309 | specbind (Qinhibit_redisplay, Qt); | 14342 | specbind (Qinhibit_redisplay, Qt); |
| 14310 | BLOCK_INPUT; | 14343 | BLOCK_INPUT; |
| 14311 | 14344 | ||
| 14312 | bzero (&file_details, sizeof (file_details)); | 14345 | bzero (&file_details, sizeof (file_details)); |
| 14313 | file_details.lStructSize = sizeof (file_details); | 14346 | file_details.lStructSize = sizeof (file_details); |
| 14314 | file_details.hwndOwner = FRAME_W32_WINDOW (f); | 14347 | file_details.hwndOwner = FRAME_W32_WINDOW (f); |
| 14315 | /* Undocumented Bug in Common File Dialog: | 14348 | /* Undocumented Bug in Common File Dialog: |
| 14316 | If a filter is not specified, shell links are not resolved. */ | 14349 | If a filter is not specified, shell links are not resolved. */ |
| 14317 | file_details.lpstrFilter = "ALL Files (*.*)\0*.*\0\0"; | 14350 | file_details.lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0"; |
| 14318 | file_details.lpstrFile = filename; | 14351 | file_details.lpstrFile = filename; |
| 14319 | file_details.nMaxFile = sizeof (filename); | 14352 | file_details.nMaxFile = sizeof (filename); |
| 14320 | file_details.lpstrInitialDir = init_dir; | 14353 | file_details.lpstrInitialDir = init_dir; |
| 14321 | file_details.lpstrTitle = XSTRING (prompt)->data; | 14354 | file_details.lpstrTitle = XSTRING (prompt)->data; |
| 14322 | file_details.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; | 14355 | file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
| 14323 | 14356 | | OFN_EXPLORER | OFN_ENABLEHOOK); | |
| 14324 | if (!NILP (mustmatch)) | 14357 | if (!NILP (mustmatch)) |
| 14325 | file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; | 14358 | file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; |
| 14326 | 14359 | ||
| 14327 | if (GetOpenFileName (&file_details)) | 14360 | file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; |
| 14328 | { | 14361 | |
| 14329 | dostounix_filename (filename); | 14362 | if (GetOpenFileName (&file_details)) |
| 14330 | file = DECODE_FILE(build_string (filename)); | 14363 | { |
| 14331 | } | 14364 | dostounix_filename (filename); |
| 14332 | else | 14365 | if (file_details.nFilterIndex == 2) |
| 14333 | file = Qnil; | 14366 | { |
| 14367 | /* "Folder Only" selected - strip dummy file name. */ | ||
| 14368 | char * last = strrchr (filename, '/'); | ||
| 14369 | *last = '\0'; | ||
| 14370 | } | ||
| 14334 | 14371 | ||
| 14335 | UNBLOCK_INPUT; | 14372 | file = DECODE_FILE(build_string (filename)); |
| 14336 | file = unbind_to (count, file); | 14373 | } |
| 14337 | } | 14374 | /* User cancelled the dialog without making a selection. */ |
| 14338 | /* Open File dialog will not allow folders to be selected, so resort | 14375 | else if (!CommDlgExtendedError ()) |
| 14339 | to minibuffer completing reads for directories. */ | 14376 | file = Qnil; |
| 14340 | else | 14377 | /* An error occurred, fallback on reading from the mini-buffer. */ |
| 14341 | file = Fcompleting_read (prompt, intern ("read-file-name-internal"), | 14378 | else |
| 14342 | dir, mustmatch, dir, Qfile_name_history, | 14379 | file = Fcompleting_read (prompt, intern ("read-file-name-internal"), |
| 14343 | default_filename, Qnil); | 14380 | dir, mustmatch, dir, Qfile_name_history, |
| 14381 | default_filename, Qnil); | ||
| 14382 | |||
| 14383 | UNBLOCK_INPUT; | ||
| 14384 | file = unbind_to (count, file); | ||
| 14385 | } | ||
| 14344 | 14386 | ||
| 14345 | UNGCPRO; | 14387 | UNGCPRO; |
| 14346 | 14388 | ||