home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1821.lha / XDME / menustrips.c < prev    next >
C/C++ Source or Header  |  1993-02-26  |  45KB  |  2,182 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     menustrips.c
  5.  
  6.     DESCRIPTION
  7.     lowlevel commands to support programmable menues
  8.     which are designed to invoke commands of a destinct
  9.     macro language
  10.  
  11.     NOTES
  12.     exerimental phase
  13.  
  14.     Eine wichtige Aenderung sollte zur Einbindung dieser Functionen
  15.     in dem [X]DME vorgenommen werden:
  16.         in Zukunft hat immer nur maximal eins - das aktive Fenster -
  17.         eine MenueLeiste; fuer den Benutzer ist dies im
  18.         Allgemeinen nicht weiter von Bedeutung, da er
  19.         ohnehin nur das Menue des aktiven Fensters benutzen kann.
  20.         wenn er also waehrend eines laengeren Macros die fenster
  21.         wechselt, und in einem anderen Fenster eine Eingabe machen
  22.         will - die ohnehin erst nach Beendigung des Macros ausgefuehrt
  23.         wuerde, so wird ihm so gezeigt, dass er noch gar keine Eingabe
  24.         machen kann.
  25.  
  26.     Eine weitere Aenderung sollte stattfinden mit MACRO
  27.         kuenftig sollte ausschliesslich eine opaque typ Macro uebergeben
  28.         werden, die AUSSERHALB von menubase.c initialisiert wurde;
  29.         dies jedoch birgt enorme probleme bei fktionen wie menudel,
  30.         da diese nicht einfach die freiwerdenen macros zurueckgeben
  31.         koennen, sondern dann wiederum selbststaendig die macros loeschen
  32.         muessen
  33.         (es ist wahrscheinlich, dass die neue version der PL keine
  34.         Bindung zwischen funktionen und Help kennt, daher muessten dann
  35.         MACROS bestehen aus einer Node, die 2 Strings klammert:
  36.         den Funktionsaufruf und den Hilfstext)
  37.         (die entscheidung spielt aber auch in diesem Modul eine Rolle
  38.         da unter Umstaenden menuload/menusave an das neue Macrohandling
  39.         angepasst werden muessen; die betreffenden Stellen wurden
  40.         soweit sie erkannt wurden geklammert mit dem folgenden Kommentar:
  41.         --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED
  42.  
  43.  
  44.     BUGS
  45.     IMPORTANT
  46.         we cannot actually react on ERRORs !!
  47.  
  48.     TODO
  49.     [SUB] - MX-CheckItems
  50.     Help-Texts - dies ist ein thema, das m.E mehr fuer Macros.c gedacht ist - oder ?
  51.     fix_items
  52.     include some error()-calls
  53.  
  54.     wuenschenwert ist eine groessere abstraktion:
  55.         es wird vermutlich eine opaque type XITEM
  56.         mit den funktionen
  57.         create,   delete,  getcheck, setcheck, settype,  gettype,
  58.         setmacro, sethelp, addsub,   getname,  getmacro, gethelp
  59.         erzeugt werden. (in diesem augenblick muss eine wesentlich
  60.         striktere memory-kontrolle eingefuhrt werden)
  61.  
  62.         es ist ueberlegenswert, ob doppelbenennungen nicht doch erlaubt werden sollen ????
  63.         ( xi = new_xitem (name, type); add_xitem (menuheader, xi); )
  64.  
  65.     EXAMPLES
  66.  
  67.     SEE ALSO
  68.  
  69.     INDEX
  70.     $Header : $
  71.  
  72.     HISTORY
  73.         18 Dec 1992 b_null created
  74.         20-Jan 1993 b_null added checkitems
  75.         27 Jan 1993 b_null added multiple menustrips (renamed menubase -> menustrips)
  76.  
  77. ******************************************************************************/
  78.  
  79. /**************************************
  80.         Includes
  81. **************************************/
  82. #include "defs.h"
  83. #include "menubase.h"
  84.  
  85.  
  86. /**************************************
  87.         Globale Variable
  88. **************************************/
  89.  
  90. Prototype void        menuclear   (MENUSTRIP * ms);
  91. Prototype int        menudel     (MENUSTRIP * ms, char * tname);
  92. Prototype struct Menu * getmenu     (MENUSTRIP * ms, char * tname);
  93. Prototype XITEM *    getitem     (MENUSTRIP * ms, char * tname, char * iname);
  94. Prototype XITEM *    getsub        (MENUSTRIP * ms, char * tname, char * iname, char * sname);
  95. Prototype int        itemdel     (MENUSTRIP * ms, char * tname, char * iname);
  96. Prototype int        subdel        (MENUSTRIP * ms, char * tname, char * iname, char * sname);
  97. Prototype XITEM *    itemadd     (MENUSTRIP * ms, char * tname, char * iname,               char * macro, char * help, int check);
  98. Prototype XITEM *    subadd        (MENUSTRIP * ms, char * tname, char * iname, char * sname, char * macro, char * help, int check);
  99. Prototype int        loadmenus   (MENUSTRIP * ms, FILE * fi, int * lineno);
  100. Prototype int        savemenus   (MENUSTRIP * ms, FILE * fo);
  101. Prototype int        chkitemcheck(MENUSTRIP * ms, char * tname, char * iname);
  102. Prototype int        chksubcheck (MENUSTRIP * ms, char * tname, char * iname, char * sname);
  103. Prototype int        setitemcheck(MENUSTRIP * ms, char * tname, char * iname,               int status);
  104. Prototype int        setsubcheck (MENUSTRIP * ms, char * tname, char * iname, char * sname, int status);
  105. Prototype APTR        menu2macro  (MENUSTRIP * ms, char * str);
  106.  
  107. Prototype MENUSTRIP * get_menustrip    (char * name);
  108. Prototype MENUSTRIP * new_menustrip    (char * name, int defaults);
  109. Prototype void         delete_menustrip (MENUSTRIP * kt, int force);
  110.  
  111. Prototype void         exit_menustrips (void);
  112.  
  113. /**************************************
  114.       Interne Defines & Strukturen
  115. **************************************/
  116. #define MENU_DELIMITER '-'  /* the char that divides menuename from itemname */
  117. #define ITEM_DELIMITER '-'  /* the char that divides itemname from subitemname */
  118.  
  119.  
  120. /**************************************
  121.         Interne Variable
  122. **************************************/
  123.  
  124. #define cmpfunc(x,y) stricmp(x,y) /* if s.o wishes case-sensitivity redefine here */
  125.  
  126. static struct Image SepImage = {
  127.     1,    /* left */
  128.     1,    /* top    */
  129.     0,    /* wid. */
  130.     2,    /* hig. */
  131.     0,    /* dep. */
  132.     NULL,/* data */
  133.     0,    /* ppik */
  134.     0,    /* poo    */
  135.     NULL/* next */
  136. };
  137.  
  138.  struct MinList MenuStrips = { &MenuStrips.mlh_Tail, NULL, &MenuStrips.mlh_Head };
  139.  
  140. /**************************************
  141.        Interne Prototypes
  142. **************************************/
  143. static    XITEM * DeleteXItem      (XITEM  * xi);
  144. static    XITEM * CreateXItem      (char   * name);
  145. static    XITEM * get_xitem      (XITEM  * start, char * name);
  146. static    XITEM * mod_or_add_xitem  (XITEM ** pr,    char * name, char * macro, char * help, int check);
  147. static    int    rem_xitem      (XITEM ** pr,    char * name);
  148.  
  149.  
  150. /* !!! achtung irgendwo muessen noch menuoff/menuon eingebaut werden !!! */
  151.  
  152.  
  153.  
  154.  
  155. /*****************************************************************************
  156.  
  157.     NAME
  158.     DeleteXItem
  159.  
  160.     PARAMETER
  161.     XITEM * xi
  162.  
  163.     RESULT
  164.     xi->next
  165.  
  166.     RETURN
  167.     XITEM *
  168.  
  169.     DESCRIPTION
  170.     remove an xitem and all associated data (name, help, com, subs)
  171.  
  172.     NOTES
  173.  
  174.     BUGS
  175.  
  176.     EXAMPLES
  177.  
  178.     SEE ALSO
  179.  
  180.     INTERNALS
  181.     text ? loesche text
  182.     loesche xitem
  183.  
  184.     HISTORY
  185.     18 Dec 1992 b_null  created
  186.     03 Feb 1993 b_null rewritten
  187.  
  188. ******************************************************************************/
  189.  
  190. static
  191. XITEM * DeleteXItem (XITEM * xi)
  192. {
  193.     if (xi) {
  194.     XITEM * next = (XITEM *)xi->item.NextItem;
  195.  
  196.     if (xi->item.Flags & ITEMTEXT) {
  197.         struct IntuiText * it = &xi->fill.it;
  198.         XITEM * sub = (XITEM *)xi->item.SubItem;
  199.  
  200.         while (sub)    { sub = DeleteXItem (sub); } /* while */
  201.         if (it->IText) { DeallocFunc (it->IText); } /* if */
  202.         if (xi->help)  { DeallocFunc (xi->help);  } /* if */
  203.         if (xi->com)   { DeallocFunc (xi->com);   } /* if */
  204.     } /* if is text */
  205.  
  206.     FreeFunc (xi, sizeof (XITEM));
  207.     return (next);
  208.     } /* if */
  209.  
  210.     return (NULL);
  211. } /* DeleteXItem */
  212.  
  213.  
  214.  
  215. /*****************************************************************************
  216.  
  217.     NAME
  218.     get_xitem
  219.  
  220.     PARAMETER
  221.     XITEM * start
  222.     char  * name
  223.  
  224.     RESULT
  225.     a item connected with name that is on the same level
  226.     and later than start or start itself
  227.     NULL if not found
  228.  
  229.     RETURN
  230.     XITEM *
  231.  
  232.     DESCRIPTION
  233.     this function can be used to search for entries in a certain level
  234.  
  235.     NOTES
  236.  
  237.     BUGS
  238.  
  239.     EXAMPLES
  240.  
  241.     SEE ALSO
  242.  
  243.     INTERNALS
  244.  
  245.     HISTORY
  246.     19 Dec 1992 b_noll  created
  247.  
  248. ******************************************************************************/
  249.  
  250. static
  251. XITEM * get_xitem (XITEM * start, char * name)
  252. {
  253.     struct MenuItem * item;
  254.  
  255.     for (item = (struct MenuItem *)start; item; item = item->NextItem) {
  256.     if ((item->Flags & ITEMTEXT) == 0) {
  257.         if (name == BAR) {
  258.         return ((XITEM *)item);
  259.         } /* if */
  260.     } else if (name != BAR) {
  261.         struct IntuiText * it = &((XITEM *)item)->fill.it;
  262.         if (strcmp (it->IText, name) == 0) {
  263.         return ((XITEM *)item);
  264.         } /* if */
  265.     } /* if */
  266.     } /* for */
  267.  
  268.     return (NULL);
  269. } /* get_xitem */
  270.  
  271.  
  272.  
  273. /*****************************************************************************
  274.  
  275.     NAME
  276.     getmenu
  277.  
  278.     PARAMETER
  279.     MENUSTRIP * ms
  280.     char      * tname
  281.  
  282.     RESULT
  283.     the menuentry connected to tname
  284.     NULL if not found
  285.  
  286.     RETURN
  287.     struct Menu *
  288.  
  289.     DESCRIPTION
  290.  
  291.     NOTES
  292.  
  293.     BUGS
  294.  
  295.     EXAMPLES
  296.  
  297.     SEE ALSO
  298.  
  299.     INTERNALS
  300.  
  301.     HISTORY
  302.     19 Dec 1992 b_noll  created
  303.  
  304. ******************************************************************************/
  305.  
  306. static
  307. struct Menu * getmenu (MENUSTRIP * ms, char * tname)
  308. {
  309.     struct Menu * menu;
  310.  
  311.     if (ms == NULL) {
  312.     return (NULL);
  313.     } /* if */
  314.  
  315.     for (menu = ms->data; menu; menu = menu->NextMenu) {
  316.     if (strcmp (menu->MenuName, tname) == 0) {
  317.         return (menu);
  318.     } /* if */
  319.     } /* for */
  320.     return (NULL);
  321. } /* getmenu */
  322.  
  323.  
  324.  
  325. /*****************************************************************************
  326.  
  327.     NAME
  328.     getitem
  329.  
  330.     PARAMETER
  331.     MENUSTRIP * ms
  332.     char      * tname
  333.     char      * iname
  334.  
  335.     RESULT
  336.     the itementry connected to tname/iname
  337.     NULL if not found
  338.  
  339.     RETURN
  340.     XITEM *
  341.  
  342.     DESCRIPTION
  343.  
  344.     NOTES
  345.  
  346.     BUGS
  347.  
  348.     EXAMPLES
  349.  
  350.     SEE ALSO
  351.  
  352.     INTERNALS
  353.  
  354.     HISTORY
  355.     19 Dec 1992 b_noll  created
  356.  
  357. ******************************************************************************/
  358.  
  359. static
  360. XITEM * getitem (MENUSTRIP * ms, char * tname, char * iname)
  361. {
  362.     struct Menu * menu = getmenu (ms, tname);
  363.  
  364.     if (menu) {
  365.     return (get_xitem ((XITEM *)menu->FirstItem, iname));
  366.     } /* if */
  367.     return (NULL);
  368. } /* getitem */
  369.  
  370.  
  371.  
  372. /*****************************************************************************
  373.  
  374.     NAME
  375.     getsub
  376.  
  377.     PARAMETER
  378.     MENUSTRIP * ms
  379.     char      * tname
  380.     char      * iname
  381.     char      * sname
  382.  
  383.     RESULT
  384.     the subentry connected to tname/iname/sname
  385.     NULL if not found
  386.  
  387.     RETURN
  388.     XITEM *
  389.  
  390.     DESCRIPTION
  391.  
  392.     NOTES
  393.  
  394.     BUGS
  395.  
  396.     EXAMPLES
  397.  
  398.     SEE ALSO
  399.  
  400.     INTERNALS
  401.  
  402.     HISTORY
  403.     19 Dec 1992 b_noll  created
  404.  
  405. ******************************************************************************/
  406.  
  407. static
  408. XITEM * getsub (MENUSTRIP * ms, char * tname, char * iname, char * sname)
  409. {
  410.     struct MenuItem * parent = getitem (ms, tname, iname);
  411.  
  412.     if (parent) {
  413.     return (get_xitem ((XITEM *)parent->SubItem, sname));
  414.     } /* if */
  415.  
  416.     return (NULL);
  417. } /* getsub */
  418.  
  419.  
  420.  
  421. /*****************************************************************************
  422.  
  423.     NAME
  424.     menudel
  425.  
  426.     PARAMETER
  427.     MENUSTRIP * ms
  428.     char      * tname
  429.  
  430.     RESULT
  431.     success:
  432.         RET_FAIL - Menu was not found
  433.         RET_SUCC - Menu deleted
  434.  
  435.     RETURN
  436.     int
  437.  
  438.     DESCRIPTION
  439.  
  440.     NOTES
  441.  
  442.     BUGS
  443.  
  444.     EXAMPLES
  445.  
  446.     SEE ALSO
  447.     menucom/do_delmenu
  448.  
  449.     INTERNALS
  450.  
  451.     HISTORY
  452.     19 Dec 1992 b_noll created
  453.     20 Jan 1993 b_noll changed return to int
  454.  
  455. ******************************************************************************/
  456.  
  457. int menudel (MENUSTRIP * ms, char * tname)
  458. {
  459.     struct Menu *  menu;
  460.     struct Menu ** pr;
  461.     XITEM    *  xi;
  462.  
  463.     if (ms == NULL) {
  464.     return (RET_FAIL);
  465.     } /* if */
  466.     pr = &ms->data;
  467.  
  468.     for (menu = *pr; menu; pr = &menu->NextMenu, menu = *pr) {
  469.     if (strcmp (tname, menu->MenuName) == 0) {
  470.         break;
  471.     } /* if menu exists */
  472.     } /* for all headers */
  473.  
  474.     if (menu) {
  475.     /* --- detach from list */
  476.     *pr = menu->NextMenu;
  477.  
  478.     /* --- delete all items */
  479.     xi = (XITEM *)menu->FirstItem;
  480.     while (xi) {
  481.         xi = DeleteXItem (xi);
  482.     } /* while */
  483.  
  484.     /* --- free data */
  485.     DeallocFunc (menu->MenuName);
  486.     FreeFunc    (menu, sizeof (struct Menu));
  487.  
  488.     return (RET_SUCC);
  489.     } /* if */
  490.  
  491.     return (RET_FAIL);
  492. } /* menudel */
  493.  
  494.  
  495.  
  496. /*****************************************************************************
  497.  
  498.     NAME
  499.     rem_xitem
  500.  
  501.     PARAMETER
  502.     XITEM ** pr
  503.     char   * name
  504.  
  505.     RESULT
  506.     success:
  507.         RET_FAIL - item name not found or wrong syntax
  508.         RET_SUCC - ok
  509.  
  510.     RETURN
  511.     int
  512.  
  513.     DESCRIPTION
  514.  
  515.     NOTES
  516.  
  517.     BUGS
  518.  
  519.     EXAMPLES
  520.  
  521.     SEE ALSO
  522.  
  523.     INTERNALS
  524.  
  525.     HISTORY
  526.     19 Dec 1992 b_noll  created
  527.  
  528. ******************************************************************************/
  529.  
  530. static
  531. int rem_xitem (XITEM ** pr, char * name)
  532. {
  533.     XITEM * xi = NULL;
  534.  
  535.     if (pr == NULL || name == NULL) {
  536.     return (RET_FAIL);
  537.     } else if (name == BAR) {
  538.     for (xi = *pr; xi; pr = &xi->item.NextItem, xi = *pr) {
  539.         if (!(xi->item.Flags & ITEMTEXT)) {
  540.         break;
  541.         } /* if found */
  542.     } /* for all entries */
  543.     } else {
  544.     for (xi = *pr; xi; pr = &xi->item.NextItem, xi = *pr) {
  545.         if (xi->item.Flags & ITEMTEXT) {
  546.         char * inter = (char *)((struct IntuiText *) xi->item.ItemFill)->IText;
  547.         if (strcmp (inter, name) == 0) {
  548.             break;
  549.         } /* if found */
  550.         } /* if no BAR */
  551.     } /* for all items  */
  552.     } /* if (no) bar/name */
  553.  
  554.     if (xi) {
  555.     *pr = (struct MenuItem *)DeleteXItem (xi);
  556.     return (RET_SUCC);
  557.     } /* if */
  558.  
  559.     return (RET_FAIL);
  560. } /* rem_xitem */
  561.  
  562.  
  563.  
  564. /*****************************************************************************
  565.  
  566.     NAME
  567.     itemdel
  568.  
  569.     PARAMETER
  570.     MENUSTRIP * ms
  571.     char      * tname
  572.     char      * iname
  573.  
  574.     RESULT
  575.     success:
  576.         RET_FAIL - item name not found or wrong syntax
  577.         RET_SUCC - ok
  578.  
  579.     RETURN
  580.     int
  581.  
  582.     DESCRIPTION
  583.  
  584.     NOTES
  585.  
  586.     BUGS
  587.  
  588.     EXAMPLES
  589.  
  590.     SEE ALSO
  591.     menucom/do_delitem, menucom/do_delitembar
  592.  
  593.     INTERNALS
  594.  
  595.     HISTORY
  596.     19 Dec 1992 b_noll created
  597.  
  598. ******************************************************************************/
  599.  
  600. int itemdel (MENUSTRIP * ms, char * tname, char * iname)
  601. {
  602.     int succ = RET_FAIL;
  603.     struct Menu * menu = getmenu (ms, tname);
  604.  
  605.     if (menu) {
  606.     succ = rem_xitem (&menu->FirstItem, iname);
  607.  
  608.     if (succ && !menu->FirstItem) {
  609.         menudel (ms, tname);
  610.     } /* if */
  611.     } /* if */
  612.     return (succ);
  613. } /* itemdel */
  614.  
  615.  
  616.  
  617. /*****************************************************************************
  618.  
  619.     NAME
  620.     subdel
  621.  
  622.     PARAMETER
  623.     MENUSTRIP * ms
  624.     char      * tname
  625.     char      * iname
  626.     char      * sname
  627.  
  628.     RESULT
  629.     success:
  630.         RET_FAIL - item name not found or wrong syntax
  631.         RET_SUCC - ok
  632.  
  633.     RETURN
  634.     int
  635.  
  636.     DESCRIPTION
  637.  
  638.     NOTES
  639.  
  640.     BUGS
  641.  
  642.     EXAMPLES
  643.  
  644.     SEE ALSO
  645.     menucom/do_delsub, menucom/do_delsubbar
  646.  
  647.     INTERNALS
  648.  
  649.     HISTORY
  650.     19 Dec 1992 b_noll created
  651.  
  652. ******************************************************************************/
  653.  
  654. int subdel (MENUSTRIP * ms, char * tname, char * iname, char * sname)
  655. {
  656.     int succ = RET_FAIL;
  657.     struct MenuItem * item = getitem (ms, tname, iname);
  658.  
  659.     if (item) {
  660.     succ = rem_xitem (&item->SubItem, sname);
  661.     if (succ && !item->SubItem) {
  662.         itemdel (ms, tname, iname);
  663.     } /* if */
  664.     } /* if */
  665.     return (succ);
  666. } /* subdel */
  667.  
  668.  
  669.  
  670. /*****************************************************************************
  671.  
  672.     NAME
  673.     menuadd
  674.  
  675.     PARAMETER
  676.     MENUSTRIP * ms
  677.     char      * tname
  678.  
  679.     RESULT
  680.     success :
  681.         ==NULL = failure
  682.         !=NULL = ok (address of menu)
  683.  
  684.     RETURN
  685.     struct Menu *
  686.  
  687.     DESCRIPTION
  688.     we try to add a new menu-header to a menubar
  689.     if it does not already exist; else we simply return it
  690.  
  691.     NOTES
  692.  
  693.     BUGS
  694.  
  695.     EXAMPLES
  696.  
  697.     SEE ALSO
  698.  
  699.     INTERNALS
  700.     falls das menu schon existiert,
  701.         gib es einfach zurueck
  702.  
  703.     erzeuge einen neuen body und
  704.     ein namens-string,
  705.     fuelle es
  706.     und gib es zurueck
  707.  
  708.     HISTORY
  709.     18 Dec 1992 b_null  created
  710.  
  711. ******************************************************************************/
  712.  
  713. static
  714. struct Menu * menuadd (MENUSTRIP * ms, char * tname)
  715. {
  716.     struct Menu *  menu;
  717.     struct Menu ** pr;
  718.  
  719.     if (ms == NULL || tname == NULL) {
  720.     return (NULL);
  721.     } /* if */
  722.  
  723.     pr = &ms->data;
  724.  
  725.     for (menu = *pr; menu; pr = &menu->NextMenu, menu = *pr) {
  726.     if (strcmp (tname, menu->MenuName) == 0) {
  727.         return (menu);
  728.     } /* if menu exists */
  729.     } /* for all headers */
  730.  
  731.     menu = AllocFunc (sizeof(struct Menu), MEMF_ANY);
  732.     if (!menu) {
  733.     return (NULL);
  734.     } /* if no heap for menu */
  735.     setmem (menu, sizeof(struct Menu), 0);
  736.  
  737.     menu->MenuName = DupFunc (tname, MEMF_ANY);
  738.     if (!menu->MenuName) {
  739.     FreeFunc (menu, sizeof (struct Menu));
  740.     return (NULL);
  741.     } /* if no heap for name */
  742.  
  743.     menu->NextMenu = *pr; /* == NULL */
  744.     *pr = menu;
  745.     menu->Flags = MENUENABLED;
  746.  
  747.     return (menu);
  748. } /* menuadd */
  749.  
  750.  
  751.  
  752. /*****************************************************************************
  753.  
  754.     NAME
  755.     CreateXItem
  756.  
  757.     PARAMETER
  758.     char * name
  759.  
  760.     RESULT
  761.     new XITEM
  762.  
  763.     RETURN
  764.     XITEM *
  765.  
  766.     DESCRIPTION
  767.     creates a new XITEM and all additional data
  768.     does NOT link a macro
  769.  
  770.     NOTES
  771.  
  772.     BUGS
  773.  
  774.     EXAMPLES
  775.  
  776.     SEE ALSO
  777.  
  778.     INTERNALS
  779.     get heap fuer body
  780.     fehler ? -> abbruch
  781.     alles loeschen
  782.     BAR ?
  783.     ja-> data initialisieren
  784.     nein-> get heap fuer string
  785.         fehler ? -> abbruch
  786.         data initailisieren
  787.     ptr auf body zurueck
  788.  
  789.     HISTORY
  790.     18 Dec 1992 b_null  created
  791.  
  792. ******************************************************************************/
  793.  
  794. static
  795. XITEM * CreateXItem (char * name)
  796. {
  797.     XITEM        * xi;
  798.     struct MenuItem * item;
  799.  
  800.     xi = AllocFunc (sizeof (XITEM), MEMF_ANY);
  801.     if (!xi) {
  802.     return (NULL);
  803.     } /* if no heap for body */
  804.  
  805.     setmem (xi, sizeof(XITEM), 0);
  806.     item       = &xi->item;
  807.     item->ItemFill = &xi->fill;
  808.     item->SubItem  = NULL;    /* doppelt gemoppelt haelt besser */
  809.  
  810.     if (name == BAR) {
  811.     struct Image * im = &xi->fill.im;
  812.  
  813.     memcpy (im, &SepImage, sizeof (struct Image));
  814.     item->Flags = HIGHNONE; /* HIGHCOMP; */
  815.     } else {
  816.     struct IntuiText * it = &xi->fill.it;
  817.  
  818.     it->IText = DupFunc (name, MEMF_ANY);
  819.     if (!it->IText) {
  820.         FreeFunc (xi, sizeof(XITEM));
  821.         return (NULL);
  822.     } /* if */
  823.  
  824.     // it->BackPen      = 1;      /* These values are set in fixmenu - i hope */
  825.     // it->FrontPen   = 0;      /* These values are set in fixmenu - i hope */
  826.     // it->DrawMode   = JAM2; /* These values are set in fixmenu - i hope */
  827.  
  828.     item->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP;
  829.     } /* if */
  830.  
  831.     return (xi);
  832. } /* CreateXItem */
  833.  
  834.  
  835.  
  836. /*****************************************************************************
  837.  
  838.     NAME
  839.     mod_or_add_xitem
  840.  
  841.     PARAMETER
  842.     XITEM ** root
  843.     char   * name
  844.     char   * macro
  845.     char   * help
  846.  
  847.     RESULT
  848.     found&modifed or created XITEM or NULL
  849.  
  850.     RETURN
  851.     XITEM *
  852.  
  853.     DESCRIPTION
  854.     try to find name in the list after pr
  855.     if not found, try to create a new one
  856.     return the result or the found
  857.     (bars are always added)
  858.  
  859.     NOTES
  860.  
  861.     BUGS
  862.  
  863.     EXAMPLES
  864.  
  865.     SEE ALSO
  866.  
  867.     INTERNALS
  868.     ein BAR immer neu
  869.     sonst suche nach name
  870.         eintrag gefunden -> modifiziere ihn & gib ihn zurueck
  871.     erzeuge neuen eintrag
  872.     und gib ihn zurueck
  873.  
  874.     HISTORY
  875.     18 Dec 1992 b_null  created
  876.  
  877. ******************************************************************************/
  878.  
  879. static
  880. XITEM * mod_or_add_xitem (XITEM ** root, char * name, char * macro, char * help, int check)
  881. {
  882.     XITEM *  xi = NULL;
  883.     XITEM ** pr = root;
  884.  
  885.     if (root == NULL || name == NULL) {
  886.     return (NULL);
  887.     } else if (name == BAR) {
  888.     for (xi = *pr; xi; pr = &xi->item.NextItem, xi = *pr) {
  889.         /* do nothing - just go to the end of the list */
  890.     } /* for all entries */
  891.     } else {
  892.     for (xi = *pr; xi; pr = &xi->item.NextItem, xi = *pr) {
  893.         if (xi->item.Flags & ITEMTEXT) {
  894.         char * inter = (char *)((struct IntuiText *) xi->item.ItemFill)->IText;
  895.         if (strcmp (inter, name) == 0) {
  896.             break;
  897.         } /* if found */
  898.         } /* if no BAR */
  899.     } /* for all items */
  900.     } /* if (no) bar/name */
  901.  
  902.     /* --- not found create a new one */
  903.     if (!xi) {
  904.     xi = CreateXItem (name);
  905.     if (xi == NULL) {
  906.         return (NULL);
  907.     } /* if fail */
  908.     } /* if */
  909.  
  910.     *pr = xi->item.NextItem; /* zunaechst aus der liste loesen */
  911.  
  912.     /*
  913.     ** das sollte bei gelegenheit geaendert werden:
  914.     ** so ist es nicht moegich, ein macro zu loeschen...
  915.     */
  916.  
  917.     if (name != BAR) {
  918.     /* dies bedeutet unnoetige fragmentation : wir sollten besser erst nachschauen, ob sich werte veraendert haben */
  919.     DeallocFunc (xi->com);  xi->com  = NULL;
  920.     DeallocFunc (xi->help); xi->help = NULL;
  921.  
  922.     if (macro) {
  923.         {    /* A MACRO-CARRIER MUST NOT BE A SUB-CARRIER */
  924.         XITEM * sub = (XITEM *)xi->item.SubItem;
  925.         while (sub) {
  926.             sub = DeleteXItem (sub);
  927.         } /* while */
  928.         }
  929.  
  930.         if (check) {
  931.         xi->item.Flags |= CHECKIT|MENUTOGGLE;
  932.         } else {
  933.         xi->item.Flags &= ~(CHECKIT|MENUTOGGLE);
  934.         } /* if */
  935.  
  936.         if (!(xi->com = DupFunc (macro, MEMF_ANY))) {
  937.         DeleteXItem (xi);
  938.         return (NULL);
  939.         } /* if !replaced */
  940.     } /* if (macro) */
  941.  
  942.     if (help) {
  943.         if (!(xi->help = DupFunc (help, MEMF_ANY))) {
  944.         DeleteXItem (xi);
  945.         return (NULL);
  946.         } /* if !replaced */
  947.     } /* if (help) */
  948.     } /* if (!bar) */
  949.  
  950.     *pr = xi; /* (wieder) einhaengen erst wenn alles ok */
  951.     return (xi);
  952. } /* mod_or_add_xitem */
  953.  
  954.  
  955.  
  956. /*****************************************************************************
  957.  
  958.     NAME
  959.     itemadd
  960.  
  961.     PARAMETER
  962.     MENUSTRIP * ms
  963.     char      * tname
  964.     char      * iname
  965.     char      * macro
  966.     char      * help
  967.     int        check
  968.  
  969.     RESULT
  970.     success :
  971.         ==NULL = failure
  972.         !=NULL = ok      (address of item)
  973.  
  974.     RETURN
  975.     XITEM *
  976.  
  977.     DESCRIPTION
  978.     find a menuitem-structure of the right names
  979.     and create one at the end of the list,
  980.     if there is none.
  981.     (we try to add a item-structure to menubar)
  982.  
  983.     NOTES
  984.  
  985.     BUGS
  986.  
  987.     EXAMPLES
  988.  
  989.     SEE ALSO
  990.     menucom/do_itemadd, menucom/do_itembar
  991.  
  992.     INTERNALS
  993.     finde das richtige menu
  994.     falls der eintrag nicht existiert
  995.         erzeuge einen neuen
  996.     revidiere das commando
  997.     gib den eintrag zurueck
  998.  
  999.     HISTORY
  1000.     18 Dec 1992 b_null  created
  1001.  
  1002. ******************************************************************************/
  1003.  
  1004. XITEM * itemadd (MENUSTRIP * ms, char * tname, char * iname, char * macro, char * help, int check)
  1005. {
  1006.     struct Menu  * menu;
  1007.     XITEM     * item;
  1008.  
  1009.     if (!(menu = menuadd (ms, tname))) {
  1010.     return (NULL);
  1011.     } /* if no header */
  1012.  
  1013.     /* menues have no commands -> no comcheck */
  1014.  
  1015.     item = mod_or_add_xitem (&menu->FirstItem, iname, macro, help, check);
  1016.     if (item == NULL && menu->FirstItem == NULL) {
  1017.     menudel (ms, tname);
  1018.     return (NULL);
  1019.     } /* if fail and only item */
  1020.  
  1021.     return (item);
  1022. } /* itemadd */
  1023.  
  1024.  
  1025.  
  1026. /*****************************************************************************
  1027.  
  1028.     NAME
  1029.     subadd
  1030.  
  1031.     PARAMETER
  1032.     MENUSTRIP * ms
  1033.     char      * tname
  1034.     char      * iname
  1035.     char      * sname
  1036.     char      * macro
  1037.     char      * help
  1038.     int        check
  1039.  
  1040.     RESULT
  1041.     success : ==NULL = failure !=NULL = ok
  1042.  
  1043.     RETURN
  1044.     XITEM *
  1045.  
  1046.     DESCRIPTION
  1047.     we try to add a subitem-structure to to menubar
  1048.  
  1049.     NOTES
  1050.  
  1051.     BUGS
  1052.  
  1053.     EXAMPLES
  1054.     menucom/do_subadd, menucom/do_subbar
  1055.  
  1056.     SEE ALSO
  1057.  
  1058.     INTERNALS
  1059.     falls es kein item mit menu/item mit d. richtigen namen gibt,
  1060.         erzeuge eins
  1061.         falls das fehlschug -> abbruch
  1062.  
  1063.     falls das item ein eigenes macro hat und daher keine
  1064.         subs unterstuetzt -> abbruch
  1065.  
  1066.     falls es noch kein sub mit dem richtigen namen gibt,
  1067.         erzeuge eins (bars werden immer addiert)
  1068.  
  1069.     falls das fehlschlug und extra ein item rzeugt worden war,
  1070.         loesche das wieder -> abbruch
  1071.  
  1072.  
  1073.     HISTORY
  1074.     18 Dec 1992 b_null created
  1075.  
  1076. ******************************************************************************/
  1077.  
  1078. XITEM * subadd (MENUSTRIP * ms, char * tname, char * iname, char * sname, char * macro, char * help, int check )
  1079. {
  1080.     XITEM        * item;
  1081.     XITEM        * sub;
  1082.  
  1083.     if (iname == BAR) {
  1084.     return (NULL);
  1085.     } /* if item=bar -    ein bar soll untermenues haben ??? */
  1086.  
  1087.     if (!(item = itemadd (ms, tname, iname, NULL, NULL, 0))) {
  1088.     return (NULL);
  1089.     } /* if no item */
  1090.  
  1091.     if (item->com != NULL) {
  1092.     return (NULL);
  1093.     } /* if no subs allowed */
  1094.  
  1095.     sub = mod_or_add_xitem (&item->item.SubItem, sname, macro, help, check);
  1096.     if (sub == NULL && item->item.SubItem == NULL) {
  1097.     itemdel (ms, tname, iname);
  1098.     return (NULL);
  1099.     } /* if fail and only sub */
  1100.  
  1101.     return (sub);
  1102. } /* subadd */
  1103.  
  1104.  
  1105.  
  1106. /*****************************************************************************
  1107.  
  1108.     NAME
  1109.     savemenus
  1110.  
  1111.     PARAMETER
  1112.     MENUSTRIP * ms
  1113.     FILE      * fo
  1114.  
  1115.     RESULT
  1116.     success (senseless for the moment)
  1117.  
  1118.     RETURN
  1119.     int
  1120.  
  1121.     DESCRIPTION
  1122.  
  1123.     NOTES
  1124.     we have used an implementation-decision here, that should
  1125.     better bew invisible -
  1126.     macros must be accessible via their name, if that model is used
  1127.     else we have to rewrite parts of that function
  1128.  
  1129.     BUGS
  1130.  
  1131.     EXAMPLES
  1132.  
  1133.     SEE ALSO
  1134.     menucom/do_menusave
  1135.  
  1136.     INTERNALS
  1137.  
  1138.     HISTORY
  1139.     19 Dec 1992 b_noll  rewritten for subs/subbars
  1140.  
  1141. ******************************************************************************/
  1142.  
  1143. int savemenus (MENUSTRIP * ms, FILE * fo)
  1144. {
  1145.     struct Menu     * menu;
  1146.     struct MenuItem * item;
  1147.  
  1148.     fprintf(fo, "MENUSTRIP START\n");
  1149.     for (menu= ms->data; menu; menu = menu->NextMenu) {
  1150.     fprintf(fo, "TITLE %s\n", menu->MenuName);
  1151.     for (item = menu->FirstItem; item; item = item->NextItem) {
  1152.         if (item->Flags & ITEMTEXT) {
  1153.         char* ptr = (char *)((struct IntuiText *)item->ItemFill)->IText;
  1154.         if (item->Flags & CHECKIT) {
  1155.             fprintf(fo, "\tITEMCHECK %s\n", ptr);
  1156. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1157.          /* fprintf(fo, "\t HELP %s\n", ((XITEM*)item)->help); */
  1158.             fprintf(fo, "\t COM  %s\n", ((XITEM*)item)->com);
  1159. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1160.         } else {
  1161.             fprintf(fo, "\tITEM %s\n", ptr);
  1162.             if (item->SubItem) {
  1163.             struct MenuItem * sub;
  1164.             for (sub = item->SubItem; sub; sub = sub->NextItem) {
  1165.                 if (sub->Flags & ITEMTEXT) {
  1166.                 char* ptr = (char *)((struct IntuiText *)sub->ItemFill)->IText;
  1167.                 if (sub->Flags & CHECKIT) {
  1168.                     fprintf (fo, "\t\tSUBCHECK %s\n", ptr);
  1169.                 } else {
  1170.                     fprintf (fo, "\t\tSUB %s\n", ptr);
  1171.                 } /* if */
  1172. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1173.                  /* fprintf (fo, "\t\t HELP %s\n", ((XITEM*)item)->help); */
  1174.                 fprintf (fo, "\t\t COM  %s\n", ((XITEM*)item)->com);
  1175. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1176.                 } else {
  1177.                 fprintf (fo, "\t\tSUBBAR");
  1178.                 } /* if (not) text */
  1179.             } /* for subs */
  1180.             } else {
  1181. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1182.              /* fprintf(fo, "\t HELP %s\n", ((XITEM*)item)->help); */
  1183.             fprintf(fo, "\t COM  %s\n", ((XITEM*)item)->com);
  1184. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1185.             } /* if (not) subs */
  1186.         } /* if (not) checkitem */
  1187.         } else {
  1188.         fprintf(fo, "\tITEMBAR\n");
  1189.         } /* if (not) text */
  1190.     } /* for items */
  1191.     } /* for headers */
  1192.     fprintf(fo, "MENUSTRIP END\n");
  1193.  
  1194.     return (RET_SUCC);
  1195. } /* savemenus */
  1196.  
  1197.  
  1198.  
  1199. /*****************************************************************************
  1200.  
  1201.     NAME
  1202.     menuclear
  1203.  
  1204.     PARAMETER
  1205.     MENUSTRIP * ms
  1206.  
  1207.     RESULT
  1208.     -/-
  1209.  
  1210.     RETURN
  1211.     void
  1212.  
  1213.     DESCRIPTION
  1214.     deletes a full Menustrip
  1215.     and all connected data
  1216.  
  1217.     NOTES
  1218.  
  1219.     BUGS
  1220.  
  1221.     EXAMPLES
  1222.  
  1223.     SEE ALSO
  1224.     menucom/do_menuclear
  1225.  
  1226.     INTERNALS
  1227.  
  1228.     HISTORY
  1229.     19 Dec 1992 b_noll  created
  1230.  
  1231. ******************************************************************************/
  1232.  
  1233. void menuclear (MENUSTRIP * ms)
  1234. {
  1235.     struct Menu * menu;
  1236.  
  1237.     while (menu = ms->data) {
  1238.     menudel (ms, menu->MenuName);
  1239.     } /* while */
  1240.     ms->data = NULL;
  1241. } /* menuclear */
  1242.  
  1243.  
  1244.  
  1245. /*****************************************************************************
  1246.  
  1247.     NAME
  1248.     loadmenues
  1249.  
  1250.     PARAMETER
  1251.     MENUSTRIP * ms
  1252.     FILE      * fi
  1253.     int      * lineno
  1254.  
  1255.     RESULT
  1256.     success:
  1257.         RET_FAIL - error
  1258.         RET_SUCC - ok
  1259.  
  1260.     RETURN
  1261.     int
  1262.  
  1263.     DESCRIPTION
  1264.  
  1265.     NOTES
  1266.     we have used an implementation-decision here, that should
  1267.     better be invisible -
  1268.     macros must be accessible via their name, if that model is used
  1269.     else we have to rewrite parts of that function
  1270.  
  1271.     BUGS
  1272.     HELP may be redefined
  1273.  
  1274.     EXAMPLES
  1275.  
  1276.     SEE ALSO
  1277.     menucom/do_menuload
  1278.  
  1279.     INTERNALS
  1280.  
  1281.     HISTORY
  1282.     20 Jan 1993 b_null added check-handling
  1283.  
  1284. ******************************************************************************/
  1285.  
  1286. #define UNEX_DEF   "Unexpected %s Definition"
  1287. #define EX_TITLE    1
  1288. #define EX_ITEM     2
  1289. #define EX_ITEMBAR  4
  1290. #define EX_SUB        8
  1291. #define EX_SUBBAR  16
  1292. #define EX_COM       32
  1293. #define EX_SCOM    64
  1294. #define EX_END      128
  1295.  
  1296. #define EX_HELP   (EX_COM|EX_SCOM) /* buggy ! */
  1297.  
  1298. int loadmenus (MENUSTRIP * ms, FILE * fi, int * lineno)
  1299. {
  1300.     char * buf;
  1301.     char   ntitle [128];
  1302.     char   nitem  [128];
  1303.     char   nsub   [128];
  1304.     char   body   [LINE_LENGTH];
  1305.     char   help   [LINE_LENGTH];
  1306.     int    doloop = -1;
  1307.     int     check =  0;
  1308.     long expected =  0;
  1309.  
  1310.     buf = getnextcomline (fi, lineno);
  1311.     if (!buf) {
  1312.     /* error ("Unexpected EndOfFile"); */
  1313.     globalflags.Abortcommand = 1;
  1314.     return (RET_FAIL);
  1315.     } /* if */
  1316.     if (strncmp (buf, "MENUSTRIP START", 15) != 0) {
  1317.     error    ("No Menustart header");
  1318.     return    (RET_FAIL);
  1319.     } /* if */
  1320.  
  1321.     ntitle[0] = 0;
  1322.     nitem [0] = 0;
  1323.     nsub  [0] = 0;
  1324.     body  [0] = 0;
  1325.     help  [0] = 0;
  1326.  
  1327.     expected = EX_TITLE|EX_END;
  1328.  
  1329.     while (globalflags.Abortcommand == 0) {
  1330.     buf = getnextcomline (fi, lineno);
  1331.     if (!buf) {
  1332.         globalflags.Abortcommand = 1;
  1333.         return (RET_FAIL);
  1334.     } /* if */
  1335.  
  1336.     if (strncmp(buf, "MENUSTRIP END", 13) == 0) {
  1337.         if (!(expected & EX_END)) {
  1338.         error  (UNEX_DEF, "End Of Menu");
  1339.         return (RET_FAIL);
  1340.         } /* if */
  1341.         return (RET_SUCC);
  1342.  
  1343.     } else if (strncmp(buf, "TITLE ", 6) == 0) {
  1344.         if (!(expected & EX_TITLE)) {
  1345.         error  (UNEX_DEF, "MenuTitle");
  1346.         return (RET_FAIL);
  1347.         } /* if */
  1348.         expected = EX_ITEM|EX_ITEMBAR;
  1349.  
  1350.         buf += 6;
  1351.         strncpy (ntitle, buf, 128);
  1352.  
  1353.     } else if (strncmp(buf, "ITEM ", 5) == 0) {
  1354.         if (!(expected & EX_ITEM)) {
  1355.         error  (UNEX_DEF, "MenuItem");
  1356.         return (RET_FAIL);
  1357.         } /* if */
  1358.         expected = EX_SUB|EX_SUBBAR|EX_COM;
  1359.  
  1360.         buf += 5;
  1361.         strncpy (nitem, buf, 128);
  1362.  
  1363.     } else if (strncmp(buf, "ITEMCHECK ", 10) == 0) {
  1364.         if (!(expected & EX_ITEM)) {
  1365.         error  (UNEX_DEF, "MenuItem");
  1366.         return (RET_FAIL);
  1367.         } /* if */
  1368.         expected = EX_COM;
  1369.  
  1370.         buf += 10;
  1371.         strncpy (nitem, buf, 128);
  1372.         check = 1;
  1373.  
  1374.     } else if (strncmp(buf, "ITEMBAR", 7) == 0) {
  1375.         if (!(expected & EX_ITEMBAR)) {
  1376.         error  (UNEX_DEF, "MenuItembar");
  1377.         return (RET_FAIL);
  1378.         } /* if */
  1379.         expected = EX_ITEM|EX_ITEMBAR|EX_TITLE|EX_END;
  1380.  
  1381.         itemadd (ms, ntitle, BAR, NULL, NULL, 0);
  1382.  
  1383.     } else if (strncmp(buf, "SUB ", 4) == 0) {
  1384.         if (!(expected & EX_SUB)) {
  1385.         error  (UNEX_DEF, "SubItem");
  1386.         return (RET_FAIL);
  1387.         } /* if */
  1388.         expected = EX_SCOM;
  1389.  
  1390.         buf += 4;
  1391.         strncpy (nsub, buf, 128);
  1392.  
  1393.     } else if (strncmp(buf, "SUBCHECK ", 9) == 0) {
  1394.         if (!(expected & EX_SUB)) {
  1395.         error  (UNEX_DEF, "SubItemCheck");
  1396.         return (RET_FAIL);
  1397.         } /* if */
  1398.         expected = EX_SCOM;
  1399.  
  1400.         buf += 9;
  1401.         strncpy (nsub, buf, 128);
  1402.         check = 1;
  1403.  
  1404.     } else if (strncmp(buf, "SUBBAR", 6) == 0) {
  1405.         if (!(expected & EX_SUBBAR)) {
  1406.         error  (UNEX_DEF, "SubItembar");
  1407.         return (RET_FAIL);
  1408.         } /* if */
  1409.         expected = EX_SUB|EX_SUBBAR|EX_TITLE|EX_ITEM|EX_ITEMBAR|EX_END;
  1410.  
  1411.         subadd (ms, ntitle, nitem, BAR, NULL, NULL, 0);
  1412.  
  1413. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1414.     } else if (strncmp(buf, "HELP", 4) == 0 && (buf[4] < 33)) {
  1415.         if (!(expected & (EX_HELP))) {
  1416.         error  (UNEX_DEF, "Help");
  1417.         return (RET_FAIL);
  1418.         } /* if */
  1419.  
  1420.         buf += 3; if (*buf) buf++;
  1421.         strncpy (help, buf, LINE_LENGTH);
  1422.         expected &= EX_COM|EX_SCOM;
  1423.  
  1424.     } else if (strncmp(buf, "COM", 3) == 0 && (buf[3] < 33)) {
  1425.         /* char * h2 = help[0] ? help : NULL; */
  1426.  
  1427.         if (!(expected & (EX_COM|EX_SCOM))) {
  1428.         error  (UNEX_DEF, "Command");
  1429.         return (RET_FAIL);
  1430.         } /* if */
  1431.         /* expected = 0; */
  1432.  
  1433.         buf += 3; if (*buf) buf++;
  1434.         strncpy (body, buf, LINE_LENGTH);
  1435.         if (expected & EX_SCOM) {
  1436.         expected = EX_SUB|EX_SUBBAR|EX_TITLE|EX_ITEM|EX_ITEMBAR|EX_END;
  1437.         subadd (ms, ntitle, nitem, nsub, body, help, check );
  1438.         } else {
  1439.         expected = EX_TITLE|EX_ITEM|EX_ITEMBAR|EX_END;
  1440.         itemadd (ms, ntitle, nitem, body, help, check);
  1441.         } /* if */
  1442.         check = 0;
  1443.         help[0] = 0;
  1444. /* --- THAT BLOCK MUST BE CHANGED IF MACROS ARE MODIFIED */
  1445.     } else {
  1446.         error ("%s:\nunknown identifier '%s'", CommandName(), buf);
  1447.     } /* if types */
  1448.     } /* while not ready */
  1449.     return(RET_FAIL);
  1450. } /* loadmenus */
  1451.  
  1452.  
  1453.  
  1454. /*****************************************************************************
  1455.  
  1456.     NAME
  1457.     chkitemcheck
  1458.  
  1459.     PARAMETER
  1460.     MENUSTRIP * ms
  1461.     char      * tname
  1462.     char      * iname
  1463.  
  1464.     RESULT
  1465.     -1 error
  1466.      0/1 status of check
  1467.  
  1468.     RETURN
  1469.     int
  1470.  
  1471.     DESCRIPTION
  1472.     check the status of a checkitem
  1473.  
  1474.     NOTES
  1475.     only works with items created as check-items
  1476.  
  1477.     BUGS
  1478.     none known
  1479.  
  1480.     EXAMPLES
  1481.  
  1482.     SEE ALSO
  1483.  
  1484.     INTERNALS
  1485.  
  1486.     HISTORY
  1487.     20 Jan 1993 b_null created
  1488.  
  1489. ******************************************************************************/
  1490.  
  1491. int chkitemcheck (MENUSTRIP * ms, char * tname, char * iname)
  1492. {
  1493.     struct MenuItem * item = getitem (ms, tname, iname);
  1494.     if ((!item) && !(item->Flags & CHECKIT)) {
  1495.     return (-1);
  1496.     } /* if */
  1497.  
  1498.     if (item->Flags & CHECKED) {
  1499.     return (1);
  1500.     } /* if */
  1501.     return (0);
  1502. } /* chkitemcheck */
  1503.  
  1504.  
  1505.  
  1506. /*****************************************************************************
  1507.  
  1508.     NAME
  1509.     chksubcheck
  1510.  
  1511.     PARAMETER
  1512.     MENUSTRIP * ms
  1513.     char      * tname
  1514.     char      * iname
  1515.     char      * sname
  1516.  
  1517.     RESULT
  1518.     -1 error
  1519.      0/1 status of check
  1520.  
  1521.     RETURN
  1522.     int
  1523.  
  1524.     DESCRIPTION
  1525.     check the status of a check-subitem
  1526.  
  1527.     NOTES
  1528.     only works with subs created as check-subitems
  1529.  
  1530.     BUGS
  1531.     none known
  1532.  
  1533.     EXAMPLES
  1534.  
  1535.     SEE ALSO
  1536.  
  1537.     INTERNALS
  1538.  
  1539.     HISTORY
  1540.     20 Jan 1993 b_null created
  1541.  
  1542. ******************************************************************************/
  1543.  
  1544. int chksubcheck (MENUSTRIP * ms, char * tname, char * iname, char * sname)
  1545. {
  1546.     struct MenuItem * sub = getsub (ms, tname, iname, sname);
  1547.  
  1548.     if ((!sub) && !(sub->Flags & CHECKIT)) {
  1549.     return (-1);
  1550.     } /* if */
  1551.  
  1552.     if (sub->Flags & CHECKED) {
  1553.     return (1);
  1554.     } /* if */
  1555.     return (0);
  1556. } /* chksubcheck */
  1557.  
  1558.  
  1559.  
  1560. /*****************************************************************************
  1561.  
  1562.     NAME
  1563.     setitemcheck
  1564.  
  1565.     PARAMETER
  1566.     MENUSTRIP * ms
  1567.     char      * tname
  1568.     char      * iname
  1569.  
  1570.     RESULT
  1571.     success :
  1572.         RET_FAIL - not found or error
  1573.         RET_SUCC - ok
  1574.  
  1575.     RETURN
  1576.     int
  1577.  
  1578.     DESCRIPTION
  1579.     set the status of a check-item
  1580.  
  1581.     NOTES
  1582.     only works with items created as check-items
  1583.  
  1584.     BUGS
  1585.     none known
  1586.  
  1587.     EXAMPLES
  1588.  
  1589.     SEE ALSO
  1590.  
  1591.     INTERNALS
  1592.  
  1593.     HISTORY
  1594.     20 Jan 1993 b_null created
  1595.  
  1596. ******************************************************************************/
  1597.  
  1598. int setitemcheck (MENUSTRIP * ms, char * tname, char * iname, int status)
  1599. {
  1600.     struct MenuItem * item = getitem (ms, tname, iname);
  1601.  
  1602.     if ((!item) && !(item->Flags & CHECKIT)) {
  1603.     return (RET_FAIL);
  1604.     } /* if */
  1605.  
  1606.     if (status) {
  1607.     item->Flags |= CHECKED;
  1608.     } else {
  1609.     item->Flags &= ~CHECKED;
  1610.     } /* if */
  1611.     return (RET_SUCC);
  1612. } /* setitemcheck */
  1613.  
  1614.  
  1615.  
  1616. /*****************************************************************************
  1617.  
  1618.     NAME
  1619.     setsubcheck
  1620.  
  1621.     PARAMETER
  1622.     MENUSTRIP * ms
  1623.     char      * tname
  1624.     char      * iname
  1625.     char      * sname
  1626.  
  1627.     RESULT
  1628.     success :
  1629.         RET_FAIL - not found or error
  1630.         RET_SUCC - ok
  1631.  
  1632.     RETURN
  1633.     int
  1634.  
  1635.     DESCRIPTION
  1636.     set the status of a check-subitem
  1637.  
  1638.     NOTES
  1639.     only works with subs created as check-subitems
  1640.  
  1641.     BUGS
  1642.     none known
  1643.  
  1644.     EXAMPLES
  1645.  
  1646.     SEE ALSO
  1647.  
  1648.     INTERNALS
  1649.  
  1650.     HISTORY
  1651.     20 Jan 1993 b_null created
  1652.  
  1653. ******************************************************************************/
  1654.  
  1655. int setsubcheck (MENUSTRIP * ms, char * tname, char * iname, char * sname, int status)
  1656. {
  1657.     struct MenuItem * sub = getsub (ms, tname, iname, sname);
  1658.  
  1659.     if ((!sub) && !(sub->Flags & CHECKIT)) {
  1660.     return (RET_FAIL);
  1661.     } /* if */
  1662.  
  1663.     if (status) {
  1664.     sub->Flags |= CHECKED;
  1665.     } else {
  1666.     sub->Flags &= ~CHECKED;
  1667.     } /* if */
  1668.     return (RET_SUCC);
  1669. } /* setsubcheck */
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678. /* old DATA */
  1679.  
  1680. /*
  1681. **  Die Folgenden functionen haben noch keine Header
  1682. **  und sind teilweise noch nicht fertig
  1683. */
  1684.  
  1685.  
  1686. /*****************************************************************************
  1687.  
  1688.     NAME
  1689.     def_menus
  1690.  
  1691.     PARAMETER
  1692.     MENUSTRIP * ms
  1693.  
  1694.     RESULT
  1695.  
  1696.     RETURN
  1697.  
  1698.     DESCRIPTION
  1699.  
  1700.     NOTES
  1701.  
  1702.     BUGS
  1703.  
  1704.     EXAMPLES
  1705.  
  1706.     SEE ALSO
  1707.  
  1708.     INTERNALS
  1709.  
  1710.     HISTORY
  1711.     Jan 1993 b_null created
  1712.  
  1713. ******************************************************************************/
  1714.  
  1715.  
  1716. int def_menus (MENUSTRIP * ms)
  1717. {
  1718. //    int i;
  1719. //    int succ;
  1720.  
  1721.     ms->offCount = 0;
  1722.     menuclear (ms);
  1723.  
  1724. #   ifdef NOT_DEF /* PATCH_NULL [04 Feb 1993] : Hierher koennte noch ein Default-menue eintrag */
  1725.     for (i = 0, succ = RET_SUCC; (succ == RET_SUCC) && (def_menu[i].title != NULL); i++) {
  1726.         if (def_menu[i].sub) {
  1727.         succ = subadd  (ms, def_menu[i].title, def_menu[i].item, def_menu[i].sub, def_menu[i].body, def_menu[i].help, def_menu[i].check);
  1728.         } else {
  1729.         succ = itemadd (ms, def_menu[i].title, def_menu[i].item,                  def_menu[i].body, def_menu[i].help, def_menu[i].check);
  1730.         } /* if sub */
  1731.     } /* for def_menu */
  1732. #   endif
  1733.  
  1734.     return (RET_SUCC);
  1735. } /* def_menus */
  1736.  
  1737.  
  1738.  
  1739.  
  1740. /*****************************************************************************
  1741.  
  1742.     NAME
  1743.     split_menu_names
  1744.  
  1745.     PARAMETER
  1746.     char *    source
  1747.     char ** menu
  1748.     char ** item
  1749.     char ** sub
  1750.  
  1751.     RESULT
  1752.     success:
  1753.         RET_SUCC == everythink ok
  1754.         RET_FAIL == any failure
  1755.  
  1756.     RETURN
  1757.     int
  1758.  
  1759.     DESCRIPTION
  1760.     that function is to extract the menu-, item- and subitem-
  1761.     names out of a single string
  1762.  
  1763.     there is no test, if these extracted names are part of a menustrip
  1764.  
  1765.     NOTES
  1766.     the MENU_DELIMITER must not be part of a menuname
  1767.     the ITEM_DELIMITER must not be part of an itemname
  1768.     else we might get serious problems
  1769.  
  1770.     BUGS
  1771.  
  1772.     EXAMPLES
  1773.  
  1774.     SEE ALSO
  1775.  
  1776.     INTERNALS
  1777.     suche nach dem MENU_DELIMITER,
  1778.         kopiere den string bis dort nach menuname
  1779.     suche nach dem ITEM_DELIMITER
  1780.         gefunden -> kopiere den string bis dort nach itemname,
  1781.             den rest nach subname
  1782.         sonst    -> kopiere den string nach itemname
  1783.  
  1784.     HISTORY
  1785.     01 Feb 1993 b_null created
  1786.  
  1787. ******************************************************************************/
  1788.  
  1789. int split_menu_names (char * source, char ** menu, char ** item, char ** sub)
  1790. {
  1791.     static char menuname[128];
  1792.     static char itemname[128];
  1793.     static char subname [128];
  1794.     int     i;
  1795.  
  1796.     *menu = NULL;
  1797.     *item = NULL;
  1798.     *sub  = NULL;
  1799.  
  1800.     for (i = 0; source[i] && source[i] != MENU_DELIMITER; ++i);
  1801.     if (source[i] == MENU_DELIMITER) {
  1802.     /* Punkt 1 : hier bin ich noch nicht zufrieden: was passiert, wenn ein name ein '-' enthaelt */
  1803.     strncpy(menuname, source, i);
  1804.     menuname[i] = 0;
  1805.     *menu = menuname;
  1806.  
  1807.     source += (i+1);
  1808.     for (i = 0; source[i] && source[i] != ITEM_DELIMITER; ++i);
  1809.     strncpy(itemname, source, i);
  1810.     *item = itemname;
  1811.     itemname[i] = 0;
  1812.  
  1813.     if (source[i] == ITEM_DELIMITER) {
  1814.         source += (i+1);
  1815.         strcpy (subname, source);
  1816.         *sub  = subname;
  1817.     } /* if contains subname */
  1818.     return (RET_SUCC);
  1819.     } /* if contains itemname */
  1820.     return (RET_FAIL);
  1821. } /* split_menu_names */
  1822.  
  1823.  
  1824.  
  1825. /*****************************************************************************
  1826.  
  1827.     NAME
  1828.     findmenu
  1829.  
  1830.     PARAMETER
  1831.     MENUSTRIP * ms
  1832.     char      * name
  1833.  
  1834.     RESULT
  1835.  
  1836.     RETURN
  1837.  
  1838.     DESCRIPTION
  1839.  
  1840.     NOTES
  1841.  
  1842.     BUGS
  1843.  
  1844.     EXAMPLES
  1845.  
  1846.     SEE ALSO
  1847.  
  1848.     INTERNALS
  1849.  
  1850.     HISTORY
  1851.     29 Dec 1992 b_null created
  1852.     01 Feb 1993 b_null splitted
  1853.  
  1854. ******************************************************************************/
  1855.  
  1856. struct MenuItem * findmenu (MENUSTRIP * ms, char * str)
  1857. {
  1858.     char        * header;
  1859.     char        * itembuf;
  1860.     char        * subbuf;
  1861. //    short        i;
  1862. //    char          * ptr;
  1863.     struct Menu     * menu;
  1864.     struct MenuItem * item;
  1865.     struct MenuItem * sub;
  1866.  
  1867.     split_menu_names (str, &header, &itembuf, &subbuf);
  1868.  
  1869.     if ((header) && (menu = getmenu (ms, header))) {
  1870.     if ((itembuf) && (item = get_xitem ((XITEM *)menu->FirstItem, itembuf))) {
  1871.         if ((subbuf) && (sub = get_xitem ((XITEM *)item->SubItem, subbuf))) {
  1872.         return (sub);
  1873.         } else if (subbuf) {
  1874.         return (NULL);
  1875.         } /* if subitem */
  1876.         return (item);
  1877.     } /* if found item */
  1878.     } /* if found menu */
  1879.     return (NULL);
  1880. } /* findmenu */
  1881.  
  1882.  
  1883. /*****************************************************************************
  1884.  
  1885.     NAME
  1886.     menu2macro
  1887.  
  1888.     PARAMETER
  1889.     MENUSTRIP * ms
  1890.     char      * name
  1891.  
  1892.     RESULT
  1893.     the macro used by the menu name
  1894.  
  1895.     RETURN
  1896.     APTR
  1897.  
  1898.     DESCRIPTION
  1899.  
  1900.     NOTES
  1901.     perhaps user has to call macroname, macrohelp or sthng like that
  1902.     to get the wanted information
  1903.  
  1904.     BUGS
  1905.  
  1906.     EXAMPLES
  1907.  
  1908.     SEE ALSO
  1909.  
  1910.     INTERNALS
  1911.  
  1912.     HISTORY
  1913.     20 Dec 1992 b_null created
  1914.  
  1915. ******************************************************************************/
  1916.  
  1917. APTR menu2macro (MENUSTRIP * ms, char * str)
  1918. {
  1919.     XITEM * xi;
  1920.  
  1921.     if (xi = (XITEM *)findmenu (ms, str)) {
  1922.     if (xi->com) {
  1923.         return (xi->com);
  1924.     } /* if */
  1925.     } /* if */
  1926.     return (NULL);
  1927. } /* menu2macro */
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933. /*****************************************************************************
  1934.  
  1935.     BASIC FUNCTIONS ON MENUSTRIPS :
  1936.  
  1937.     get, new, delete
  1938.  
  1939.     all menustrips created with new_menustrip are deleted at program termination
  1940.  
  1941. *****************************************************************************/
  1942.  
  1943. /*****************************************************************************
  1944.  
  1945.     NAME
  1946.     get_menustrip
  1947.  
  1948.     PARAMETER
  1949.     char * name
  1950.  
  1951.     RESULT
  1952.     the menustrip with the name name, if it is already existing
  1953.     else NULL
  1954.  
  1955.     RETURN
  1956.     MENUSTRIP *
  1957.  
  1958.     DESCRIPTION
  1959.     search function on the hidden list of menustrips
  1960.  
  1961.     NOTES
  1962.     useful only, if we are using multiple menustrips
  1963.  
  1964.     BUGS
  1965.  
  1966.     EXAMPLES
  1967.  
  1968.     SEE ALSO
  1969.  
  1970.     INTERNALS
  1971.  
  1972.     HISTORY
  1973.     27 Jan 1993 b_null created
  1974.  
  1975. ******************************************************************************/
  1976.  
  1977. MENUSTRIP * get_menustrip (char * name)
  1978. {
  1979.     MENUSTRIP * ms;
  1980.  
  1981.     if (name == NULL) {
  1982.     return (GetHead (&MenuStrips));
  1983.     } /* if wanted default */
  1984.  
  1985.     for (ms = GetHead (&MenuStrips); ms; ms = GetSucc(ms)) {
  1986.     if (strcmp (ms->node.ln_Name, name) == 0) {
  1987.         return (ms);
  1988.     } /* if */
  1989.     } /* for */
  1990.     return (NULL);
  1991. } /* get_menustrip */
  1992.  
  1993.  
  1994.  
  1995. /*****************************************************************************
  1996.  
  1997.     NAME
  1998.     delete_menustrip
  1999.  
  2000.     PARAMETER
  2001.     MENUSTRIP * ms
  2002.     int        force
  2003.  
  2004.     RESULT
  2005.     -/-
  2006.  
  2007.     RETURN
  2008.     void
  2009.  
  2010.     DESCRIPTION
  2011.     delete a full menustrip
  2012.     that function does NOT delete the last menustrip,
  2013.     unless force is set to 1
  2014.  
  2015.     NOTES
  2016.     useful only, if we are using multiple menustrips
  2017.  
  2018.     that function does NOT take care of any references to a menustrip
  2019.     You must do that job on a higher abstraction-level
  2020.         (e.g. in menucom.c - for all ED's if )
  2021.  
  2022.     BUGS
  2023.  
  2024.     EXAMPLES
  2025.  
  2026.     SEE ALSO
  2027.  
  2028.     INTERNALS
  2029.     ausklinken aus der menustrip-liste
  2030.     loeschen der menuestruktur
  2031.     loeschen des namens
  2032.     loeschen des bodies
  2033.  
  2034.     HISTORY
  2035.     27 Jan 1993 b_null created
  2036.  
  2037. ******************************************************************************/
  2038.  
  2039. void delete_menustrip (MENUSTRIP * ms, int force)
  2040. {
  2041.     if (ms) {
  2042.     Remove (&ms->node);
  2043.     if ((!force) && (!GetHead (&MenuStrips))) {
  2044.         AddHead ((struct List *)&MenuStrips, &ms->node);
  2045.         return;
  2046.     } /* if */
  2047.  
  2048.     menuclear (ms);
  2049.     DeallocFunc (ms->node.ln_Name);
  2050.     FreeFunc    (ms, sizeof (MENUSTRIP));
  2051.     } /* if */
  2052. } /* delete_menustrip */
  2053.  
  2054.  
  2055.  
  2056. /*****************************************************************************
  2057.  
  2058.     NAME
  2059.     new_menustrip
  2060.  
  2061.     PARAMETER
  2062.     char * name
  2063.     int    defaults
  2064.  
  2065.     RESULT
  2066.     either a new menustrip, if there is not already one with that name
  2067.     or the first menustrip, that matches that name
  2068.     if we have to create a new one, we can set defaults to 1 to
  2069.     fill in the default-menustrip
  2070.  
  2071.     RETURN
  2072.     MENUSTRIP *
  2073.  
  2074.     DESCRIPTION
  2075.  
  2076.     NOTES
  2077.     useful only, if we are using multiple menustrips
  2078.  
  2079.     if we can fill in only parts of the deafult-information,
  2080.     we do NOT fail
  2081.  
  2082.     BUGS
  2083.  
  2084.     EXAMPLES
  2085.  
  2086.     SEE ALSO
  2087.  
  2088.     INTERNALS
  2089.  
  2090.     HISTORY
  2091.     27 Jan 1993 b_null created
  2092.  
  2093. ******************************************************************************/
  2094.  
  2095. MENUSTRIP * new_menustrip (char * name, int defaults)
  2096. {
  2097.     MENUSTRIP * ms;
  2098.  
  2099.     if (ms = get_menustrip(name)) {
  2100.     /* goto newvalue; */ /* that way we do reset an existing menustrip, if we call new */
  2101.     return (ms);         /* that way we only use an existing menustrip, if we call new */
  2102.     } /* if */
  2103.  
  2104.     ms = AllocFunc (sizeof(MENUSTRIP), MEMF_ANY);
  2105.     if (ms == NULL) {
  2106.     return (NULL);
  2107.     } /* if */
  2108.  
  2109.     setmem (ms, sizeof(MENUSTRIP), 0);
  2110.     ms->node.ln_Name = DupFunc (name, MEMF_ANY);
  2111.     if (ms->node.ln_Name == NULL) {
  2112.     FreeFunc (ms, sizeof (MENUSTRIP));
  2113.     return (NULL);
  2114.     } /* if */
  2115.  
  2116.     AddTail ((struct List *)&MenuStrips, &ms->node);
  2117.  
  2118. newvalue:
  2119.  
  2120.     if (defaults) {
  2121.     def_menus (ms);
  2122.     } /* if */
  2123.  
  2124.     return (ms);
  2125. } /* new_menustrip */
  2126.  
  2127.  
  2128.  
  2129. /*****************************************************************************
  2130.  
  2131.     NAME
  2132.     exit_menustrips
  2133.  
  2134.     PARAMETER
  2135.     void
  2136.  
  2137.     RESULT
  2138.     -/-
  2139.  
  2140.     RETURN
  2141.     void
  2142.  
  2143.     DESCRIPTION
  2144.     exit function for menustrips
  2145.  
  2146.     NOTES
  2147.     useful only, if we are using multiple menustrips
  2148.  
  2149.     THIS is an __AUTOEXIT - function !!!!
  2150.  
  2151.     BUGS
  2152.  
  2153.     EXAMPLES
  2154.  
  2155.     SEE ALSO
  2156.  
  2157.     INTERNALS
  2158.  
  2159.     HISTORY
  2160.     27 Jan 1993 b_null created
  2161.  
  2162. ******************************************************************************/
  2163.  
  2164. __autoexit
  2165. void exit_menustrips (void)
  2166. {
  2167.     MENUSTRIP * ms;
  2168.  
  2169. /* PutStr ("menu_exiting\n"); */
  2170.     while (ms = GetHead (&MenuStrips)) {
  2171.     delete_menustrip (ms, 1);
  2172.     } /* while */
  2173. /* PutStr ("menu_exited\n"); */
  2174. } /* exit_menustrips */
  2175.  
  2176.  
  2177.  
  2178.  
  2179. /******************************************************************************
  2180. *****  ENDE menustrips.c
  2181. ******************************************************************************/
  2182.