home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / source.lha / src / RSysTreeHunks.c < prev    next >
C/C++ Source or Header  |  1995-01-09  |  15KB  |  586 lines

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