]> git.eshelyaron.com Git - emacs.git/commitdiff
fileio.c (Fread_file_name): Call x_file_dialog on carbon on
authorSteven Tamm <steventamm@mac.com>
Thu, 26 Aug 2004 18:28:44 +0000 (18:28 +0000)
committerSteven Tamm <steventamm@mac.com>
Thu, 26 Aug 2004 18:28:44 +0000 (18:28 +0000)
tool-bar/menu click
macfns.c (Fx_file_dialog): Implemented using NavServices

src/ChangeLog
src/fileio.c
src/macfns.c

index d49514b2fc09b0bcfdcc4495057e4fd3c2048533..fa1922c625590358156d5192c6f77c6a8c149962 100644 (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\e,Ad\e(Brv  <jan.h.d@swipnet.se>
 
        * xterm.c (x_catch_errors_unwind): Do not XSync if display has closed.
index 5acfee7c02c4e65d32cdc9be6dce11ba58b3eeb8..b92999101861c22b2c2040aafc76c733bd5ddf78 100644 (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
index ec014e772e35ac303bcc1a7d24d8d15d0d59d2be..fbade05ea17e865996844267cc75372accd8eb6e 100644 (file)
@@ -4192,19 +4192,27 @@ Value is t if tooltip was open, nil otherwise.  */)
 
 
 \f
+#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);
-
-      unixtodos_filename (full_path_name);
-
-      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;
+  {
+    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;
+    */
+
+    /* 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);
+      }
 
-      /* Prevent redisplay.  */
-      specbind (Qinhibit_redisplay, Qt);
       BLOCK_INPUT;
+      status = NavDialogRun(dialogRef);
+      UNBLOCK_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 (saveName) CFRelease(saveName);
+    if (client) CFRelease(client);
+    if (message) CFRelease(message);
 
-      if (GetOpenFileName (&file_details))
-        {
-          dostounix_filename (filename);
-          file = build_string (filename);
-        }
-      else
-        file = Qnil;
-
-      UNBLOCK_INPUT;
-      file = unbind_to (count, file);
+    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);
     }
-  /* 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);
+    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
 \f
 /***********************************************************************
                            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
 }