aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2002-06-22 19:52:29 +0000
committerJason Rumney2002-06-22 19:52:29 +0000
commit1030b26bcc03cc968021979b9754a93f91921e8d (patch)
treefa000a88815a14e096dc8704749e74e2bd52cee3 /src
parent29c3cbf0f36fe92cb2be88b7e7daa03d67124399 (diff)
downloademacs-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/ChangeLog5
-rw-r--r--src/w32fns.c132
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 @@
12002-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
12002-06-21 Pavel Jan,Bm(Bk <Pavel@Janik.cz> 62002-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
55extern void free_frame_menubar (); 58extern void free_frame_menubar ();
56extern void x_compute_fringe_widths P_ ((struct frame *, int)); 59extern void x_compute_fringe_widths P_ ((struct frame *, int));
57extern double atof (); 60extern 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
14248extern Lisp_Object Qfile_name_history; 14250extern 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. */
14257UINT CALLBACK
14258file_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
14250DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, 14291DEFUN ("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.
14252Use a file selection dialog. 14293Use 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