# HG changeset patch # User Jan Dj¸«£rv # Date 1099383676 0 # Node ID c955f6add62a436f786ecaa8dd68fc0e52da381b # Parent 5a547995da89b82a4b202fbfce70ea5adb318c5a * fileio.c (Fread_file_name): Pass Qt as fifth parameter to Fx_file_dialog if only directories should be read. * lisp.h: Fx_file_dialog takes 5 parameters. * xfns.c (Fx_file_dialog): Both Motif and GTK version: Add parameter only_dir_p. In Motif version, don't put DEFAULT_FILENAME in filter part of the dialog, just text field part. Do not add DEFAULT_FILENAME to list of files if it isn't there. In GTK version, pass only_dir_p parameter to xg_get_file_name. * macfns.c (Fx_file_dialog): Add parameter only_dir_p. Check only_dir_p instead of comparing prompt to "Dired". When using a save dialog, add option kNavDontConfirmReplacement, change title to "Enter name", change text for save button to "Ok". * w32fns.c (Fx_file_dialog): Add parameter only_dir_p. Check only_dir_p instead of comparing prompt to "Dired". * gtkutil.c (xg_get_file_with_chooser) (xg_get_file_with_selection): New functions, only defined ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW and HAVE_GTK_FILE_SELECTION_NEW respectively. (xg_get_file_name): Add parameter only_dir_p. Call xg_get_file_with_chooser or xg_get_file_with_selection depending on HAVE_GTK_FILE* and the value of use_old_gtk_file_dialog. (xg_initialize): New DEFVAR_BOOL use_old_gtk_file_dialog. * gtkutil.h (xg_get_file_name): Add parameter only_dir_p. diff -r 5a547995da89 -r c955f6add62a src/ChangeLog --- a/src/ChangeLog Tue Nov 02 07:57:53 2004 +0000 +++ b/src/ChangeLog Tue Nov 02 08:21:16 2004 +0000 @@ -1,5 +1,36 @@ 2004-11-02 Jan Dj,Ad(Brv + * fileio.c (Fread_file_name): Pass Qt as fifth parameter to + Fx_file_dialog if only directories should be read. + + * lisp.h: Fx_file_dialog takes 5 parameters. + + * xfns.c (Fx_file_dialog): Both Motif and GTK version: Add + parameter only_dir_p. + In Motif version, don't put DEFAULT_FILENAME in filter part of the + dialog, just text field part. Do not add DEFAULT_FILENAME + to list of files if it isn't there. + In GTK version, pass only_dir_p parameter to xg_get_file_name. + + * macfns.c (Fx_file_dialog): Add parameter only_dir_p. Check + only_dir_p instead of comparing prompt to "Dired". When using + a save dialog, add option kNavDontConfirmReplacement, change title + to "Enter name", change text for save button to "Ok". + + * w32fns.c (Fx_file_dialog): Add parameter only_dir_p. Check + only_dir_p instead of comparing prompt to "Dired". + + * gtkutil.c (xg_get_file_with_chooser) + (xg_get_file_with_selection): New functions, only defined ifdef + HAVE_GTK_FILE_CHOOSER_DIALOG_NEW and HAVE_GTK_FILE_SELECTION_NEW + respectively. + (xg_get_file_name): Add parameter only_dir_p. + Call xg_get_file_with_chooser or xg_get_file_with_selection + depending on HAVE_GTK_FILE* and the value of use_old_gtk_file_dialog. + (xg_initialize): New DEFVAR_BOOL use_old_gtk_file_dialog. + + * gtkutil.h (xg_get_file_name): Add parameter only_dir_p. + * config.in: Rebuild (added HAVE_GTK_FILE_*). 2004-11-01 Kim F. Storm diff -r 5a547995da89 -r c955f6add62a src/fileio.c --- a/src/fileio.c Tue Nov 02 07:57:53 2004 +0000 +++ b/src/fileio.c Tue Nov 02 08:21:16 2004 +0000 @@ -6321,7 +6321,8 @@ } if (!NILP(default_filename)) default_filename = Fexpand_file_name (default_filename, dir); - val = Fx_file_dialog (prompt, dir, default_filename, mustmatch); + val = Fx_file_dialog (prompt, dir, default_filename, mustmatch, + EQ (predicate, Qfile_directory_p) ? Qt : Qnil); add_to_history = 1; } else diff -r 5a547995da89 -r c955f6add62a src/gtkutil.c --- a/src/gtkutil.c Tue Nov 02 07:57:53 2004 +0000 +++ b/src/gtkutil.c Tue Nov 02 08:21:16 2004 +0000 @@ -1118,6 +1118,10 @@ } + +/*********************************************************************** + File dialog functions + ***********************************************************************/ enum { XG_FILE_NOT_DONE, @@ -1126,6 +1130,69 @@ XG_FILE_DESTROYED, }; +#ifdef HAVE_GTK_FILE_BOTH +static int use_old_gtk_file_dialog; +#endif + + +#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW +/* Read a file name from the user using a file chooser dialog. + F is the current frame. + PROMPT is a prompt to show to the user. May not be NULL. + DEFAULT_FILENAME is a default selection to be displayed. May be NULL. + If MUSTMATCH_P is non-zero, the returned file name must be an existing + file. + + Returns a file name or NULL if no file was selected. + The returned string must be freed by the caller. */ + +static char * +xg_get_file_with_chooser (f, prompt, default_filename, mustmatch_p, only_dir_p) + FRAME_PTR f; + char *prompt; + char *default_filename; + int mustmatch_p, only_dir_p; +{ + GtkWidget *filewin; + GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)); + + char *fn = 0; + GtkFileChooserAction action = (mustmatch_p ? + GTK_FILE_CHOOSER_ACTION_OPEN : + GTK_FILE_CHOOSER_ACTION_SAVE); + + if (only_dir_p) + action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; + + filewin = gtk_file_chooser_dialog_new (prompt, gwin, action, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + (mustmatch_p || only_dir_p ? + GTK_STOCK_OPEN : GTK_STOCK_SAVE), + GTK_RESPONSE_OK, + NULL); + + xg_set_screen (filewin, f); + gtk_widget_set_name (filewin, "emacs-filedialog"); + gtk_window_set_transient_for (GTK_WINDOW (filewin), gwin); + gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE); + + + if (default_filename) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filewin), + default_filename); + + gtk_widget_show (filewin); + + if (gtk_dialog_run (GTK_DIALOG (filewin)) == GTK_RESPONSE_OK) + fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filewin)); + + gtk_widget_destroy (filewin); + + return fn; +} +#endif /* HAVE_GTK_FILE_CHOOSER_DIALOG_NEW */ + +#ifdef HAVE_GTK_FILE_SELECTION_NEW /* Callback function invoked when the Ok button is pressed in a file dialog. W is the file dialog widget, @@ -1167,7 +1234,7 @@ *(int*)arg = XG_FILE_DESTROYED; } -/* Read a file name from the user using a file dialog. +/* Read a file name from the user using a file selection dialog. F is the current frame. PROMPT is a prompt to show to the user. May not be NULL. DEFAULT_FILENAME is a default selection to be displayed. May be NULL. @@ -1177,12 +1244,13 @@ Returns a file name or NULL if no file was selected. The returned string must be freed by the caller. */ -char * -xg_get_file_name (f, prompt, default_filename, mustmatch_p) +static char * +xg_get_file_with_selection (f, prompt, default_filename, + mustmatch_p, only_dir_p) FRAME_PTR f; char *prompt; char *default_filename; - int mustmatch_p; + int mustmatch_p, only_dir_p; { GtkWidget *filewin; GtkFileSelection *filesel; @@ -1193,9 +1261,7 @@ filesel = GTK_FILE_SELECTION (filewin); xg_set_screen (filewin, f); - gtk_widget_set_name (filewin, "emacs-filedialog"); - gtk_window_set_transient_for (GTK_WINDOW (filewin), GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE); @@ -1237,6 +1303,49 @@ return fn; } +#endif /* HAVE_GTK_FILE_SELECTION_NEW */ + +/* Read a file name from the user using a file dialog, either the old + file selection dialog, or the new file chooser dialog. Which to use + depends on what the GTK version used has, and what the value of + gtk-use-old-file-dialog. + F is the current frame. + PROMPT is a prompt to show to the user. May not be NULL. + DEFAULT_FILENAME is a default selection to be displayed. May be NULL. + If MUSTMATCH_P is non-zero, the returned file name must be an existing + file. + + Returns a file name or NULL if no file was selected. + The returned string must be freed by the caller. */ + +char * +xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p) + FRAME_PTR f; + char *prompt; + char *default_filename; + int mustmatch_p, only_dir_p; +{ +#ifdef HAVE_GTK_FILE_BOTH + if (use_old_gtk_file_dialog) + return xg_get_file_with_selection (f, prompt, default_filename, + mustmatch_p, only_dir_p); + return xg_get_file_with_chooser (f, prompt, default_filename, + mustmatch_p, only_dir_p); + +#else /* not HAVE_GTK_FILE_BOTH */ + +#ifdef HAVE_GTK_FILE_SELECTION_DIALOG_NEW + return xg_get_file_with_selection (f, prompt, default_filename, + mustmatch_p, only_dir_p); +#endif +#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW + return xg_get_file_with_chooser (f, prompt, default_filename, + mustmatch_p, only_dir_p); +#endif + +#endif /* HAVE_GTK_FILE_BOTH */ + return 0; +} /*********************************************************************** @@ -3429,6 +3538,14 @@ "gtk-key-theme-name", "Emacs", EMACS_CLASS); + +#ifdef HAVE_GTK_FILE_BOTH + DEFVAR_BOOL ("use-old-gtk-file-dialog", &use_old_gtk_file_dialog, + doc: /* *Non-nil means that the old GTK file selection dialog is used. + If nil the new GTK file chooser is used instead. To turn off + all file dialogs set the variable `use-file-dialog'. */); + use_old_gtk_file_dialog = 0; +#endif } #endif /* USE_GTK */ diff -r 5a547995da89 -r c955f6add62a src/gtkutil.h --- a/src/gtkutil.h Tue Nov 02 07:57:53 2004 +0000 +++ b/src/gtkutil.h Tue Nov 02 08:21:16 2004 +0000 @@ -132,7 +132,8 @@ extern char *xg_get_file_name P_ ((FRAME_PTR f, char *prompt, char *default_filename, - int mustmatch_p)); + int mustmatch_p, + int only_dir_p)); extern GtkWidget *xg_create_widget P_ ((char *type, char *name, diff -r 5a547995da89 -r c955f6add62a src/lisp.h --- a/src/lisp.h Tue Nov 02 07:57:53 2004 +0000 +++ b/src/lisp.h Tue Nov 02 08:21:16 2004 +0000 @@ -3121,7 +3121,7 @@ #ifdef HAVE_WINDOW_SYSTEM /* Defined in xfns.c, w32fns.c, or macfns.c */ EXFUN (Fxw_display_color_p, 1); -EXFUN (Fx_file_dialog, 4); +EXFUN (Fx_file_dialog, 5); #endif /* HAVE_WINDOW_SYSTEM */ /* Defined in xsmfns.c */ diff -r 5a547995da89 -r c955f6add62a src/macfns.c --- a/src/macfns.c Tue Nov 02 07:57:53 2004 +0000 +++ b/src/macfns.c Tue Nov 02 08:21:16 2004 +0000 @@ -4216,22 +4216,23 @@ extern Lisp_Object Qfile_name_history; -DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, +DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, doc: /* Read file name, prompting with PROMPT in directory DIR. Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file selection box, if -specified. Ensure that file exists if MUSTMATCH is non-nil. */) - (prompt, dir, default_filename, mustmatch) - Lisp_Object prompt, dir, default_filename, mustmatch; +specified. Ensure that file exists if MUSTMATCH is non-nil. +If ONLY-DIR-P is non-nil, the user can only select directories. */) + (prompt, dir, default_filename, mustmatch, only_dir_p) + Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { struct frame *f = SELECTED_FRAME (); Lisp_Object file = Qnil; int count = SPECPDL_INDEX (); - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; char filename[1001]; int default_filter_index = 1; /* 1: All Files, 2: Directories only */ - GCPRO5 (prompt, dir, default_filename, mustmatch, file); + GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p); CHECK_STRING (prompt); CHECK_STRING (dir); @@ -4245,7 +4246,8 @@ NavDialogRef dialogRef; NavTypeListHandle fileTypes = NULL; NavUserAction userAction; - CFStringRef message=NULL, client=NULL, saveName = NULL; + CFStringRef message=NULL, client=NULL, saveName = NULL, ok = NULL; + CFStringRef title = NULL; BLOCK_INPUT; /* No need for a callback function because we are modal */ @@ -4268,13 +4270,19 @@ options.clientName = client; */ - /* Do Dired hack copied from w32fns.c */ - if (!NILP(prompt) && strncmp (SDATA(prompt), "Dired", 5) == 0) + if (!NILP (only_dir_p)) status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL, &dialogRef); else if (NILP (mustmatch)) { /* This is a save dialog */ + ok = CFStringCreateWithCString (NULL, "Ok", kCFStringEncodingUTF8); + title = CFStringCreateWithCString (NULL, "Enter name", + kCFStringEncodingUTF8); + options.optionFlags |= kNavDontConfirmReplacement; + options.actionButtonLabel = ok; + options.windowTitle = title; + if (!NILP(default_filename)) { saveName = CFStringCreateWithCString(NULL, SDATA(default_filename), @@ -4282,20 +4290,10 @@ options.saveFileName = saveName; options.optionFlags |= kNavSelectDefaultLocation; } - /* MAC_TODO: Find a better way to determine if this is a save - or load dialog than comparing dir with default_filename */ - if (EQ(dir, default_filename)) - { - status = NavCreateChooseFileDialog(&options, fileTypes, - NULL, NULL, NULL, NULL, - &dialogRef); - } - else { status = NavCreatePutFileDialog(&options, 'TEXT', kNavGenericSignature, NULL, NULL, &dialogRef); } - } else { /* This is an open dialog*/ @@ -4324,6 +4322,8 @@ if (saveName) CFRelease(saveName); if (client) CFRelease(client); if (message) CFRelease(message); + if (ok) CFRelease(ok); + if (title) CFRelease(title); if (status == noErr) { userAction = NavDialogGetUserAction(dialogRef); diff -r 5a547995da89 -r c955f6add62a src/w32fns.c --- a/src/w32fns.c Tue Nov 02 07:57:53 2004 +0000 +++ b/src/w32fns.c Tue Nov 02 08:21:16 2004 +0000 @@ -7742,23 +7742,24 @@ return 0; } -DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, +DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, doc: /* Read file name, prompting with PROMPT in directory DIR. Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file selection box, if -specified. Ensure that file exists if MUSTMATCH is non-nil. */) - (prompt, dir, default_filename, mustmatch) - Lisp_Object prompt, dir, default_filename, mustmatch; +specified. Ensure that file exists if MUSTMATCH is non-nil. +If ONLY-DIR-P is non-nil, the user can only select directories. */) + (prompt, dir, default_filename, mustmatch, only_dir_p) + Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { struct frame *f = SELECTED_FRAME (); Lisp_Object file = Qnil; int count = SPECPDL_INDEX (); - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; char filename[MAX_PATH + 1]; char init_dir[MAX_PATH + 1]; int default_filter_index = 1; /* 1: All Files, 2: Directories only */ - GCPRO5 (prompt, dir, default_filename, mustmatch, file); + GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); CHECK_STRING (prompt); CHECK_STRING (dir); @@ -7806,10 +7807,7 @@ file_details.lpstrInitialDir = init_dir; file_details.lpstrTitle = SDATA (prompt); - /* If prompt starts with Dired, default to directories only. */ - /* A bit hacky, but there doesn't seem to be a better way to - DTRT for dired. */ - if (strncmp (file_details.lpstrTitle, "Dired", 5) == 0) + if (! NILP (only_dir_p)) default_filter_index = 2; file_details.nFilterIndex = default_filter_index; diff -r 5a547995da89 -r c955f6add62a src/xfns.c --- a/src/xfns.c Tue Nov 02 07:57:53 2004 +0000 +++ b/src/xfns.c Tue Nov 02 08:21:16 2004 +0000 @@ -5106,27 +5106,26 @@ } -DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, +DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, doc: /* Read file name, prompting with PROMPT in directory DIR. -Use a file selection dialog. -Select DEFAULT-FILENAME in the dialog's file selection box, if -specified. Don't let the user enter a file name in the file -selection dialog's entry field, if MUSTMATCH is non-nil. */) - (prompt, dir, default_filename, mustmatch) - Lisp_Object prompt, dir, default_filename, mustmatch; +Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file +selection box, if specified. If MUSTMATCH is non-nil, the returned file +or directory must exist. ONLY-DIR-P is ignored." */) + (prompt, dir, default_filename, mustmatch, only_dir_p) + Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { int result; struct frame *f = SELECTED_FRAME (); Lisp_Object file = Qnil; - Widget dialog, text, list, help; + Widget dialog, text, help; Arg al[10]; int ac = 0; extern XtAppContext Xt_app_con; XmString dir_xmstring, pattern_xmstring; int count = SPECPDL_INDEX (); - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; - - GCPRO5 (prompt, dir, default_filename, mustmatch, file); + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; + + GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); CHECK_STRING (prompt); CHECK_STRING (dir); @@ -5159,9 +5158,9 @@ XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb, (XtPointer) &result); - /* Disable the help button since we can't display help. */ + /* Remove the help button since we can't display help. */ help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON); - XtSetSensitive (help, False); + XtUnmanageChild (help); /* Mark OK button as default. */ XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON), @@ -5183,30 +5182,30 @@ /* Manage the dialog, so that list boxes get filled. */ XtManageChild (dialog); - /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME - must include the path for this to work. */ - list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST); if (STRINGP (default_filename)) { XmString default_xmstring; - int item_pos; - - default_xmstring - = XmStringCreateLocalized (SDATA (default_filename)); - - if (!XmListItemExists (list, default_xmstring)) - { - /* Add a new item if DEFAULT_FILENAME is not in the list. */ - XmListAddItem (list, default_xmstring, 0); - item_pos = 0; - } - else - item_pos = XmListItemPos (list, default_xmstring); + Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT); + Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST); + + XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext); + XmTextFieldReplace (wtext, 0, last_pos, + (SDATA (Ffile_name_nondirectory (default_filename)))); + + /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME + must include the path for this to work. */ + + default_xmstring = XmStringCreateLocalized (SDATA (default_filename)); + + if (XmListItemExists (list, default_xmstring)) + { + int item_pos = XmListItemPos (list, default_xmstring); + /* Select the item and scroll it into view. */ + XmListSelectPos (list, item_pos, True); + XmListSetPos (list, item_pos); + } + XmStringFree (default_xmstring); - - /* Select the item and scroll it into view. */ - XmListSelectPos (list, item_pos, True); - XmListSetPos (list, item_pos); } /* Process events until the user presses Cancel or OK. */ @@ -5250,23 +5249,23 @@ #ifdef USE_GTK -DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, - "Read file name, prompting with PROMPT in directory DIR.\n\ -Use a file selection dialog.\n\ -Select DEFAULT-FILENAME in the dialog's file selection box, if\n\ -specified. Don't let the user enter a file name in the file\n\ -selection dialog's entry field, if MUSTMATCH is non-nil.") - (prompt, dir, default_filename, mustmatch) - Lisp_Object prompt, dir, default_filename, mustmatch; +DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, + doc: /* Read file name, prompting with PROMPT in directory DIR. +Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file +selection box, if specified. If MUSTMATCH is non-nil, the returned file +or directory must exist. If ONLY-DIR-P is non-nil, the user can only select +directories. */) + (prompt, dir, default_filename, mustmatch, only_dir_p) + Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p; { FRAME_PTR f = SELECTED_FRAME (); char *fn; Lisp_Object file = Qnil; int count = specpdl_ptr - specpdl; - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; char *cdef_file; - GCPRO5 (prompt, dir, default_filename, mustmatch, file); + GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); CHECK_STRING (prompt); CHECK_STRING (dir); @@ -5280,7 +5279,9 @@ else cdef_file = SDATA (dir); - fn = xg_get_file_name (f, SDATA (prompt), cdef_file, ! NILP (mustmatch)); + fn = xg_get_file_name (f, SDATA (prompt), cdef_file, + ! NILP (mustmatch), + ! NILP (only_dir_p)); if (fn) {