home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / Fab Libraries / StdGetFolder.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-03  |  6.4 KB  |  286 lines  |  [TEXT/MPS ]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. /* I did not write the code in this file; I took it from some sample code
  11. from Apple, I think.
  12. I modified the original code a little bit, though. */
  13.  
  14. #pragma load "MacDump"
  15.  
  16. #include    "StdGetFolder.h"
  17. #include    "Utils.h"
  18.  
  19. #pragma segment Main
  20.  
  21. /* prototypes */
  22.  
  23. static pascal short MyDlgHook(short item,DialogPtr theDlg,Ptr userData);
  24. static pascal Boolean MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData);
  25. static void HitButton(DialogPtr theDlg,short item);
  26. static pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
  27. static void SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg);
  28. static Boolean SameFile(FSSpec *file1,FSSpec *file2);
  29. static Boolean GetFSSpecPartialName(FSSpec *file,StringPtr fName);
  30. static OSErr GetDeskFolderSpec(FSSpec *fSpec,short vRefNum);
  31. static OSErr MakeCanonFSSpec(FSSpec *fSpec);
  32. static Boolean ShouldHiliteSelect(FSSpec *fSpec);
  33.  
  34. /* typedefs */
  35.  
  36. typedef struct {
  37.     StandardFileReply *replyPtr;
  38.     FSSpec oldSelection;
  39. } SFData, *SFDataPtr;
  40.  
  41. /* constants */
  42.  
  43. #define    kSelectItem            10
  44. #define    kSFDlg                128
  45. #define    kCanSelectDesktop    true
  46. #define    kSelectStrRsrc        129
  47. #define    kDeskStrRsrc        130
  48. #define    kSelectKey            's'
  49.  
  50. /* globals */
  51.  
  52. Boolean gHasFindFolder;
  53. FSSpec gDeskFolderSpec;
  54.  
  55. /*
  56.     strHndl = GetString(kSelectStrRsrc);
  57.     strHndl = GetString(kDeskStrRsrc);
  58. */
  59.  
  60. /* do getfile */
  61.  
  62. Boolean CustomGet(FSSpec *fSpec)
  63. {
  64. Point where = {-1,-1};
  65. StandardFileReply sfReply;
  66. SFData sfUserData;
  67. OSErr err;
  68. Boolean targetIsFolder, wasAliased;
  69.  
  70. /* initialize user data area */
  71.  
  72. sfUserData.replyPtr = &sfReply;
  73. sfUserData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  74.  
  75. CustomGetFile((FileFilterYDProcPtr)FilterAllFiles,-1,nil,&sfReply,kSFDlg,where,MyDlgHook,
  76.                 MyModalFilter,nil,nil,&sfUserData);
  77.  
  78. if (sfReply.sfGood) {
  79.     err = ResolveAliasFile(&sfReply.sfFile,true,&targetIsFolder,&wasAliased);
  80.     if (err)
  81.         return false;
  82. }
  83.  
  84. err = FSMakeFSSpec(sfReply.sfFile.vRefNum,sfReply.sfFile.parID,sfReply.sfFile.name,fSpec);
  85. if (err)
  86.     return false;
  87.  
  88. return sfReply.sfGood;
  89. }
  90.  
  91.  
  92. /*    this dialog hook checks the contents of the additional edit fields
  93.     when the user selects a file.  The focus of the dialog is changed if one
  94.     of the fields is out of range.
  95. */
  96.  
  97. pascal short MyDlgHook(short item,DialogPtr theDlg,Ptr userData)
  98. {
  99. SFDataPtr sfUserData;
  100. FSSpec curSpec;
  101. OSType refCon;
  102.  
  103. refCon = GetWRefCon(theDlg);
  104. if (refCon != sfMainDialogRefCon)
  105.     return item;
  106.     
  107. sfUserData = (SFDataPtr) userData;
  108.  
  109. if (item==sfHookFirstCall || item==sfHookLastCall)
  110.     return item;
  111.  
  112. if (item==sfItemVolumeUser) {
  113.     sfUserData->replyPtr->sfFile.name[0] = '\0';
  114.     sfUserData->replyPtr->sfFile.parID = 2;
  115.     sfUserData->replyPtr->sfIsFolder = false;
  116.     sfUserData->replyPtr->sfIsVolume = false;
  117.     sfUserData->replyPtr->sfFlags = 0;
  118.     item = sfHookChangeSelection;
  119.     }
  120.     
  121. if (!SameFile(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection)) {
  122.     curSpec = sfUserData->replyPtr->sfFile;
  123.     MakeCanonFSSpec(&curSpec);
  124.     
  125.     if (curSpec.vRefNum != sfUserData->oldSelection.vRefNum)
  126.         GetDeskFolderSpec(&gDeskFolderSpec,curSpec.vRefNum);    
  127.     SetSelectButtonName(curSpec.name,ShouldHiliteSelect(&curSpec),theDlg);
  128.     
  129.     sfUserData->oldSelection = sfUserData->replyPtr->sfFile;
  130.     }
  131.  
  132. if (item == kSelectItem)
  133.     item = sfItemOpenButton;
  134.     
  135. return item;
  136. }
  137.  
  138.  
  139. pascal Boolean MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr /*myData*/)
  140. {
  141. Boolean evHandled;
  142. char keyPressed;
  143. OSType refCon;
  144.  
  145. refCon = GetWRefCon(theDlg);
  146. if (refCon != sfMainDialogRefCon)
  147.     return false;
  148.     
  149. evHandled = false;
  150.  
  151. switch (ev->what) {
  152.     case keyDown:
  153.     case autoKey:
  154.         keyPressed = CHARFROMMESSAGE(ev->message);
  155.         if ((ev->modifiers & cmdKey) != 0) {
  156.             switch (keyPressed) {
  157.                 case kSelectKey:
  158.                     HitButton(theDlg,kSelectItem);
  159.                     *itemHit = kSelectItem;
  160.                     evHandled = true;
  161.                     break;
  162.             }
  163.         }
  164.         break;
  165. }
  166.  
  167. return evHandled;
  168. }
  169.  
  170.  
  171. void HitButton(DialogPtr theDlg, short item)
  172. {
  173. Rect iRect;
  174. ControlHandle iHndl;
  175. long fTicks;
  176. short iType;
  177.  
  178. GetDItem(theDlg, item, &iType, &(Handle)iHndl, &iRect);
  179. HiliteControl(iHndl,inButton);
  180. Delay(5,&fTicks);
  181. HiliteControl(iHndl,0);
  182. }
  183.  
  184.  
  185. pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr /*myDataPtr*/)
  186. {/* file is a directory */
  187. return ((pb->hFileInfo.ioFlAttrib & (1<<4)) == 0);
  188. }
  189.  
  190.  
  191. void SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg)
  192. {
  193. Str255 storeName, tempLenStr, tempSelName;
  194. Rect iRect;
  195. StringHandle    theString;
  196. Handle iHndl;
  197. short iType;
  198. short btnWidth;
  199.  
  200. (void) PLstrcpy(tempSelName, selName);
  201. GetDItem(theDlg,kSelectItem,&iType,&iHndl,&iRect);
  202.  
  203. /* truncate select name to fit in button */
  204.  
  205. btnWidth = iRect.right - iRect.left;
  206. theString = GetString(kSelectStrRsrc);
  207.  
  208. (void) PLstrcpy(tempLenStr, *theString);
  209.  
  210. PLstrcat((char *)tempLenStr,"\p “”  ");
  211. btnWidth -= StringWidth(tempLenStr);
  212. TruncString(btnWidth,tempSelName,smTruncMiddle);
  213.  
  214. (void) PLstrcpy(storeName, *theString);
  215. PLstrcat((char *)storeName,"\p “");
  216. PLstrcat((char *)storeName,(char *)tempSelName);
  217. PLstrcat((char *)storeName,"\p”");
  218.  
  219. SetCTitle((ControlHandle)iHndl,storeName);
  220.  
  221. SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
  222.  
  223. HiliteControl((ControlHandle)iHndl, hilited ? 0 : 255);
  224. }
  225.  
  226.  
  227. Boolean SameFile(FSSpec *file1,FSSpec *file2)
  228. {
  229. return ((file1->vRefNum == file2->vRefNum) &&
  230.         (file1->parID == file2->parID) &&
  231.         (EqualString(file1->name,file2->name,false,true)));
  232. }
  233.  
  234.  
  235. OSErr GetDeskFolderSpec(FSSpec *fSpec,short vRefNum)
  236. {
  237. register OSErr err;
  238.  
  239. if (!gHasFindFolder) {
  240.     fSpec->vRefNum = -9999;
  241.     return -1;
  242.     }
  243.  
  244. fSpec->name[0] = '\0';
  245. err = FindFolder(vRefNum,kDesktopFolderType,kDontCreateFolder,
  246.                     &fSpec->vRefNum,&fSpec->parID);
  247. if (err == noErr)
  248.     err = MakeCanonFSSpec(fSpec);
  249.  
  250. return err;
  251. }
  252.  
  253.  
  254. Boolean ShouldHiliteSelect(FSSpec *fSpec)
  255. {
  256. StringHandle    strHndl;
  257.  
  258. if (SameFile(fSpec,&gDeskFolderSpec)) {
  259.     strHndl = GetString(kDeskStrRsrc);
  260.     (void) PLstrcpy(fSpec->name, *strHndl);
  261.     return kCanSelectDesktop;
  262.     }
  263. else
  264.     return true;
  265. }
  266.  
  267.  
  268. OSErr MakeCanonFSSpec(FSSpec *fSpec)
  269. {
  270. DirInfo infoPB;
  271. OSErr err;
  272.  
  273. if (fSpec->name[0] != '\0')
  274.     return noErr; /* controllare */
  275.     
  276. infoPB.ioNamePtr = fSpec->name;
  277. infoPB.ioVRefNum = fSpec->vRefNum;
  278. infoPB.ioDrDirID = fSpec->parID;
  279. infoPB.ioFDirIndex = -1;
  280. err = PBGetCatInfo((CInfoPBPtr)&infoPB,false);
  281. fSpec->parID = infoPB.ioDrParID;
  282.  
  283. return err;
  284. }
  285.  
  286.