home *** CD-ROM | disk | FTP | other *** search
- // YaST2 main menu
- {
- /*
- * In order to have a menu entry in the YaST2 menu, a component
- * needs to fullfill the following properties:
- * - A file in YASTHOME/menuentries must exist and end in .ycp
- * - One of the following two properies must hold:
- * 1) The menuentry file must contain a YCP list describing the menu entry, or
- * 2) The menuentry file must contain an expression that evaluates to such a list.
- * This expression is usually of the form CallModule("modulename", [ "get_menuentry" ])
- * - The list describing the menuentry has the form
- * [ string modulname, map moduleinfo ], where moduleinfo is a map with the folloing keys:
- * `menuentry : string ( Path in the menu, for example Hardware/ISDN )
- * `arguments : list ( Argument list for calling the menu )
- * `widget : term ( A widget to display at the right part )
- * `codefragment : any ( An optional code fragment that is evaluate of one of the
- * widgets in `widget is triggered with the variable widgetid
- * set to the id of the widget )
- */
-
-
- /*
- * Define UI macros
- */
-
- UI(``{
- /*
- * Create and show the dialog. As parameter I get a prepared list of items.
- * Each item represents one YaST2 module and has the form
- * `item(`id(string modulename, term|void widget), string menuentry).
- * The widget is a term structure representing a widget, which is then being
- * displayed. If widget is nil, `Empty() is displayed.
- */
- define OpenMenu(list itemlist, any logo) ``{
- OpenDialog(`opt(`defaultsize),
- `VBox(
- `Image(logo, "SuSE"),
-
- `HCenter(`Heading(_("YaST2 System Configuration and Administration"))),
-
- `HBox(`HWeight(30,
- `SelectionBox(`id(`modulelist), `opt(`notify, `immediate),
- _("Available modules"),
- itemlist)
- ),
- `HWeight(70,
- `VBox(`Label(" "),
- `HVCenter(`ReplacePoint(`id(`content), `Empty()))
- )
- )
- ),
- `HBox(
- `HWeight(25, `HStretch()),
- `HWeight(50, `PushButton(`id(`launch), `opt(`disabled, `default, `hstretch), _("&Launch module"))),
- `HWeight(25, `HStretch()),
- `PushButton(`id(`cancel), _("&Quit")))
- )
- );
- };
-
-
- /*
- * Wait for user input and handle the showing of the module dependent
- * widget, if the user selects the module in the selectionbox.
- * Returns `cancel, if the user cancels.
- * Returns `launch(string modulename), if the user wants to start a module
- * Returns `module(string modulename, any widgetid), if the user clicked some
- * widget that is contained in the module specific widget.
- */
- define MenuUserInput() ``{
-
- while (true)
- {
- any input = UserInput();
- if (input == `cancel) return `cancel;
-
- else if (input == `modulelist) {
- any id = QueryWidget(`id(`modulelist), `CurrentItem);
- boolean launch = substring(select(id, 0), 0, 1) != "#";
- term widget = select(id, 1);
- ReplaceWidget(`id(`content), widget);
- ChangeWidget(`id(`launch), `Enabled, launch);
- }
-
- else if (input == `launch)
- return `launch(select(QueryWidget(`id(`modulelist), `CurrentItem), 0));
-
- else // module specific widget triggered
- return `module(select(QueryWidget(`id(`modulelist), `CurrentItem), 0), input);
- }
- };
-
-
- /*
- * Closes the Dialog
- */
- define CloseMenu() ``CloseDialog();
- });
-
- /*
- * Now I prepare the map of modules. I read all .ycp files in MENUENTRYDIR.
- * In order to create a menuentry, put a ycp file into MENUENTRYDIR. The ycp
- * file must contain a data structure of the form [ string modulname, map moduleinfo ].
- * The following keys are defined for the map:
- * `menuentry : A module name string for the selection box
- * `arguments : (optional) A list of arguments the module shall be called with
- * `widget : (optional) A widget to be displayed
- * `codefragment : (optional) A code fragment to be executed when a widget is triggered
- *
- * Any other ycp files not conforming to that format are reported as warnings
- * in the y2log.
- *
- * Each entry gets a key/value pair in the modulemap. The key is the name of
- * the module.
- */
- string MENUENTRYDIR = "/lib/YaST2/menuentries";
- map modulemap = $[ "#welcome" :
- $[
- `menuentry : UI(_(" WELCOME ")),
- `arguments : [ ],
- `widget : `Label(UI(_("Welcome to YaST2!"))),
- `codefragment : nil
- ]];
-
- foreach(`entry, Dir(MENUENTRYDIR), ``{
-
- if (substring(entry, size(entry)-4) == ".ycp")
- {
- any content = Read(MENUENTRYDIR + "/" + entry);
- if (is(content, [ string modulname, map moduleinfo ]))
- {
- modulemap = add(modulemap, select(content, 0), select(content, 1));
- }
- else // try to evaluate
- {
- any entryvalue = eval(content);
- if (is(entryvalue, [ string modulname, map moduleinfo ]))
- modulemap = add(modulemap, select(entryvalue, 0), select(entryvalue, 1));
- else
- y2log(.warning, "menu", 1, "Invalid menuentry file " + MENUENTRYDIR + "/" + entry);
- }
- }
- });
-
-
- /*
- * Read the special log for the menu. If it's not available, fall back
- * to the normal suse header.
- */
-
- any logo = `suseheader; // ReadByteblock("/lib/YaST2/images/menulogo.png");
- // if (!is(logo, byteblock)) logo = `suseheader;
-
- list itemlist = sort(`item1, `item2,
- maplist(`key, `value, modulemap, ``(`item(`id([key, lookup(value, `widget, `Empty())]),
- lookup(value, `menuentry, key)))),
- ``(select(item1, 1) < select(item2,1)));
-
- UI(`OpenMenu(itemlist, logo));
- while (true) {
- any ret = UI(`MenuUserInput());
- if (ret == `cancel) break;
- else if (is(ret, term) && symbolof(ret) == `launch)
- {
- CallModule(select(ret, 0), []);
- UI(`SetModulename("menu"));
- }
- else if (is(ret, term) && symbolof(ret) == `module)
- {
- string module = select(ret, 0);
- any widgetid = select(ret, 1);
- any codefragment = lookup(lookup(modulemap, module), `codefragment, nil);
- eval(codefragment);
- }
- }
-
- UI(`CloseMenu());
- }
-