filedialog.c

Go to the documentation of this file.
00001 
00002 /*  $Id: filedialog.c 1254 2006-04-12 20:27:14Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #ifdef MACVERSION
00032 #   include "mac.h"
00033 #endif
00034 
00035 #include "filealias.h"
00036 #include "cursor.h"
00037 #include "dialogs.h"
00038 #include "error.h"
00039 #include "memory.h"
00040 #include "ops.h"
00041 #include "quickdraw.h"
00042 #include "resources.h"
00043 #include "scrap.h"
00044 #include "strings.h"
00045 #include "threads.h"
00046 #include "frontierwindows.h"
00047 #include "file.h"
00048 #include "shell.h"
00049 #include "shell.rsrc.h"
00050 #include "langinternal.h" /*for langbackgroundtask*/
00051 #include "versions.h" /* 2005-09-23 creedon */
00052 
00053 
00054 #ifdef MACVERSION
00055 
00056 #include "SetUpA5.h"
00057 
00058 #define sfgetfileid 5000
00059 #define sfputfileid 5001
00060 #define sfgetfolderid 5002
00061 #define sfgetdiskid 5003
00062 
00063 #define sfgetfolderbutton 11
00064 #define sfgetpromptitem 10
00065 
00066 
00067 typedef struct tysfdata { /*data passed to hook routines*/
00068     
00069     StandardFileReply sfreply;
00070     
00071     bigstring sfprompt;
00072     
00073     Str63 sfname;
00074     
00075     ptrsftypelist sftypes;
00076     } tysfdata, *ptrsfdata;
00077 
00078 
00079 #if !TARGET_API_MAC_CARBON
00080 
00081 static pascal short sfputfilehook (short item, DialogPtr pdialog, tysfdata *pdata) {
00082     
00083     /*
00084     6/11/93 dmb: added for System 7 Standard File
00085     */
00086 #ifdef flcomponent
00087     long curA5;
00088 #endif
00089     if (GetWRefCon (pdialog) != sfMainDialogRefCon)
00090         return (item);
00091     
00092 #ifdef flcomponent
00093     
00094     curA5 = SetUpAppA5 ();
00095     
00096 #endif
00097     
00098     if (item == sfHookFirstCall) {
00099         
00100         if ((*pdata).sfreply.sfFile.vRefNum != 0)
00101             item = sfHookChangeSelection;
00102         }
00103     
00104 #ifdef flcomponent
00105     
00106     RestoreA5 (curA5);
00107     
00108 #endif
00109     
00110     return (item);
00111     } /*sfputfilehook*/
00112 
00113 
00114 static pascal short sfprompthook (short item, DialogPtr pdialog, tysfdata *pdata) {
00115     
00116     /*
00117     6/11/93 dmb: recoded to System 7 Standard File
00118     */
00119 #ifdef flcomponent
00120     long curA5;
00121 #endif
00122 
00123     if (GetWRefCon (pdialog) != sfMainDialogRefCon)
00124         return (item);
00125     
00126 #ifdef flcomponent
00127     
00128     curA5 = SetUpAppA5 ();
00129     
00130 #endif
00131     
00132     if (item == sfHookFirstCall) {
00133         Rect ritem, rdialog;
00134         CGrafPtr    dialogPort;
00135         dialoggetobjectrect (pdialog, sfgetpromptitem, &ritem);
00136         
00137         //Code change by Timothy Paustian Sunday, April 30, 2000 9:20:45 PM
00138         //Changed to Opaque call for Carbon
00139 #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00140         dialogPort = GetDialogPort(pdialog);
00141         GetPortBounds(dialogPort, &rdialog);
00142 #else
00143         //old code
00144 #pragma unused(dialogPort)
00145         rdialog = (*pdialog).portRect;
00146 #endif
00147         if (isemptystring ((*pdata).sfprompt)) {
00148             
00149             rdialog.bottom = ritem.top;
00150             
00151             /*
00152             hidedialogitem (pdialog, sfgetpromptitem);
00153             */
00154             }
00155         else {
00156             
00157             rdialog.bottom = ritem.bottom + 4;
00158             
00159             setdialogtext (pdialog, sfgetpromptitem, (*pdata).sfprompt);
00160             }
00161         
00162         sizewindow (pdialog, rdialog.right - rdialog.left, rdialog.bottom - rdialog.top);
00163         
00164         if ((*pdata).sfreply.sfFile.vRefNum != 0)
00165             item = sfHookChangeSelection;
00166         }
00167     
00168 #ifdef flcomponent
00169     
00170     RestoreA5 (curA5);
00171     
00172 #endif
00173     
00174     return (item);
00175     } /*sfprompthook*/
00176 
00177 
00178 static pascal short sffolderhook (short item, DialogPtr pdialog, tysfdata *pdata) {
00179     
00180     /*
00181     12/5/91 dmb: if a folder is selected, use it instead of the current folder
00182     
00183     1/30/92 dmb: added code to handle folder aliases, which are files
00184     
00185     9/15/92 dmb: save path in sfstring (255 chars) instead of reply.fName (63 chars)
00186     
00187     6/11/93 dmb: recoded to System 7 Standard File
00188     
00189     2.1b9 dmb: push dialog port when ellipsizing button title
00190     */
00191     
00192     bigstring bs;
00193 #ifdef flcomponent
00194     long curA5;
00195 #endif
00196     
00197     if (GetWRefCon (pdialog) != sfMainDialogRefCon)
00198         return (item);
00199     
00200 #ifdef flcomponent
00201     
00202     curA5 = SetUpAppA5 ();
00203     
00204 #endif
00205     
00206     item = sfprompthook (item, pdialog, pdata);
00207     
00208     switch (item) {
00209         
00210         case sfgetfolderbutton: {
00211         
00212             if ((*pdata).sfreply.sfFlags & kIsAlias) { /*must be the alias of a folder*/
00213                 Boolean flfolder, flwasalias;
00214                 OSErr errcode;
00215                 
00216                 errcode = ResolveAliasFile (&(*pdata).sfreply.sfFile, true, &flfolder, &flwasalias);
00217                 
00218                 switch (errcode) {
00219                     
00220                     case noErr:
00221                         break;
00222                     
00223                     case userCanceledErr:
00224                         item = sfHookNullEvent;
00225                         
00226                         goto exit;
00227                     
00228                     default:
00229                         getsystemerrorstring (errcode, bs);
00230                         
00231                         parsedialogstring (bs, (*pdata).sfreply.sfFile.name, nil, nil, nil, bs);
00232                         
00233                         customalert (sferrordialogid, bs);
00234                         
00235                         item = sfHookNullEvent;
00236                         
00237                         goto exit;
00238                     }
00239                 }
00240             
00241             (*pdata).sfreply.sfGood = true;
00242             
00243             item = sfItemCancelButton; /*force exit*/
00244             
00245             break;
00246             };
00247         
00248         case sfHookNullEvent:
00249             if (!equalstrings ((*pdata).sfname, (*pdata).sfreply.sfFile.name)) { /*selection changed*/
00250                 FSSpec fs;
00251                 
00252                 fs = (*pdata).sfreply.sfFile;
00253                 
00254                 copystring (fs.name, (*pdata).sfname); /*remember for next time before changing*/
00255                 
00256                 if (isemptystring (fs.name)) /*nothing selected*/
00257                     FSMakeFSSpec (fs.vRefNum, fs.parID, nil, &fs);
00258                 
00259                 copystring (fs.name, bs);
00260                 //Code change by Timothy Paustian Monday, August 21, 2000 4:20:21 PM
00261                 //pushport must have a CGrafPtr on OS X
00262                 {
00263                 CGrafPtr    thePort;
00264                 #if TARGET_API_MAC_CARBON == 1
00265                 thePort = GetDialogPort(pdialog);
00266                 #else
00267                 thePort = (CGrafPtr)pdialog;
00268                 #endif
00269         
00270                 pushport (thePort);
00271                 }
00272                 ellipsize (bs, 72);
00273                 
00274                 popport ();
00275                 
00276                 setdialogbutton (pdialog, sfgetfolderbutton, bs);
00277                 }
00278             
00279             break;
00280         }
00281     
00282     exit:
00283     
00284     #ifdef flcomponent
00285     
00286     RestoreA5 (curA5);
00287     
00288     #endif
00289     
00290     return (item);
00291     } /*sffolderhook*/
00292 
00293 
00294 static pascal short sfdiskhook (short item, DialogPtr pdialog, tysfdata *pdata) {
00295     
00296     /*
00297     6/11/93 dmb: recoded to System 7 Standard File; back to using Drive 
00298     button like Frontier 1.0.
00299     */
00300 #ifdef flcomponent
00301     long curA5;
00302 #endif
00303 
00304     if (GetWRefCon (pdialog) != sfMainDialogRefCon)
00305         return (item);
00306     
00307 #ifdef flcomponent
00308     
00309     curA5 = SetUpAppA5 ();
00310     
00311 #endif
00312     
00313     item = sfprompthook (item, pdialog, pdata);
00314     
00315     switch (item) {
00316         
00317         case sfItemOpenButton:
00318         case sfHookOpenFolder:
00319             #if 0
00320             
00321             (*pdata).sfreply.vRefNum = -SFSaveDisk; /*IM IV-72*/
00322             
00323             setemptystring ((*pdata).sfreply.fName); /*we just want the volume*/
00324             
00325             #endif
00326             
00327             FSMakeFSSpec ((*pdata).sfreply.sfFile.vRefNum, 0, 0, &(*pdata).sfreply.sfFile);
00328             
00329             (*pdata).sfreply.sfGood = true;
00330             
00331             item = sfItemCancelButton; /*force exit*/
00332             
00333             break;
00334         
00335         case sfHookGoToDesktop:
00336             item = sfHookGoToNextDrive;
00337             
00338             break;
00339         
00340         case sfHookNullEvent:
00341             if ((*pdata).sfreply.sfIsVolume) /*need to open volume to enable Drive button*/
00342                 item = sfHookOpenFolder;
00343             else {
00344                 if (isemptystring ((*pdata).sfreply.sfFile.name)) /*no selection*/
00345                     item = sfHookGoToParent;
00346                 }
00347             
00348             break;
00349         
00350         case sfHookGoToParent:
00351             item = sfHookNullEvent;
00352             
00353             break;
00354         
00355         default:
00356             if (item >= sfHookCharOffset) /*typing -- ignore*/
00357                 item = sfHookNullEvent;
00358         }
00359     
00360 #ifdef flcomponent
00361     
00362     RestoreA5 (curA5);
00363     
00364 #endif
00365     
00366     return (item);
00367     } /*sfdiskhook*/
00368 
00369 
00370 static pascal Boolean onlyfoldersfilter (ParmBlkPtr pb, tysfdata *pdata) {
00371 #pragma unused (pdata)
00372     
00373     /*
00374     if (foldertest (pb))
00375     */
00376     
00377     if (pb->fileParam.ioFlAttrib & ioDirMask)
00378         return (0);
00379     
00380     return (-1); /*...don't show files*/
00381     } /*onlyfoldersfilter*/
00382 
00383 
00384 static pascal Boolean knowntypesfilter (ParmBlkPtr pb, tysfdata *pdata) {
00385     
00386     short i;
00387     
00388     if (pb->fileParam.ioFlAttrib & ioDirMask)
00389         return (0);
00390     
00391     if (pdata->sftypes == nil) // show all files
00392         return (0);
00393     
00394     for (i = 0; i < pdata->sftypes->cttypes; ++i) {
00395         
00396         OSType type = pdata->sftypes->types [i];
00397         byte bstype [6];
00398         bigstring bssuffix;
00399         
00400         ostypetostring (type, bstype);
00401         
00402         lastword (pb->fileParam.ioNamePtr, '.', bssuffix);
00403         
00404         if (stringlength (bssuffix) == 3) //handle 8.3 names
00405             setstringlength (bstype, 3);
00406         
00407         if (equalidentifiers (bssuffix, bstype))
00408             return (0);
00409         
00410         if (pb->fileParam.ioFlFndrInfo.fdType == type)
00411             return (0);
00412         }
00413     
00414     return (-1); // didn't find it in our list
00415     } /*knowntypesfilter*/
00416 
00417 
00418         
00419 #if !TARGET_RT_MAC_CFM
00420     
00421     #define onlyfoldersfilterUPP ((FileFilterYDUPP) &onlyfoldersfilter)
00422     #define knowntypesfilterUPP ((FileFilterYDUPP) &knowntypesfilter)
00423     #define sfputfilehookUPP (&sfputfilehook)
00424     #define sfprompthookUPP (&sfprompthook)
00425     #define sffolderhookUPP (&sffolderhook)
00426     #define sfdiskhookUPP (&sfdiskhook)
00427 
00428 #else
00429 
00430     #if !TARGET_API_MAC_CARBON
00431     static RoutineDescriptor onlyfoldersfilterDesc = BUILD_ROUTINE_DESCRIPTOR (uppFileFilterYDProcInfo, onlyfoldersfilter);
00432     static RoutineDescriptor knowntypesfilterDesc = BUILD_ROUTINE_DESCRIPTOR (uppFileFilterYDProcInfo, knowntypesfilter);
00433     static RoutineDescriptor sfputfilehookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sfputfilehook);
00434     static RoutineDescriptor sfprompthookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sfprompthook);
00435     static RoutineDescriptor sffolderhookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sffolderhook);
00436     static RoutineDescriptor sfdiskhookDesc = BUILD_ROUTINE_DESCRIPTOR (uppDlgHookYDProcInfo, sfdiskhook);
00437 
00438     
00439     #define onlyfoldersfilterUPP (&onlyfoldersfilterDesc)
00440     #define knowntypesfilterUPP (&knowntypesfilterDesc)
00441     #define sfputfilehookUPP (&sfputfilehookDesc)
00442     #define sfprompthookUPP (&sfprompthookDesc)
00443     #define sffolderhookUPP (&sffolderhookDesc)
00444     #define sfdiskhookUPP (&sfdiskhookDesc)
00445     
00446     #endif
00447 
00448 
00449 #endif
00450 
00451 #endif /* !TARGET_API_MAC_CARBON */
00452 
00453     
00454     boolean sfdialog (tysfverb sfverb, bigstring bsprompt, ptrsftypelist filetypes, tyfilespec *fspec, OSType filecreator) {
00455     
00456     /*
00457     return true if the user selected a file with one of the SF routines,
00458     return false otherwise.
00459     
00460     as a bonus, we return the full path for the selected file in the path string.
00461     
00462     2005-10-06 creedon: added filecreator parameter, used for get file dialog
00463     
00464     2005-09-21 creedon: changed from TimsGetFile to getafile
00465     
00466     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
00467     
00468     4.1b13 dmb: un-commented out the shellwritescrap and shellactive calls.
00469     I don't know how they got commented; I must have been experimenting with 
00470     something.
00471     
00472     2.1b2 dmb: updated interface to be filespec-based. for putfile, the name in the 
00473     filespec is the default name. for all verbs, a non-empty filespec seeds the dialog
00474     
00475     2.1b1 dmb: set sfdata.sfname to an impossible value to ensure button update
00476     
00477     6/11/93 dmb: recoded to System 7 Standard File
00478     
00479     12/18/92 dmb: call shellwritescrap
00480     
00481     9/15/92 dmb: when picking a folder, grab path from sfstring instead of reply
00482     record.
00483     
00484     2/10/92 dmb: added call to new shellactivate; standard file breaks when brought 
00485     up in the background.
00486     
00487     12/27/91 dmb: if the default fname includes a colon, attempt to set default 
00488     directory, and remove folder specification from dialog default
00489     
00490     4/16/91 dmb: replaced filetype parameter with pointer to type list.  callers 
00491     can pass nil when irrelevant, or when all types are to be shown.
00492     
00493     11/16/90 dmb:  replace flput boolean with sfverb enum.  added code for folder 
00494     and disk selection dialogs
00495 
00496     8/1/90 dmb:  if filetype is zero, show all files by passing zero to SFGetFile
00497     */
00498     
00499     Str255 bs;
00500     tysfdata sfdata;
00501     FSSpec *fs = &sfdata.sfreply.sfFile;
00502     OSErr   anErr = noErr;
00503 
00504 #if !TARGET_API_MAC_CARBON
00505     Point pt = {-1, -1};
00506     short cttypes = -1;
00507     OSType *types = nil;
00508 #endif  
00509 
00510 #ifdef flcomponent
00511     long appA5;
00512 #endif
00513 
00514     //move the switch statement to below because it's smarter to call it there when using 
00515     //the new routines for Nav services.
00516     
00517     clearbytes (&sfdata, sizeof (sfdata));
00518     
00519     copystring (bsprompt, sfdata.sfprompt);
00520     
00521     sfdata.sftypes = filetypes;
00522     
00523     setemptystring (bs);
00524     
00525     if (!isemptystring ((*fspec).name)) { /*if path is included, set default dir and strip to file name*/
00526         
00527         *fs = *fspec; /*seed directory & file selection*/
00528         
00529         /*
00530         if (pathtofilespec (fname, fs) && ((*fs).vRefNum != 0))
00531             copystring ((*fs).name, fname);
00532         else
00533             filefrompath (fname, fname);
00534         */
00535         }
00536     
00537     setstringlength (sfdata.sfname, -1); /*make sure it can't match fsspec*/
00538     
00539     shellwritescrap (textscraptype);
00540     
00541     shellactivate ();
00542     
00543 #ifdef flcomponent
00544     
00545     appA5 = SetUpCurA5 (); /*for system*/
00546     
00547 #endif
00548     
00549     switch (sfverb) {
00550         
00551         case sfputfileverb:
00552             if(gCanUseNavServ) {
00553                 anErr = TimsPutFile(bsprompt, (*fs).name, &sfdata.sfreply);
00554                 }
00555 #if TARGET_API_MAC_CARBON != 1
00556             //we can get away with this because nav services is always there in OSX.
00557             else
00558                 CustomPutFile (
00559                         bsprompt,
00560                         (*fs).name,
00561                         &sfdata.sfreply,
00562                         sfputfileid,
00563                         pt, 
00564                         sfputfilehookUPP,
00565                         nil, nil, nil,
00566                         &sfdata);
00567 #endif
00568 
00569             break;
00570         
00571         case sfgetfileverb:
00572 #if TARGET_API_MAC_CARBON == 1
00573             anErr = getafile (bsprompt, filetypes, &sfdata.sfreply, filecreator);
00574 #else
00575                 CustomGetFile (
00576                     knowntypesfilterUPP,
00577                     cttypes,
00578                     types,
00579                     &sfdata.sfreply,
00580                     sfgetfileid,
00581                     pt,
00582                     sfprompthookUPP,
00583                     nil, nil, nil,
00584                     &sfdata);
00585 #endif
00586             break;
00587         
00588         case sfgetfolderverb:
00589             if(gCanUseNavServ) 
00590                 anErr = TimsGetFolderOrVolume(bsprompt, sfgetfolderid, &sfdata.sfreply);
00591 #if !TARGET_API_MAC_CARBON
00592             else
00593                 CustomGetFile (onlyfoldersfilterUPP, cttypes, types, &sfdata.sfreply, sfgetfolderid, pt, 
00594                         sffolderhookUPP, nil, nil, nil, &sfdata);
00595 #endif
00596             break;
00597         
00598         case sfgetdiskverb:
00599             if(gCanUseNavServ) 
00600                 anErr = TimsGetFolderOrVolume(bsprompt, sfgetdiskid, &sfdata.sfreply);
00601 #if !TARGET_API_MAC_CARBON
00602             else
00603                 CustomGetFile (nil, cttypes, types, &sfdata.sfreply, sfgetdiskid, pt, 
00604                         sfdiskhookUPP, nil, nil, nil, &sfdata);
00605 #endif
00606 
00607             break;
00608         }
00609     
00610     //code moved to above
00611     //if (sfverb == sfputfileverb)
00612         //Code change by Timothy Paustian Tuesday, June 20, 2000 8:44:39 PM
00613         //I added nav services as the dialog. This works well so I updated it
00614         //in the PPC version also.
00615         //CustomPutFile (bsprompt, (*fs).name, &sfdata.sfreply, id, pt, 
00616         //  sfhook, nil, nil, nil, &sfdata);
00617     //else
00618         //Code change by Timothy Paustian Tuesday, June 20, 2000 2:58:33 PM
00619         //Use nav services verbs and a switch statment
00620         
00621         //CustomGetFile (sffilefilter, cttypes, types, &sfdata.sfreply, id, pt, 
00622         //  sfhook, nil, nil, nil, &sfdata);
00623     
00624 #ifdef flcomponent
00625     
00626     RestoreA5 (appA5);
00627     
00628 #endif
00629     //if the user canceled return false
00630     //I know that oserror can handle this, but lets make it
00631     //obvious that we are checking.
00632     if (userCanceledErr == anErr) 
00633         return false;
00634 
00635     if(oserror(anErr)) 
00636         return false;
00637 
00638     if (sfdata.sfreply.sfGood) {
00639         
00640         FSMakeFSSpec ((*fs).vRefNum, (*fs).parID, (*fs).name, fspec); /*canonize*/
00641         
00642         /*
00643         *fspec = sfdata.sfreply.sfFile;
00644         */
00645         return (true);
00646         }
00647     
00648     return (false);
00649     } /*sfdialog*/
00650 
00651 #endif
00652 
00653 #ifdef WIN95VERSION
00654 static void buildfilter (char * filter, short * len, bigstring bsname, bigstring bsext) {
00655     short namelen, extlen;
00656 
00657     namelen = stringlength (bsname);
00658     extlen = stringlength (bsext);
00659 
00660     memmove (filter + *len, stringbaseaddress(bsname), namelen);
00661     *len = *len + namelen;
00662     memmove (filter + *len, "\0", 1);
00663     *len = *len + 1;
00664     memmove (filter + *len, stringbaseaddress(bsext), extlen);
00665     *len = *len + extlen;
00666     memmove (filter + *len, "\0", 1);
00667     *len = *len + 1;
00668     memmove (filter + *len, "\0", 1);  //alway finish the filter but don't count it in the length
00669     } /*buildfilter*/
00670 
00671 
00672 boolean sfdialog (tysfverb sfverb, bigstring bsprompt, ptrsftypelist filetypes, tyfilespec *fspec, OSType filecreator) {
00673 #pragma unused (filecreator)
00674     
00675     /*
00676     2005-10-06 creedon: added filecreator, unused on Windows
00677     
00678     5.0.2b4 dmb: fixed bug in above change that would generate an error for empty paths
00679 
00680     5.0.1 dmb: make sure default file and directory are valid, or we'll fail (silently)
00681     */
00682 
00683     TCHAR szFile[MAX_PATH];
00684     OPENFILENAME OpenFileName;
00685     BROWSEINFO BrowseInfo;
00686     LPITEMIDLIST itemList;
00687     char title [256];
00688     char filter [1024];
00689     short filterlen = 0;
00690     char defaultdir [256];
00691     char defaultfile [256];
00692     bigstring extension;
00693     byte type [6];
00694     bigstring osstring;
00695     boolean fl = false;
00696     short i;
00697     boolean fldatabases = false;
00698     boolean flfatpages = false;
00699     // Global pointer to the shell's IMalloc interface.  
00700     static LPMALLOC pMalloc = NULL;
00701 
00702 
00703     OpenFileName.lStructSize       = sizeof(OPENFILENAME);
00704     OpenFileName.hwndOwner         = shellframewindow;
00705     OpenFileName.hInstance         = shellinstance;
00706     OpenFileName.lpstrFilter       = NULL;
00707     OpenFileName.lpstrCustomFilter = NULL;
00708     OpenFileName.nMaxCustFilter    = 0;
00709     OpenFileName.nFilterIndex      = 0;
00710     OpenFileName.lpstrFile         = stringbaseaddress(fsname (fspec));
00711     OpenFileName.nMaxFile          = sizeof(fsname (fspec)) - 2;
00712     OpenFileName.lpstrFileTitle    = NULL;
00713     OpenFileName.nMaxFileTitle     = 0;
00714     OpenFileName.lpstrTitle         = title;
00715     OpenFileName.lpstrInitialDir    = NULL;
00716     OpenFileName.lpstrTitle         = NULL;
00717     OpenFileName.nFileOffset       = 0;
00718     OpenFileName.nFileExtension    = 0;
00719     OpenFileName.lpstrDefExt       = NULL;
00720     OpenFileName.lCustData         = (LPARAM)NULL;
00721     OpenFileName.lpfnHook          = NULL;
00722     OpenFileName.lpTemplateName    = 0;
00723 
00724     strcpy (szFile, "");
00725     
00726     // set the title
00727     if (bsprompt != NULL) {
00728         
00729         copyptocstring (bsprompt, title);
00730         
00731         OpenFileName.lpstrTitle = title;
00732         }
00733 
00734     // set default dir, file and extension fields
00735     if (!isemptystring (fsname (fspec))) {
00736 
00737         tyfilespec fsdir;
00738         boolean flfolder;
00739 
00740         folderfrompath (fsname (fspec), defaultdir);
00741         
00742         if (pathtofilespec (defaultdir, &fsdir) && 
00743             fileexists (&fsdir, &flfolder) && flfolder) {
00744             
00745             OpenFileName.lpstrInitialDir = defaultdir;
00746             
00747             //if (!isemptystring (defaultdir))
00748             //  OpenFileName.nFileOffset = stringlength (defaultdir) + 1;
00749             
00750             convertpstring (defaultdir);
00751             }
00752         
00753         filefrompath (fsname (fspec), defaultfile);
00754 
00755         lastword (defaultfile, ':', defaultfile); //skip any Mac path 
00756 
00757         //OpenFileName.nFileExtension = stringlength (fsname (fspec));
00758         
00759         lastword (defaultfile, '.', extension);
00760         
00761         //if (stringlength (extension) < stringlength (fsname (fspec)))
00762         //  OpenFileName.nFileExtension -= stringlength (extension);
00763         
00764         copystring (defaultfile, fsname (fspec));
00765 
00766         nullterminate (fsname (fspec));
00767         }
00768 
00769     releasethreadglobals ();
00770     
00771     switch (sfverb) {
00772         
00773         case sfputfileverb:
00774             OpenFileName.Flags = OFN_SHOWHELP | OFN_EXPLORER | OFN_OVERWRITEPROMPT; //| OFN_NOCHANGEDIR;
00775             
00776             if (filetypes != nil) {
00777                 setemptystring (filter);
00778 
00779                 //RAB: 1/22/98 use string since the windows type can be any case
00780                 ostypetostring ((*filetypes).types [0], osstring);
00781 
00782                 if (equalidentifiers (osstring, BIGSTRING ("\x04" "fatp")))
00783                     copystring (BIGSTRING ("\x016" "Fat Page [*.fatp]\0*.*\0"), filter);
00784 
00785                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "ftop")))
00786                     copystring (BIGSTRING ("\x015" "Outline [*.ftop]\0*.*\0"), filter);
00787 
00788                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "ftwp")))
00789                     copystring (BIGSTRING ("\x019" "WP Document [*.ftwp]\0*.*\0"), filter);
00790 
00791                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "fttb")))
00792                     copystring (BIGSTRING ("\x013" "Table [*.fttb]\0*.*\0"), filter);
00793 
00794                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "ftmb")))
00795                     copystring (BIGSTRING ("\x012" "Menu [*.ftmb]\0*.*\0"), filter);
00796 
00797                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "ftsc")))
00798                     copystring (BIGSTRING ("\x014" "Script [*.ftsc]\0*.*\0"), filter);
00799 
00800                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "ftds")))
00801                     copystring (BIGSTRING ("\x01c" "Desktop Script [*.ftds]\0*.*\0"), filter);
00802 
00803                 else if (equalidentifiers (osstring, BIGSTRING ("\x04" "root")))
00804                     copystring (BIGSTRING ("\x016" "Database [*.root]\0*.*\0"), filter);
00805 
00806                 if (! isemptystring (filter)) {
00807                     convertpstring (filter);
00808 
00809                     OpenFileName.lpstrFilter = filter;
00810                     }
00811 
00812                 ostypetostring ((*filetypes).types [0], type);
00813                 
00814                 popleadingchars (type, '.');
00815 
00816                 poptrailingwhitespace (type);
00817                     
00818 //              convertpstring (type);
00819                 
00820 //              OpenFileName.lpstrDefExt = type;
00821                 OpenFileName.lpstrDefExt = NULL;
00822                 }
00823 
00824             // Call the common dialog function.
00825             fl = GetSaveFileName (&OpenFileName);
00826 
00827             if (fl && (filetypes != NULL) && (stringlength(type) > 0)) {
00828 
00829                 setstringlength (fsname (fspec), strlen(stringbaseaddress(fsname (fspec))));
00830                 lastword (fsname (fspec), '.', extension);
00831 
00832                 if ((stringlength (fsname (fspec)) == stringlength (extension)) || (stringlength (extension) > 4)) {    /* no extension */
00833                     pushstring ("\x01.", fsname(fspec));
00834                     pushstring (type, fsname(fspec));
00835                     nullterminate (fsname (fspec));
00836                     }
00837                 }
00838         
00839             break;
00840         
00841         case sfgetfileverb:
00842             OpenFileName.Flags = OFN_SHOWHELP | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; //| OFN_NOCHANGEDIR;
00843 
00844             // create the filter string
00845             if (filetypes != nil) { /*showing specific files*/
00846 
00847                 //copystring ("\x09Types: [\0", filter);
00848                 setemptystring (extension);
00849 
00850                 for (i = 0; i < (*filetypes).cttypes; ++i) {
00851                     
00852                     if (i > 0)
00853                         pushchar (';', extension);
00854                     
00855                     if ((*filetypes).types [i] == 'root')
00856                         fldatabases = true;
00857 
00858                     if ((*filetypes).types [i] == 'fatp')
00859                         flfatpages = true;
00860 
00861                     if ((*filetypes).types [i] == 'ROOT')
00862                         fldatabases = true;
00863 
00864                     if ((*filetypes).types [i] == 'FATP')
00865                         flfatpages = true;
00866 
00867                     ostypetostring ((*filetypes).types [i], type);
00868                     
00869                     popleadingchars (type, '.');
00870 
00871                     poptrailingwhitespace (type);
00872                     
00873                     pushstring (BIGSTRING ("\x02" "*."), extension);
00874 
00875                     pushstring (type, extension);
00876 
00877                     if (stringlength (type) > 3) {
00878                         
00879                         setstringlength (type, 3);
00880 
00881                         pushstring (BIGSTRING ("\x03" ";*."), extension);
00882                         
00883                         pushstring (type, extension);
00884                         }
00885                     }
00886                 
00887 
00888                 filterlen = 0;
00889 
00890                 buildfilter (filter, &filterlen, BIGSTRING ("\x1c" "Openable Types: [*.clickers]"), extension);
00891                 
00892                 if (fldatabases)
00893                     buildfilter (filter, &filterlen, BIGSTRING ("\x12" "Databases [*.root]"), BIGSTRING ("\x0c" "*.root;*.roo"));
00894 
00895                 //                  pushstring ("\x20\0Databases [*.root]\0*.roo;*.root", filter);
00896 
00897                 if (flfatpages) {
00898                     buildfilter (filter, &filterlen, BIGSTRING ("\x12" "Fat Pages [*.fatp]"), BIGSTRING ("\x5a" "*.fatp;*.fat;*.FTsc;*.FTs;*.FTwp;*.FTw;*.FTop;*.FTo;*.FTmb;*.FTm;*.FTtb;*.FTt;*.Ftds;*.FTd"));
00899                     buildfilter (filter, &filterlen, BIGSTRING ("\x17" "Frontier Menus [*.FTmb]"),    BIGSTRING ("\x0c" "*.FTmb;*.FTm"));
00900                     buildfilter (filter, &filterlen, BIGSTRING ("\x1a" "Frontier Outlines [*.FTop]"), BIGSTRING ("\x0c" "*.FTop;*.FTo"));
00901                     buildfilter (filter, &filterlen, BIGSTRING ("\x19" "Frontier Scripts [*.FTsc]"),  BIGSTRING ("\x0c" "*.FTsc;*.FTs"));
00902                     buildfilter (filter, &filterlen, BIGSTRING ("\x21" "Frontier Desktop Scripts [*.FTds]"),  BIGSTRING ("\x0c" "*.FTds;*.FTd"));
00903                     buildfilter (filter, &filterlen, BIGSTRING ("\x18" "Frontier Tables [*.FTtb]"),   BIGSTRING ("\x0c" "*.FTtb;*.FTt"));
00904                     buildfilter (filter, &filterlen, BIGSTRING ("\x19" "Frontier WP Text [*.FTwp]"),  BIGSTRING ("\x0c" "*.FTwp;*.FTw"));
00905                     }
00906 
00907                 //                  pushstring ("\x20\0Fat Pages [*.fatp]\0*.fat;*.fatp", filter);
00908 
00909                 buildfilter (filter, &filterlen, BIGSTRING ("\x12" "Plain Text [*.txt]"),  BIGSTRING ("\x12" "*.Text;*.txt;*.tex"));
00910                 buildfilter (filter, &filterlen, BIGSTRING ("\x0f" "All Files [*.*]"),  BIGSTRING ("\x03" "*.*"));
00911 
00912                 OpenFileName.lpstrFilter = filter;
00913 
00914                 ostypetostring ((*filetypes).types [0], type);
00915                 
00916                 //RAB: 1/22/98  added next two lines
00917                 //              poptrailingwhitespace is no longer done in ostypetostring.
00918                 popleadingchars (type, '.');
00919 
00920                 poptrailingwhitespace (type);
00921 
00922                 convertpstring (type);
00923                 
00924                 OpenFileName.lpstrDefExt = type;
00925                 }
00926 
00927             // Call the common dialog function.
00928             fl = GetOpenFileName (&OpenFileName);
00929         
00930             break;
00931         
00932         case sfgetfolderverb:
00933         case sfgetdiskverb:
00934             // Get the shell's allocator. 
00935             if (pMalloc == NULL && !SUCCEEDED(SHGetMalloc(&pMalloc))) 
00936                 break; 
00937  
00938             BrowseInfo.hwndOwner = OpenFileName.hwndOwner;
00939             BrowseInfo.pidlRoot = NULL;
00940             BrowseInfo.pszDisplayName = szFile;
00941             BrowseInfo.lpszTitle = OpenFileName.lpstrTitle;
00942             BrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS;
00943             if (sfverb == sfgetdiskverb)
00944                 BrowseInfo.ulFlags |= BIF_RETURNFSANCESTORS;
00945             BrowseInfo.lpfn = NULL;
00946             BrowseInfo.lParam = 0;
00947             
00948             itemList = SHBrowseForFolder (&BrowseInfo);
00949             
00950             if (itemList != NULL) {
00951 
00952                 fl = SHGetPathFromIDList (itemList, szFile);
00953 
00954                 copyctopstring (szFile, fsname (fspec));
00955 
00956                 if (sfverb == sfgetdiskverb) {
00957 
00958                     firstword (fsname (fspec), ':', fsname (fspec));
00959                 
00960                     pushstring ("\x02:\\", fsname (fspec));
00961                     }
00962                 else {
00963 
00964                     pushstring ("\x01\\", fsname (fspec));
00965                     }
00966                 
00967                 nullterminate (fsname (fspec));
00968 
00969                 // deallocate itemList
00970                 pMalloc->lpVtbl->Free (pMalloc, itemList);
00971 
00972         /*
00973         LPSHELLFOLDER ppshf;
00974         if (SHGetDesktopFolder (&ppshf) == NOERROR) {
00975             ULONG ctchars;
00976             WCHAR szWide [300];
00977 
00978             MultiByteToWideChar (CP_ACP, 0, szFile, -1, szWide, 300);
00979 
00980             ppshf->lpVtbl->ParseDisplayName (ppshf, NULL, szWide, &ctchars, &itemList,NULL);
00981 
00982             fl = SHGetPathFromIDList (itemList, szFile);
00983 
00984             pMalloc->lpVtbl->Free (pMalloc, itemList);
00985 
00986             ppshf->lpVtbl->Release (ppshf);
00987             }
00988         */
00989                 }
00990             
00991             break;
00992         
00993         }
00994     
00995     grabthreadglobals ();
00996     
00997     if (!fl) {
00998         
00999         oserror (GetLastError ());
01000         
01001         return (false);
01002         }
01003     
01004     setstringlength (fsname (fspec), strlen(stringbaseaddress(fsname (fspec))));
01005     
01006     return (true);
01007     } /*sfdialog*/
01008 
01009 #endif
01010 
01011 
01012 #ifdef MACVERSION
01013 
01014 boolean initfiledialog (void) {
01015 
01016     #ifdef flcomponent
01017     
01018     #if !TARGET_API_MAC_CARBON
01019     RememberA5 ();
01020     #endif /*for hook*/
01021     
01022     #endif
01023     
01024     return (true);
01025     } /*initfile*/
01026 
01027 
01028 //Code change by Timothy Paustian Tuesday, June 20, 2000 2:55:17 PM
01029 //New routine to use Nav services for this instead of CustomPutFile.
01030 OSErr
01031 TimsPutFile(bigstring prompt, Str255 fileName, StandardFileReply *  outReply)
01032 {
01033 
01034     OSErr               anErr = noErr;
01035     NavReplyRecord      reply;
01036     NavDialogOptions    dialogOptions;
01037     OSType              fileTypeToSave = 'TEXT';
01038     NavEventUPP         eventProc = NewNavEventUPP(NavEventProc);
01039 
01040     anErr = NavGetDefaultDialogOptions(&dialogOptions);
01041     copystring(fileName, dialogOptions.savedFileName);
01042     copystring(prompt, dialogOptions.message);
01043     dialogOptions.dialogOptionFlags |= kNavNoTypePopup; /* 08/25/2000 AR */
01044     if (anErr == noErr)
01045     {
01046         anErr = NavPutFile( nil, &reply, &dialogOptions, eventProc,
01047                             fileTypeToSave, 'LAND', nil);
01048 
01049         if (anErr == noErr && reply.validRecord)
01050         {
01051             AEKeyword   theKeyword;
01052             DescType    actualType;
01053             Size        actualSize;
01054             FSSpec      documentFSSpec;
01055 
01056             anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS,
01057                                 &theKeyword, &actualType,
01058                                 &documentFSSpec, sizeof(documentFSSpec),
01059                                 &actualSize );
01060            if (anErr == noErr)
01061             {
01062 
01063                 outReply->sfReplacing = reply.replacing;
01064                 FSMakeFSSpec (documentFSSpec.vRefNum, documentFSSpec.parID, documentFSSpec.name, &(outReply->sfFile));
01065                 outReply->sfGood = true;
01066             }
01067             // Always call NavCompleteSave() to complete
01068             #if TARGET_API_MAC_CARBON != 1
01069                 anErr = NavCompleteSave(&reply, kNavTranslateInPlace);
01070             #endif
01071  
01072             (void) NavDisposeReply(&reply);
01073         }
01074     }
01075     DisposeNavEventUPP(eventProc);
01076     return anErr;
01077 }
01078 
01079 
01080 OSErr getafile (bigstring prompt, ptrsftypelist filetypes, StandardFileReply * outReply, OSType filecreator) {
01081 
01082     /*
01083     2005-10-06 creedon: added filecreator parameter
01084     
01085     2005-09-21 creedon: created, cribbed from TimsGetFile
01086     */ 
01087 
01088     NavDialogCreationOptions    dialogOptions;
01089     NavDialogRef            dialogRef;
01090     NavEventUPP         eventProc = NewNavEventUPP (NavEventProc);
01091     NavReplyRecord          reply;
01092     NavTypeListHandle       typeList = nil;
01093     OSErr               anErr = noErr;
01094 
01095     anErr = NavGetDefaultDialogCreationOptions (&dialogOptions);
01096     
01097     dialogOptions.clientName = CFStringCreateWithCString (NULL, APPNAME_SHORT, kCFStringEncodingMacRoman);
01098     dialogOptions.message = CFStringCreateWithPascalString (NULL, prompt, kCFStringEncodingMacRoman);
01099     
01100     if (anErr == noErr) {
01101     
01102         if (filetypes == nil)
01103             dialogOptions.optionFlags -= kNavNoTypePopup;
01104         else
01105             dialogOptions.optionFlags += kNavAllFilesInPopup; // add all documents to show pop-up
01106 
01107         dialogOptions.optionFlags ^=kNavAllowMultipleFiles; //no multiple files for now
01108         
01109         dialogOptions.optionFlags ^= kNavAllowPreviews; // clear preview option
01110         
01111         dialogOptions.optionFlags += kNavSupportPackages; // see packages
01112         
01113         // dialogOptions.dialogOptionFlags += kNavAllowOpenPackages; // can open packages
01114 
01115         if (filetypes != nil) { // translate into a type list NavServices understands
01116         
01117             NavTypeListPtr  typesP = nil;
01118             SInt32      hSize = (sizeof (NavTypeList) + sizeof (OSType) * (filetypes->cttypes - 1));
01119             newhandle       (hSize, (Handle*) &typeList);
01120             typesP      = (NavTypeListPtr) *((Handle) typeList);
01121             
01122             typesP->componentSignature = filecreator;
01123             typesP->reserved = 0;
01124             typesP->osTypeCount = filetypes->cttypes;
01125             
01126             BlockMoveData (&(filetypes->types), typesP->osType, (Size) (sizeof (OSType) * filetypes->cttypes));
01127             }
01128         
01129         anErr = NavCreateGetFileDialog (&dialogOptions, typeList, eventProc, NULL, NULL, NULL, &dialogRef);
01130 
01131         anErr = NavDialogRun (dialogRef);
01132         
01133         anErr = NavDialogGetReply (dialogRef, &reply);
01134 
01135         if (anErr == noErr && reply.validRecord) {
01136         
01137             AEKeyword theKeyword;
01138             DescType actualType;
01139             Size actualSize;
01140             FSSpec documentFSSpec;
01141 
01142             anErr = AEGetNthPtr (&(reply.selection), 1, typeFSS, &theKeyword, &actualType, &documentFSSpec, sizeof (documentFSSpec), &actualSize); // get a pointer to selected file
01143             
01144             assert (actualType == typeFSS);
01145             
01146             if (anErr == noErr) {
01147                 FSMakeFSSpec (documentFSSpec.vRefNum, documentFSSpec.parID, documentFSSpec.name, &(outReply->sfFile));
01148             
01149                 outReply->sfGood = true;
01150                 }
01151 
01152             anErr = NavDisposeReply (&reply); // dispose of NavReplyRecord, resources, descriptors
01153             }
01154         }
01155         
01156     DisposeNavEventUPP (eventProc);
01157     
01158     NavDialogDispose (dialogRef);
01159  
01160     return anErr;
01161     } /* getafile */
01162 
01163 
01164 OSErr
01165 TimsGetFolderOrVolume(bigstring prompt, SInt16 dialogType, StandardFileReply *  outReply)
01166 {
01167     NavDialogOptions        dialogOptions;
01168     NavEventUPP             eventProc = NewNavEventUPP(NavEventProc);
01169     OSErr                   anErr = noErr;
01170     NavReplyRecord          reply;
01171         
01172     //  Specify default options for dialog box
01173     //we don't really need to modify this, but it is needed for NavChooseFolder
01174     anErr = NavGetDefaultDialogOptions(&dialogOptions);
01175      copystring(prompt, dialogOptions.message);
01176     
01177     if(anErr == noErr)
01178     {
01179         //display the dialog
01180         if(sfgetfolderid == dialogType)
01181             anErr = NavChooseFolder(nil, &reply, &dialogOptions, eventProc, nil, nil);
01182         else
01183         {
01184             assert(sfgetdiskid == dialogType); 
01185             anErr = NavChooseVolume(nil, &reply, &dialogOptions, eventProc, nil, nil);
01186         }
01187         
01188         if (anErr == noErr && reply.validRecord)
01189         {
01190             AEKeyword   theKeyword;
01191             DescType    actualType;
01192             Size        actualSize;
01193             FSSpec      documentFSSpec;
01194             
01195             // Get a pointer to selected file
01196             anErr = AEGetNthPtr(&(reply.selection), 1,
01197                                 typeFSS, &theKeyword,
01198                                 &actualType, &documentFSSpec,
01199                                 sizeof(documentFSSpec),
01200                                 &actualSize);
01201             assert(actualType == typeFSS);       
01202             if (anErr == noErr)
01203             {
01204                 FSMakeFSSpec (documentFSSpec.vRefNum, documentFSSpec.parID, documentFSSpec.name, &(outReply->sfFile));
01205                 outReply->sfGood = true;
01206             }
01207             //  Dispose of NavReplyRecord
01208             anErr = NavDisposeReply(&reply);
01209         }
01210     }
01211      DisposeNavEventUPP (eventProc);
01212      return anErr;
01213 }
01214 
01215 
01216 
01217 
01218 
01219 
01220 //Code change by Timothy Paustian Tuesday, June 20, 2000 9:07:26 PM
01221 //a very simple event proc so that Nav file service dialogs are movable and resizable.
01222 pascal void NavEventProc(NavEventCallbackMessage callBackSelector,
01223                         NavCBRecPtr callBackParms,
01224                         NavCallBackUserData callBackUD)
01225 {
01226 #pragma unused(callBackUD)
01227     if (callBackSelector == kNavCBEvent)
01228     {
01229         if( ((callBackParms->eventData).eventDataParms).event->what == updateEvt)
01230         {
01231             //I was having a crash due to getting the window ptr outside the switch statement.
01232             // This now works.
01233             //10/30/00 Timothy Paustian
01234             WindowPtr window = (WindowPtr)(((callBackParms->eventData).eventDataParms).event)->message;
01235             shellupdatenow(window);
01236         }
01237     }
01238 }
01239 
01240 #endif

Generated on Wed May 31 18:19:46 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6