home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / sfmulti.cpt / SFMultiGet / SFMultiGet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-10  |  8.5 KB  |  360 lines

  1. #include <StandardFile.h>
  2. #include <Resources.h>
  3. #include <Memory.h>
  4. #include <Lists.h>
  5. #include <Packages.h>
  6. #include <Files.h>
  7. #include <Controls.h>
  8.  
  9. #define SFSaveDisk     0x214
  10. #define CurDirStore 0x398
  11.     
  12. enum
  13. {
  14.     okButton = 1,
  15.     blank2,
  16.     cancelButton,
  17.     item1,
  18.     ejectButton,
  19.     driveButton,
  20.     sfListBox,
  21.     scrollBar,
  22.     line1,
  23.     blank10,
  24.     filesBox,
  25.     removeButton,
  26.     addButton,
  27.     line,
  28.     myScrollBar,
  29.     kMyDialog = 128
  30. };
  31.  
  32. ListHandle    gTheList;            // list of files selected
  33. SFReply        gTheReply;            // the sf reply
  34. ControlHandle    gTheScrollBar;    // the scrollbar
  35.  
  36. /*
  37.     NOTE: the refCon of the control holds the # of files in the list AND the # of files
  38.     that are visible. The refCon starts out as a negative #; when a file is added, the
  39.     refCon is incremented. When refCon == 1, that means that scrolling must take place.
  40.     When a file is removed, the refCon is decremented by 1. Presumably, when all files
  41.     are removed the refCon == the original value.
  42. */
  43.  
  44. pascal void setItem(DialogPtr theDialog, short item, Handle theProc);
  45. pascal void hiliteItem(DialogPtr theDialog, short item, short hiliteValue);
  46. pascal void getBox(DialogPtr theDialog, short item, Rect *box);
  47. void addData(void);
  48. void removeCells(void);
  49. Boolean selected(void);
  50. pascal void myItem(DialogPtr theDialog, short itemNumber);
  51. pascal void initList(DialogPtr theDialog);
  52. pascal Boolean myFileFilter(CInfoPBPtr pb);
  53. pascal short myDlgHook(short item, DialogPtr theDialog);
  54. pascal Boolean myFilterProc(DialogPtr theDialog, EventRecord *event, short *itemHit);
  55. pascal void cleanup(void);
  56. void processData(void);
  57. void handleScrollBar(DialogPtr, EventRecord*);
  58. pascal void scrollProc(ControlHandle theControl, short theCode);
  59.  
  60. pascal void setItem(DialogPtr theDialog, short item, Handle theProc)
  61. {
  62.     short    itemType;
  63.     Rect    box;
  64.     Handle    theControl;
  65.     
  66.     GetDItem(theDialog, item, &itemType, &theControl, &box);
  67.     SetDItem(theDialog, item, itemType, theProc, &box);
  68. }
  69.     
  70. pascal void hiliteItem(DialogPtr theDialog, short item, short hiliteValue)
  71. {
  72.     short    itemType;
  73.     Rect    box;
  74.     Handle    theControl;
  75.     
  76.     GetDItem(theDialog, item, &itemType, &theControl, &box);
  77.     HiliteControl((ControlHandle) theControl, hiliteValue);
  78. }
  79.  
  80. pascal void getBox(DialogPtr theDialog, short item, Rect *box)
  81. {
  82.     short    itemType;
  83.     Handle    theControl;
  84.     
  85.     GetDItem(theDialog, item, &itemType, &theControl, box);
  86. }
  87.  
  88. /*
  89.     Initializes the list within the sfdialog. Sets the useritem to the
  90.     updateProc.
  91. */
  92.  
  93. pascal void initList(DialogPtr theDialog)
  94. {
  95.     Rect        rView, dataBounds;
  96.     Point        cSize = {0, 0};
  97.     short        temp;
  98.     FontInfo    fInfo;
  99.     GrafPtr        oldPort;
  100.     Boolean        good = false;
  101.  
  102.     GetPort(&oldPort);
  103.     SetPort(theDialog);
  104.     getBox(theDialog, filesBox, &rView);
  105.     SetRect(&dataBounds, 0, 0, 3, 0);
  106.     GetFontInfo(&fInfo);
  107.     cSize.h = rView.right;
  108.     cSize.v = fInfo.ascent + fInfo.descent + fInfo.leading;
  109.     gTheList = LNew(&rView, &dataBounds, cSize, 0, theDialog, true, false, false, false);
  110.     if (gTheList)
  111.     {
  112.         LDoDraw(true, gTheList);
  113.         (*gTheList)->selFlags = lNoNilHilite + lUseSense + lOnlyOne;
  114.         (*gTheList)->listFlags = lDoVAutoscroll;
  115.         LActivate(true, gTheList);
  116.         hiliteItem(theDialog, removeButton, 255);
  117.         setItem(theDialog, filesBox, (Handle) myItem);
  118.     }
  119.     hiliteItem(theDialog, myScrollBar, 255);
  120.     GetDItem(theDialog, myScrollBar, &temp, &gTheScrollBar, &dataBounds);
  121.     SetCRefCon(gTheScrollBar, -((rView.bottom - rView.top)/cSize.v));    // # of lines in box, negativized
  122.     SetCtlMin(gTheScrollBar, 0);
  123.     SetCtlMax(gTheScrollBar, GetCRefCon(gTheScrollBar));
  124.     SetPort(oldPort);
  125.     return;
  126. }
  127.  
  128. pascal void cleanup(void)
  129. {
  130.     if (gTheList) LDispose(gTheList);
  131. }
  132.  
  133. /*
  134.     Updates the list display, and does sundry drawing activities.
  135. */
  136.  
  137. pascal void myItem(DialogPtr theDialog, short itemNumber)
  138. {
  139.     Rect    box;
  140.     GrafPtr    oldPort;
  141.     
  142.     GetPort(&oldPort);
  143.     SetPort(theDialog);
  144.     
  145.     getBox(theDialog, filesBox, &box);
  146.     InsetRect(&box, -1, -1);
  147.     FrameRect(&box);
  148.     getBox(theDialog, line, &box);
  149.     FrameRect(&box);
  150.     LUpdate(theDialog->visRgn, gTheList);
  151.     SetPort(oldPort);
  152. }
  153.  
  154. // false displays the file, true doesnâ•’t.
  155.  
  156. pascal Boolean myFileFilter(CInfoPBPtr pb)
  157. {
  158.     return false;
  159. }
  160.  
  161. /*
  162.     must return item #; if no number, nothing happens. I've remapped the
  163.     add button to the okButton, and vice-versa to avoid lots of exess code.
  164. */
  165.  
  166. pascal short myDlgHook(short item, DialogPtr theDialog)
  167. {
  168.     switch (item)
  169.     {
  170.         case sfHookFirstCall:
  171.             initList(theDialog);
  172.             break;
  173.         case okButton:            // maps to add!
  174.             addData();
  175.             if (GetCRefCon(gTheScrollBar)>0) hiliteItem(theDialog, myScrollBar, 0);
  176.             else hiliteItem(theDialog, myScrollBar, 255);
  177.             item = addButton;
  178.             break;
  179.         case addButton:            // maps to ok!
  180.             item = okButton;
  181.             break;
  182.         case removeButton:
  183.             removeCells();
  184.             hiliteItem(theDialog, removeButton, 255);
  185.             if (GetCRefCon(gTheScrollBar)>0) hiliteItem(theDialog, myScrollBar, 0);
  186.             else hiliteItem(theDialog, myScrollBar, 255);
  187.             break;
  188.     }
  189.     return item;
  190. }
  191.  
  192. // false->handle the event || true->ignore the event
  193.  
  194. pascal Boolean myFilterProc(DialogPtr theDialog, EventRecord *event, short *itemHit)
  195. {
  196.     if (event->what == mouseDown)
  197.     {
  198.         if (FrontWindow() == theDialog)
  199.         {
  200.             Rect    theView;
  201.             getBox(theDialog, filesBox, &theView);
  202.             GlobalToLocal(&(event->where));
  203.             if (PtInRect(event->where, &theView))
  204.             {
  205.                 LClick(event->where, event->modifiers, gTheList);
  206.             }
  207.             else
  208.             {
  209.                 getBox(theDialog, myScrollBar, &theView);
  210.                 if (PtInRect(event->where, &theView))
  211.                 {
  212.                     handleScrollBar(theDialog, event);
  213.                 }
  214.             }
  215.             LocalToGlobal(&(event->where));
  216.             hiliteItem(theDialog, removeButton, selected() ? 0 : 255);
  217.         }
  218.     }
  219.     return false;
  220. }
  221.  
  222. // are any cells selected?
  223.  
  224. Boolean selected(void)
  225. {
  226.     Cell    theCell = {0, 0};
  227.     
  228.     return LGetSelect(true, &theCell, gTheList);
  229. }
  230.  
  231. // remove active cells. Even though there should be only one, I go thru them all anyway.
  232. void removeCells(void)
  233. {
  234.     Cell    theCell = {0, 0};
  235.     
  236.     while(LGetSelect(true, &theCell, gTheList))
  237.     {
  238.         LDelRow(1, theCell.v, gTheList);
  239.         SetCRefCon(gTheScrollBar, GetCRefCon(gTheScrollBar) -1);    // subtract
  240.         SetCtlMax(gTheScrollBar, GetCRefCon(gTheScrollBar));            // set scroll limit
  241.     }
  242. }
  243.  
  244. //    ugly, but effective: the list is 3 columns wide, so I just stuff
  245. //    the other 2 colums with the parID and the vRefNum, respectively.
  246.  
  247. void addData(void)
  248. {
  249.     long    parID;
  250.     short    vRefNum;
  251.     Str32    text;
  252.     short    len;
  253.     Cell    theCell = {0, 0};
  254.     
  255.     theCell.v = (**gTheList).dataBounds.bottom+1;
  256.     theCell.v = LAddRow(1, theCell.v, gTheList);
  257.     
  258.     parID = *((long *)CurDirStore);
  259.     vRefNum = -1 * (*(short *)SFSaveDisk);
  260.  
  261.     len = gTheReply.fName[0];
  262.     LSetCell(&(gTheReply.fName[1]), len, theCell, gTheList);    // name
  263.  
  264.     NumToString(parID, text);
  265.     len = text[0];
  266.     theCell.h++;
  267.     LSetCell(&(text[1]), len, theCell, gTheList);                // parent id
  268.     
  269.     parID = vRefNum;
  270.     NumToString(parID, text);
  271.     len = text[0];
  272.     theCell.h++;
  273.     LSetCell(&(text[1]), len, theCell, gTheList);                // vrefnum
  274.     SetCRefCon(gTheScrollBar, GetCRefCon(gTheScrollBar) + 1);    // add 1 file to count
  275.     SetCtlMax(gTheScrollBar, GetCRefCon(gTheScrollBar));            // set scroll limit
  276. }
  277.  
  278. //    just a test, to make sure all the files are there.
  279.  
  280. void processData(void)
  281. {
  282.     FSSpec    theFile;
  283.     long    num;
  284.     Str32    text;
  285.     Cell    theCell = {0, 2};
  286.     short    len;
  287.     
  288.     for (theCell.v = 0; theCell.v < (**gTheList).dataBounds.bottom; theCell.v++)
  289.     {
  290.         len = 63;
  291.         LGetCell((theFile.name)+1, &len, theCell, gTheList);
  292.         theFile.name[0] = len;
  293.         StringToNum(theFile.name, &(theFile.parID));
  294.         theFile.vRefNum = theFile.parID;
  295.         
  296.         theCell.h--;
  297.         len = 63;
  298.         LGetCell((theFile.name)+1, &len, theCell, gTheList);
  299.         theFile.name[0] = len;
  300.         StringToNum(theFile.name, &(theFile.parID));
  301.         
  302.         theCell.h--;
  303.         len = 63;
  304.         LGetCell(theFile.name+1, &len, theCell, gTheList);
  305.         theFile.name[0] = len;
  306.         theCell.h = 2;
  307.     }
  308. }
  309.  
  310. void main(void)
  311. {
  312.     Point    where = {-1, -1};
  313.         
  314.     // note: the file filter can be omitted, if you want.
  315.     SFPGetFile(where, "\pSelect files:", myFileFilter, -1, nil, myDlgHook, &gTheReply, kMyDialog, myFilterProc);
  316.  
  317.     if (gTheReply.good)
  318.     {
  319.         processData();
  320.     }
  321.     cleanup();
  322. }
  323.  
  324. void handleScrollBar(DialogPtr theDialog, EventRecord *event)
  325. {
  326.     short            thePart, oldVal;
  327.     Point            pt = (*event).where;
  328.     ControlHandle    theControl;
  329.     
  330.     if ((thePart = FindControl(pt, theDialog, &theControl)) == inThumb)
  331.     {
  332.         oldVal = GetCtlValue(theControl);
  333.         thePart = TrackControl(theControl, pt, nil);
  334.         LScroll(0, GetCtlValue(theControl) - oldVal, gTheList);
  335.     }
  336.     else
  337.     {
  338.         thePart = TrackControl(theControl, pt, &scrollProc);
  339.     }
  340. }
  341.  
  342. pascal void scrollProc(ControlHandle theControl, short theCode)
  343. {
  344.     short    theValue = GetCtlValue(theControl);
  345.     switch (theCode)
  346.     {
  347.         case inPageDown:
  348.         case inDownButton:
  349.             theValue++;
  350.             LScroll(0, 1, gTheList);
  351.             break;
  352.         case inPageUp:
  353.         case inUpButton:
  354.             LScroll(0, -1, gTheList);
  355.             theValue--;
  356.             break;
  357.     }
  358.     SetCtlValue(theControl, theValue);
  359. }
  360.