Mercurial > emacs
comparison src/macfns.c @ 56798:df3c9bb112b3
fileio.c (Fread_file_name): Call x_file_dialog on carbon on
tool-bar/menu click
macfns.c (Fx_file_dialog): Implemented using NavServices
author | Steven Tamm <steventamm@mac.com> |
---|---|
date | Thu, 26 Aug 2004 18:28:44 +0000 |
parents | 5e784b2ea638 |
children | a81166121d93 d8411455de48 |
comparison
equal
deleted
inserted
replaced
56797:2383026ff0d9 | 56798:df3c9bb112b3 |
---|---|
4190 return unbind_to (count, deleted); | 4190 return unbind_to (count, deleted); |
4191 } | 4191 } |
4192 | 4192 |
4193 | 4193 |
4194 | 4194 |
4195 #ifdef TARGET_API_MAC_CARBON | |
4195 /*********************************************************************** | 4196 /*********************************************************************** |
4196 File selection dialog | 4197 File selection dialog |
4197 ***********************************************************************/ | 4198 ***********************************************************************/ |
4198 | 4199 |
4199 #if 0 /* MAC_TODO: can standard file dialog */ | 4200 /** |
4201 There is a relatively standard way to do this using applescript to run | |
4202 a (choose file) method. However, this doesn't do "the right thing" | |
4203 by working only if the find-file occurred during a menu or toolbar | |
4204 click. So we must do the file dialog by hand, using the navigation | |
4205 manager. This also has more flexibility in determining the default | |
4206 directory and whether or not we are going to choose a file. | |
4207 **/ | |
4208 | |
4200 extern Lisp_Object Qfile_name_history; | 4209 extern Lisp_Object Qfile_name_history; |
4201 | 4210 |
4202 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, | 4211 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, |
4203 doc: /* Read file name, prompting with PROMPT in directory DIR. | 4212 doc: /* Read file name, prompting with PROMPT in directory DIR. |
4204 Use a file selection dialog. | 4213 Use a file selection dialog. |
4205 Select DEFAULT-FILENAME in the dialog's file selection box, if | 4214 Select DEFAULT-FILENAME in the dialog's file selection box, if |
4206 specified. Don't let the user enter a file name in the file | 4215 specified. Ensure that file exists if MUSTMATCH is non-nil. */) |
4207 selection dialog's entry field, if MUSTMATCH is non-nil. */) | |
4208 (prompt, dir, default_filename, mustmatch) | 4216 (prompt, dir, default_filename, mustmatch) |
4209 Lisp_Object prompt, dir, default_filename, mustmatch; | 4217 Lisp_Object prompt, dir, default_filename, mustmatch; |
4210 { | 4218 { |
4211 struct frame *f = SELECTED_FRAME (); | 4219 struct frame *f = SELECTED_FRAME (); |
4212 Lisp_Object file = Qnil; | 4220 Lisp_Object file = Qnil; |
4213 int count = SPECPDL_INDEX (); | 4221 int count = SPECPDL_INDEX (); |
4214 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 4222 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
4215 char filename[MAX_PATH + 1]; | 4223 char filename[1001]; |
4216 char init_dir[MAX_PATH + 1]; | 4224 int default_filter_index = 1; /* 1: All Files, 2: Directories only */ |
4217 int use_dialog_p = 1; | |
4218 | 4225 |
4219 GCPRO5 (prompt, dir, default_filename, mustmatch, file); | 4226 GCPRO5 (prompt, dir, default_filename, mustmatch, file); |
4220 CHECK_STRING (prompt); | 4227 CHECK_STRING (prompt); |
4221 CHECK_STRING (dir); | 4228 CHECK_STRING (dir); |
4222 | 4229 |
4223 /* Create the dialog with PROMPT as title, using DIR as initial | 4230 /* Create the dialog with PROMPT as title, using DIR as initial |
4224 directory and using "*" as pattern. */ | 4231 directory and using "*" as pattern. */ |
4225 dir = Fexpand_file_name (dir, Qnil); | 4232 dir = Fexpand_file_name (dir, Qnil); |
4226 strncpy (init_dir, SDATA (dir), MAX_PATH); | 4233 |
4227 init_dir[MAX_PATH] = '\0'; | 4234 { |
4228 unixtodos_filename (init_dir); | 4235 OSStatus status; |
4229 | 4236 NavDialogCreationOptions options; |
4230 if (STRINGP (default_filename)) | 4237 NavDialogRef dialogRef; |
4231 { | 4238 NavTypeListHandle fileTypes = NULL; |
4232 char *file_name_only; | 4239 NavUserAction userAction; |
4233 char *full_path_name = SDATA (default_filename); | 4240 CFStringRef message=NULL, client=NULL, saveName = NULL; |
4234 | 4241 |
4235 unixtodos_filename (full_path_name); | 4242 /* No need for a callback function because we are modal */ |
4236 | 4243 NavGetDefaultDialogCreationOptions(&options); |
4237 file_name_only = strrchr (full_path_name, '\\'); | 4244 options.modality = kWindowModalityAppModal; |
4238 if (!file_name_only) | 4245 options.location.h = options.location.v = -1; |
4239 file_name_only = full_path_name; | 4246 options.optionFlags = kNavDefaultNavDlogOptions; |
4240 else | 4247 options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */ |
4241 { | 4248 options.optionFlags |= kNavSelectAllReadableItem; |
4242 file_name_only++; | 4249 if (!NILP(prompt)) |
4243 | 4250 { |
4244 /* If default_file_name is a directory, don't use the open | 4251 message = CFStringCreateWithCStringNoCopy(NULL, SDATA(prompt), |
4245 file dialog, as it does not support selecting | 4252 kCFStringEncodingUTF8, |
4246 directories. */ | 4253 kCFAllocatorNull); |
4247 if (!(*file_name_only)) | 4254 options.message = message; |
4248 use_dialog_p = 0; | 4255 } |
4249 } | 4256 /* Don't set the application, let it use default. |
4250 | 4257 client = CFStringCreateWithCStringNoCopy(NULL, "Emacs", |
4251 strncpy (filename, file_name_only, MAX_PATH); | 4258 kCFStringEncodingMacRoman, NULL); |
4252 filename[MAX_PATH] = '\0'; | 4259 options.clientName = client; |
4253 } | 4260 */ |
4254 else | 4261 |
4255 filename[0] = '\0'; | 4262 /* Do Dired hack copied from w32fns.c */ |
4256 | 4263 if (!NILP(prompt) && strncmp (SDATA(prompt), "Dired", 5) == 0) |
4257 if (use_dialog_p) | 4264 status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL, |
4258 { | 4265 &dialogRef); |
4259 OPENFILENAME file_details; | 4266 else if (NILP (mustmatch)) |
4260 char *filename_file; | 4267 { |
4261 | 4268 /* This is a save dialog */ |
4262 /* Prevent redisplay. */ | 4269 if (!NILP(default_filename)) |
4263 specbind (Qinhibit_redisplay, Qt); | 4270 { |
4271 saveName = CFStringCreateWithCString(NULL, SDATA(default_filename), | |
4272 kCFStringEncodingUTF8); | |
4273 options.saveFileName = saveName; | |
4274 options.optionFlags |= kNavSelectDefaultLocation; | |
4275 } | |
4276 /* MAC_TODO: Find a better way to determine if this is a save | |
4277 or load dialog than comparing dir with default_filename */ | |
4278 if (EQ(dir, default_filename)) | |
4279 { | |
4280 status = NavCreateChooseFileDialog(&options, fileTypes, | |
4281 NULL, NULL, NULL, NULL, | |
4282 &dialogRef); | |
4283 } | |
4284 else { | |
4285 status = NavCreatePutFileDialog(&options, | |
4286 'TEXT', kNavGenericSignature, | |
4287 NULL, NULL, &dialogRef); | |
4288 } | |
4289 } | |
4290 else | |
4291 { | |
4292 /* This is an open dialog*/ | |
4293 status = NavCreateChooseFileDialog(&options, fileTypes, | |
4294 NULL, NULL, NULL, NULL, | |
4295 &dialogRef); | |
4296 } | |
4297 | |
4298 /* Set the default location and continue*/ | |
4299 if (status == noErr) { | |
4300 if (!NILP(dir)) { | |
4301 FSRef defLoc; | |
4302 AEDesc defLocAed; | |
4303 status = FSPathMakeRef(SDATA(dir), &defLoc, NULL); | |
4304 if (status == noErr) | |
4305 { | |
4306 AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed); | |
4307 NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); | |
4308 } | |
4309 AEDisposeDesc(&defLocAed); | |
4310 } | |
4311 | |
4264 BLOCK_INPUT; | 4312 BLOCK_INPUT; |
4265 | 4313 status = NavDialogRun(dialogRef); |
4266 bzero (&file_details, sizeof (file_details)); | |
4267 file_details.lStructSize = sizeof (file_details); | |
4268 file_details.hwndOwner = FRAME_W32_WINDOW (f); | |
4269 file_details.lpstrFile = filename; | |
4270 file_details.nMaxFile = sizeof (filename); | |
4271 file_details.lpstrInitialDir = init_dir; | |
4272 file_details.lpstrTitle = SDATA (prompt); | |
4273 file_details.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; | |
4274 | |
4275 if (!NILP (mustmatch)) | |
4276 file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; | |
4277 | |
4278 if (GetOpenFileName (&file_details)) | |
4279 { | |
4280 dostounix_filename (filename); | |
4281 file = build_string (filename); | |
4282 } | |
4283 else | |
4284 file = Qnil; | |
4285 | |
4286 UNBLOCK_INPUT; | 4314 UNBLOCK_INPUT; |
4287 file = unbind_to (count, file); | 4315 } |
4288 } | 4316 |
4289 /* Open File dialog will not allow folders to be selected, so resort | 4317 if (saveName) CFRelease(saveName); |
4290 to minibuffer completing reads for directories. */ | 4318 if (client) CFRelease(client); |
4291 else | 4319 if (message) CFRelease(message); |
4292 file = Fcompleting_read (prompt, intern ("read-file-name-internal"), | 4320 |
4293 dir, mustmatch, dir, Qfile_name_history, | 4321 if (status == noErr) { |
4294 default_filename, Qnil); | 4322 userAction = NavDialogGetUserAction(dialogRef); |
4323 switch (userAction) | |
4324 { | |
4325 case kNavUserActionNone: | |
4326 case kNavUserActionCancel: | |
4327 NavDialogDispose(dialogRef); | |
4328 Fsignal (Qquit, Qnil); /* Treat cancel like C-g */ | |
4329 return; | |
4330 case kNavUserActionOpen: | |
4331 case kNavUserActionChoose: | |
4332 case kNavUserActionSaveAs: | |
4333 { | |
4334 NavReplyRecord reply; | |
4335 AEDesc aed; | |
4336 FSRef fsRef; | |
4337 status = NavDialogGetReply(dialogRef, &reply); | |
4338 AECoerceDesc(&reply.selection, typeFSRef, &aed); | |
4339 AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef)); | |
4340 FSRefMakePath(&fsRef, (UInt8 *) filename, 1000); | |
4341 AEDisposeDesc(&aed); | |
4342 if (reply.saveFileName) | |
4343 { | |
4344 /* If it was a saved file, we need to add the file name */ | |
4345 int len = strlen(filename); | |
4346 if (len && filename[len-1] != '/') | |
4347 filename[len++] = '/'; | |
4348 CFStringGetCString(reply.saveFileName, filename+len, | |
4349 1000-len, kCFStringEncodingUTF8); | |
4350 } | |
4351 file = DECODE_FILE(build_string (filename)); | |
4352 NavDisposeReply(&reply); | |
4353 } | |
4354 break; | |
4355 } | |
4356 NavDialogDispose(dialogRef); | |
4357 } | |
4358 else { | |
4359 /* Fall back on minibuffer if there was a problem */ | |
4360 file = Fcompleting_read (prompt, intern ("read-file-name-internal"), | |
4361 dir, mustmatch, dir, Qfile_name_history, | |
4362 default_filename, Qnil); | |
4363 } | |
4364 } | |
4295 | 4365 |
4296 UNGCPRO; | 4366 UNGCPRO; |
4297 | 4367 |
4298 /* Make "Cancel" equivalent to C-g. */ | 4368 /* Make "Cancel" equivalent to C-g. */ |
4299 if (NILP (file)) | 4369 if (NILP (file)) |
4300 Fsignal (Qquit, Qnil); | 4370 Fsignal (Qquit, Qnil); |
4301 | 4371 |
4302 return unbind_to (count, file); | 4372 return unbind_to (count, file); |
4303 } | 4373 } |
4304 #endif /* MAC_TODO */ | 4374 |
4305 | 4375 |
4306 | 4376 #endif |
4307 | 4377 |
4308 /*********************************************************************** | 4378 /*********************************************************************** |
4309 Initialization | 4379 Initialization |
4310 ***********************************************************************/ | 4380 ***********************************************************************/ |
4311 | 4381 |
4505 staticpro (&tip_frame); | 4575 staticpro (&tip_frame); |
4506 | 4576 |
4507 last_show_tip_args = Qnil; | 4577 last_show_tip_args = Qnil; |
4508 staticpro (&last_show_tip_args); | 4578 staticpro (&last_show_tip_args); |
4509 | 4579 |
4510 #if 0 /* MAC_TODO */ | 4580 #if TARGET_API_MAC_CARBON |
4511 defsubr (&Sx_file_dialog); | 4581 defsubr (&Sx_file_dialog); |
4512 #endif | 4582 #endif |
4513 } | 4583 } |
4514 | 4584 |
4515 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc | 4585 /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc |