home *** CD-ROM | disk | FTP | other *** search
/ Executor 2.0 / executorv2.0.iso / pc / dos / extra / source / browser / browser.hqx / Browser / inithotband.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-28  |  10.0 KB  |  431 lines

  1. #include "go.h"
  2. #include <string.h>
  3. #include "xfer.h"
  4. #include "display.h"
  5.  
  6. #include "inithotband.proto.h"
  7. #include "init.proto.h"
  8. #include "initicons.proto.h"
  9. #include "mouse.proto.h"
  10. #include "misc.proto.h"
  11. #include "view.proto.h"
  12. #include "menu.proto.h"
  13.  
  14. DialogPtr g_hotband;
  15. bandinfo bands[NUMBANDS];
  16. short g_currentband;
  17. Handle g_iconcdefproc;
  18. short g_numdispinhotband;
  19.  
  20. void
  21. additemtohotband (short whichband, char **path, long parid, short vrefnum,
  22.           short action)
  23. {
  24.   bandinfo *p;
  25.   ControlHandle c;
  26.   Str255 s;
  27.   item **ih;
  28.  
  29.   p = &bands[whichband];
  30.   checkgrowitemarray (p->numitems, p->items);
  31.   tail (*path, s);
  32.   c = (**p->items)[p->numitems] = getnewiconcontrol (g_hotband, path, parid,
  33.                              vrefnum, s, ICONVIEW);
  34.   ih = (item **) (*c)->contrlData;
  35.   (*ih)->action = action;
  36.  
  37. /* setoneicon calls PBGetCatInfo which crashes when called with an offline volume */
  38.   if (whichband != VOLBAND)
  39.     setoneicon (c);
  40.   else
  41.     (*(item **) (*c)->contrlData)->iconfam = g_diskicons;
  42.   if (g_currentband != whichband)
  43.     setband (whichband);
  44.   if (p->bandpos + g_numdispinhotband > p->numitems)
  45.     {
  46.       MoveControl (c, (p->numitems - p->bandpos) * ICONWIDTHUSED + FIRSTICONX, 0);
  47.       ShowControl (c);
  48.     }
  49.   p->numitems++;
  50.   checkhotbandcontrol ();
  51. }
  52.  
  53. void
  54. adjust_ctl_value (ControlHandle c, bandinfo *p)
  55. {
  56.   if (p->bandpos == 0)
  57.     SetCtlValue (c, 0);
  58.   else if (p->bandpos == p->numitems - g_numdispinhotband)
  59.     SetCtlValue (c, 2);
  60.   else
  61.     SetCtlValue (c, 1);
  62. }
  63.  
  64. void
  65. checkhotbandcontrol (void)
  66. {
  67.   Rect r;
  68.   ControlHandle c;
  69.   short type;
  70.   bandinfo *p;
  71.   short new_hilite_val;
  72.   int old_ctl_val;
  73.  
  74.   GetDItem (g_hotband, SCROLLITEM, &type, (Handle *) &c, &r);
  75.   old_ctl_val = GetCtlValue (c);
  76.   p = &bands[g_currentband];
  77.   if (p->numitems > g_numdispinhotband)
  78.     {
  79.       new_hilite_val = 0;
  80.       adjust_ctl_value (c, p);
  81.     }
  82.   else
  83.     {
  84.       if (p->bandpos > 0)
  85.     {
  86.       shiftband (p->bandpos, p->bandpos);
  87.       p->bandpos = 0;
  88.     }
  89.       new_hilite_val = 255;
  90.     }
  91.   if (GetCtlValue (c) != old_ctl_val || (*c)->contrlHilite != new_hilite_val)
  92.     {
  93.       if ((*c)->contrlHilite != new_hilite_val)
  94.     HiliteControl (c, new_hilite_val);
  95.       Draw1Control (c);
  96.     }
  97. }
  98.  
  99. void
  100. shiftband (short start, short offset)
  101. {
  102.   ControlHandle c;
  103.   bandinfo *p;
  104.   short pixoffset, first, last, i, x, y;
  105.   short type, old_ctl_val;
  106.   Rect r;
  107.  
  108.   GetDItem (g_hotband, SCROLLITEM, &type, (Handle *) & c, &r);
  109.   old_ctl_val = GetCtlValue (c);
  110.   p = &bands[g_currentband];
  111.   pixoffset = offset * ICONWIDTHUSED;
  112.   last = start + g_numdispinhotband;
  113.   if (last > p->numitems)
  114.     last = p->numitems;
  115.   if (offset < 0)
  116.     {
  117.       for (i = start; i < last; i++)
  118.     MoveControl ((**p->items)[i],
  119.              (*(**p->items)[i])->contrlRect.left + pixoffset,
  120.              (*(**p->items)[i])->contrlRect.top);
  121.     }
  122.   else
  123.     {
  124.       for (i = last - 1; i >= start; i--)
  125.     MoveControl ((**p->items)[i],
  126.              (*(**p->items)[i])->contrlRect.left + pixoffset,
  127.              (*(**p->items)[i])->contrlRect.top);
  128.     }
  129.  
  130.   y = (*(**p->items)[start])->contrlRect.top;
  131.   if (offset < 0)
  132.     {
  133.       first = p->bandpos + g_numdispinhotband + offset;
  134.       last = first - offset;
  135.       if (last > p->numitems)
  136.     last = p->numitems;
  137.       if (first <= p->numitems && first > 0)
  138.     x = (*(**p->items)[first - 1])->contrlRect.left + ICONWIDTHUSED;
  139.     }
  140.   else
  141.     {
  142.       first = start - offset;
  143.       last = start;
  144.       if (last > p->numitems)
  145.     last = p->numitems;
  146.       x = (*(**p->items)[start])->contrlRect.left - pixoffset;
  147.     }
  148.  
  149.   for (i = first; i < last; i++)
  150.     {
  151.       MoveControl ((**p->items)[i], x, y);
  152.       ShowControl ((**p->items)[i]);
  153.       x += ICONWIDTHUSED;
  154.     }
  155.   adjust_ctl_value (c, p);
  156.   if (GetCtlValue (c) != old_ctl_val)
  157.     Draw1Control (c);
  158. }
  159.  
  160. void
  161. removeitemfromhotband (ControlHandle c)
  162. {
  163. /* NOTE: this only works for items in the current band */
  164.   short pos, i;
  165.   bandinfo *p;
  166.   ParamBlockRec pb;
  167.  
  168.   replaceselected((ControlHandle) 0);
  169.   p = &bands[g_currentband];
  170.   pos = ((*c)->contrlRect.left - FIRSTICONX) / ICONWIDTHUSED + p->bandpos;
  171.   p->numitems--;
  172.   for (i = pos; i < p->numitems; i++)
  173.     (**p->items)[i] = (**p->items)[i + 1];
  174.   Dispose_Icon (c, TRUE);
  175.   shiftband (pos, -1);
  176.   checkhotbandcontrol ();
  177.   
  178.   if (g_currentband == FONTBAND || g_currentband == DABAND)
  179.     {
  180.       pb.ioParam.ioCompletion = 0;
  181.       pb.ioParam.ioNamePtr = HELPER_FILE_NAME;
  182.       pb.ioParam.ioVRefNum = BootDrive;
  183.       PBDelete (&pb, false);
  184.       build_helper_system_file ();
  185.     }
  186. }
  187.  
  188. static boolean_t
  189. already_on_band (short band, short vref, long parid, Str255 name)
  190. {
  191.   boolean_t retval;
  192.   int i;
  193.   ControlHandle (**items)[];
  194.   short num_items;
  195.  
  196.   retval = FALSE;
  197.   items = bands[band].items;
  198.   num_items = bands[band].numitems;
  199.   for (i = 0; i < num_items; ++i)
  200.     {
  201.       ControlHandle ch;
  202.       
  203.       ch = (**items)[i];
  204.       if (ICON_VREF (ch) == vref && ICON_PARENT_ID (ch) == parid
  205.           && EqualString (name, ICON_TITLE (ch), false, false))
  206.         {
  207.           retval = TRUE;
  208.           break;
  209.         }
  210.     }
  211.   return retval;
  212. }
  213.  
  214. void
  215. copycontroltohotband (ControlHandle c)
  216. {
  217.   Handle newpath;
  218.   typeinfo *tip;
  219.   item **ih;
  220.   opendirinfo **infoh;
  221.   short i, band;
  222.   GrafPtr saveport;
  223.  
  224.   ih = (item **) (*c)->contrlData;
  225.   if ((*ih)->action == OPENDIR)
  226.     {
  227.       band = FOLDERBAND;
  228.     }
  229.   else
  230.     {
  231.       tip = gettypeinfo ((*ih)->type);
  232.       band = tip->band;
  233.     }
  234.   
  235.   if (already_on_band (band, (*ih)->vrefnum, (*ih)->ioparid, (*c)->contrlTitle))
  236.     {
  237. #define ALREADY_IN_BAND 128
  238.       NoteAlert (ALREADY_IN_BAND, 0);
  239.       if (g_currentband != band)
  240.         setband (band);
  241.       return;
  242.     }
  243.   
  244.   newpath = (*ih)->path;
  245.   HandToHand (&newpath);
  246.   appenddir (&newpath, (*c)->contrlTitle);
  247.   hashicons (c);
  248.   additemtohotband (band, (char **) newpath, (*ih)->ioparid,
  249.             (*ih)->vrefnum, (*ih)->action);
  250.  
  251.   if (band == FONTBAND || band == DABAND)
  252.     {
  253.     add_item_to_system_file (c);
  254.     update_da_menu ();
  255.     }
  256.   infoh = (opendirinfo **) ((WindowPeek) (*c)->contrlOwner)->refCon;
  257.   for (i = 0; i < (*infoh)->numitems; i++)
  258.     setoneicon ((**(*infoh)->items)[i]);
  259.   GetPort (&saveport);
  260.   SetPort ((*c)->contrlOwner);
  261.   InvalRect (&(*c)->contrlOwner->portRect);
  262.   SetPort (saveport);
  263. }
  264.  
  265. void
  266. selectiontohotband (void)
  267. {
  268.   copycontroltohotband ((**g_selection)[0]);
  269. }
  270.  
  271. void
  272. addvolumes (void)
  273. {
  274.   OSErr e;
  275.   ParamBlockRec pb;
  276.   short i, len;
  277.   Str255 s;
  278.   char **path;
  279.  
  280.   e = noErr;
  281.   pb.volumeParam.ioNamePtr = s;
  282.   for (i = 1; e == noErr; i++)
  283.     {
  284.       pb.volumeParam.ioVolIndex = i;
  285.       e = PBGetVInfo (&pb, false);
  286. /* todo: figure out which type of disk icon to use */
  287.       if (e == noErr)
  288.     {
  289.       len = pb.volumeParam.ioNamePtr[0];
  290.       path = (char **) NewHandle (len + 2);
  291.       PtoCstr (pb.volumeParam.ioNamePtr);
  292.       strcpy (*path, (char *) pb.volumeParam.ioNamePtr);
  293.       (*path)[len] = ':';
  294.       (*path)[len + 1] = 0;
  295.       additemtohotband (VOLBAND, path, 0, pb.volumeParam.ioVRefNum, OPENDIR);
  296.     }
  297.     }
  298.   g_iconcdefproc = (*(**bands[VOLBAND].items)[0])->contrlDefProc;
  299. }
  300.  
  301. /*
  302.  * Done properly, path would probably always be disposed.  Right now I
  303.  * suspect there's a memory leak, but I don't have time to overhaul this.
  304.  */
  305.  
  306. void
  307. Dispose_Icon (ControlHandle c, boolean_t dispose_path_p)
  308. {
  309.   if ((**g_selection)[0] == c)
  310.     (**g_selection)[0] = 0;
  311.   if (dispose_path_p)
  312.     DisposHandle ((*(item **) (*c)->contrlData)->path);
  313.   DisposeControl (c);
  314. }
  315.  
  316. void
  317. resetvolumes (void)
  318. {
  319.   bandinfo *p;
  320.   ControlHandle c;
  321.   short i;
  322.   GrafPtr saveport;
  323.  
  324.   p = &bands[VOLBAND];
  325.   for (i = p->numitems - 1; i >= 0; i--)
  326.     {
  327.       c = (**p->items)[i];
  328.       Dispose_Icon (c, TRUE);
  329.     }
  330.   p->numitems = 0;
  331.   p->bandpos = 0;
  332.  
  333.   addvolumes ();
  334.   for (i = 0; i < p->numitems; i++)
  335.     (*(item **) (*(**p->items)[i])->contrlData)->iconfam = g_diskicons;
  336.   GetPort (&saveport);
  337.   SetPort (g_hotband);
  338.   InvalRect (&g_hotband->portRect);
  339.   SetPort (saveport);
  340. }
  341.  
  342. void
  343. fillbands (FILE * f)
  344. {
  345. /* todo: check the value of e after the getinfo calls */
  346.   CInfoPBRec cpb;
  347.   short c, whichband, action;
  348.   OSErr e;
  349.   char **path;
  350.   short volume;
  351.   typeinfo *tip;
  352.  
  353.   cpb.hFileInfo.ioFDirIndex = 0;
  354.   while ((c = getc (f)) && (c != EOF) && (c != '\n'))
  355.     {
  356.       ungetc (c, f);
  357.       e = getonefileinfo (f, &cpb, &path, &volume);
  358.       if (cpb.hFileInfo.ioFlAttrib & DIRBIT)
  359.     {
  360.       whichband = FOLDERBAND;
  361.       action = OPENDIR;
  362.     }
  363.       else
  364.     {
  365.       tip = gettypeinfo (cpb.hFileInfo.ioFlFndrInfo.fdType);
  366.       whichband = tip->band;
  367.       action = tip->action;
  368.     }
  369.       if (e == noErr)
  370.     additemtohotband (whichband, path, cpb.hFileInfo.ioFlParID,
  371.               volume, action);
  372. #if 0
  373.       else
  374.     printf ("couldn't find %s\n", *path);
  375. #endif
  376.     }
  377. }
  378.  
  379. void
  380. inithotband (FILE * f)
  381. {
  382.   short type;
  383.   Handle h;
  384.   Rect r;
  385.   short i, j;
  386.  
  387.   g_hotband = GetNewDialog (HOTBANDRESID, (Ptr) 0, (WindowPtr) - 1);
  388.   MoveWindow (g_hotband, 0, MENUBARHEIGHT, false);
  389.   SizeWindow (g_hotband, qd.screenBits.bounds.right, HOTBANDHEIGHT, true);
  390.  
  391.   GetDItem (g_hotband, SCROLLITEM, &type, &h, &r);
  392.   SetCtlMin ((ControlHandle) h, 0);
  393.   SetCtlMax ((ControlHandle) h, 2);
  394.   MoveControl ((ControlHandle) h, FIRSTICONX - ICONWIDTHUSED / 2, 0);
  395.   SizeControl ((ControlHandle) h, qd.screenBits.bounds.right -
  396.            (*(ControlHandle) h)->contrlRect.left, ICONHEIGHTUSED);
  397.   SetDItem (g_hotband, SCROLLITEM, type, h, &(*(ControlHandle) h)->contrlRect);
  398.   SetCtlAction ((ControlHandle) h, scrollicons);
  399.   g_numdispinhotband = (qd.screenBits.bounds.right - FIRSTICONX) / ICONWIDTHUSED;
  400.   if (g_numdispinhotband < 1)
  401.     g_numdispinhotband = 1;
  402.  
  403.   for (i = 0; i < NUMBANDS; i++)
  404.     {
  405.       bands[i].bandpos = 0;
  406.       bands[i].numitems = 0;
  407.       bands[i].sortorder = ALPHABETIC;
  408.       bands[i].items =
  409.     (ControlHandle (**)[])NewHandle (BANDARRAYSIZE * sizeof (ControlHandle));
  410.     }
  411.   inithash ();
  412. /* This line is important.  g_currentband must be initialized before setband is called */
  413.   g_currentband = APPBAND;
  414.   addvolumes ();
  415.  
  416.   if (f != 0)
  417.     fillbands (f);
  418.  
  419.   for (j = 0; j < NUMBANDS; j++)
  420.     if (j != VOLBAND && j != FOLDERBAND)
  421.       for (i = 0; i < bands[j].numitems; i++)
  422.     hashicons ((**bands[j].items)[i]);
  423.  
  424.   seticons ();
  425.   if (bands[APPBAND].numitems > 0)
  426.     setband (APPBAND);
  427.   else
  428.     setband (VOLBAND);
  429.   ShowWindow (g_hotband);
  430. }
  431.