home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / rsyssrc.lha / RSysTreeHunks.c < prev    next >
C/C++ Source or Header  |  1993-09-23  |  14KB  |  520 lines

  1. /*
  2. ***************************************************************************
  3. *
  4. * Datei:
  5. *    RSysTreeHunks.c
  6. *
  7. * Inhalt:
  8. *
  9. *      --- Globale Routinen ---
  10. *
  11. *    BOOL ClickedCloseGadget ( void );
  12. *    long OpenTreeWindow ( char *name , int hunk );
  13. *    void PrintTree ( struct objectid *obj );
  14. *
  15. *      --- Lokale  Routinen ---
  16. *
  17. *    static struct diskhunkentry *makede ( struct diskhunkentry *last , int depth , char *name , int lastde );
  18. *    static struct TextFont *Toggleibm8Font ( void );
  19. *    static void ScanDirs ( char *name , int depth , int lastde );
  20. *    static void ToggleListView ( ULONG code );
  21. *
  22. * Bemerkungen:
  23. *    Routinen zur Anzeige von Verzeichnisbäumen und
  24. *    Hunk-Strukturen ausführbarer Files.
  25. *
  26. * Erstellungsdatum:
  27. *    07-Jul-93    Rolf Böhme
  28. *
  29. * Änderungen:
  30. *    07-Jul-93    Rolf Böhme    Erstellung
  31. *
  32. ***************************************************************************
  33. */
  34.  
  35. #include "RSys.h"
  36.  
  37. struct TextFont *Toggleibm8Font(void);
  38. struct TextFont *tf = NULL;
  39. struct TextAttr tree_ta = {(STRPTR)"ibm.font",8,0,2};
  40.  
  41. static struct diskhunkentry
  42. {
  43.    struct Node denode;
  44.    char *name;
  45.    char *fullname;
  46.    struct diskhunkentry *next;
  47. };
  48.  
  49. static struct diskhunkentry *loop, *firstde;
  50.  
  51. static struct List Tree;
  52.  
  53. static struct Remember *dekey = NULL;
  54.  
  55. struct Window *TreeWnd = NULL;
  56. struct Gadget *TreeGList = NULL;
  57. struct Gadget *TreeGadgets[3];
  58. UBYTE *TreeWdt = (UBYTE *) NAME " " VERSION " - Directory Tree Lister";
  59. UBYTE *TreeWdt1 = (UBYTE *) NAME " " VERSION " - Hunk Lister";
  60. static UBYTE *KindCY0Labels[]=
  61. {
  62.    (UBYTE *) "Tree",
  63.    (UBYTE *) "Path",
  64.    NULL
  65. };
  66.  
  67. static ULONG mask = 0L;
  68. int decnt = 0, breakit = FALSE;
  69.  
  70.    /*
  71.     * makede() erzeugt ein Element einer verketteten Liste, deren
  72.     * Elemente später in ein ListView eingebracht werden. Dabei wird
  73.     * ein Eintrag mit einem vollständigen Dateinamen und einer
  74.     * Baumstrukturdarstellung erzeugt
  75.     */
  76. static struct diskhunkentry *
  77. makede(struct diskhunkentry *last, int depth, char *name, int lastde)
  78. {
  79.    int   i;
  80.    char  fpart[MAXFULLNAME];
  81.    static int max = -1;
  82.  
  83.    strncpy(fpart, (char *)FilePart((UBYTE *) name), MAXFULLNAME);
  84.  
  85.    if ((last = (struct diskhunkentry *) AllocRemember(RKEY, SIZEDE, MEMF_CLEAR | MEMF_ANY)) &&
  86.        (last->name = (char *)AllocRemember(RKEY, BUFSIZE, MEMF_CLEAR | MEMF_ANY)) &&
  87.        (last->fullname = (char *)AllocRemember(RKEY, strlen(name) + 3, MEMF_CLEAR | MEMF_ANY)))
  88.    {
  89.       last->next           = NULL;
  90.       last->denode.ln_Name = last->name;
  91.       last->denode.ln_Type = 0;
  92.  
  93.       for (i = depth + 1; i <= max; i++) UNSET(i);
  94.  
  95.       max = depth;
  96.  
  97.       if (lastde) SET(depth);
  98.       else
  99.          UNSET(depth);
  100.  
  101.       strcpy(last->fullname, name);
  102.  
  103.       if (depth != 0) strcat(last->fullname, "/");
  104.  
  105.       if (depth == 0) strncpy(last->name, name, BUFSIZE);
  106.       else
  107.       {
  108.          if (depth == 1)
  109.          {
  110.             if(tf) strncpy(last->name, (lastde ? ILASTDIR ISUBDIR : IDIR ISUBDIR), BUFSIZE);
  111.             else
  112.                strncpy(last->name, (lastde ? "\`" ASUBDIR : ADIR ASUBDIR), BUFSIZE);
  113.  
  114.             strncat(last->name, fpart, BUFSIZE - strlen(last->name) - 1);
  115.          }
  116.          else
  117.          {
  118.             if (IS_SET(1)) strncpy(last->name, "   ", BUFSIZE);
  119.             else
  120.                strncpy(last->name, (tf ? ILEVEL : ALEVEL), BUFSIZE );
  121.  
  122.             for (i = 2; i < depth; i++)
  123.                if (IS_SET(i)) strncat(last->name, "   ", BUFSIZE - strlen(last->name) - 1);
  124.                else
  125.                   strncat(last->name, (tf ? ILEVEL : ALEVEL), BUFSIZE - strlen(last->name) - 1);
  126.  
  127.             if(tf) strncat(last->name, (lastde ? ILASTDIR ISUBDIR  : IDIR ISUBDIR ), BUFSIZE - strlen(last->name) - 1);
  128.             else
  129.                strncat(last->name, (lastde ? "\`" ASUBDIR  : ADIR ASUBDIR ), BUFSIZE - strlen(last->name) - 1);
  130.  
  131.             strncat(last->name, fpart, BUFSIZE - strlen(last->name) - 1);
  132.          }
  133.       }
  134.  
  135.       InitListView(TreeWnd,TreeGadgets[GD_TreeLV - GD_TreeLV],NULL,UNSETLVPOS);
  136.  
  137.       AddTail(&Tree, &last->denode);
  138.  
  139.       InitListView(TreeWnd,TreeGadgets[0],&Tree,decnt);
  140.  
  141.       decnt++;
  142.  
  143.       return last->next;
  144.    }
  145.    else ErrorHandle("Directory tree",MEMORY_ERR, ALLOC_FAIL, KILL);
  146.  
  147.    return NULL;
  148. }
  149.  
  150.    /*
  151.     * ClickedCloseGadget() prüft, ob das CloseGadget geklickt
  152.     * worden ist und bietet eine Abfrage an, ob die laufenden
  153.     * Operation abgebrochen werden soll
  154.     */
  155. BOOL
  156. ClickedCloseGadget(void)
  157. {
  158.    register struct IntuiMessage *mess;
  159.    ULONG class;
  160.    BOOL  ret = FALSE;
  161.  
  162.    while ((mess = (struct IntuiMessage *)
  163.            GT_GetIMsg(TreeWnd->UserPort)) != NULL)
  164.    {
  165.       class = mess->Class;
  166.       GT_ReplyIMsg(mess);
  167.  
  168.       if ((class == IDCMP_CLOSEWINDOW) && Question(TreeWnd, "Do you want to cancel reading?", YES))
  169.       {
  170.          ret = TRUE;
  171.          breakit = TRUE;
  172.       }
  173.    }
  174.  
  175.    return (ret);
  176. }
  177.  
  178.    /*
  179.     * ScanDirs() durchläuft rekursiv eine vorgegebene Directory
  180.     * und baut dabei eine Baumstruktur auf
  181.     */
  182. static void
  183. ScanDirs(char *name, int depth, int lastde)
  184. {
  185.    struct ExAllControl *eac;
  186.    struct ExAllData *EAData,
  187.         *ead,
  188.         *eadtmp;
  189.    int   more;
  190.    BPTR  lock;
  191.    UBYTE newdir[MAXFULLNAME];
  192.  
  193.    if (ClickedCloseGadget()|| breakit) return;
  194.  
  195.    loop = makede(loop, depth, name, lastde);
  196.  
  197.    if (NOT(lock = Lock((UBYTE *) name, ACCESS_READ))) return;
  198.  
  199.    if (eac = AllocDosObject(DOS_EXALLCONTROL, NULL))
  200.    {
  201.       eac->eac_LastKey = 0;
  202.  
  203.       EAData = MyAllocVec((MAXLARGEMEM+1) * sizeof(struct ExAllData), MEMF_ANY | MEMF_CLEAR, NO_KILL);
  204.  
  205.       if (EAData)
  206.       {
  207.          do
  208.          {
  209.             more = ExAll(lock, EAData, MAXLARGEMEM * sizeof(struct ExAllData), ED_SIZE, eac);
  210.  
  211.             if ((!more) && (IoErr()!= ERROR_NO_MORE_ENTRIES))
  212.             {
  213.                ErrorHandle(name, DOS_EXALL_ERR, EXALL_FAIL, NO_KILL);
  214.                break;
  215.             }
  216.  
  217.             if (eac->eac_Entries == 0) continue;
  218.  
  219.             ead = EAData;
  220.  
  221.             do
  222.             {
  223.                if (ead->ed_Type > 0)
  224.                {
  225.                   int   lastentry = TRUE;
  226.  
  227.                   strcpy((char *)newdir, name);
  228.  
  229.                   for (eadtmp = ead->ed_Next; eadtmp; eadtmp = eadtmp->ed_Next)
  230.                      if (eadtmp->ed_Type > 0)
  231.                      {
  232.                         lastentry = FALSE;
  233.                         break;
  234.                      }
  235.  
  236.                   if (AddPart(newdir, ead->ed_Name, MAXFULLNAME))
  237.                      ScanDirs((char *)newdir, depth + 1, lastentry);
  238.                }
  239.  
  240.                ead = ead->ed_Next;
  241.             } while (ead);
  242.          } while (more);
  243.  
  244.          MyFreeVec(EAData);
  245.       }
  246.  
  247.       FreeDosObject(DOS_EXALLCONTROL, eac);
  248.    }
  249.    else ErrorHandle("ExAll()-Control", MEMORY_ERR, ALLOC_FAIL, NO_KILL);
  250.  
  251.    UnLock(lock);
  252.  
  253.    return;
  254. }
  255.  
  256. static struct TextFont *
  257. Toggleibm8Font(void)
  258. {
  259.    STATIC BOOL Access = FALSE;
  260.    STATIC struct TextFont *ibm8Font = NULL;
  261.  
  262.    Access ^= TRUE;
  263.  
  264.    if(Access) ibm8Font = OpenDiskFont(&tree_ta);
  265.    else
  266.       if(ibm8Font)
  267.       {
  268.          CloseFont(ibm8Font);
  269.          ibm8Font = NULL;
  270.       }
  271.  
  272.    return ibm8Font;
  273. }
  274.  
  275.    /*
  276.     * OpenTreeWindow() öffnet das Kontrollfenster zur Ausgabe
  277.     * eines Verzeichnisbaumes
  278.     */
  279. long
  280. OpenTreeWindow(char *name, int hunk)
  281. {
  282.    struct NewGadget ng;
  283.    struct Gadget *g;
  284.    UWORD wleft = 113,
  285.          wtop = 26,
  286.          ww,
  287.          wh;
  288.    int gl[] = {GD_TreeLV - GD_TreeLV};
  289.  
  290.    AdjustWindowDimensions(Scr, (UWORD)113, (UWORD)26, (UWORD)463, (UWORD)143,
  291.                           &wleft, &wtop, &ww, &wh);
  292.  
  293.    if (NOT(g = CreateContext(&TreeGList))) return (1L);
  294.  
  295.    ng.ng_LeftEdge = compute(OffX, FontX, 8);
  296.    ng.ng_TopEdge = compute(OffY, FontY, 21);
  297.    ng.ng_Width = compute((UWORD) 0, FontX, 449);
  298.    ng.ng_Height = compute((UWORD) 0, FontY, 116);
  299.    ng.ng_GadgetText = (UBYTE *) name;
  300.    ng.ng_TextAttr = (tf ? &tree_ta : Font);
  301.    ng.ng_GadgetID = GD_TreeLV;
  302.    ng.ng_Flags = PLACETEXT_ABOVE | NG_HIGHLABEL;
  303.    ng.ng_VisualInfo = VisualInfo;
  304.  
  305.    g = CreateGadget(LISTVIEW_KIND, g, &ng,
  306.                     GTLV_Labels, NULL,
  307.                     GTLV_ReadOnly, (hunk ? TRUE : FALSE),
  308.                     TAG_DONE);
  309.  
  310.    TreeGadgets[0] = g;
  311.    makelabelvisible(TreeGadgets[0]);
  312.  
  313.    ng.ng_LeftEdge = compute(OffX, FontX, 368);
  314.    ng.ng_TopEdge = compute(OffY, FontY, 5);
  315.    ng.ng_Width = compute((UWORD) 0, FontX, 89);
  316.    ng.ng_Height = compute((UWORD) 0, FontY, 13);
  317.    ng.ng_GadgetText = NOT(hunk) ? (UBYTE *) "Save Tree" : (UBYTE *) "Save List";
  318.    ng.ng_TextAttr = Font;
  319.    ng.ng_GadgetID = GD_SaveGad;
  320.    ng.ng_Flags = PLACETEXT_IN;
  321.  
  322.    g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);
  323.  
  324.    TreeGadgets[1] = g;
  325.    makelabelvisible(TreeGadgets[1]);
  326.  
  327.    if (NOT(hunk))
  328.    {
  329.       ng.ng_LeftEdge = compute(OffX, FontX, 8);
  330.       ng.ng_Width = compute((UWORD) 0, FontX, 105);
  331.       ng.ng_GadgetText = NULL;
  332.       ng.ng_TextAttr = Font;
  333.       ng.ng_GadgetID = GD_KindCY;
  334.       ng.ng_Flags = 0;
  335.  
  336.       g = CreateGadget(CYCLE_KIND, g, &ng, GTCY_Labels, &KindCY0Labels[0], TAG_DONE);
  337.  
  338.       TreeGadgets[2] = g;
  339.    }
  340.    else
  341.    {
  342.       ng.ng_LeftEdge = compute(OffX, FontX, 8);
  343.       ng.ng_Width = compute((UWORD) 0, FontX, 105);
  344.       ng.ng_GadgetText = (UBYTE *)"Load";
  345.       ng.ng_TextAttr = Font;
  346.       ng.ng_GadgetID = GD_KindCY;
  347.       ng.ng_Flags = 0;
  348.  
  349.       g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);
  350.  
  351.       TreeGadgets[2] = g;
  352.    }
  353.  
  354.    if (NOT g) return (2L);
  355.  
  356.    if (NOT(TreeWnd = OpenWindowTags(NULL,
  357.                                     WA_Left, wleft,
  358.                                     WA_Top, wtop,
  359.                                     WA_Width, ww,
  360.                                     WA_Height, wh,
  361.                                     WA_IDCMP, BUTTONIDCMP |
  362.                                     LISTVIEWIDCMP |
  363.                                     IDCMP_MOUSEBUTTONS |
  364.                                     IDCMP_MOUSEMOVE |
  365.                                     IDCMP_CLOSEWINDOW |
  366.                                     IDCMP_VANILLAKEY |
  367.                                     IDCMP_REFRESHWINDOW,
  368.                                     WA_Flags, WFLG_DRAGBAR |
  369.                                     WFLG_DEPTHGADGET |
  370.                                     WFLG_CLOSEGADGET |
  371.                                     WFLG_SMART_REFRESH |
  372.                                     WFLG_ACTIVATE |
  373.                                     WFLG_RMBTRAP,
  374.                                     WA_Title, hunk ? TreeWdt1 : TreeWdt,
  375.                                     WA_PubScreenFallBack,TRUE,
  376.                                     WA_PubScreen, Scr,
  377.                                     TAG_DONE)))
  378.       return 4L;
  379.  
  380.    RefreshRastPort(TreeWnd,TreeGadgets,gl, 1, FALSE, TreeGList);
  381.  
  382.    return NULL;
  383. }
  384.  
  385.    /*
  386.     * ToggleListView() schaltet zwischen der Baum- und der
  387.     * Dateidarstellung der Verzeichniseinträge um
  388.     */
  389. static void
  390. ToggleListView(ULONG code)
  391. {
  392.    struct diskhunkentry *de;
  393.    struct Node *node;
  394.  
  395.    InitListView(TreeWnd,TreeGadgets[0],NULL,UNSETLVPOS);
  396.  
  397.    for (node = Tree.lh_Head; node->ln_Succ; node = node->ln_Succ)
  398.    {
  399.       de = (struct diskhunkentry *) node;
  400.       node->ln_Name = ((code == 0L) ? de->name : de->fullname);
  401.    }
  402.  
  403.    InitListView(TreeWnd,TreeGadgets[0],&Tree,UNSETLVPOS);
  404.  
  405.    return;
  406. }
  407.  
  408.    /*
  409.     * PrintTree() öffnet ein Fenster und gibt alle Verzeichnisse eines
  410.     * Verzeichnisobjektes obj in einem ListView aus
  411.     */
  412. void
  413. PrintTree(struct objectid *obj)
  414. {
  415.    struct IntuiMessage *message;
  416.    ULONG class,
  417.          code;
  418.    APTR  object;
  419.    struct Node *node;
  420.    int id;
  421.  
  422.    DPOS;
  423.  
  424.    Flags.quit_tree = 0;
  425.  
  426.    tf = Toggleibm8Font();
  427.  
  428.    NewList(&Tree);
  429.  
  430.    if (NOT(OpenTreeWindow(obj->fullname, FALSE)))
  431.    {
  432.       LockMainWindow(LOCK);
  433.  
  434.       decnt = 0;
  435.       breakit = FALSE;
  436.  
  437.       loop = firstde;
  438.  
  439.       PrintInfo("Scanning Device", SPEAK, 0);
  440.  
  441.       SetWindowTitles(TreeWnd, (UBYTE *) "<- Cancel reading Tree...",
  442.                       NOSCREENTITLECHANGE);
  443.  
  444.       EnableGadget(TreeWnd, TreeGadgets[GD_SaveGad - GD_TreeLV], FALSE);
  445.       EnableGadget(TreeWnd, TreeGadgets[GD_KindCY - GD_TreeLV], FALSE);
  446.  
  447.       ScanDirs(obj->fullname, 0, TRUE);
  448.  
  449.       SetWindowTitles(TreeWnd, TreeWdt, NOSCREENTITLECHANGE);
  450.  
  451.       EnableGadget(TreeWnd, TreeGadgets[GD_SaveGad - GD_TreeLV], TRUE);
  452.       EnableGadget(TreeWnd, TreeGadgets[GD_KindCY - GD_TreeLV], TRUE);
  453.  
  454.       do
  455.       {
  456.          Wait(1L << TreeWnd->UserPort->mp_SigBit);
  457.  
  458.          while ((message = (struct IntuiMessage *) GT_GetIMsg(TreeWnd->UserPort)) != NULL)
  459.          {
  460.             class  = message->Class;
  461.             code   = message->Code;
  462.             object = message->IAddress;
  463.  
  464.             GT_ReplyIMsg(message);
  465.  
  466.             switch(class)
  467.             {
  468.                case IDCMP_CLOSEWINDOW:
  469.                   Flags.quit_tree = 1;
  470.                   break;
  471.  
  472.                case IDCMP_GADGETUP:
  473.                   id = ((struct Gadget *)object)->GadgetID;
  474.  
  475.                   HandleHelp((enum RSysNumbers)id);
  476.  
  477.                   switch(id)
  478.                   {
  479.                      case GD_TreeLV:
  480.                         if(node = GetNode(&Tree, code))
  481.                            DisplayDirectoryInfo(((struct diskhunkentry *) node)->fullname);
  482.                         break;
  483.  
  484.                      case GD_SaveGad:
  485.                         if (GetFile(TreeWnd,"RAM:","RSys-Tree.DAT","#?.dat",
  486.                                     "Select File for saving treelist","Save"))
  487.                            SaveList(TreeWnd,(char *)_fullpath, (char *)obj->fullname,&Tree, FALSE);
  488.                         break;
  489.  
  490.                      case GD_KindCY:
  491.                         ToggleListView(code);
  492.                         break;
  493.                   }
  494.                   break;
  495.  
  496.                case IDCMP_VANILLAKEY:
  497.                   if((char)code == ESC) Flags.quit_tree = 1;
  498.                   break;
  499.             }
  500.          }
  501.       } while (NOT(Flags.quit_tree));
  502.  
  503.       InitListView(TreeWnd,TreeGadgets[GD_TreeLV - GD_TreeLV],NULL,UNSETLVPOS);
  504.  
  505.       NewList(&Tree);
  506.  
  507.       FreeRemember(RKEY, TRUE);
  508.  
  509.       CloseASysWindow(&TreeWnd, &TreeGList, NULL);
  510.  
  511.       LockMainWindow(UNLOCK);
  512.    }
  513.    else ErrorHandle((char *)TreeWdt, WINDOW_ERR, OPEN_FAIL, NO_KILL);
  514.  
  515.    Toggleibm8Font();
  516.  
  517.    return;
  518. }
  519.  
  520.