home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Ph 1.1.1 / Lib / scn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  18.7 KB  |  632 lines  |  [TEXT/MPS ]

  1. /*______________________________________________________________________
  2.  
  3.     scn.c - Volume Scanning Module.
  4.     
  5.     Copyright © 1988-1991 Northwestern University.
  6.     
  7.     This reusable module implements volume scanning.
  8.     
  9.     The caller supplies a pointer to a function to be called for each file
  10.     and folder on the volume.  In addition, the caller may supply three 
  11.     optional rectangles which are updated as the scan progresses, for the 
  12.     folder name currently being scanned, the file name currently being scanned, 
  13.     and a thermometer.
  14.     
  15.     The module handles both HFS and MFS volumes.
  16.     
  17.     The caller may also specify that only a single folder or file be 
  18.     scanned.
  19.     
  20.     See TN 68 for details on the scan algorithm.  The algorithm has been
  21.     modified to improve its behaviour when other users or tasks are creating
  22.     or deleting files or folders while the scan is in progress.  This is
  23.     especially important on server volume scans.
  24.     
  25.     All of the code is placed in its own segment named "scn".
  26. _____________________________________________________________________*/
  27.  
  28. #pragma load "precompile"
  29. #include "scn.h"
  30. #include "utl.h"
  31.  
  32. #pragma segment scn
  33.  
  34. /*______________________________________________________________________
  35.  
  36.     Global Variables.
  37. _____________________________________________________________________*/
  38.  
  39. /* Global variables are used instead of local variables to minimize the size
  40.     of the stack frames for recursive calls to the ScanCat routine.
  41.     See TN 68. */
  42.  
  43. static scn_DoFilePtr    DoFile;                /* ptr to func to be called to process
  44.                                                         each file */
  45. static scn_CheckCancelPtr        CheckCancel;
  46.                                                     /* ptr to func to be called to check 
  47.                                                         for cancel of scan */
  48. static long                RefCon;                /* value passed through to DoFile */
  49. static Rect                *FoldNameRect;        /* folder name rectangle, or nil */
  50. static Rect                *FileNameRect;        /* file name rectangle, or nil */
  51. static Rect                *ThermRect;            /* thermometer rectangle, or nil */
  52. static Boolean            MFS;                    /* true if mfs volume */
  53. static CInfoPBRec        PBlock;                /* PBGetCatInfo param block for hfs
  54.                                                         scanning. */
  55. static ParamBlockRec    MFSPBlock;            /* PBGetFInfo param block for mfs
  56.                                                         scanning */
  57. static Str255            FName;                /* current folder or file name */
  58. static Str255            OldFName;            /* old folder or file name */
  59. static long                TotFiles;            /* total num files on vol */
  60. static long                NumFiles;            /* num files scanned so far */
  61. static Rect                GrayRect;            /* therm subrect to be filled */
  62. static Boolean            Canceled;            /* true if scan canceled */
  63. static short            NameFont;            /* font num for fold and file names */
  64. static short            NameSize;            /* font size for fold and file names */
  65. static short            FontNum;                /* window's font number */
  66. static short            FontSize;            /* window's font size */
  67. static scn_FListElHandle    FolderList;    /* handle to head of folder list */
  68. static scn_FListElHandle    NextFolder;    /* handle to next el of folder list */
  69. static Boolean            DoingScan = false;    /* true while scan in progress */
  70. static short            OldIndex;            /* index in directory of file */
  71.  
  72. /*______________________________________________________________________
  73.  
  74.     DrawName - Draw File or Folder Name.
  75.     
  76.     Entry:    drawRect = pointer to rectangle in which the name should
  77.                     be drawn, or nil if none.
  78.                 fName = pointer to file or folder name.
  79. _____________________________________________________________________*/
  80.  
  81. static void DrawName (Rect *drawRect, Str255 fName)
  82.  
  83. {
  84.     Rect            rect;            /* rectangle to be erased */
  85.     short            nameWidth;    /* width of name */
  86.     
  87.     if (drawRect) {
  88.         TextFont(NameFont); TextSize(NameSize);
  89.         rect = *drawRect;
  90.         nameWidth = StringWidth(fName);
  91.         TextBox(fName+1, *fName, drawRect, teJustLeft);
  92.         if (nameWidth < (rect.right-rect.left)) {
  93.             rect.left += nameWidth;
  94.             EraseRect(&rect);
  95.         }
  96.         TextFont(FontNum); TextSize(FontSize);
  97.     }
  98. }
  99.  
  100. /*______________________________________________________________________
  101.  
  102.     DrawTherm - Update Thermometer.
  103. _____________________________________________________________________*/
  104.  
  105. static void DrawTherm (void)
  106.  
  107. {
  108.     short            newRight;            /* new right coord of therm rect */
  109.     
  110.     if (ThermRect) {
  111.         NumFiles++;
  112.         newRight = ThermRect->left + NumFiles * 
  113.             (ThermRect->right - ThermRect->left - 1) / TotFiles;
  114.         if (newRight > ThermRect->right) newRight = ThermRect->right;
  115.         if (newRight > GrayRect.right) {
  116.             GrayRect.left = GrayRect.right-1;
  117.             GrayRect.right = newRight;
  118.             FillRect(&GrayRect, qd.gray);
  119.         }
  120.     }
  121. }
  122.  
  123. /*______________________________________________________________________
  124.  
  125.     ScanMFSVol - Scan MFS Volume.
  126. _____________________________________________________________________*/
  127.  
  128. static void ScanMFSVol (void)
  129.  
  130. {
  131.     short            index;                /* cur index in volume */
  132.     
  133.     index = 1;
  134.     
  135.     while (true) {
  136.     
  137.         MFSPBlock.fileParam.ioFDirIndex = index;
  138.         if (PBGetFInfo(&MFSPBlock, false)) break;
  139.             
  140.         /*  Update the file name rectangle. */
  141.     
  142.         DrawName(FileNameRect, FName);
  143.         
  144.         /* Update the thermometer. */
  145.         
  146.         DrawTherm();
  147.         
  148.         /* Copy fields from MFSPBlock to PBlock. */
  149.         
  150.         PBlock.hFileInfo.ioFRefNum = MFSPBlock.fileParam.ioFRefNum;
  151.         PBlock.hFileInfo.ioFlAttrib = MFSPBlock.fileParam.ioFlAttrib;
  152.         PBlock.hFileInfo.ioFlFndrInfo = MFSPBlock.fileParam.ioFlFndrInfo;
  153.         PBlock.hFileInfo.ioFlCrDat = MFSPBlock.fileParam.ioFlCrDat;
  154.         PBlock.hFileInfo.ioFlMdDat = MFSPBlock.fileParam.ioFlMdDat;
  155.         /* PBlock.hFileInfo.ioACUser = 0; */
  156.         *(&PBlock.hFileInfo.ioFlAttrib+1) = 0;
  157.                     
  158.         /* Call the user-specified function. */
  159.         
  160.         if (DoFile) {
  161.             if (Canceled = 
  162.                 (*DoFile)(&PBlock, FolderList, RefCon, true)) return;
  163.         }
  164.         
  165.         /* Check for user cancel. */
  166.         
  167.         if (CheckCancel)
  168.             if (Canceled = (*CheckCancel)()) return;
  169.         
  170.         /* The following code deals with the problem of other users or
  171.             tasks creating or deleting files while we are scanning, and also
  172.             the case where the DoFile routine deleted the file. */
  173.             
  174.         utl_CopyPString(OldFName, FName);
  175.         MFSPBlock.fileParam.ioFDirIndex = index;
  176.         if (!PBGetFInfo(&MFSPBlock, false)) {
  177.             if (EqualString(OldFName, FName, true, true)) {
  178.                 index++;
  179.                 continue;
  180.             }
  181.         }
  182.         OldIndex = index;
  183.         index = 1;
  184.         while (true) {
  185.             MFSPBlock.fileParam.ioFDirIndex = index;
  186.             if (PBGetFInfo(&MFSPBlock, false)) {
  187.                 index = OldIndex;
  188.                 break;
  189.             }
  190.             if (EqualString(OldFName, FName, true, true)) {
  191.                     index++;
  192.                     break;
  193.             }
  194.             index++;
  195.         }
  196.                 
  197.     }
  198.             
  199. }
  200.  
  201. /*______________________________________________________________________
  202.  
  203.     ScanCat - Scan Catalog.
  204.     
  205.     Entry:    dirID = directory id of catalog to scan.
  206. _____________________________________________________________________*/
  207.  
  208. static void ScanCat (long dirID)
  209.  
  210. {
  211.     short            index;            /* cur index in directory */
  212.     
  213.     index = 1;
  214.     
  215.     while (true) {
  216.     
  217.         PBlock.hFileInfo.ioFDirIndex = index;
  218.         PBlock.hFileInfo.ioDirID = dirID;
  219.         /* PBlock.hFileInfo.ioACUser = 0; */
  220.         *(&PBlock.hFileInfo.ioFlAttrib+1) = 0;
  221.         if (PBGetCatInfo(&PBlock, false)) break;
  222.         if ((PBlock.hFileInfo.ioFlAttrib >> 4) & 1) {
  223.         
  224.             /* Folder.  Update the file and folder name rectangles. */
  225.         
  226.             if (FileNameRect) EraseRect(FileNameRect);
  227.             DrawName(FoldNameRect, FName);
  228.             
  229.             /* Call the user-specified function. */
  230.             
  231.             if (DoFile) {
  232.                 if (Canceled = 
  233.                     (*DoFile)(&PBlock, FolderList, RefCon, false)) return;
  234.             }
  235.     
  236.             /* Check for user cancel. */
  237.             
  238.             if (CheckCancel)
  239.                 if (Canceled = (*CheckCancel)()) return;
  240.                 
  241.             /* Push the folder name onto the folder list. */
  242.             
  243.             NextFolder =  (scn_FListElHandle) NewHandle(sizeof(scn_FListEl));
  244.             (**NextFolder).next = FolderList;
  245.             utl_CopyPString((**NextFolder).name, FName);
  246.             /* (**NextFolder).accessRights = PBlock.hFileInfo.ioACUser; */
  247.             (**NextFolder).accessRights = *(&PBlock.hFileInfo.ioFlAttrib+1);
  248.             FolderList = NextFolder;
  249.             
  250.             /* Call ourselves recursively to scan the new folder. */
  251.             
  252.             ScanCat(PBlock.hFileInfo.ioDirID);
  253.             if (Canceled) return;
  254.             
  255.             /* Pop the folder name from the folder list. */
  256.             
  257.             utl_CopyPString(FName, (**FolderList).name);
  258.             NextFolder = (**FolderList).next;
  259.             DisposHandle((Handle)FolderList);
  260.             FolderList = NextFolder;
  261.             
  262.             /* Update the file and folder name rectangles. */
  263.             
  264.             if (FileNameRect) EraseRect(FileNameRect);
  265.             HLock((Handle)FolderList);
  266.             DrawName(FoldNameRect, (**FolderList).name);
  267.             HUnlock((Handle)FolderList);
  268.             
  269.         } else {
  270.         
  271.             /* File. Update the file name rectangle. */
  272.         
  273.             DrawName(FileNameRect, FName);
  274.             
  275.             /* Update the thermometer. */
  276.             
  277.             DrawTherm();
  278.             
  279.             /* Call the user-specified function. */
  280.             
  281.             if (DoFile) {
  282.                 if (Canceled = 
  283.                     (*DoFile)(&PBlock, FolderList, RefCon, false)) return;
  284.             }
  285.     
  286.             /* Check for user cancel. */
  287.             
  288.             if (CheckCancel)
  289.                 if (Canceled = (*CheckCancel)()) return;
  290.                 
  291.         }
  292.         
  293.         /* The following code deals with the problem of other users or
  294.             tasks creating or deleting files or folders while we are scanning.
  295.             This activity can invalidate our index in the current directory.
  296.             This problem is especially serious when scanning servers. The code
  297.             also covers the case where the DoFile routine deleted the file or
  298.             folder.
  299.             
  300.             The basic idea is to recall PBGetCatInfo to see if our position
  301.             in the directory has changed.  If it has changed we search the
  302.             directory to attempt to locate the new location. */
  303.         
  304.         utl_CopyPString(OldFName, FName);        /* save name of file or folder */
  305.         PBlock.hFileInfo.ioDirID = dirID;
  306.         PBlock.hFileInfo.ioFDirIndex = index;
  307.         if (!PBGetCatInfo(&PBlock, false)) {
  308.             if (EqualString(OldFName, FName, true, true)) {
  309.                 index++;
  310.                 continue;
  311.             }
  312.         }
  313.         OldIndex = index;
  314.         index = 1;
  315.         while (true) {
  316.             PBlock.hFileInfo.ioDirID = dirID;
  317.             PBlock.hFileInfo.ioFDirIndex = index;
  318.             if (PBGetCatInfo(&PBlock, false)) {
  319.                 index = OldIndex;
  320.                 break;
  321.             }
  322.             if (EqualString(OldFName, FName, true, true)) {
  323.                 index++;
  324.                 break;
  325.             }
  326.             index++;
  327.         }
  328.     }
  329. }
  330.  
  331. /*______________________________________________________________________
  332.  
  333.     scn_Scan - Scan Volume, Folder, or File.
  334.     
  335.     Entry:    fSpec = pointer to spec of file, folder, or volume to scan.
  336.                 kind = scan kind (scn_Volume, scn_Folder, or scn_File).
  337.                 doFile = pointer to function to be called for each file and
  338.                     folder, or nil if none.
  339.                 refCon = a longword passed through to doFile on each call.
  340.                 checkCancel = pointer to function to be called to check for
  341.                     a cancel of the scan in progress, or nil if none.
  342.                 foldNameRect = pointer to folder name rectangle, or nil if none.
  343.                 fileNameRect = pointer to file name rectangle, or nil if none.
  344.                 thermRect = pointer to thermometer rectangle, or nil if none.
  345.                 nameFont = font number for folder and file names.
  346.                 nameSize = font size for folder and file names.
  347.                 
  348.     Exit:        function result = true if scan was canceled.
  349.     
  350.     Don't forget to do a SetPort to the window before calling this routine.
  351.  
  352.     The CheckCancel routine is declared as follows:
  353.     
  354.     Boolean CheckCancel(void)
  355.     
  356.     The function should return true if the scan should be canceled, 
  357.     or false to continue the scan.  It's called once for every directory and 
  358.     file encountered in the scan.  
  359.  
  360.     The DoFile routine is declared as follows:
  361.     
  362.     Boolean DoFile (CInfoPBRec *pBlock, scn_FListElHandle folderList, 
  363.         long refCon, Boolean mfs)
  364.     
  365.     This function, like CheckCancel, is called once for every directory 
  366.     and file encountered in the scan.    
  367.     
  368.     pBlock points to a PBGetCatInfo parameter block containing all sorts
  369.     of useful information about the file or folder.  See IM IV-125 and 155
  370.     for details.
  371.     
  372.     folderList is a handle to a linked list of all the folder names in 
  373.     the current path, in reverse order (lowest-level folder name to highest-level 
  374.     folder name).  The list is maintained as a push-down stack:  When a new folder 
  375.     is encountered it is added to the head of the list, and it is removed when the 
  376.     scan of that folder is complete.
  377.     
  378.     The first (lowest-level) folder name in the list is the name of the folder
  379.     that contains the current file or folder.
  380.     
  381.     The last (highest-level) folder name in the list depends on the type of scan:
  382.     a) Volume scans:  The root folder (volume name).
  383.     b) Folder scans:  The folder being scanned.
  384.     c) File scans: The folder containing the file being scanned.
  385.     
  386.     The folder list is terminated by a dummy element containing an empty name.
  387.     
  388.     Example: Suppose you are doing a volume scan of a volume named "MyVol",
  389.     and the current file being scanned is named "MyFile".  "MyFile" is located
  390.     inside folder "Folder1", which in turn is located inside folder "Folder2",
  391.     which is not located inside any other folders.  When your DoFile routine
  392.     is called for file "MyFile" the folder list contains four elements in the 
  393.     following order:  "Folder1", "Folder2", "MyVol", "".
  394.         
  395.     refCon is the longword parameter passed by the caller to the scn_Scan
  396.     function.
  397.     
  398.     mfs is true if the volume is in mfs format.  In this case only the
  399.     following fields in the parameter block are filled in:
  400.     
  401.         ioNamePtr        pointer to file name.
  402.         ioVRefNum        volume reference number.
  403.         ioFRefNum        path reference number.
  404.         ioFlAttrib        file attributes.
  405.         ioFlFndrInfo    finder info.
  406.         ioACUser            access rights = 0 (all rights).
  407.         ioFlCrDat        creation date/time.
  408.         ioFlMdDat        last mod date/time.
  409.         
  410.     For HFS volumes the parameter block fields are left as set by the call
  411.     to PBGetCatInfo.
  412.     
  413.     The function should return true if the scan should be canceled, 
  414.     or false to continue the scan.
  415.     
  416.     The function may delete the file or folder.
  417. _____________________________________________________________________*/
  418.  
  419. Boolean scn_Scan (FSSpec *fSpec, scn_Kind kind, 
  420.     scn_DoFilePtr doFile, long refCon, scn_CheckCancelPtr checkCancel, 
  421.     Rect *fldNameRect, Rect *fleNameRect, Rect *thrmRect, 
  422.     short nameFont, short nameSize)
  423.  
  424. {
  425.     CInfoPBRec            dBlock;                /* dir info param block */
  426.     scn_FListElHandle    newEl;                /* handle to new folder list el */
  427.     Str255                dirName;                /* directory name */
  428.     char                    accessRights;        /* directory access rights */
  429.     
  430.     /* Copy params to global variables. */
  431.     
  432.     DoFile = doFile;
  433.     RefCon = refCon;
  434.     CheckCancel = checkCancel;
  435.     FoldNameRect = fldNameRect;
  436.     FileNameRect = fleNameRect;
  437.     ThermRect = thrmRect;
  438.     NameFont = nameFont;
  439.     NameSize = nameSize;
  440.     
  441.     /* Save the current window's font number and size in global variables. */
  442.     
  443.     FontNum = qd.thePort->txFont;
  444.     FontSize = qd.thePort->txSize;
  445.     
  446.     /* Initialize thermometer.  Disable the thermometer if the number
  447.         of files on the volume is 0, to prevent divide by 0 errors.  Also
  448.         disable it on folder and file scans. */
  449.     
  450.     if (ThermRect) {
  451.         if (kind != scn_Volume) {
  452.             EraseRect(ThermRect);
  453.             ThermRect = nil;
  454.         } else {
  455.             if (TotFiles = utl_GetVolFilCnt(fSpec->vRefNum)) {
  456.                 NumFiles = 0;
  457.                 GrayRect = *ThermRect;
  458.                 InsetRect(&GrayRect, 1, 1);
  459.                 GrayRect.right = GrayRect.left + 1;
  460.             } else {
  461.                 EraseRect(ThermRect);
  462.                 ThermRect = nil;
  463.             }
  464.         }
  465.     }
  466.     
  467.     /* Determine whether the volume is HFS or MFS. */
  468.     
  469.     MFS = utl_VolIsMFS(fSpec->vRefNum);
  470.     
  471.     /* Initialize folder list */
  472.     
  473.     FolderList = (scn_FListElHandle) NewHandle(sizeof(scn_FListEl));
  474.     (**FolderList).next = nil;
  475.     *(**FolderList).name = 0;
  476.     newEl = (scn_FListElHandle)NewHandle(sizeof(scn_FListEl));
  477.     (**newEl).next = FolderList;
  478.     FolderList = newEl;
  479.     if (MFS) {
  480.         utl_CopyPString(dirName, fSpec->name);
  481.         accessRights = 0;
  482.     } else {
  483.         dBlock.dirInfo.ioVRefNum = fSpec->vRefNum;
  484.         /* dBlock.dirInfo.ioACUser = 0; */
  485.         *(&dBlock.dirInfo.ioFlAttrib+1) = 0;
  486.         if (kind == scn_File) {
  487.             dBlock.dirInfo.ioNamePtr = dirName;
  488.             dBlock.dirInfo.ioFDirIndex = -1;
  489.             dBlock.dirInfo.ioDrDirID = fSpec->parID;
  490.         } else {
  491.             utl_CopyPString(dirName, fSpec->name);
  492.             dBlock.dirInfo.ioNamePtr = fSpec->name;
  493.             dBlock.dirInfo.ioFDirIndex = 0;
  494.             dBlock.dirInfo.ioDrDirID = fSpec->parID;
  495.         }
  496.         PBGetCatInfo(&dBlock, false);
  497.         /* accessRights = dBlock.dirInfo.ioACUser; */
  498.         accessRights = *(&dBlock.dirInfo.ioFlAttrib+1);
  499.     }
  500.     utl_CopyPString((**FolderList).name, dirName);
  501.     (**FolderList).accessRights = accessRights;
  502.     
  503.     /* Draw the folder name. */
  504.     
  505.     if (FoldNameRect) {
  506.         DrawName(FoldNameRect, dirName);
  507.     }
  508.     
  509.     /* Erase the file name rectangle. */
  510.     
  511.     if (FileNameRect) EraseRect(FileNameRect);
  512.     
  513.     /* Do the scan. */
  514.     
  515.     Canceled = false;
  516.     DoingScan = true;
  517.     
  518.     if (kind == scn_File) {
  519.         
  520.         /* File scan. */
  521.         
  522.         utl_CopyPString(FName, fSpec->name);
  523.         DrawName(FileNameRect, FName);
  524.         PBlock.hFileInfo.ioNamePtr = FName;
  525.         PBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
  526.         if (MFS) {
  527.             MFSPBlock.fileParam.ioNamePtr = FName;
  528.             MFSPBlock.fileParam.ioVRefNum = fSpec->vRefNum;
  529.             MFSPBlock.fileParam.ioFVersNum = 0;
  530.             MFSPBlock.fileParam.ioFDirIndex = 0;
  531.             (void) PBGetFInfo(&MFSPBlock, false);
  532.             PBlock.hFileInfo.ioFRefNum = MFSPBlock.fileParam.ioFRefNum;
  533.             PBlock.hFileInfo.ioFlAttrib = MFSPBlock.fileParam.ioFlAttrib;
  534.             PBlock.hFileInfo.ioFlFndrInfo = MFSPBlock.fileParam.ioFlFndrInfo;
  535.             PBlock.hFileInfo.ioFlCrDat = MFSPBlock.fileParam.ioFlCrDat;
  536.             PBlock.hFileInfo.ioFlMdDat = MFSPBlock.fileParam.ioFlMdDat;
  537.             if (DoFile) Canceled = 
  538.                 (*DoFile)(&PBlock, FolderList, RefCon, true);
  539.         } else {
  540.             PBlock.hFileInfo.ioFDirIndex = 0;
  541.             PBlock.hFileInfo.ioDirID = fSpec->parID;
  542.             (void) PBGetCatInfo(&PBlock, false);
  543.             if (DoFile) Canceled =
  544.                 (*DoFile)(&PBlock, FolderList, RefCon, false);
  545.         }
  546.         
  547.     } else {
  548.     
  549.         /* Folder or volume scan. 
  550.             Initialize param block. */
  551.     
  552.         if (MFS) {
  553.             MFSPBlock.fileParam.ioNamePtr = FName;
  554.             MFSPBlock.fileParam.ioVRefNum = fSpec->vRefNum;
  555.             MFSPBlock.fileParam.ioFVersNum = 0;
  556.         }
  557.         PBlock.hFileInfo.ioNamePtr = FName;
  558.         PBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
  559.         
  560.         /*    Scan the directory. */
  561.         
  562.         if (MFS) {
  563.             ScanMFSVol();
  564.         } else {
  565.             ScanCat(dBlock.dirInfo.ioDrDirID);
  566.         }
  567.     }
  568.     
  569.     DoingScan = false;
  570.     
  571.     /* Clear the thermometer and folder and file names. */
  572.     
  573.     if (ThermRect) {
  574.         GrayRect = *ThermRect;
  575.         InsetRect(&GrayRect, 1, 1);
  576.         EraseRect(&GrayRect);
  577.     }
  578.     if (FoldNameRect) EraseRect(FoldNameRect);
  579.     if (FileNameRect) EraseRect(FileNameRect);
  580.     
  581.     /* Dispose of the folder list. */
  582.     
  583.     while (FolderList) {
  584.         NextFolder = (**FolderList).next;
  585.         DisposHandle((Handle)FolderList);
  586.         FolderList = NextFolder;
  587.     }
  588.     
  589.     return Canceled;
  590. }
  591.  
  592. /*______________________________________________________________________
  593.  
  594.     scn_Update - Process an Update Event.
  595.     
  596.     Entry:        thermRect = pointer to thermometer rectangle, or nil if none.
  597.     
  598.     This routine should be called whenever an update event occurs.
  599.     It redraws the volume, folder and file names and the thermometer if a 
  600.     scan is in progress.
  601. _____________________________________________________________________*/
  602.  
  603. void scn_Update (Rect *thrmRect)
  604.  
  605. {
  606.     Rect            grayRect;        /* part of therm rect to be filled with
  607.                                             gray */
  608.  
  609.     if (!DoingScan) {
  610.         if (thrmRect) FrameRect(thrmRect);
  611.     } else {
  612.         if (ThermRect) {
  613.             FrameRect(ThermRect);
  614.             grayRect = GrayRect;
  615.             grayRect.left = ThermRect->left + 1;
  616.             FillRect(&grayRect, qd.gray);
  617.         }
  618.         if (FoldNameRect) {
  619.             EraseRect(FoldNameRect);
  620.             if (((PBlock.hFileInfo.ioFlAttrib >> 4) & 1) == 1) {
  621.                 DrawName(FoldNameRect, FName);
  622.             } else {
  623.                 MoveHHi((Handle)FolderList);
  624.                 HLock((Handle)FolderList);
  625.                 DrawName(FoldNameRect, (**FolderList).name);
  626.                 HUnlock((Handle)FolderList);
  627.             }
  628.         }
  629.         if (FileNameRect) EraseRect(FileNameRect);
  630.         DrawName(FileNameRect, FName);
  631.     }
  632. }