Mercurial > emacs
changeset 45963:e4d2d8c8186f
(file_dialog_callback): New function.
(Fx_file_dialog): Allow selecting directories as well as files.
author | Jason Rumney <jasonr@gnu.org> |
---|---|
date | Sat, 22 Jun 2002 19:49:44 +0000 |
parents | 56be1b705050 |
children | 1cfc5b600782 |
files | src/w32fns.c |
diffstat | 1 files changed, 90 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/src/w32fns.c Fri Jun 21 21:00:03 2002 +0000 +++ b/src/w32fns.c Sat Jun 22 19:49:44 2002 +0000 @@ -52,6 +52,9 @@ #include <shellapi.h> #include <ctype.h> +#include <dlgs.h> +#define FILE_NAME_TEXT_FIELD edt1 + extern void free_frame_menubar (); extern void x_compute_fringe_widths P_ ((struct frame *, int)); extern double atof (); @@ -14244,9 +14247,47 @@ /*********************************************************************** File selection dialog ***********************************************************************/ - extern Lisp_Object Qfile_name_history; +/* Callback for altering the behaviour of the Open File dialog. + Makes the Filename text field contain "Current Directory" and be + read-only when "Directories" is selected in the filter. This + allows us to work around the fact that the standard Open File + dialog does not support directories. */ +UINT CALLBACK +file_dialog_callback (hwnd, msg, wParam, lParam) + HWND hwnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; +{ + if (msg == WM_NOTIFY) + { + OFNOTIFY * notify = (OFNOTIFY *)lParam; + /* Detect when the Filter dropdown is changed. */ + if (notify->hdr.code == CDN_TYPECHANGE) + { + HWND dialog = GetParent (hwnd); + HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); + + /* Directories is in index 2. */ + if (notify->lpOFN->nFilterIndex == 2) + { + CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, + "Current Directory"); + EnableWindow (edit_control, FALSE); + } + else + { + CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, + ""); + EnableWindow (edit_control, TRUE); + } + } + } + return 0; +} + DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, doc: /* Read file name, prompting with PROMPT in directory DIR. Use a file selection dialog. @@ -14261,7 +14302,6 @@ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; char filename[MAX_PATH + 1]; char init_dir[MAX_PATH + 1]; - int use_dialog_p = 1; GCPRO5 (prompt, dir, default_filename, mustmatch, file); CHECK_STRING (prompt); @@ -14287,12 +14327,6 @@ else { file_name_only++; - - /* If default_file_name is a directory, don't use the open - file dialog, as it does not support selecting - directories. */ - if (!(*file_name_only)) - use_dialog_p = 0; } strncpy (filename, file_name_only, MAX_PATH); @@ -14301,46 +14335,54 @@ else filename[0] = '\0'; - if (use_dialog_p) - { - OPENFILENAME file_details; - - /* Prevent redisplay. */ - specbind (Qinhibit_redisplay, Qt); - BLOCK_INPUT; - - bzero (&file_details, sizeof (file_details)); - file_details.lStructSize = sizeof (file_details); - file_details.hwndOwner = FRAME_W32_WINDOW (f); - /* Undocumented Bug in Common File Dialog: - If a filter is not specified, shell links are not resolved. */ - file_details.lpstrFilter = "ALL Files (*.*)\0*.*\0\0"; - file_details.lpstrFile = filename; - file_details.nMaxFile = sizeof (filename); - file_details.lpstrInitialDir = init_dir; - file_details.lpstrTitle = XSTRING (prompt)->data; - file_details.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; - - if (!NILP (mustmatch)) - file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; - - if (GetOpenFileName (&file_details)) - { - dostounix_filename (filename); - file = DECODE_FILE(build_string (filename)); - } - else - file = Qnil; - - UNBLOCK_INPUT; - file = unbind_to (count, file); - } - /* Open File dialog will not allow folders to be selected, so resort - to minibuffer completing reads for directories. */ - else - file = Fcompleting_read (prompt, intern ("read-file-name-internal"), - dir, mustmatch, dir, Qfile_name_history, - default_filename, Qnil); + { + OPENFILENAME file_details; + + /* Prevent redisplay. */ + specbind (Qinhibit_redisplay, Qt); + BLOCK_INPUT; + + bzero (&file_details, sizeof (file_details)); + file_details.lStructSize = sizeof (file_details); + file_details.hwndOwner = FRAME_W32_WINDOW (f); + /* Undocumented Bug in Common File Dialog: + If a filter is not specified, shell links are not resolved. */ + file_details.lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0"; + file_details.lpstrFile = filename; + file_details.nMaxFile = sizeof (filename); + file_details.lpstrInitialDir = init_dir; + file_details.lpstrTitle = XSTRING (prompt)->data; + file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR + | OFN_EXPLORER | OFN_ENABLEHOOK); + if (!NILP (mustmatch)) + file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; + + file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; + + if (GetOpenFileName (&file_details)) + { + dostounix_filename (filename); + if (file_details.nFilterIndex == 2) + { + /* "Folder Only" selected - strip dummy file name. */ + char * last = strrchr (filename, '/'); + *last = '\0'; + } + + file = DECODE_FILE(build_string (filename)); + } + /* User cancelled the dialog without making a selection. */ + else if (!CommDlgExtendedError ()) + file = Qnil; + /* An error occurred, fallback on reading from the mini-buffer. */ + else + file = Fcompleting_read (prompt, intern ("read-file-name-internal"), + dir, mustmatch, dir, Qfile_name_history, + default_filename, Qnil); + + UNBLOCK_INPUT; + file = unbind_to (count, file); + } UNGCPRO;