~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Frontier Kernel
Frontier/Common/source/filedialog.c

Version: ~ [ 10.0 ] ~

** Warning: Cannot open xref database.

1 2 /* $Id: filedialog.c,v 1.7 2005/10/07 04:07:42 icreedon Exp $ */ 3 4 /****************************************************************************** 5 6 UserLand Frontier(tm) -- High performance Web content management, 7 object database, system-level and Internet scripting environment, 8 including source code editing and debugging. 9 10 Copyright (C) 1992-2004 UserLand Software, Inc. 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 26 ******************************************************************************/ 27 28 #include "frontier.h" 29 #include "standard.h" 30 31 #ifdef MACVERSION 32 #include "mac.h" 33 #endif 34 35 #include "filealias.h" 36 #include "cursor.h" 37 #include "dialogs.h" 38 #include "error.h" 39 #include "memory.h" 40 #include "ops.h" 41 #include "quickdraw.h" 42 #include "resources.h" 43 #include "scrap.h" 44 #include "strings.h" 45 #include "threads.h" 46 #include "frontierwindows.h" 47 #include "file.h" 48 #include "shell.h" 49 #include "shell.rsrc.h" 50 #include "langinternal.h" /*for langbackgroundtask*/ 51 #include "versions.h" /* 2005-09-23 creedon */ 52 53 54 #ifdef MACVERSION 55 56 #include "SetUpA5.h" 57 58 #define sfgetfileid 5000 59 #define sfputfileid 5001 60 #define sfgetfolderid 5002 61 #define sfgetdiskid 5003 62 63 #define sfgetfolderbutton 11 64 #define sfgetpromptitem 10 65 66 67 typedef struct tysfdata { /*data passed to hook routines*/ 68 69 StandardFileReply sfreply; 70 71 bigstring sfprompt; 72 73 Str63 sfname; 74 75 ptrsftypelist sftypes; 76 } tysfdata, *ptrsfdata; 77 78 79 #if !TARGET_API_MAC_CARBON 80 81 static pascal short sfputfilehook (short item, DialogPtr pdialog, tysfdata *pdata) { 82 83 /* 84 6/11/93 dmb: added for System 7 Standard File 85 */ 86 #ifdef flcomponent 87 long curA5; 88 #endif 89 if (GetWRefCon (pdialog) != sfMainDialogRefCon) 90 return (item); 91 92 #ifdef flcomponent 93 94 curA5 = SetUpAppA5 (); 95 96 #endif 97 98 if (item == sfHookFirstCall) { 99 100 if ((*pdata).sfreply.sfFile.vRefNum != 0) 101 item = sfHookChangeSelection; 102 } 103 104 #ifdef flcomponent 105 106 RestoreA5 (curA5); 107 108 #endif 109 110 return (item); 111 } /*sfputfilehook*/ 112 113 114 static pascal short sfprompthook (short item, DialogPtr pdialog, tysfdata *pdata) { 115 116 /* 117 6/11/93 dmb: recoded to System 7 Standard File 118 */ 119 #ifdef flcomponent 120 long curA5; 121 #endif 122 if (GetWRefCon (pdialog) != sfMainDialogRefCon) 123 return (item); 124 125 #ifdef flcomponent 126 127 curA5 = SetUpAppA5 (); 128 129 #endif 130 131 if (item == sfHookFirstCall) { 132 Rect ritem, rdialog; 133 CGrafPtr dialogPort; 134 dialoggetobjectrect (pdialog, sfgetpromptitem, &ritem); 135 136 //Code change by Timothy Paustian Sunday, April 30, 2000 9:20:45 PM 137 //Changed to Opaque call for Carbon 138 #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1 139 dialogPort = GetDialogPort(pdialog); 140 GetPortBounds(dialogPort, &rdialog); 141 #else 142 //old code 143 #pragma unused(dialogPort) 144 rdialog = (*pdialog).portRect; 145 #endif 146 if (isemptystring ((*pdata).sfprompt)) { 147 148 rdialog.bottom = ritem.top; 149 150 /* 151 hidedialogitem (pdialog, sfgetpromptitem); 152 */ 153 } 154 else { 155 156 rdialog.bottom = ritem.bottom + 4; 157 158 setdialogtext (pdialog, sfgetpromptitem, (*pdata).sfprompt); 159 } 160 161 sizewindow (pdialog, rdialog.right - rdialog.left, rdialog.bottom - rdialog.top); 162 163 if ((*pdata).sfreply.sfFile.vRefNum != 0) 164 item = sfHookChangeSelection; 165 } 166 167 #ifdef flcomponent 168 169 RestoreA5 (curA5); 170 171 #endif 172 173 return (item); 174 } /*sfprompthook*/ 175 176 177 static pascal short sffolderhook (short item, DialogPtr pdialog, tysfdata *pdata) { 178 179 /* 180 12/5/91 dmb: if a folder is selected, use it instead of the current folder 181 182 1/30/92 dmb: added code to handle folder aliases, which are files 183 184 9/15/92 dmb: save path in sfstring (255 chars) instead of reply.fName (63 chars) 185 186 6/11/93 dmb: recoded to System 7 Standard File 187 188 2.1b9 dmb: push dialog port when ellipsizing button title 189 */ 190 191 bigstring bs; 192 #ifdef flcomponent 193 long curA5; 194 #endif 195 196 if (GetWRefCon (pdialog) != sfMainDialogRefCon) 197 return (item); 198 199 #ifdef flcomponent 200 201 curA5 = SetUpAppA5 (); 202 203 #endif 204 205 item = sfprompthook (item, pdialog, pdata); 206 207 switch (item) { 208 209 case sfgetfolderbutton: { 210 211 if ((*pdata).sfreply.sfFlags & kIsAlias) { /*must be the alias of a folder*/ 212 Boolean flfolder, flwasalias; 213 OSErr errcode; 214 215 errcode = ResolveAliasFile (&(*pdata).sfreply.sfFile, true, &flfolder, &flwasalias); 216 217 switch (errcode) { 218 219 case noErr: 220 break; 221 222 case userCanceledErr: 223 item = sfHookNullEvent; 224 225 goto exit; 226 227 default: 228 getsystemerrorstring (errcode, bs); 229 230 parsedialogstring (bs, (*pdata).sfreply.sfFile.name, nil, nil, nil, bs); 231 232 customalert (sferrordialogid, bs); 233 234 item = sfHookNullEvent; 235 236 goto exit; 237 } 238 } 239 240 (*pdata).sfreply.sfGood = true; 241 242 item = sfItemCancelButton; /*force exit*/ 243 244 break; 245 }; 246 247 case sfHookNullEvent: 248 if (!equalstrings ((*pdata).sfname, (*pdata).sfreply.sfFile.name)) { /*selection changed*/ 249 FSSpec fs; 250 251 fs = (*pdata).sfreply.sfFile; 252 253 copystring (fs.name, (*pdata).sfname); /*remember for next time before changing*/ 254 255 if (isemptystring (fs.name)) /*nothing selected*/ 256 FSMakeFSSpec (fs.vRefNum, fs.parID, nil, &fs); 257 258 copystring (fs.name, bs); 259 //Code change by Timothy Paustian Monday, August 21, 2000 4:20:21 PM 260 //pushport must have a CGrafPtr on OS X 261 { 262 CGrafPtr thePort; 263 #if TARGET_API_MAC_CARBON == 1 264 thePort = GetDialogPort(pdialog); 265 #else 266 thePort = (CGrafPtr)pdialog; 267 #endif 268 269 pushport (thePort); 270 } 271 ellipsize (bs, 72); 272 273 popport (); 274 275 setdialogbutton (pdialog, sfgetfolderbutton, bs); 276 } 277 278 break; 279 } 280 281 exit: 282 283 #ifdef flcomponent 284 285 RestoreA5 (curA5); 286 287 #endif 288 289 return (item); 290 } /*sffolderhook*/ 291 292 293 static pascal short sfdiskhook (short item, DialogPtr pdialog, tysfdata *pdata) { 294 295 /* 296 6/11/93 dmb: recoded to System 7 Standard File; back to using Drive 297 button like Frontier 1.0. 298 */ 299 #ifdef flcomponent 300 long curA5; 301 #endif 302 if (GetWRefCon (pdialog) != sfMainDialogRefCon) 303 return (item); 304 305 #ifdef flcomponent 306 307 curA5 = SetUpAppA5 (); 308 309 #endif 310 311 item = sfprompthook (item, pdialog, pdata); 312 313 switch (item) { 314 315 case sfItemOpenButton: 316 case sfHookOpenFolder: 317 #if 0 318 319 (*pdata).sfreply.vRefNum = -SFSaveDisk; /*IM IV-72*/ 320 321 setemptystring ((*pdata).sfreply.fName); /*we just want the volume*/ 322 323 #endif 324 325 FSMakeFSSpec ((*pdata).sfreply.sfFile.vRefNum, 0, 0, &(*pdata).sfreply.sfFile); 326 327 (*pdata).sfreply.sfGood = true; 328 329 item = sfItemCancelButton; /*force exit*/ 330 331 break; 332 333 case sfHookGoToDesktop: 334 item = sfHookGoToNextDrive; 335 336 break; 337 338 case sfHookNullEvent: 339 if ((*pdata).sfreply.sfIsVolume) /*need to open volume to enable Drive button*/ 340 item = sfHookOpenFolder; 341 else { 342 if (isemptystring ((*pdata).sfreply.sfFile.name)) /*no selection*/ 343 item = sfHookGoToParent; 344 } 345 346 break; 347 348 case sfHookGoToParent: 349 item = sfHookNullEvent; 350 351 break; 352 353 default: 354 if (item >= sfHookCharOffset) /*typing -- ignore*/ 355 item = sfHookNullEvent; 356 } 357 358 #ifdef flcomponent 359 360 RestoreA5 (curA5); 361 362 #endif 363 364 return (item); 365 } /*sfdiskhook*/ 366 367 368 static pascal Boolean onlyfoldersfilter (ParmBlkPtr pb, tysfdata *pdata) { 369 370 #pragma unused (pdata) 371 372 /* 373 if (foldertest (pb)) 374 */ 375 376 if (pb->fileParam.ioFlAttrib & ioDirMask) 377 return (0); 378 379 return (-1); /*...don't show files*/ 380 } /*onlyfoldersfilter*/ 381 382 383 static pascal Boolean knowntypesfilter (ParmBlkPtr pb, tysfdata *pdata) { 384 385 short i; 386 387 if (pb->fileParam.ioFlAttrib & ioDirMask) 388 return (0); 389 390 if (pdata->sftypes == nil) // show all files 391 return (0); 392 393 for (i = 0; i < pdata->sftypes->cttypes; ++i) { 394 395 OSType type = pdata->sftypes->types [i]; 396 byte bstype [6]; 397 bigstring bssuffix; 398 399 ostypetostring (type, bstype); 400 401 lastword (pb->fileParam.ioNamePtr, '.', bssuffix); 402 403 if (stringlength (bssuffix) == 3) //handle 8.3 names 404 setstringlength (bstype, 3); 405 406 if (equalidentifiers (bssuffix, bstype)) 407 return (0); 408 409 if (pb->fileParam.ioFlFndrInfo.fdType == type) 410 return (0); 411 } 412 413 return (-1); // didn't find it in our list 414 } /*knowntypesfilter*/ 415 416 417 418 #if !TARGET_RT_MAC_CFM 419 420 #define onlyfoldersfilterUPP ((FileFilterYDUPP) &onlyfoldersfilter) 421 #define knowntypesfilterUPP ((FileFilterYDUPP) &knowntypesfilter) 422 #define sfputfilehookUPP (&sfputfilehook) 423 #define sfprompthookUPP (&sfprompthook) 424 #define sffolderhookUPP (&sffolderhook) 425 #define sfdiskhookUPP (&sfdiskhook) 426 427 #else 428 429 #if !TARGET_API_MAC_CARBON 430 static RoutineDescriptor onlyfoldersfilterDesc = BUILD_ROUTINE_DESCRIPTOR (uppFileFilterYDProcInfo, onlyfoldersfilter); 431 static RoutineDescriptor knowntypesfilterDesc = BUILD_ROUTINE_DESCRIPTOR (uppFileFilterYDProcInfo, knowntypesfilter); 432 static RoutineDescriptor sfputfilehookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sfputfilehook); 433 static RoutineDescriptor sfprompthookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sfprompthook); 434 static RoutineDescriptor sffolderhookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sffolderhook); 435 static RoutineDescriptor sfdiskhookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sfdiskhook); 436 437 438 #define onlyfoldersfilterUPP (&onlyfoldersfilterDesc) 439 #define knowntypesfilterUPP (&knowntypesfilterDesc) 440 #define sfputfilehookUPP (&sfputfilehookDesc) 441 #define sfprompthookUPP (&sfprompthookDesc) 442 #define sffolderhookUPP (&sffolderhookDesc) 443 #define sfdiskhookUPP (&sfdiskhookDesc) 444 445 #endif 446 447 448 #endif 449 450 #endif /* !TARGET_API_MAC_CARBON */ 451 452 453 boolean sfdialog (tysfverb sfverb, bigstring bsprompt, ptrsftypelist filetypes, tyfilespec *fspec, OSType filecreator) { 454 455 /* 456 return true if the user selected a file with one of the SF routines, 457 return false otherwise. 458 459 as a bonus, we return the full path for the selected file in the path string. 460 461 2005-10-06 creedon: added filecreator parameter, used for get file dialog 462 463 2005-09-21 creedon: changed from TimsGetFile to getafile 464 465 Tuesday, June 20, 2000 8:50:41 PM Timothy Paustian: I am going to hack the heck out of this routine. See what you think 466 467 4.1b13 dmb: un-commented out the shellwritescrap and shellactive calls. 468 I don't know how they got commented; I must have been experimenting with 469 something. 470 471 2.1b2 dmb: updated interface to be filespec-based. for putfile, the name in the 472 filespec is the default name. for all verbs, a non-empty filespec seeds the dialog 473 474 2.1b1 dmb: set sfdata.sfname to an impossible value to ensure button update 475 476 6/11/93 dmb: recoded to System 7 Standard File 477 478 12/18/92 dmb: call shellwritescrap 479 480 9/15/92 dmb: when picking a folder, grab path from sfstring instead of reply 481 record. 482 483 2/10/92 dmb: added call to new shellactivate; standard file breaks when brought 484 up in the background. 485 486 12/27/91 dmb: if the default fname includes a colon, attempt to set default 487 directory, and remove folder specification from dialog default 488 489 4/16/91 dmb: replaced filetype parameter with pointer to type list. callers 490 can pass nil when irrelevant, or when all types are to be shown. 491 492 11/16/90 dmb: replace flput boolean with sfverb enum. added code for folder 493 and disk selection dialogs 494 495 8/1/90 dmb: if filetype is zero, show all files by passing zero to SFGetFile 496 */ 497 498 Str255 bs; 499 tysfdata sfdata; 500 FSSpec *fs = &sfdata.sfreply.sfFile; 501 OSErr anErr = noErr; 502 #if !TARGET_API_MAC_CARBON 503 Point pt = {-1, -1}; 504 short cttypes = -1; 505 OSType *types = nil; 506 #endif 507 #ifdef flcomponent 508 long appA5; 509 #endif 510 511 //move the switch statement to below because it's smarter to call it there when using 512 //the new routines for Nav services. 513 514 clearbytes (&sfdata, sizeof (sfdata)); 515 516 copystring (bsprompt, sfdata.sfprompt); 517 518 sfdata.sftypes = filetypes; 519 520 setemptystring (bs); 521 522 if (!isemptystring ((*fspec).name)) { /*if path is included, set default dir and strip to file name*/ 523 524 *fs = *fspec; /*seed directory & file selection*/ 525 526 /* 527 if (pathtofilespec (fname, fs) && ((*fs).vRefNum != 0)) 528 copystring ((*fs).name, fname); 529 else 530 filefrompath (fname, fname); 531 */ 532 } 533 534 setstringlength (sfdata.sfname, -1); /*make sure it can't match fsspec*/ 535 536 shellwritescrap (textscraptype); 537 538 shellactivate (); 539 540 #ifdef flcomponent 541 542 appA5 = SetUpCurA5 (); /*for system*/ 543 544 #endif 545 546 switch (sfverb) { 547 548 case sfputfileverb: 549 if(gCanUseNavServ) { 550 anErr = TimsPutFile(bsprompt, (*fs).name, &sfdata.sfreply); 551 } 552 #if TARGET_API_MAC_CARBON != 1 553 //we can get away with this because nav services is always there in OSX. 554 else 555 CustomPutFile (bsprompt, (*fs).name, &sfdata.sfreply, sfputfileid, pt, 556 sfputfilehookUPP, nil, nil, nil, &sfdata); 557 #endif 558 559 break; 560 561 case sfgetfileverb: 562 if(gCanUseNavServ) 563 anErr = getafile (bsprompt, filetypes, &sfdata.sfreply, filecreator); 564 #if !TARGET_API_MAC_CARBON 565 else 566 CustomGetFile (knowntypesfilterUPP, cttypes, types, &sfdata.sfreply, sfgetfileid, pt, 567 sfprompthookUPP, nil, nil, nil, &sfdata); 568 #endif 569 break; 570 571 case sfgetfolderverb: 572 if(gCanUseNavServ) 573 anErr = TimsGetFolderOrVolume(bsprompt, sfgetfolderid, &sfdata.sfreply); 574 #if !TARGET_API_MAC_CARBON 575 else 576 CustomGetFile (onlyfoldersfilterUPP, cttypes, types, &sfdata.sfreply, sfgetfolderid, pt, 577 sffolderhookUPP, nil, nil, nil, &sfdata); 578 #endif 579 break; 580 581 case sfgetdiskverb: 582 if(gCanUseNavServ) 583 anErr = TimsGetFolderOrVolume(bsprompt, sfgetdiskid, &sfdata.sfreply); 584 #if !TARGET_API_MAC_CARBON 585 else 586 CustomGetFile (nil, cttypes, types, &sfdata.sfreply, sfgetdiskid, pt, 587 sfdiskhookUPP, nil, nil, nil, &sfdata); 588 #endif 589 590 break; 591 } 592 593 //code moved to above 594 //if (sfverb == sfputfileverb) 595 //Code change by Timothy Paustian Tuesday, June 20, 2000 8:44:39 PM 596 //I added nav services as the dialog. This works well so I updated it 597 //in the PPC version also. 598 //CustomPutFile (bsprompt, (*fs).name, &sfdata.sfreply, id, pt, 599 // sfhook, nil, nil, nil, &sfdata); 600 //else 601 //Code change by Timothy Paustian Tuesday, June 20, 2000 2:58:33 PM 602 //Use nav services verbs and a switch statment 603 604 //CustomGetFile (sffilefilter, cttypes, types, &sfdata.sfreply, id, pt, 605 // sfhook, nil, nil, nil, &sfdata); 606 607 #ifdef flcomponent 608 609 RestoreA5 (appA5); 610 611 #endif 612 //if the user canceled return false 613 //I know that oserror can handle this, but lets make it 614 //obvious that we are checking. 615 if (userCanceledErr == anErr) 616 return false; 617 618 if(oserror(anErr)) 619 return false; 620 621 if (sfdata.sfreply.sfGood) { 622 623 FSMakeFSSpec ((*fs).vRefNum, (*fs).parID, (*fs).name, fspec); /*canonize*/ 624 625 /* 626 *fspec = sfdata.sfreply.sfFile; 627 */ 628 return (true); 629 } 630 631 return (false); 632 } /*sfdialog*/ 633 634 #endif 635 636 #ifdef WIN95VERSION 637 static void buildfilter (char * filter, short * len, bigstring bsname, bigstring bsext) { 638 short namelen, extlen; 639 640 namelen = stringlength (bsname); 641 extlen = stringlength (bsext); 642 643 memmove (filter + *len, stringbaseaddress(bsname), namelen); 644 *len = *len + namelen; 645 memmove (filter + *len, "\0", 1); 646 *len = *len + 1; 647 memmove (filter + *len, stringbaseaddress(bsext), extlen); 648 *len = *len + extlen; 649 memmove (filter + *len, "\0", 1); 650 *len = *len + 1; 651 memmove (filter + *len, "\0", 1); //alway finish the filter but don't count it in the length 652 } /*buildfilter*/ 653 654 655 boolean sfdialog (tysfverb sfverb, bigstring bsprompt, ptrsftypelist filetypes, tyfilespec *fspec, OSType filecreator) { 656 657 #pragma unused (filecreator) 658 659 /* 660 2005-10-06 creedon: added filecreator, unused on Windows 661 662 5.0.2b4 dmb: fixed bug in above change that would generate an error for empty paths 663 664 5.0.1 dmb: make sure default file and directory are valid, or we'll fail (silently) 665 */ 666 667 TCHAR szFile[MAX_PATH]; 668 OPENFILENAME OpenFileName; 669 BROWSEINFO BrowseInfo; 670 LPITEMIDLIST itemList; 671 char title [256]; 672 char filter [1024]; 673 short filterlen = 0; 674 char defaultdir [256]; 675 char defaultfile [256]; 676 bigstring extension; 677 byte type [6]; 678 bigstring osstring; 679 boolean fl = false; 680 short i; 681 boolean fldatabases = false; 682 boolean flfatpages = false; 683 // Global pointer to the shell's IMalloc interface. 684 static LPMALLOC pMalloc = NULL; 685 686 OpenFileName.lStructSize = sizeof(OPENFILENAME); 687 OpenFileName.hwndOwner = shellframewindow; 688 OpenFileName.hInstance = shellinstance; 689 OpenFileName.lpstrFilter = NULL; 690 OpenFileName.lpstrCustomFilter = NULL; 691 OpenFileName.nMaxCustFilter = 0; 692 OpenFileName.nFilterIndex = 0; 693 OpenFileName.lpstrFile = stringbaseaddress(fsname (fspec)); 694 OpenFileName.nMaxFile = sizeof(fsname (fspec)) - 2; 695 OpenFileName.lpstrFileTitle = NULL; 696 OpenFileName.nMaxFileTitle = 0; 697 OpenFileName.lpstrTitle = title; 698 OpenFileName.lpstrInitialDir = NULL; 699 OpenFileName.lpstrTitle = NULL; 700 OpenFileName.nFileOffset = 0; 701 OpenFileName.nFileExtension = 0; 702 OpenFileName.lpstrDefExt = NULL; 703 OpenFileName.lCustData = (LPARAM)NULL; 704 OpenFileName.lpfnHook = NULL; 705 OpenFileName.lpTemplateName = 0; 706 707 strcpy (szFile, ""); 708 709 // set the title 710 if (bsprompt != NULL) { 711 712 copyptocstring (bsprompt, title); 713 714 OpenFileName.lpstrTitle = title; 715 } 716 717 // set default dir, file and extension fields 718 if (!isemptystring (fsname (fspec))) { 719 720 tyfilespec fsdir; 721 boolean flfolder; 722 723 folderfrompath (fsname (fspec), defaultdir); 724 725 if (pathtofilespec (defaultdir, &fsdir) && 726 fileexists (&fsdir, &flfolder) && flfolder) { 727 728 OpenFileName.lpstrInitialDir = defaultdir; 729 730 //if (!isemptystring (defaultdir)) 731 // OpenFileName.nFileOffset = stringlength (defaultdir) + 1; 732 733 convertpstring (defaultdir); 734 } 735 736 filefrompath (fsname (fspec), defaultfile); 737 738 lastword (defaultfile, ':', defaultfile); //skip any Mac path 739 740 //OpenFileName.nFileExtension = stringlength (fsname (fspec)); 741 742 lastword (defaultfile, '.', extension); 743 744 //if (stringlength (extension) < stringlength (fsname (fspec))) 745 // OpenFileName.nFileExtension -= stringlength (extension); 746 747 copystring (defaultfile, fsname (fspec)); 748 749 nullterminate (fsname (fspec)); 750 } 751 752 releasethreadglobals (); 753 754 switch (sfverb) { 755 756 case sfputfileverb: 757 OpenFileName.Flags = OFN_SHOWHELP | OFN_EXPLORER | OFN_OVERWRITEPROMPT; //| OFN_NOCHANGEDIR; 758 759 if (filetypes != nil) { 760 setemptystring (filter); 761 762 //RAB: 1/22/98 use string since the windows type can be any case 763 ostypetostring ((*filetypes).types [0], osstring); 764 765 if (equalidentifiers (osstring, "\x04" "fatp")) 766 copystring ("\x016" "Fat Page [*.fatp]\0*.*\0", filter); 767 768 else if (equalidentifiers (osstring, "\x04" "ftop")) 769 copystring ("\x015" "Outline [*.ftop]\0*.*\0", filter); 770 771 else if (equalidentifiers (osstring, "\x04" "ftwp")) 772 copystring ("\x019" "WP Document [*.ftwp]\0*.*\0", filter); 773 774 else if (equalidentifiers (osstring, "\x04" "fttb")) 775 copystring ("\x013" "Table [*.fttb]\0*.*\0", filter); 776 777 else if (equalidentifiers (osstring, "\x04" "ftmb")) 778 copystring ("\x012" "Menu [*.ftmb]\0*.*\0", filter); 779 780 else if (equalidentifiers (osstring, "\x04" "ftsc")) 781 copystring ("\x014" "Script [*.ftsc]\0*.*\0", filter); 782 783 else if (equalidentifiers (osstring, "\x04" "ftds")) 784 copystring ("\x01c" "Desktop Script [*.ftds]\0*.*\0", filter); 785 786 else if (equalidentifiers (osstring, "\x04" "root")) 787 copystring ("\x016" "Database [*.root]\0*.*\0", filter); 788 789 if (! isemptystring (filter)) { 790 convertpstring (filter); 791 792 OpenFileName.lpstrFilter = filter; 793 } 794 795 ostypetostring ((*filetypes).types [0], type); 796 797 popleadingchars (type, '.'); 798 799 poptrailingwhitespace (type); 800 801 // convertpstring (type); 802 803 // OpenFileName.lpstrDefExt = type; 804 OpenFileName.lpstrDefExt = NULL; 805 } 806 807 // Call the common dialog function. 808 fl = GetSaveFileName (&OpenFileName); 809 810 if (fl && (filetypes != NULL) && (stringlength(type) > 0)) { 811 812 setstringlength (fsname (fspec), strlen(stringbaseaddress(fsname (fspec)))); 813 lastword (fsname (fspec), '.', extension); 814 815 if ((stringlength (fsname (fspec)) == stringlength (extension)) || (stringlength (extension) > 4)) { /* no extension */ 816 pushstring ("\x01.", fsname(fspec)); 817 pushstring (type, fsname(fspec)); 818 nullterminate (fsname (fspec)); 819 } 820 } 821 822 break; 823 824 case sfgetfileverb: 825 OpenFileName.Flags = OFN_SHOWHELP | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; //| OFN_NOCHANGEDIR; 826 827 // create the filter string 828 if (filetypes != nil) { /*showing specific files*/ 829 830 //copystring ("\x09Types: [\0", filter); 831 setemptystring (extension); 832 833 for (i = 0; i < (*filetypes).cttypes; ++i) { 834 835 if (i > 0) 836 pushchar (';', extension); 837 838 if ((*filetypes).types [i] == 'root') 839 fldatabases = true; 840 841 if ((*filetypes).types [i] == 'fatp') 842 flfatpages = true; 843 844 if ((*filetypes).types [i] == 'ROOT') 845 fldatabases = true; 846 847 if ((*filetypes).types [i] == 'FATP') 848 flfatpages = true; 849 850 ostypetostring ((*filetypes).types [i], type); 851 852 popleadingchars (type, '.'); 853 854 poptrailingwhitespace (type); 855 856 pushstring ("\x02" "*.", extension); 857 858 pushstring (type, extension); 859 860 if (stringlength (type) > 3) { 861 862 setstringlength (type, 3); 863 864 pushstring ("\x03" ";*.", extension); 865 866 pushstring (type, extension); 867 } 868 } 869 870 871 filterlen = 0; 872 873 buildfilter (filter, &filterlen, "\x1c" "Openable Types: [*.clickers]", extension); 874 875 if (fldatabases) 876 buildfilter (filter, &filterlen, "\x12" "Databases [*.root]", "\x0c" "*.root;*.roo"); 877 878 // pushstring ("\x20\0Databases [*.root]\0*.roo;*.root", filter); 879 880 if (flfatpages) { 881 buildfilter (filter, &filterlen, "\x12" "Fat Pages [*.fatp]", "\x5a" "*.fatp;*.fat;*.FTsc;*.FTs;*.FTwp;*.FTw;*.FTop;*.FTo;*.FTmb;*.FTm;*.FTtb;*.FTt;*.Ftds;*.FTd"); 882 buildfilter (filter, &filterlen, "\x17" "Frontier Menus [*.FTmb]", "\x0c" "*.FTmb;*.FTm"); 883 buildfilter (filter, &filterlen, "\x1a" "Frontier Outlines [*.FTop]", "\x0c" "*.FTop;*.FTo"); 884 buildfilter (filter, &filterlen, "\x19" "Frontier Scripts [*.FTsc]", "\x0c" "*.FTsc;*.FTs"); 885 buildfilter (filter, &filterlen, "\x21" "Frontier Desktop Scripts [*.FTds]", "\x0c" "*.FTds;*.FTd"); 886 buildfilter (filter, &filterlen, "\x18" "Frontier Tables [*.FTtb]", "\x0c" "*.FTtb;*.FTt"); 887 buildfilter (filter, &filterlen, "\x19" "Frontier WP Text [*.FTwp]", "\x0c" "*.FTwp;*.FTw"); 888 } 889 890 // pushstring ("\x20\0Fat Pages [*.fatp]\0*.fat;*.fatp", filter); 891 892 buildfilter (filter, &filterlen, "\x12" "Plain Text [*.txt]", "\x12" "*.Text;*.txt;*.tex"); 893 buildfilter (filter, &filterlen, "\x0f" "All Files [*.*]", "\x03" "*.*"); 894 895 OpenFileName.lpstrFilter = filter; 896 897 ostypetostring ((*filetypes).types [0], type); 898 899 //RAB: 1/22/98 added next two lines 900 // poptrailingwhitespace is no longer done in ostypetostring. 901 popleadingchars (type, '.'); 902 903 poptrailingwhitespace (type); 904 905 convertpstring (type); 906 907 OpenFileName.lpstrDefExt = type; 908 } 909 910 // Call the common dialog function. 911 fl = GetOpenFileName (&OpenFileName); 912 913 break; 914 915 case sfgetfolderverb: 916 case sfgetdiskverb: 917 // Get the shell's allocator. 918 if (pMalloc == NULL && !SUCCEEDED(SHGetMalloc(&pMalloc))) 919 break; 920 921 BrowseInfo.hwndOwner = OpenFileName.hwndOwner; 922 BrowseInfo.pidlRoot = NULL; 923 BrowseInfo.pszDisplayName = szFile; 924 BrowseInfo.lpszTitle = OpenFileName.lpstrTitle; 925 BrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS; 926 if (sfverb == sfgetdiskverb) 927 BrowseInfo.ulFlags |= BIF_RETURNFSANCESTORS; 928 BrowseInfo.lpfn = NULL; 929 BrowseInfo.lParam = 0; 930 931 itemList = SHBrowseForFolder (&BrowseInfo); 932 933 if (itemList != NULL) { 934 935 fl = SHGetPathFromIDList (itemList, szFile); 936 937 copyctopstring (szFile, fsname (fspec)); 938 939 if (sfverb == sfgetdiskverb) { 940 941 firstword (fsname (fspec), ':', fsname (fspec)); 942 943 pushstring ("\x02:\\", fsname (fspec)); 944 } 945 else { 946 947 pushstring ("\x01\\", fsname (fspec)); 948 } 949 950 nullterminate (fsname (fspec)); 951 952 // deallocate itemList 953 pMalloc->lpVtbl->Free (pMalloc, itemList); 954 955 /* 956 LPSHELLFOLDER ppshf; 957 if (SHGetDesktopFolder (&ppshf) == NOERROR) { 958 ULONG ctchars; 959 WCHAR szWide [300]; 960 961 MultiByteToWideChar (CP_ACP, 0, szFile, -1, szWide, 300); 962 963 ppshf->lpVtbl->ParseDisplayName (ppshf, NULL, szWide, &ctchars, &itemList,NULL); 964 965 fl = SHGetPathFromIDList (itemList, szFile); 966 967 pMalloc->lpVtbl->Free (pMalloc, itemList); 968 969 ppshf->lpVtbl->Release (ppshf); 970 } 971 */ 972 } 973 974 break; 975 976 } 977 978 grabthreadglobals (); 979 980 if (!fl) { 981 982 oserror (GetLastError ()); 983 984 return (false); 985 } 986 987 setstringlength (fsname (fspec), strlen(stringbaseaddress(fsname (fspec)))); 988 989 return (true); 990 } /*sfdialog*/ 991 992 #endif 993 994 995 #ifdef MACVERSION 996 997 boolean initfiledialog (void) { 998 999 #ifdef flcomponent 1000 1001 #if !TARGET_API_MAC_CARBON 1002 RememberA5 (); 1003 #endif /*for hook*/ 1004 1005 #endif 1006 1007 return (true); 1008 } /*initfile*/ 1009 1010 1011 //Code change by Timothy Paustian Tuesday, June 20, 2000 2:55:17 PM 1012 //New routine to use Nav services for this instead of CustomPutFile. 1013 OSErr 1014 TimsPutFile(bigstring prompt, Str255 fileName, StandardFileReply * outReply) 1015 { 1016 1017 OSErr anErr = noErr; 1018 NavReplyRecord reply; 1019 NavDialogOptions dialogOptions; 1020 OSType fileTypeToSave = 'TEXT'; 1021 NavEventUPP eventProc = NewNavEventUPP(NavEventProc); 1022 1023 anErr = NavGetDefaultDialogOptions(&dialogOptions); 1024 copystring(fileName, dialogOptions.savedFileName); 1025 copystring(prompt, dialogOptions.message); 1026 dialogOptions.dialogOptionFlags |= kNavNoTypePopup; /* 08/25/2000 AR */ 1027 if (anErr == noErr) 1028 { 1029 anErr = NavPutFile( nil, &reply, &dialogOptions, eventProc, 1030 fileTypeToSave, 'LAND', nil); 1031 1032 if (anErr == noErr && reply.validRecord) 1033 { 1034 AEKeyword theKeyword; 1035 DescType actualType; 1036 Size actualSize; 1037 FSSpec documentFSSpec; 1038 1039 anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, 1040 &theKeyword, &actualType, 1041 &documentFSSpec, sizeof(documentFSSpec), 1042 &actualSize ); 1043 if (anErr == noErr) 1044 { 1045 1046 outReply->sfReplacing = reply.replacing; 1047 FSMakeFSSpec (documentFSSpec.vRefNum, documentFSSpec.parID, documentFSSpec.name, &(outReply->sfFile)); 1048 outReply->sfGood = true; 1049 } 1050 // Always call NavCompleteSave() to complete 1051 #if TARGET_API_MAC_CARBON != 1 1052 anErr = NavCompleteSave(&reply, kNavTranslateInPlace); 1053 #endif 1054 1055 (void) NavDisposeReply(&reply); 1056 } 1057 } 1058 DisposeNavEventUPP(eventProc); 1059 return anErr; 1060 } 1061 1062 1063 OSErr getafile (bigstring prompt, ptrsftypelist filetypes, StandardFileReply * outReply, OSType filecreator) { 1064 1065 /* 1066 2005-10-06 creedon: added filecreator parameter 1067 1068 2005-09-21 creedon: created, cribbed from TimsGetFile 1069 */ 1070 1071 NavDialogCreationOptions dialogOptions; 1072 NavDialogRef dialogRef; 1073 NavEventUPP eventProc = NewNavEventUPP (NavEventProc); 1074 NavReplyRecord reply; 1075 NavTypeListHandle typeList = nil; 1076 OSErr anErr = noErr; 1077 1078 anErr = NavGetDefaultDialogCreationOptions (&dialogOptions); 1079 1080 dialogOptions.clientName = CFStringCreateWithCString (NULL, APPNAME_SHORT, kCFStringEncodingMacRoman); 1081 dialogOptions.message = CFStringCreateWithPascalString (NULL, prompt, kCFStringEncodingMacRoman); 1082 1083 if (anErr == noErr) { 1084 1085 if (filetypes == nil) 1086 dialogOptions.optionFlags -= kNavNoTypePopup; 1087 else 1088 dialogOptions.optionFlags += kNavAllFilesInPopup; // add all documents to show pop-up 1089 1090 dialogOptions.optionFlags ^=kNavAllowMultipleFiles; //no multiple files for now 1091 1092 dialogOptions.optionFlags ^= kNavAllowPreviews; // clear preview option 1093 1094 dialogOptions.optionFlags += kNavSupportPackages; // see packages 1095 1096 // dialogOptions.dialogOptionFlags += kNavAllowOpenPackages; // can open packages 1097 1098 if (filetypes != nil) { // translate into a type list NavServices understands 1099 1100 NavTypeListPtr typesP = nil; 1101 SInt32 hSize = (sizeof (NavTypeList) + sizeof (OSType) * (filetypes->cttypes - 1)); 1102 newhandle (hSize, (Handle*) &typeList); 1103 typesP = (NavTypeListPtr) *((Handle) typeList); 1104 1105 typesP->componentSignature = filecreator; 1106 typesP->reserved = 0; 1107 typesP->osTypeCount = filetypes->cttypes; 1108 1109 BlockMoveData (&(filetypes->types), typesP->osType, (Size) (sizeof (OSType) * filetypes->cttypes)); 1110 } 1111 1112 anErr = NavCreateGetFileDialog (&dialogOptions, typeList, eventProc, NULL, NULL, NULL, &dialogRef); 1113 1114 anErr = NavDialogRun (dialogRef); 1115 1116 anErr = NavDialogGetReply (dialogRef, &reply); 1117 1118 if (anErr == noErr && reply.validRecord) { 1119 1120 AEKeyword theKeyword; 1121 DescType actualType; 1122 Size actualSize; 1123 FSSpec documentFSSpec; 1124 1125 anErr = AEGetNthPtr (&(reply.selection), 1, typeFSS, &theKeyword, &actualType, &documentFSSpec, sizeof (documentFSSpec), &actualSize); // get a pointer to selected file 1126 1127 assert (actualType == typeFSS); 1128 1129 if (anErr == noErr) { 1130 FSMakeFSSpec (documentFSSpec.vRefNum, documentFSSpec.parID, documentFSSpec.name, &(outReply->sfFile)); 1131 1132 outReply->sfGood = true; 1133 } 1134 1135 anErr = NavDisposeReply (&reply); // dispose of NavReplyRecord, resources, descriptors 1136 } 1137 } 1138 1139 DisposeNavEventUPP (eventProc); 1140 1141 NavDialogDispose (dialogRef); 1142 1143 return anErr; 1144 } /* getafile */ 1145 1146 1147 OSErr 1148 TimsGetFolderOrVolume(bigstring prompt, SInt16 dialogType, StandardFileReply * outReply) 1149 { 1150 NavDialogOptions dialogOptions; 1151 NavEventUPP eventProc = NewNavEventUPP(NavEventProc); 1152 OSErr anErr = noErr; 1153 NavReplyRecord reply; 1154 1155 // Specify default options for dialog box 1156 //we don't really need to modify this, but it is needed for NavChooseFolder 1157 anErr = NavGetDefaultDialogOptions(&dialogOptions); 1158 copystring(prompt, dialogOptions.message); 1159 1160 if(anErr == noErr) 1161 { 1162 //display the dialog 1163 if(sfgetfolderid == dialogType) 1164 anErr = NavChooseFolder(nil, &reply, &dialogOptions, eventProc, nil, nil); 1165 else 1166 { 1167 assert(sfgetdiskid == dialogType); 1168 anErr = NavChooseVolume(nil, &reply, &dialogOptions, eventProc, nil, nil); 1169 } 1170 1171 if (anErr == noErr && reply.validRecord) 1172 { 1173 AEKeyword theKeyword; 1174 DescType actualType; 1175 Size actualSize; 1176 FSSpec documentFSSpec; 1177 1178 // Get a pointer to selected file 1179 anErr = AEGetNthPtr(&(reply.selection), 1, 1180 typeFSS, &theKeyword, 1181 &actualType, &documentFSSpec, 1182 sizeof(documentFSSpec), 1183 &actualSize); 1184 assert(actualType == typeFSS); 1185 if (anErr == noErr) 1186 { 1187 FSMakeFSSpec (documentFSSpec.vRefNum, documentFSSpec.parID, documentFSSpec.name, &(outReply->sfFile)); 1188 outReply->sfGood = true; 1189 } 1190 // Dispose of NavReplyRecord 1191 anErr = NavDisposeReply(&reply); 1192 } 1193 } 1194 DisposeNavEventUPP (eventProc); 1195 return anErr; 1196 } 1197 1198 1199 1200 1201 1202 1203 //Code change by Timothy Paustian Tuesday, June 20, 2000 9:07:26 PM 1204 //a very simple event proc so that Nav file service dialogs are movable and resizable. 1205 pascal void NavEventProc(NavEventCallbackMessage callBackSelector, 1206 NavCBRecPtr callBackParms, 1207 NavCallBackUserData callBackUD) 1208 { 1209 #pragma unused(callBackUD) 1210 if (callBackSelector == kNavCBEvent) 1211 { 1212 if(((callBackParms->eventData) 1213 .eventDataParms).event->what == updateEvt) 1214 { 1215 //I was having a crash due to getting the window ptr outside the switch statement. 1216 // This now works. 1217 //10/30/00 Timothy Paustian 1218 WindowPtr window = (WindowPtr)(((callBackParms->eventData).eventDataParms).event)->message; 1219 shellupdatenow(window); 1220 } 1221 } 1222 } 1223 1224 #endif 1225

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.