* 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.
This commit is contained in:
Jan Djärv 2004-11-02 08:21:16 +00:00
parent 46bfc73bed
commit f9d64bb358
8 changed files with 228 additions and 79 deletions

View file

@ -1,5 +1,36 @@
2004-11-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* 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 <storm@cua.dk>

View file

@ -6321,7 +6321,8 @@ and `read-file-name-function'. */)
}
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

View file

@ -1118,6 +1118,10 @@ create_dialog (wv, select_cb, deactivate_cb)
}
/***********************************************************************
File dialog functions
***********************************************************************/
enum
{
XG_FILE_NOT_DONE,
@ -1126,6 +1130,69 @@ enum
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 @@ xg_file_sel_destroy (w, arg)
*(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 @@ xg_file_sel_destroy (w, arg)
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 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p)
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 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p)
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 @@ xg_initialize ()
"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 */

View file

@ -132,7 +132,8 @@ extern void free_widget_value P_ ((widget_value *));
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,

View file

@ -3121,7 +3121,7 @@ extern void syms_of_xfns P_ ((void));
#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 */

View file

@ -4216,22 +4216,23 @@ Value is t if tooltip was open, nil otherwise. */)
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 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
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 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
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 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
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 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
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);

View file

@ -7742,23 +7742,24 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
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 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
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;

View file

@ -5106,27 +5106,26 @@ file_dialog_unmap_cb (widget, client_data, call_data)
}
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;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
GCPRO5 (prompt, dir, default_filename, mustmatch, file);
GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
CHECK_STRING (prompt);
CHECK_STRING (dir);
@ -5159,9 +5158,9 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
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 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
/* 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;
Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
default_xmstring
= XmStringCreateLocalized (SDATA (default_filename));
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);
}
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);
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 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
#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 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
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)
{