home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************************************
- *
- * Name: SFGetFolder.c
- * Description: Standard File stuff for choosing a folder
- *
- *
- * ©ImproVision Ltd. All Rights Reserved. ***** Company Confidential *****
- *
- * Created: May 26th, 1995
- * Author: Graham Cox
- * Mod History:
- *
- * This code mostly based on "Macintosh Programming Secrets, 2nd. Ed. pp 385 - 388
- *
- ***********************************************************************************************/
-
- #include "SFGetFolder.h"
- #include "DirectoryUtils.h"
- #include "LowMem.h"
- #include "TBUtilities.h"
- #include "DialogUtils.h"
- #include "ThreeDEffects.h"
- #include "TCLMoveableModalFilter.h"
-
- typedef struct
- {
- StandardFileReply aReply;
- Boolean selectHit;
- Boolean dirFlag;
- }
- tFolderInfo;
-
-
- static pascal Boolean GetDirFileFilter(ParmBlkPtr pb,tFolderInfo* fInfo);
- static pascal short GetDirDlgHook(short item, DialogPtr theDialog, tFolderInfo* fInfo);
- static void SetSFButtonTitle(ControlHandle theButton,FSSpec* theFile,Rect* buttonRect);
- static short GetSFCurVol(void);
- static long GetSFCurDir(void);
- static void pStrInsert(StringPtr dest,StringPtr src);
- static pascal void SFGFDialogUserItem(DialogPtr theDialog,short item);
- static OSErr MakeCanonFSSpec ( FSSpec *spec );
-
- Boolean SameFile ( FSSpec *spec1, FSSpec *spec2 );
-
-
- // code for this is in "PicPreviewGetFile.c"
-
- pascal Boolean CustFileMoveableModalFilterProc( DialogPtr theDialog,
- EventRecord* theEvent,
- short* itemHit,
- Ptr myDataPtr);
-
-
-
-
- Boolean ChooseFolder(FSSpec* folderSpec)
- {
- SFTypeList fTypes;
- Point where = {-1,-1};
- FileFilterYDUPP ffUPP;
- DlgHookYDUPP dhUPP;
- tFolderInfo folderInfo;
- OSErr err;
- short aHit,dummyActiveList = 0;
- Boolean targetIsFolder,wasAliased;
- ModalFilterYDUPP mmUPP;
-
- ffUPP = NewFileFilterYDProc((ProcPtr) GetDirFileFilter);
- dhUPP = NewDlgHookYDProc((ProcPtr) GetDirDlgHook);
- mmUPP = NewModalFilterYDProc((ProcPtr) CustFileMoveableModalFilterProc);
-
- folderInfo.selectHit = FALSE;
- folderInfo.dirFlag = FALSE;
-
- CustomPutFile("\p","\p",
- &folderInfo.aReply,
- kSFGetFolderDialogID,
- where,
- dhUPP,
- mmUPP,
- &dummyActiveList,
- NULL,
- &folderInfo);
-
- DisposeRoutineDescriptor(ffUPP);
- DisposeRoutineDescriptor(dhUPP);
- DisposeRoutineDescriptor(mmUPP);
-
- if (folderInfo.selectHit)
- {
- if ( !folderInfo.aReply.sfIsFolder && !folderInfo.aReply.sfIsVolume )
- {
- FSSpec tempSpec;
- CInfoPBRec infoPB;
- Boolean isDirectory;
-
- tempSpec = folderInfo.aReply.sfFile;
-
- if (tempSpec.name[0] != '\0')
- return FALSE; //err
-
- infoPB.dirInfo.ioNamePtr = tempSpec.name;
- infoPB.dirInfo.ioVRefNum = tempSpec.vRefNum;
- infoPB.dirInfo.ioDrDirID = tempSpec.parID;
- infoPB.dirInfo.ioFDirIndex = -1;
-
- err = PBGetCatInfo( &infoPB, false );
- if (err)
- return FALSE;
-
- tempSpec.parID = infoPB.dirInfo.ioDrParID ;
-
- // make sure that it's a directory
-
- isDirectory = (infoPB.dirInfo.ioFlAttrib & 0x10) ;
- if ( !isDirectory )
- return FALSE; //err
-
- folderInfo.aReply.sfFile = tempSpec ;
- folderInfo.aReply.sfScript = infoPB.dirInfo.ioDrFndrInfo.frScript ;
- folderInfo.aReply.sfFlags = infoPB.dirInfo.ioDrUsrWds.frFlags ;
- folderInfo.aReply.sfIsFolder = (tempSpec.parID == 1) ? (0x00) : (0xFF) ;
- folderInfo.aReply.sfIsVolume = (tempSpec.parID == 1) ? (0xFF) : (0x00) ; ;
- }
-
- *folderSpec = folderInfo.aReply.sfFile;
-
- return TRUE;
- }
- return FALSE;
- }
-
-
-
- static pascal Boolean GetDirFileFilter(ParmBlkPtr pb,tFolderInfo* fInfo)
- {
- return ((pb->fileParam.ioFlAttrib & ioDirMask) == 0);
- }
-
-
-
- static pascal short GetDirDlgHook(short item, DialogPtr theDialog, tFolderInfo* fInfo)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
- OSErr theErr;
- FSSpec fRef;
- static FSSpec lastFile;
-
- if (GetWRefCon(theDialog) == (long) sfMainDialogRefCon)
- {
- fRef = fInfo->aReply.sfFile;
-
- switch (item)
- {
- case sfHookFirstCall:
- SetUniversalUserItem(theDialog,kGnrlUserItem,(ProcPtr) SFGFDialogUserItem);
- GetDItem(theDialog,kPickFolderButton,&itemType,&itemHand,&itemBox);
- SetSFButtonTitle((ControlHandle) itemHand,&fRef,&itemBox);
-
- lastFile.vRefNum = -9999;
-
- break;
- case sfHookLastCall:
- DisposeUserItem(theDialog,kGnrlUserItem);
- break;
- default:
- break;
- case sfHookNullEvent:
- if (! SameFile(&fRef,&lastFile))
- {
- lastFile = fRef;
-
- MakeCanonFSSpec(&fRef);
- GetDItem(theDialog,kPickFolderButton,&itemType,&itemHand,&itemBox);
- SetSFButtonTitle((ControlHandle) itemHand,&fRef,&itemBox);
- }
- break;
- case kPickFolderButton:
- fInfo->selectHit = TRUE;
- item = sfItemCancelButton;
- break;
- }
- }
- return item;
- }
-
-
- static void SetSFButtonTitle(ControlHandle theButton,FSSpec* theFile,Rect* buttonRect)
- {
- // sets the button title to <Select “<name>”>, but truncated to fit the rect.
-
- short width,saveSize,saveFont;
- StringHandle nStr;
- Str255 bStr;
-
- saveSize = qd.thePort->txSize;
- saveFont = qd.thePort->txFont;
-
- TextSize(12);
- TextFont(0);
-
- nStr = GetString(kStdButtonTextStrID);
- HLock((Handle) nStr);
- CopyPString(*nStr,bStr);
- HUnlock((Handle) nStr);
- ReleaseResource((Handle) nStr);
-
- width = buttonRect->right - buttonRect->left - 32 - StringWidth(bStr);
- TruncString(width,theFile->name,smTruncMiddle);
-
-
- ConcatPStrings(bStr,"\p “");
- ConcatPStrings(bStr,theFile->name);
- ConcatPStrings(bStr,"\p”");
-
- SetCTitle(theButton,bStr);
- ValidRect(buttonRect);
-
- TextFont(saveFont);
- TextSize(saveSize);
- }
-
-
- static short GetSFCurVol()
- {
- return -(LMGetSFSaveDisk());
- }
-
- static long GetSFCurDir()
- {
- return LMGetCurDirStore();
- }
-
-
- static void pStrInsert(StringPtr dest,StringPtr src)
- {
- // inserts <src> at the beginning of <dest>
-
- BlockMoveData(dest + 1,dest + *src + 1,*dest);
- BlockMoveData(src + 1,dest + 1,*src);
- *dest += *src;
- }
-
-
- Boolean GetFullPathname(FSSpec* aSpec,Str255 pathname)
- {
- // returns the full pathname for the file spec passed. If the file does not exist, this
- // returns FALSE, if it does, it returns TRUE.
-
- DirInfo blk;
- Str255 dirName;
- OSErr theErr;
- Boolean result = TRUE;
-
- pathname[0] = 0;
-
- blk.ioDrParID = aSpec->parID;
- blk.ioNamePtr = dirName;
-
- do
- {
- blk.ioVRefNum = aSpec->vRefNum;
- blk.ioFDirIndex = -1;
- blk.ioDrDirID = blk.ioDrParID;
-
- theErr = PBGetCatInfo((CInfoPBPtr) &blk,FALSE);
-
- if (theErr)
- {
- result = FALSE;
- break;
- }
-
- ConcatPStrings(dirName,"\p:");
- pStrInsert(pathname,dirName);
- }
- while(blk.ioDrDirID != 2);
- if (result)
- ConcatPStrings(pathname,aSpec->name);
- return result;
- }
-
-
- static pascal void SFGFDialogUserItem(DialogPtr theDialog,short item)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,sfItemFileListUser,&itemType,&itemHand,&itemBox);
- Frame3DRect(&itemBox,kRecessedEmbossed);
- }
-
-
- OSErr MakeCanonFSSpec ( FSSpec *spec )
- {
- OSErr err ;
-
- err = FSMakeFSSpec( spec->vRefNum,
- spec->parID,
- spec->name,
- spec ) ;
- return noErr ;
- }
-
-
- Boolean SameFile ( FSSpec *spec1, FSSpec *spec2 )
- {
- if (spec1->vRefNum != spec2->vRefNum)
- return false;
- if (spec1->parID != spec2->parID)
- return false;
- if ( !EqualString( spec1->name, spec2->name, false, true ) )
- return false;
- return true;
- }
-
-
-