home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Ph 1.1.1 / Lib / sfu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-29  |  11.2 KB  |  370 lines  |  [TEXT/MPS ]

  1. /*______________________________________________________________________
  2.  
  3.     sfu.c - Standard File Utilities.
  4.     
  5.     Copyright © 1988-1991 Northwestern University.
  6.     
  7.     This module exports reusable standard file utility routines.
  8.     
  9.     The primary purpose of this module is to permit the use of the new
  10.     System 7 standard file routines, even on pre-System 7 sytems.
  11.     
  12.     This reusable module presents a modified standard open file dialog.
  13.     There are two extra buttons which can be used to pick a folder instead
  14.     of a file.  
  15. _____________________________________________________________________*/
  16.  
  17. #pragma load "precompile"
  18. #include "sfu.h"
  19. #include "utl.h"
  20.  
  21. #pragma segment sfu
  22.  
  23. /*______________________________________________________________________
  24.  
  25.     Constant Definitions.
  26. _____________________________________________________________________*/
  27.  
  28. #define sfItemMyPromptTest7        10        /* item number of 7.0 prompt string
  29.                                                         static text field */
  30. #define sfItemMyDoitButton7        11        /* item number of 7.0 "Doit" button */
  31.  
  32. #define sfItemMyPromptTest6        10        /* item number of pre-7.0 prompt string
  33.                                                         static text field */
  34. #define sfItemMyDoitButton6        11        /* item number of pre-7.0 "Doit" button */
  35.  
  36. /*______________________________________________________________________
  37.  
  38.     Global Variables.
  39. _____________________________________________________________________*/
  40.  
  41. static short                    Item;                    /* item number of selected item */
  42. static Str255                    DoitButtonName;    /* name of "Doit" button */
  43.  
  44. /* The following globals are used only on 7.0 systems. */
  45.  
  46. static StandardFileReply    *Reply7;                /* pointer to reply record *.
  47.  
  48. /* The following globals are used only on pre-7.0 systems. */
  49.  
  50. static FileFilterYDProcPtr    FileFilter;            /* pointer to file filter proc */
  51. static void                        *YourDataPtr;        /* pointer to application data */
  52. static SFReply                    Reply6;                /* pre-7.0 reply record */
  53.  
  54. /*______________________________________________________________________
  55.  
  56.     sfu_StandardGetFile - Standard Get File Dialog.
  57.     
  58.     Entry:    fileFilter = pointer to file filter function, or nil if none.
  59.                 numTypes = number of file types in typeList, or -1 if none.
  60.                 typeList = file type list, or nil if none.
  61.                 reply = pointer to reply record.
  62.                                 
  63.     Exit:        reply record completed. Only the following fields are valid:
  64.                 sfGood and sfFile.
  65. _____________________________________________________________________*/
  66.  
  67. void sfu_StandardGetFile (FileFilterProcPtr fileFilter, short numTypes,
  68.     SFTypeList typeList, StandardFileReply *reply)
  69.     
  70. {
  71.     SFReply            reply6;        /* System 6 reply */
  72.     Handle            h;                /* handle to System 6 dialog */
  73.     Point                where;        /* location of centered System 6 dialog */
  74.  
  75.     if (utl_GestaltFlag(gestaltStandardFileAttr, gestaltStandardFile58)) {
  76.     
  77.         /* System 7. */
  78.         
  79.         StandardGetFile(fileFilter, numTypes, typeList, reply);
  80.         
  81.     } else {
  82.         
  83.         /* Pre-System 7. */
  84.         
  85.         h = GetResource('DLOG', getDlgID);
  86.         utl_CenterDlogRect(*(Rect**)h, true);
  87.         where = **(Point**)h;
  88.         SFGetFile(where, "\p", fileFilter, numTypes, typeList, nil, &reply6);
  89.         if (!(reply->sfGood = reply6.good)) return;
  90.         reply->sfFile.vRefNum = -*(short*)SFSaveDisk;
  91.         reply->sfFile.parID = *(long*)CurDirStore;
  92.         utl_CopyPString(reply->sfFile.name, reply6.fName);
  93.         
  94.     }
  95. }
  96.  
  97. /*______________________________________________________________________
  98.  
  99.     sfu_StandardPutFile - Standard Put File Dialog.
  100.     
  101.     Entry:    prompt = prompt string.
  102.                 defaultName = default file name.
  103.                 reply = pointer to reply record.
  104.                                 
  105.     Exit:        reply record completed. Only the following fields are valid:
  106.                 sfGood and sfFile.
  107. _____________________________________________________________________*/
  108.  
  109. void sfu_StandardPutFile (Str255 prompt, Str255 defaultName,
  110.     StandardFileReply *reply)
  111.     
  112. {
  113.     SFReply            reply6;        /* System 6 reply */
  114.     Handle            h;                /* handle to System 6 dialog */
  115.     Point                where;        /* location of centered System 6 dialog */
  116.  
  117.     if (utl_GestaltFlag(gestaltStandardFileAttr, gestaltStandardFile58)) {
  118.     
  119.         /* System 7. */
  120.         
  121.         StandardPutFile(prompt, defaultName, reply);
  122.         
  123.     } else {
  124.         
  125.         /* Pre-System 7. */
  126.         
  127.         h = GetResource('DLOG', putDlgID);
  128.         utl_CenterDlogRect(*(Rect**)h, true);
  129.         where = **(Point**)h;
  130.         SFPutFile(where, prompt, defaultName, nil, &reply6);
  131.         if (!(reply->sfGood = reply6.good)) return;
  132.         reply->sfFile.vRefNum = -*(short*)SFSaveDisk;
  133.         reply->sfFile.parID = *(long*)CurDirStore;
  134.         utl_CopyPString(reply->sfFile.name, reply6.fName);
  135.         
  136.     }
  137. }
  138.  
  139. /*______________________________________________________________________
  140.  
  141.     FileFilter6 - Pre-7.0 File Filter Proc.
  142.     
  143.     Entry:    pBlock = pointer to file info param block.
  144. _____________________________________________________________________*/
  145.  
  146. static pascal Boolean FileFilter6 (ParmBlkPtr pBlock)
  147.  
  148. {
  149.     return (*FileFilter)(pBlock, YourDataPtr);
  150. }
  151.  
  152. /*______________________________________________________________________
  153.  
  154.     MyHook7 - 7.0 CustomGetFile Dialog Hook.
  155.     
  156.     Entry:    item = item number of selected item.
  157.                 theDialog = pointer to dialog.
  158.                 yourDataPtr = pointer to application data (unused).
  159.                 
  160.     Exit:        function result = item number of selected item.
  161. _____________________________________________________________________*/
  162.  
  163. static pascal short MyHook7 (short item, DialogPtr theDialog, void *yourDataPtr)
  164.  
  165. {
  166. #pragma unused (yourDataPtr)
  167.  
  168.     short                    itemType;            /* item type */
  169.     ControlHandle        doit;                    /* handle to doit button */
  170.     ControlHandle        open;                    /* handle to open button */
  171.     Rect                    box;                    /* item rect */
  172.     
  173.     /* The following line of code fixes a mysterious problem in CustomGetFile.
  174.         This problem showed up when I tried to do an option-Scan and select
  175.         one of my Disinfectant test files (the Red Ryder 10.0 Scores-infected
  176.         acid test). This file has two CODE id=35 resources, but is otherwise
  177.         normal.
  178.         
  179.         Without the following line of code, CustomGetFile bombed!
  180.         
  181.         The line of code makes a click on the Open button (or an equivalent
  182.         press of the Return or Enter key) when a file is
  183.         selected be treated the same as a click on the "Doit" button. I have
  184.         no idea why this works and fixes the problem, but it does. */
  185.     
  186.     if (item == sfItemOpenButton) item = sfItemMyDoitButton7;
  187.  
  188.     if (item != sfHookLastCall) Item = item;
  189.     GetDItem(theDialog, sfItemMyDoitButton7, &itemType, (Handle*)&doit, &box);
  190.     GetDItem(theDialog, sfItemOpenButton, &itemType, (Handle*)&open, &box);
  191.     
  192.     /* Set name of "Doit" button if first call. */
  193.     
  194.     if (item == sfHookFirstCall) SetCTitle(doit, DoitButtonName);
  195.     
  196.     /* Hilite the "Doit" button iff the Open button is hilited. */
  197.     
  198.     HiliteControl(doit, (**open).contrlHilite); 
  199.     
  200.     /* If the "Doit" button was selected, pretend the Cancel button was 
  201.         selected to force CustomGetFile to return. */
  202.     
  203.     if (item == sfItemMyDoitButton7) return sfItemCancelButton;
  204.     
  205.     /* For all other items do nothing. */
  206.     
  207.     return item;
  208. }
  209.  
  210. /*______________________________________________________________________
  211.  
  212.     MyHook6 - Pre-7.0 SFPGetFile Dialog Hook.
  213.     
  214.     Entry:    item = item number of selected item.
  215.                 theDialog = pointer to dialog.
  216.                 
  217.     Exit:        function result = item number of selected item.
  218. _____________________________________________________________________*/
  219.  
  220. static pascal short MyHook6 (short item, DialogPtr theDialog)
  221.  
  222. {
  223.     short                    itemType;            /* item type */
  224.     ControlHandle        doit;                    /* handle to doit button */
  225.     ControlHandle        open;                    /* handle to open button */
  226.     Rect                    box;                    /* item rect */
  227.     
  228.     Item = item;
  229.     GetDItem(theDialog, sfItemMyDoitButton6, &itemType, (Handle*)&doit, &box);
  230.     GetDItem(theDialog, getOpen, &itemType, (Handle*)&open, &box);
  231.     
  232.     /* Set name of "Doit" button if first call. */
  233.     
  234.     if (item == sfHookFirstCall) SetCTitle(doit, DoitButtonName);
  235.     
  236.     /* Hilite the "Doit" button iff the Open button is hilited. */
  237.     
  238.     HiliteControl(doit, (**open).contrlHilite); 
  239.     
  240.     /* If the "Doit" button was selected, pretend the Cancel button was 
  241.         selected to force SFPGetFile to return. */
  242.     
  243.     if (item == sfItemMyDoitButton6) return getCancel;
  244.     
  245.     /* For all other items do nothing. */
  246.     
  247.     return item;
  248. }
  249.  
  250. /*______________________________________________________________________
  251.  
  252.     sfu_GetFileOrFolder - Get File or Folder.
  253.     
  254.     Entry:    fileFilter = file selection filter procedure.
  255.                 numTypes = number of file types.
  256.                 typeList = array of file types.
  257.                 reply = pointer to standard file package reply record.
  258.                 dlgID6 = pre-7.0 dialog resource id.
  259.                 dlgID7 = 7.0 dialog resource id.
  260.                 where = location of top left corner of dialog, in global coords,
  261.                     or (-1,-1) to center dialog on main screen.
  262.                 yourDataPtr = optional pointer to application data.
  263.                 doitButtonName = name of "Doit" button.
  264.                 prompt = prompt string.
  265.                                 
  266.     Exit:        reply record completed. Only the following fields are valid:
  267.                 sfGood, sfFile, sfIsFolder, and sfIsVolume.
  268. _____________________________________________________________________*/
  269.  
  270. void sfu_GetFileOrFolder (FileFilterYDProcPtr fileFilter, short numTypes,
  271.     SFTypeList typeList, StandardFileReply *reply,
  272.     short dlgID6, short dlgID7, Point where, 
  273.     void *yourDataPtr, Str255 doitButtonName, Str255 prompt)
  274.  
  275. {
  276.     CInfoPBRec        catPBlock;        /* PBGetCatInfo param block */
  277.     Handle            h;                    /* handle to DLOG resource */
  278.     Boolean            isFolderAlias;    /* true if item is folder or vol alias */
  279.     Boolean            isAlias;            /* true if item is alias */
  280.     OSErr                rCode;            /* result code */
  281.     
  282.     utl_CopyPString(DoitButtonName, doitButtonName);
  283.     
  284.     if (utl_GestaltFlag(gestaltStandardFileAttr, gestaltStandardFile58)) {
  285.     
  286.         /* System 7. */
  287.         
  288.         Reply7 = reply;
  289.         ParamText(prompt, nil, nil, nil);
  290.         
  291.         while (true) {
  292.         
  293.             /* Call the standard file package. */
  294.             
  295.             CustomGetFile(fileFilter, numTypes, typeList, reply, dlgID7,
  296.                 where, MyHook7, nil, nil, nil, yourDataPtr);
  297.                 
  298.             /* Return if dialog canceled. */
  299.             
  300.             if (Item == sfItemCancelButton) return;
  301.             reply->sfGood = true;
  302.             
  303.             /* Resolve aliases. */
  304.     
  305.             if (Item == sfItemMyDoitButton7) {
  306.                 rCode = ResolveAliasFile(&reply->sfFile, true, 
  307.                     &isFolderAlias, &isAlias);
  308.                 if (rCode) continue;
  309.                 if (isFolderAlias) reply->sfIsFolder = true;
  310.                 break;
  311.             }
  312.         
  313.         }
  314.     
  315.         /* If a folder was selected check to see if it's really a volume. */
  316.         
  317.         if (reply->sfIsFolder && reply->sfFile.parID == fsRtParID) {
  318.             reply->sfIsFolder = false;
  319.             reply->sfIsVolume = true;
  320.         }
  321.     
  322.     } else {
  323.     
  324.         /* Pre-System 7. */
  325.         
  326.         FileFilter = fileFilter;
  327.         YourDataPtr = yourDataPtr;
  328.         
  329.         /* Center the dialog if requested. */
  330.             
  331.         if (where.h == -1 && where.v == -1) {
  332.             h = GetResource('DLOG', dlgID6);
  333.             utl_CenterDlogRect(*(Rect**)h, true);
  334.             where = **(Point**)h;
  335.         }
  336.         
  337.         /* Call the standard file package. */
  338.         
  339.         SFPGetFile(where, prompt, fileFilter ? FileFilter6 : nil, 
  340.             numTypes, typeList, MyHook6,
  341.             &Reply6, dlgID6, nil);
  342.         
  343.         /* Return if dialog canceled. */
  344.         
  345.         if (Item == getCancel) {
  346.             reply->sfGood = false;
  347.             return;
  348.         }
  349.         
  350.         /* Set reply fields. */
  351.         
  352.         reply->sfGood = true;
  353.         reply->sfIsVolume = false;
  354.         reply->sfFile.vRefNum = -*(short*)SFSaveDisk;
  355.         if (Item == sfItemMyDoitButton6 && !*Reply6.fName) {
  356.             reply->sfIsFolder = true;
  357.             reply->sfFile.parID = *(long*)CurDirStore;
  358.             catPBlock.dirInfo.ioNamePtr = reply->sfFile.name;
  359.             catPBlock.dirInfo.ioVRefNum = reply->sfFile.vRefNum;
  360.             catPBlock.dirInfo.ioFDirIndex = -1;
  361.             catPBlock.dirInfo.ioDrDirID = Reply6.fType;
  362.             PBGetCatInfo(&catPBlock, false);
  363.         } else {
  364.             reply->sfIsFolder = false;
  365.             reply->sfFile.parID = *(long*)CurDirStore;
  366.             utl_CopyPString(reply->sfFile.name, Reply6.fName);
  367.         }
  368.     }
  369. }
  370.