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