1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-17 17:58:46 +00:00

fileio.c (Fread_file_name): Call x_file_dialog on carbon on

tool-bar/menu click
macfns.c (Fx_file_dialog): Implemented using NavServices
This commit is contained in:
Steven Tamm 2004-08-26 18:28:44 +00:00
parent 0e48150a65
commit 6eb3ee72e0
3 changed files with 150 additions and 74 deletions

View File

@ -1,3 +1,9 @@
2004-08-26 Steven Tamm <steventamm@mac.com>
* fileio.c (Fread_file_name): Call x_file_dialog on carbon on
tool-bar/menu click
* macfns.c (Fx_file_dialog): Implemented using NavServices
2004-08-24 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* xterm.c (x_catch_errors_unwind): Do not XSync if display has closed.

View File

@ -6304,7 +6304,7 @@ and `read-file-name-function'. */)
GCPRO2 (insdef, default_filename);
#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined(TARGET_API_MAC_CARBON)
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& use_file_dialog

View File

@ -4192,19 +4192,27 @@ Value is t if tooltip was open, nil otherwise. */)
#ifdef TARGET_API_MAC_CARBON
/***********************************************************************
File selection dialog
***********************************************************************/
#if 0 /* MAC_TODO: can standard file dialog */
/**
There is a relatively standard way to do this using applescript to run
a (choose file) method. However, this doesn't do "the right thing"
by working only if the find-file occurred during a menu or toolbar
click. So we must do the file dialog by hand, using the navigation
manager. This also has more flexibility in determining the default
directory and whether or not we are going to choose a file.
**/
extern Lisp_Object Qfile_name_history;
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.
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. */)
specified. Ensure that file exists if MUSTMATCH is non-nil. */)
(prompt, dir, default_filename, mustmatch)
Lisp_Object prompt, dir, default_filename, mustmatch;
{
@ -4212,9 +4220,8 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
Lisp_Object file = Qnil;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
char filename[MAX_PATH + 1];
char init_dir[MAX_PATH + 1];
int use_dialog_p = 1;
char filename[1001];
int default_filter_index = 1; /* 1: All Files, 2: Directories only */
GCPRO5 (prompt, dir, default_filename, mustmatch, file);
CHECK_STRING (prompt);
@ -4223,87 +4230,150 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
/* Create the dialog with PROMPT as title, using DIR as initial
directory and using "*" as pattern. */
dir = Fexpand_file_name (dir, Qnil);
strncpy (init_dir, SDATA (dir), MAX_PATH);
init_dir[MAX_PATH] = '\0';
unixtodos_filename (init_dir);
if (STRINGP (default_filename))
{
char *file_name_only;
char *full_path_name = SDATA (default_filename);
{
OSStatus status;
NavDialogCreationOptions options;
NavDialogRef dialogRef;
NavTypeListHandle fileTypes = NULL;
NavUserAction userAction;
CFStringRef message=NULL, client=NULL, saveName = NULL;
/* No need for a callback function because we are modal */
NavGetDefaultDialogCreationOptions(&options);
options.modality = kWindowModalityAppModal;
options.location.h = options.location.v = -1;
options.optionFlags = kNavDefaultNavDlogOptions;
options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */
options.optionFlags |= kNavSelectAllReadableItem;
if (!NILP(prompt))
{
message = CFStringCreateWithCStringNoCopy(NULL, SDATA(prompt),
kCFStringEncodingUTF8,
kCFAllocatorNull);
options.message = message;
}
/* Don't set the application, let it use default.
client = CFStringCreateWithCStringNoCopy(NULL, "Emacs",
kCFStringEncodingMacRoman, NULL);
options.clientName = client;
*/
unixtodos_filename (full_path_name);
/* Do Dired hack copied from w32fns.c */
if (!NILP(prompt) && strncmp (SDATA(prompt), "Dired", 5) == 0)
status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL,
&dialogRef);
else if (NILP (mustmatch))
{
/* This is a save dialog */
if (!NILP(default_filename))
{
saveName = CFStringCreateWithCString(NULL, SDATA(default_filename),
kCFStringEncodingUTF8);
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*/
status = NavCreateChooseFileDialog(&options, fileTypes,
NULL, NULL, NULL, NULL,
&dialogRef);
}
/* Set the default location and continue*/
if (status == noErr) {
if (!NILP(dir)) {
FSRef defLoc;
AEDesc defLocAed;
status = FSPathMakeRef(SDATA(dir), &defLoc, NULL);
if (status == noErr)
{
AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
}
AEDisposeDesc(&defLocAed);
}
file_name_only = strrchr (full_path_name, '\\');
if (!file_name_only)
file_name_only = full_path_name;
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);
filename[MAX_PATH] = '\0';
}
else
filename[0] = '\0';
if (use_dialog_p)
{
OPENFILENAME file_details;
char *filename_file;
/* 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);
file_details.lpstrFile = filename;
file_details.nMaxFile = sizeof (filename);
file_details.lpstrInitialDir = init_dir;
file_details.lpstrTitle = SDATA (prompt);
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 = build_string (filename);
}
else
file = Qnil;
status = NavDialogRun(dialogRef);
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);
if (saveName) CFRelease(saveName);
if (client) CFRelease(client);
if (message) CFRelease(message);
if (status == noErr) {
userAction = NavDialogGetUserAction(dialogRef);
switch (userAction)
{
case kNavUserActionNone:
case kNavUserActionCancel:
NavDialogDispose(dialogRef);
Fsignal (Qquit, Qnil); /* Treat cancel like C-g */
return;
case kNavUserActionOpen:
case kNavUserActionChoose:
case kNavUserActionSaveAs:
{
NavReplyRecord reply;
AEDesc aed;
FSRef fsRef;
status = NavDialogGetReply(dialogRef, &reply);
AECoerceDesc(&reply.selection, typeFSRef, &aed);
AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef));
FSRefMakePath(&fsRef, (UInt8 *) filename, 1000);
AEDisposeDesc(&aed);
if (reply.saveFileName)
{
/* If it was a saved file, we need to add the file name */
int len = strlen(filename);
if (len && filename[len-1] != '/')
filename[len++] = '/';
CFStringGetCString(reply.saveFileName, filename+len,
1000-len, kCFStringEncodingUTF8);
}
file = DECODE_FILE(build_string (filename));
NavDisposeReply(&reply);
}
break;
}
NavDialogDispose(dialogRef);
}
else {
/* Fall back on minibuffer if there was a problem */
file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
dir, mustmatch, dir, Qfile_name_history,
default_filename, Qnil);
}
}
UNGCPRO;
/* Make "Cancel" equivalent to C-g. */
if (NILP (file))
Fsignal (Qquit, Qnil);
return unbind_to (count, file);
}
#endif /* MAC_TODO */
#endif
/***********************************************************************
Initialization
@ -4507,7 +4577,7 @@ Chinese, Japanese, and Korean. */);
last_show_tip_args = Qnil;
staticpro (&last_show_tip_args);
#if 0 /* MAC_TODO */
#if TARGET_API_MAC_CARBON
defsubr (&Sx_file_dialog);
#endif
}