home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Simple Slideshow / SFGetFolder.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-06  |  7.2 KB  |  321 lines  |  [TEXT/CWIE]

  1. /***********************************************************************************************
  2. *
  3. *        Name:              SFGetFolder.c
  4. *        Description:    Standard File stuff for choosing a folder
  5. *
  6. *
  7. *        ©ImproVision Ltd. All Rights Reserved. ***** Company Confidential *****
  8. *
  9. *        Created:        May 26th, 1995
  10. *        Author:            Graham Cox
  11. *        Mod History:
  12. *
  13. *        This code mostly based on "Macintosh Programming Secrets, 2nd. Ed. pp 385 - 388    
  14. *
  15. ***********************************************************************************************/
  16.  
  17. #include    "SFGetFolder.h"
  18. #include    "DirectoryUtils.h"
  19. #include    "LowMem.h"
  20. #include    "TBUtilities.h"
  21. #include    "DialogUtils.h"
  22. #include    "ThreeDEffects.h"
  23. #include    "TCLMoveableModalFilter.h"
  24.  
  25. typedef struct
  26. {
  27.     StandardFileReply    aReply;
  28.     Boolean                selectHit;
  29.     Boolean                dirFlag;
  30. }
  31. tFolderInfo;
  32.  
  33.  
  34. static pascal Boolean    GetDirFileFilter(ParmBlkPtr pb,tFolderInfo* fInfo);
  35. static pascal short        GetDirDlgHook(short item, DialogPtr theDialog, tFolderInfo* fInfo);
  36. static void                SetSFButtonTitle(ControlHandle theButton,FSSpec* theFile,Rect* buttonRect);
  37. static short            GetSFCurVol(void);
  38. static long                GetSFCurDir(void);
  39. static void                pStrInsert(StringPtr dest,StringPtr src);
  40. static pascal void        SFGFDialogUserItem(DialogPtr theDialog,short item);
  41. static OSErr             MakeCanonFSSpec ( FSSpec *spec );
  42.  
  43. Boolean                  SameFile ( FSSpec *spec1, FSSpec *spec2 );
  44.  
  45.  
  46. // code for this is in "PicPreviewGetFile.c"
  47.  
  48. pascal Boolean    CustFileMoveableModalFilterProc(     DialogPtr theDialog,
  49.                                                     EventRecord* theEvent,
  50.                                                     short*    itemHit,
  51.                                                     Ptr myDataPtr);
  52.  
  53.  
  54.  
  55.  
  56. Boolean        ChooseFolder(FSSpec* folderSpec)
  57. {
  58.     SFTypeList            fTypes;
  59.     Point                where = {-1,-1};
  60.     FileFilterYDUPP        ffUPP;
  61.     DlgHookYDUPP        dhUPP;
  62.     tFolderInfo            folderInfo;
  63.     OSErr                err;
  64.     short                aHit,dummyActiveList = 0;
  65.     Boolean                targetIsFolder,wasAliased;
  66.     ModalFilterYDUPP    mmUPP;
  67.     
  68.     ffUPP = NewFileFilterYDProc((ProcPtr) GetDirFileFilter);
  69.     dhUPP = NewDlgHookYDProc((ProcPtr) GetDirDlgHook);
  70.     mmUPP = NewModalFilterYDProc((ProcPtr) CustFileMoveableModalFilterProc);
  71.     
  72.     folderInfo.selectHit = FALSE;
  73.     folderInfo.dirFlag = FALSE;
  74.  
  75.     CustomPutFile("\p","\p",
  76.                     &folderInfo.aReply,
  77.                     kSFGetFolderDialogID,
  78.                     where,
  79.                     dhUPP,
  80.                     mmUPP,
  81.                     &dummyActiveList,
  82.                     NULL,
  83.                     &folderInfo);
  84.                     
  85.     DisposeRoutineDescriptor(ffUPP);
  86.     DisposeRoutineDescriptor(dhUPP);
  87.     DisposeRoutineDescriptor(mmUPP);
  88.     
  89.     if (folderInfo.selectHit)
  90.     {
  91.         if ( !folderInfo.aReply.sfIsFolder && !folderInfo.aReply.sfIsVolume )
  92.         {
  93.             FSSpec        tempSpec;
  94.             CInfoPBRec    infoPB;
  95.             Boolean        isDirectory;
  96.     
  97.             tempSpec = folderInfo.aReply.sfFile;
  98.             
  99.             if (tempSpec.name[0] != '\0')
  100.                 return FALSE; //err
  101.     
  102.             infoPB.dirInfo.ioNamePtr = tempSpec.name;
  103.             infoPB.dirInfo.ioVRefNum = tempSpec.vRefNum;
  104.             infoPB.dirInfo.ioDrDirID = tempSpec.parID;
  105.             infoPB.dirInfo.ioFDirIndex = -1;
  106.             
  107.             err = PBGetCatInfo( &infoPB, false );
  108.             if (err)
  109.                 return FALSE;
  110.             
  111.             tempSpec.parID = infoPB.dirInfo.ioDrParID ;
  112.             
  113.             // make sure that it's a directory
  114.             
  115.             isDirectory = (infoPB.dirInfo.ioFlAttrib & 0x10) ;
  116.             if ( !isDirectory )
  117.                 return FALSE; //err
  118.             
  119.             folderInfo.aReply.sfFile = tempSpec ;
  120.             folderInfo.aReply.sfScript = infoPB.dirInfo.ioDrFndrInfo.frScript ;
  121.             folderInfo.aReply.sfFlags = infoPB.dirInfo.ioDrUsrWds.frFlags ;
  122.             folderInfo.aReply.sfIsFolder = (tempSpec.parID == 1) ? (0x00) : (0xFF) ;
  123.             folderInfo.aReply.sfIsVolume = (tempSpec.parID == 1) ? (0xFF) : (0x00) ; ;
  124.         }
  125.  
  126.         *folderSpec = folderInfo.aReply.sfFile;
  127.  
  128.         return TRUE;
  129.     }    
  130.     return FALSE;
  131. }
  132.  
  133.  
  134.  
  135. static pascal Boolean    GetDirFileFilter(ParmBlkPtr pb,tFolderInfo* fInfo)
  136. {
  137.     return ((pb->fileParam.ioFlAttrib & ioDirMask) == 0);
  138. }
  139.  
  140.  
  141.  
  142. static pascal short        GetDirDlgHook(short item, DialogPtr theDialog, tFolderInfo* fInfo)
  143. {
  144.     short            itemType;
  145.     Handle            itemHand;
  146.     Rect            itemBox;
  147.     OSErr            theErr;
  148.     FSSpec            fRef;
  149.     static FSSpec    lastFile;
  150.     
  151.     if (GetWRefCon(theDialog) == (long) sfMainDialogRefCon)
  152.     {
  153.         fRef = fInfo->aReply.sfFile;
  154.         
  155.         switch (item)
  156.         {
  157.             case sfHookFirstCall:
  158.                 SetUniversalUserItem(theDialog,kGnrlUserItem,(ProcPtr) SFGFDialogUserItem);
  159.                 GetDItem(theDialog,kPickFolderButton,&itemType,&itemHand,&itemBox);
  160.                 SetSFButtonTitle((ControlHandle) itemHand,&fRef,&itemBox);
  161.                 
  162.                 lastFile.vRefNum = -9999;
  163.                 
  164.                 break;
  165.             case sfHookLastCall:
  166.                 DisposeUserItem(theDialog,kGnrlUserItem);
  167.                 break;
  168.             default:
  169.                 break;
  170.             case sfHookNullEvent:
  171.                 if (! SameFile(&fRef,&lastFile))
  172.                 {
  173.                     lastFile = fRef;
  174.                     
  175.                     MakeCanonFSSpec(&fRef);    
  176.                     GetDItem(theDialog,kPickFolderButton,&itemType,&itemHand,&itemBox);
  177.                     SetSFButtonTitle((ControlHandle) itemHand,&fRef,&itemBox);
  178.                 }
  179.                 break;
  180.             case kPickFolderButton:
  181.                 fInfo->selectHit = TRUE;
  182.                 item = sfItemCancelButton;
  183.                 break;
  184.         }
  185.     }
  186.     return item;
  187. }
  188.  
  189.  
  190. static void        SetSFButtonTitle(ControlHandle theButton,FSSpec* theFile,Rect* buttonRect)
  191. {
  192.     // sets the button title to <Select “<name>”>, but truncated to fit the rect.
  193.     
  194.     short            width,saveSize,saveFont;
  195.     StringHandle    nStr;
  196.     Str255            bStr;
  197.     
  198.     saveSize = qd.thePort->txSize;
  199.     saveFont = qd.thePort->txFont;
  200.     
  201.     TextSize(12);
  202.     TextFont(0);
  203.     
  204.     nStr = GetString(kStdButtonTextStrID);
  205.     HLock((Handle) nStr);
  206.     CopyPString(*nStr,bStr);
  207.     HUnlock((Handle) nStr);
  208.     ReleaseResource((Handle) nStr);
  209.  
  210.     width = buttonRect->right - buttonRect->left - 32 - StringWidth(bStr);
  211.     TruncString(width,theFile->name,smTruncMiddle);
  212.     
  213.     
  214.     ConcatPStrings(bStr,"\p “");
  215.     ConcatPStrings(bStr,theFile->name);
  216.     ConcatPStrings(bStr,"\p”");
  217.  
  218.     SetCTitle(theButton,bStr);
  219.     ValidRect(buttonRect);
  220.     
  221.     TextFont(saveFont);
  222.     TextSize(saveSize);
  223. }
  224.  
  225.  
  226. static short    GetSFCurVol()
  227. {
  228.     return -(LMGetSFSaveDisk());
  229. }
  230.  
  231. static long        GetSFCurDir()
  232. {
  233.     return LMGetCurDirStore();
  234. }
  235.  
  236.  
  237. static void        pStrInsert(StringPtr dest,StringPtr src)
  238. {
  239.     // inserts <src> at the beginning of <dest>
  240.     
  241.     BlockMoveData(dest + 1,dest + *src + 1,*dest);
  242.     BlockMoveData(src + 1,dest + 1,*src);
  243.     *dest += *src;
  244. }
  245.  
  246.  
  247. Boolean        GetFullPathname(FSSpec* aSpec,Str255 pathname)
  248. {
  249.     // returns the full pathname for the file spec passed. If the file does not exist, this
  250.     // returns FALSE, if it does, it returns TRUE.
  251.     
  252.     DirInfo        blk;
  253.     Str255        dirName;
  254.     OSErr        theErr;
  255.     Boolean     result = TRUE;
  256.  
  257.     pathname[0] = 0;
  258.     
  259.     blk.ioDrParID = aSpec->parID;
  260.     blk.ioNamePtr = dirName;
  261.     
  262.     do
  263.     {
  264.         blk.ioVRefNum = aSpec->vRefNum;
  265.         blk.ioFDirIndex = -1;
  266.         blk.ioDrDirID = blk.ioDrParID;
  267.         
  268.         theErr = PBGetCatInfo((CInfoPBPtr) &blk,FALSE);
  269.         
  270.         if (theErr)
  271.         {
  272.             result = FALSE;
  273.             break;
  274.         }
  275.         
  276.         ConcatPStrings(dirName,"\p:");
  277.         pStrInsert(pathname,dirName);
  278.     }
  279.     while(blk.ioDrDirID != 2);
  280.     if (result)
  281.         ConcatPStrings(pathname,aSpec->name);
  282.     return result;
  283. }
  284.  
  285.  
  286. static pascal void        SFGFDialogUserItem(DialogPtr theDialog,short item)
  287. {
  288.     short        itemType;
  289.     Handle        itemHand;
  290.     Rect        itemBox;
  291.  
  292.     GetDItem(theDialog,sfItemFileListUser,&itemType,&itemHand,&itemBox);
  293.     Frame3DRect(&itemBox,kRecessedEmbossed);
  294. }
  295.  
  296.  
  297. OSErr MakeCanonFSSpec ( FSSpec *spec )
  298. {
  299.     OSErr        err ;
  300.     
  301.     err = FSMakeFSSpec( spec->vRefNum,
  302.                         spec->parID,
  303.                         spec->name,
  304.                         spec ) ;
  305.     return noErr ;
  306. }
  307.  
  308.  
  309. Boolean SameFile ( FSSpec *spec1, FSSpec *spec2 )
  310. {
  311.     if (spec1->vRefNum != spec2->vRefNum)
  312.         return false;
  313.     if (spec1->parID != spec2->parID)
  314.         return false;
  315.     if ( !EqualString( spec1->name, spec2->name, false, true ) )
  316.         return false;
  317.     return true;
  318. }
  319.  
  320.  
  321.