home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd2.bin / suse / inst-sys / lib / YaST2 / clients / menu.ycp < prev    next >
Encoding:
Text File  |  2000-03-30  |  6.2 KB  |  179 lines

  1. // YaST2 main menu
  2. {
  3.     /*
  4.      * In order to have a menu entry in the YaST2 menu, a component
  5.      * needs to fullfill the following properties:
  6.      * - A file in YASTHOME/menuentries must exist and end in .ycp
  7.      * - One of the following two properies must hold:
  8.      *   1) The menuentry file must contain a YCP list describing the menu entry, or
  9.      *   2) The menuentry file must contain an expression that evaluates to such a list.
  10.      *      This expression is usually of the form CallModule("modulename", [ "get_menuentry" ])
  11.      * - The list describing the menuentry has the form
  12.      *   [ string modulname, map moduleinfo ], where moduleinfo is a map with the folloing keys:
  13.      *   `menuentry    : string   ( Path in the menu, for example Hardware/ISDN )
  14.      *   `arguments    : list     ( Argument list for calling the menu )
  15.      *   `widget       : term     ( A widget to display at the right part )
  16.      *   `codefragment : any      ( An optional code fragment that is evaluate of one of the 
  17.      *                              widgets in `widget is triggered with the variable widgetid
  18.      *                              set to the id of the widget )
  19.      */
  20.  
  21.  
  22.     /* 
  23.      * Define UI macros
  24.      */
  25.  
  26.   UI(``{
  27.       /*
  28.        * Create and show the dialog. As parameter I get a prepared list of items.
  29.        * Each item represents one YaST2 module and has the form 
  30.        * `item(`id(string modulename, term|void widget), string menuentry).
  31.        * The widget is a term structure representing a widget, which is then being
  32.        * displayed. If widget is nil, `Empty() is displayed.
  33.        */
  34.       define OpenMenu(list itemlist, any logo) ``{
  35.       OpenDialog(`opt(`defaultsize), 
  36.              `VBox(
  37.                `Image(logo, "SuSE"),
  38.  
  39.                `HCenter(`Heading(_("YaST2 System Configuration and Administration"))),
  40.  
  41.                `HBox(`HWeight(30, 
  42.                         `SelectionBox(`id(`modulelist), `opt(`notify, `immediate),
  43.                                   _("Available modules"),
  44.                                   itemlist)
  45.                       ),
  46.                  `HWeight(70, 
  47.                       `VBox(`Label(" "),
  48.                         `HVCenter(`ReplacePoint(`id(`content), `Empty()))
  49.                         )
  50.                       )
  51.                  ),
  52.                `HBox(
  53.                  `HWeight(25, `HStretch()),
  54.                  `HWeight(50, `PushButton(`id(`launch), `opt(`disabled, `default, `hstretch), _("&Launch module"))),
  55.                  `HWeight(25, `HStretch()),
  56.                  `PushButton(`id(`cancel), _("&Quit")))
  57.                )
  58.              );
  59.       };
  60.  
  61.       
  62.       /*
  63.        * Wait for user input and handle the showing of the module dependent
  64.        * widget, if the user selects the module in the selectionbox. 
  65.        * Returns `cancel, if the user cancels.
  66.        * Returns `launch(string modulename), if the user wants to start a module
  67.        * Returns `module(string modulename, any widgetid), if the user clicked some
  68.        * widget that is contained in the module specific widget.
  69.        */
  70.       define MenuUserInput() ``{
  71.  
  72.       while (true) 
  73.       {
  74.           any input = UserInput();
  75.           if      (input == `cancel) return `cancel;
  76.           
  77.           else if (input == `modulelist) {
  78.           any id      = QueryWidget(`id(`modulelist), `CurrentItem);
  79.           boolean launch = substring(select(id, 0), 0, 1) != "#";
  80.           term widget = select(id, 1);
  81.           ReplaceWidget(`id(`content), widget);
  82.           ChangeWidget(`id(`launch), `Enabled, launch);
  83.           }
  84.           
  85.           else if (input == `launch)
  86.           return `launch(select(QueryWidget(`id(`modulelist), `CurrentItem), 0));
  87.           
  88.           else // module specific widget triggered
  89.           return `module(select(QueryWidget(`id(`modulelist), `CurrentItem), 0), input);
  90.       }
  91.       };
  92.   
  93.     
  94.       /*
  95.        * Closes the Dialog
  96.        */ 
  97.       define CloseMenu() ``CloseDialog();
  98.   });
  99.   
  100.   /*
  101.  * Now I prepare the map of modules. I read all .ycp files in MENUENTRYDIR.
  102.    * In order to create a menuentry, put a ycp file into MENUENTRYDIR. The ycp
  103.    * file must contain a data structure of the form [ string modulname, map moduleinfo ].
  104.    * The following keys are defined for the map:
  105.    * `menuentry    :  A module name string for the selection box
  106.    * `arguments    : (optional) A list of arguments the module shall be called with
  107.    * `widget       : (optional) A widget to be displayed
  108.    * `codefragment : (optional) A code fragment to be executed when a widget is triggered
  109.    * 
  110.    * Any other ycp files not conforming to that format are reported as warnings
  111.    * in the y2log.
  112.    *
  113.    * Each entry gets a key/value pair in the modulemap. The key is the name of
  114.    * the module.
  115.    */
  116.   string MENUENTRYDIR = "/lib/YaST2/menuentries";
  117.   map modulemap = $[ "#welcome" :
  118.            $[
  119.              `menuentry    : UI(_(" WELCOME ")),
  120.              `arguments    : [ ],
  121.              `widget       : `Label(UI(_("Welcome to YaST2!"))),
  122.              `codefragment : nil
  123.            ]];
  124.  
  125.   foreach(`entry, Dir(MENUENTRYDIR), ``{
  126.  
  127.       if (substring(entry, size(entry)-4) == ".ycp") 
  128.     {
  129.       any content =  Read(MENUENTRYDIR + "/" + entry);
  130.       if (is(content, [ string modulname, map moduleinfo ]))
  131.         {
  132.           modulemap = add(modulemap, select(content, 0), select(content, 1));
  133.         }
  134.       else // try to evaluate
  135.         {
  136.           any entryvalue = eval(content);
  137.           if (is(entryvalue, [ string modulname, map moduleinfo ]))
  138.         modulemap = add(modulemap, select(entryvalue, 0), select(entryvalue, 1));
  139.           else
  140.         y2log(.warning, "menu", 1, "Invalid menuentry file " + MENUENTRYDIR + "/" + entry);
  141.         }
  142.     }
  143.   });
  144.  
  145.  
  146.   /*
  147.    * Read the special log for the menu. If it's not available, fall back 
  148.    * to the normal suse header.
  149.    */
  150.  
  151.   any logo = `suseheader; // ReadByteblock("/lib/YaST2/images/menulogo.png");
  152. //  if (!is(logo, byteblock)) logo = `suseheader;
  153.  
  154.   list itemlist = sort(`item1, `item2,
  155.                maplist(`key, `value, modulemap, ``(`item(`id([key, lookup(value, `widget, `Empty())]), 
  156.                                  lookup(value, `menuentry, key)))),
  157.                ``(select(item1, 1) < select(item2,1)));
  158.                
  159.   UI(`OpenMenu(itemlist, logo));
  160.   while (true) {
  161.     any ret = UI(`MenuUserInput());
  162.     if (ret == `cancel) break;
  163.     else if (is(ret, term) && symbolof(ret) == `launch) 
  164.     {
  165.         CallModule(select(ret, 0), []);
  166.     UI(`SetModulename("menu"));
  167.     }
  168.     else if (is(ret, term) && symbolof(ret) == `module) 
  169.     {
  170.         string module       = select(ret, 0);
  171.         any    widgetid     = select(ret, 1);
  172.         any    codefragment = lookup(lookup(modulemap, module), `codefragment, nil);
  173.     eval(codefragment);
  174.     }
  175.   }
  176.  
  177.   UI(`CloseMenu());
  178. }
  179.