home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / WizardHW.ycp < prev    next >
Text File  |  2006-11-29  |  15KB  |  534 lines

  1. /**
  2.  * File:    modules/WizardHW
  3.  * Package:    Base YaST package
  4.  * Summary:    Routines for generic hardware summary dialog
  5.  * Authors:    Jiri Srain <jsrain@suse.cz>
  6.  *
  7.  * $Id: WizardHW.ycp 31290 2006-06-02 10:54:10Z jsrain $
  8.  *
  9.  */
  10.  
  11. {
  12.  
  13. module "WizardHW";
  14. textdomain "base";
  15.  
  16. import "CWM";
  17. import "Label";
  18. import "Report";
  19. import "Popup";
  20. import "Wizard";
  21.  
  22.  
  23.  
  24.  
  25.  
  26. // local store
  27.  
  28. /**
  29.  * List of items in the currently displayed dialog
  30.  */
  31. list<map<string,any> > current_items = [];
  32.  
  33. /**
  34.  * Map of rich text descriptions for all items
  35.  * Contained info can be reachable through current_items, this is for
  36.  * faster access
  37.  */
  38. map<string,string> descriptions = $[];
  39.  
  40. /**
  41.  * The last handled UI event
  42.  */
  43. map last_event = $[];
  44.  
  45. /**
  46.  * The return value to be returned by WizardHW::WaitForEvent ()
  47.  */
  48. map<string,any> dialog_ret = nil;
  49.  
  50. // callbacks
  51.  
  52. /**
  53.  * Callback
  54.  * Perform an action (when an event which is not handled internally occurred)
  55.  */
  56. symbol(string,map) action_callback = nil;
  57.  
  58. /**
  59.  * Callback
  60.  * Get rich text description of an item.
  61.  * This can be used to set it dynamically
  62.  */
  63. string(string) get_item_descr_callback = nil;
  64.  
  65. /**
  66.  * Callback
  67.  * Set all the items
  68.  * Should call the SetContents function of this module
  69.  */
  70. void() set_items_callback = nil;
  71.  
  72. /**
  73.  * Callback
  74.  * Select the initial item
  75.  * If not set, the first is selected
  76.  */
  77. void() select_initial_item_callback = nil;
  78.  
  79. // internal functions
  80.  
  81. /**
  82.  * Store the event description in internal variable
  83.  * To be used by WizardHW::WaitForEvent function
  84.  * @param selected string the ID of the currently selected item
  85.  * @param event a map of the current item
  86.  * @return always a non-nil symbol (needed just to finish event loop
  87.  */
  88. symbol SimpleStoreReturnValue (string selected, map event) {
  89.     dialog_ret = $[
  90.     "event" : event,
  91.     "selected" : selected,
  92.     ];
  93.     return `next; // anything but nil
  94. }
  95.  
  96. /**
  97.  * Set which item is to be selected
  98.  * @param selected string the item that is should be marked as selected
  99.  */
  100. void _SetSelectedItem (string selected) {
  101.     if (selected != nil)
  102.     {
  103.     UI::ChangeWidget (`id (`_hw_items), `CurrentItem, selected);
  104.     UI::ChangeWidget (`id (`_hw_sum), `Value, descriptions[selected]:"");
  105.     }
  106. }
  107.  
  108. /**
  109.  * Init function of the widget
  110.  * Used when using the callback interface
  111.  * @param key strnig the widget key
  112.  */
  113. void Init (string key) {
  114.     if (set_items_callback != nil)
  115.     set_items_callback ();
  116.     else
  117.     y2warning ("No initialization callback");
  118.     if (select_initial_item_callback != nil)
  119.     select_initial_item_callback ();
  120.     else
  121.     _SetSelectedItem ((string)(current_items[0, "id"]:nil));
  122. }
  123.  
  124. /**
  125.  * Handle function of the widget
  126.  * Used when using the callback interface
  127.  * @param key strnig the widget key
  128.  * @param key strnig the widget key
  129.  * @param event map event to be handled
  130.  * @return symbol for wizard sequencer or nil
  131.  */
  132. symbol Handle (string key, map event) {
  133.     last_event = event;
  134.     string current = (string)UI::QueryWidget (`id (`_hw_items), `CurrentItem);
  135.     if (event["ID"]:nil == `_hw_items)
  136.     {
  137.     string descr = "";
  138.     if (get_item_descr_callback == nil)
  139.         descr = descriptions[current]:"";
  140.     else
  141.         descr = get_item_descr_callback(current);
  142.     UI::ChangeWidget (`id (`_hw_sum), `Value, descr);
  143.     return nil;
  144.     }
  145.     if (action_callback == nil)
  146.     {
  147.     any ret = event["ID"]:nil;
  148.     if (is (ret, symbol))
  149.         return (symbol)ret;
  150.     else
  151.         return nil;
  152.     }
  153.     else
  154.     {
  155.     return action_callback (current, event);
  156.     }
  157. }
  158.  
  159.  
  160. // internal functions
  161.  
  162. void StoreCurrentItems (list<map<string,any> > items) {
  163.     current_items = items;
  164.     descriptions = listmap (map<string,any> i, items, {
  165.     return $[ i["id"]:"" : i["rich_descr"]:"" ];
  166.     });
  167. }
  168.  
  169. /**
  170.  * Get the description label for the action
  171.  * @param action a list describing the action
  172.  * @return string the label of the action
  173.  */
  174. string GetActionLabel (list action) {
  175.     string fallback = "";
  176.     if (is (action[0]:nil, string))
  177.     fallback = action[0]:"";
  178.     return action[1]:fallback;
  179. }
  180.  
  181. /**
  182.  * Create the Push/Menu button for additional actions
  183.  * @param actions a list of the actions
  184.  * @return term the widget
  185.  */
  186. term CreateActionsButton (list<list> actions) {
  187.     integer sz = size (actions);
  188.     if (sz == 0)
  189.     {
  190.     return `Empty ();
  191.     }
  192.     if (sz == 1)
  193.     {
  194.     any id = actions[0,0]:nil;
  195.     if (id == nil)
  196.     {
  197.         y2error ("Unknown ID for button: %1", actions[0]:nil);
  198.         id = "nil";
  199.     }
  200.     return `PushButton (`id (id),
  201.         GetActionLabel (actions[0]:[]));
  202.     }
  203.     list<term> items = maplist (list i, actions, {
  204.     any id = i[0]:nil;
  205.     if (id == nil)
  206.     {
  207.         y2error ("Unknown ID for button: %1", actions[0]:nil);
  208.         id = "nil";
  209.     }
  210.     return `item (`id (id), GetActionLabel (i));
  211.     });
  212.     // menu button
  213.     return `MenuButton (_("&Other"), items);
  214. }
  215.  
  216. // CWM widget
  217.  
  218. /**
  219.  * Create CWM widtet for the hardware settings
  220.  * NOTE: The Init and Handle callbacks must be defined
  221.  * @stable
  222.  * @param headers a list of headers of the table
  223.  * @param actions a list of additionaly offered actions, see CreateHWDialog
  224.  *  function for details
  225.  * @return a map a widget for CWM
  226.  */
  227. global map<string,any> CreateWidget (
  228.     list<string> headers,
  229.     list<list> actions
  230. ) {
  231.  
  232.     term hdr = `header ();
  233.     foreach (string hi, headers, {
  234.     hdr = add (hdr, hi);
  235.     });
  236.     term item_list = `Table (`id (`_hw_items), `opt (`notify, `immediate), hdr);
  237.     term buttons = `HBox (
  238.     `PushButton (`id (`add), Label::AddButton ()),
  239.     `PushButton (`id (`edit), Label::EditButton ()),
  240.     `PushButton (`id (`delete), Label::DeleteButton ()),
  241.     `HStretch (),
  242.     CreateActionsButton (actions)
  243.     );
  244.     term item_summary = `RichText (`id (`_hw_sum), "");
  245.  
  246.     term contents = `VBox (
  247.     `VWeight (3, item_list),
  248.     `VWeight (1, item_summary),
  249.     buttons
  250.     );
  251.  
  252.     list handle_events = [ `_hw_items, `add, `edit, `delete ];
  253.     list extra_events = maplist (list i, actions, {
  254.     return i[1]:nil;
  255.     });
  256.     extra_events = filter (any i, extra_events, {
  257.     return i != nil;
  258.     });
  259.     handle_events = merge (handle_events, extra_events);
  260.  
  261.     map<string,any> ret = $[
  262.     "widget" : `custom,
  263.     "custom_widget" : contents,
  264.     "handle_events" : handle_events,
  265.     ];
  266.  
  267.     return ret;
  268. }
  269.  
  270. // callback iface
  271.  
  272. /**
  273.  * Draw the dialog, handle all its events via callbacks
  274.  * @stable
  275.  * @param settings a map containing all the settings:
  276.  *  $[
  277.  *   "action_callback" : symbol(string,map<string,any>) -- callback to handle
  278.  *      all events which aren't handled internally, first parameter is
  279.  *      the ID of the selected item, second is the event. If not set,
  280.  *      events which are symbols are returned to wizard sequencer
  281.  *  "set_items_callback" : void() -- callback to set the items to be displayed.
  282.  *      Should called WizardHW::SetContents instead of direct widgets
  283.  *      modification, as it stores the settings also internally. This callback
  284.  *      must be set.
  285.  *  "set_initial_item_callback" : void() -- callback to set the selected item
  286.  *      when dialog initialized. Should call the function
  287.  *      WizardHW::SetSelectedItem instead of manual widget modification.
  288.  *      If not set, the first item is selected.
  289.  *  "item_descr_callback" : string(string) -- callback to get rich text
  290.  *      description of the item if it is intended to be dynamical.
  291.  *      if not set, static description set via "set_items_callback" is
  292.  *      used.
  293.  *  "actions" : list<list> -- a list of actions to be offered
  294.  *      via additional button next to Add/Edit/Delete button. Each item is
  295.  *      a two-item-list, where the first item is the event ID and the second
  296.  *      item is the label of the entry of the menu button. If there is only
  297.  *      one entry, menu button is replaced by push button. If empty
  298.  *      (or not specifued), nothing is shown.
  299.  *  "title" : string -- the dialog title, must be specified
  300.  *  "help" : string -- the help for the dialog, must be specifed
  301.  *  "headers" : list<string> --  a list of the table headers, must be specified
  302.  *  "next_button" : string -- label for the "Next" button. To hide it, set to
  303.  *      nil. If not specified, "Next" is used.
  304.  *  "back_button" : string -- label for the "Back" button. To hide it, set to
  305.  *      nil. If not specified, "Back" is used.
  306.  *  "abort_button" : string -- label for the "Abort" button. To hide it, set to
  307.  *      nil. If not specified, "Abort" is used.
  308.  *  ]
  309.  * @return symbol for wizard sequencer
  310.  */
  311. global symbol RunHWDialog (map settings) {
  312.     // reinitialize internal variables
  313.     current_items = [];
  314.     descriptions = $[];
  315.     last_event = $[];
  316.  
  317.     // callbacks
  318.     action_callback = (symbol(string,map))
  319.     settings["action_callback"]:nil;
  320.     get_item_descr_callback = (string(string))
  321.     settings["item_descr_callback"]:nil;
  322.     set_items_callback = (void())
  323.     settings["set_items_callback"]:nil;
  324.     select_initial_item_callback = (void ())
  325.     settings["set_initial_item_callback"]:nil;
  326.  
  327.     // other variables
  328.     list<list> actions = settings["actions"]:[];
  329.     list<string> headers = settings["headers"]:[];
  330.     string title = settings["title"]:"";
  331.     string help = settings["help"]:"HELP";
  332.  
  333.     // adapt the widget description map
  334.     map<string,any> widget = CreateWidget (headers, actions);
  335.     widget = remove (widget, "handle_events");
  336.     widget["help"] = help;
  337.     widget["init"] = Init;
  338.     widget["handle"] = Handle;
  339.     map<string,map<string,any> > widget_descr = $[
  340.     "wizard_hw" : widget,
  341.     ];
  342.  
  343.     // now run the dialog via CWM with handler set
  344.     return CWM::ShowAndRun ($[
  345.     "widget_descr" : widget_descr,
  346.     "widget_names" : ["wizard_hw"],
  347.     "contents" : `VBox ("wizard_hw"),
  348.     "caption" : title,
  349.     "abort_button" : settings["abort_button"]:Label::AbortButton (),
  350.     "back_button" : settings["back_button"]:Label::BackButton (),
  351.     "next_button" : settings["next_button"]:Label::NextButton (),
  352.     ]);
  353. }
  354.  
  355.  
  356. // simple iface
  357.  
  358. /**
  359.  * Create the Hardware Wizard dialog
  360.  * Draw the dialog
  361.  * @stable
  362.  * @param title string the dialog title
  363.  * @param help string the help for the dialog
  364.  * @param headers a list of the table headers
  365.  * @param actions a list of actions to be offered
  366.  *      via additional button next to Add/Edit/Delete button. Each item is
  367.  *      a two-item-list, where the first item is the event ID and the second
  368.  *      item is the label of the entry of the menu button. If there is only
  369.  *      one entry, menu button is replaced by push button. If empty
  370.  *      (or not specifued), nothing is shown.
  371.  *  below the widgets (next to other buttons)
  372.  */
  373. global void CreateHWDialog (
  374.     string title,
  375.     string help,
  376.     list<string> headers,
  377.     list<list> actions
  378. ) {
  379.     // reinitialize internal variables
  380.     current_items = [];
  381.     descriptions = $[];
  382.     last_event = $[];
  383.     get_item_descr_callback = nil;
  384.     action_callback = SimpleStoreReturnValue;
  385.  
  386.     // now create the dialog
  387.     map<string,any> widget_descr = CreateWidget (headers, actions);
  388.     widget_descr["help"] = help; // to suppress error in log
  389.     list<map<string,any> > w = CWM::CreateWidgets (["wizard_hw"],
  390.     $[ "wizard_hw" : widget_descr ]);
  391.     term contents = w[0, "widget"]:`VBox ();
  392.     Wizard::SetContents (title, contents, help, false, true);
  393. }
  394.  
  395. /**
  396.  * Set which item is to be selected
  397.  * @stable
  398.  * @param selected string the item that is should be marked as selected
  399.  */
  400. global void SetSelectedItem (string selected) {
  401.     _SetSelectedItem (selected);
  402. }
  403.  
  404.  
  405. /**
  406.  * Return the id of the currently selected item in the table
  407.  * @stable
  408.  * @return id of the selected item
  409.  */
  410. global string SelectedItem () {
  411.     return (string) UI::QueryWidget (`id(`_hw_items), `CurrentItem);
  412. }
  413.  
  414. /**
  415.  * Set the rich text description.
  416.  * @stable
  417.  * @param descr rich text description
  418.  */
  419. global void SetRichDescription (string descr) {
  420.     UI::ChangeWidget (`id (`_hw_sum), `Value, descr);
  421. }
  422.  
  423. /**
  424.  * Set the information about hardware
  425.  * @stable
  426.  * @param items a list of maps, one item per item in the dialog, with keys
  427.  *  "id" : string = the identification of the device,
  428.  *  "rich_descr" : string = RichText description of the device
  429.  *  "table_descr" : list<string> = fields of the table
  430.  */
  431. global void SetContents (list<map<string,any> > items) {
  432.     list<term> term_items = maplist (map<string,any> i, items, {
  433.     term t = `item (`id (i["id"]:""));
  434.     foreach (string l, i["table_descr"]:[], {
  435.         t = add (t, l);
  436.     });
  437.     return t;
  438.     });
  439.     UI::ChangeWidget (`id (`_hw_items), `Items, term_items);
  440.     StoreCurrentItems (items);
  441.     boolean enabled = size (items) > 0;
  442.     UI::ChangeWidget (`id (`edit), `Enabled, enabled);
  443.     UI::ChangeWidget (`id (`delete), `Enabled, enabled);
  444.     if (enabled)
  445.     SetSelectedItem (items[0, "id"]:"");
  446. }
  447.  
  448. /**
  449.  * Wait for event from the event
  450.  * @stable
  451.  * @return a map with keys:
  452.  *  "event" : map = event as returned from UI::WaitForEvent (),
  453.  *  "selected" : string = ID of the selected item in the list box
  454.  */
  455. global map<string,any> WaitForEvent () {
  456.     map event = nil;
  457.     while (event == nil)
  458.     {
  459.     event = (map)UI::WaitForEvent ();
  460.     if (Handle ("wizard_hw", event) == nil)
  461.     {
  462.         event = nil;
  463.     }
  464.     }
  465.     return dialog_ret;
  466. }
  467.  
  468. /**
  469.  * Wait for event from the event
  470.  * @stable
  471.  * @return a map with keys:
  472.  *  "event" : any = event as returned from UI::UserInoput ()
  473.  *  "selected" : string = ID of the selected item in the list box
  474.  */
  475. global map<string,any> UserInput () {
  476.     map<string,any> ret = WaitForEvent ();
  477.     ret["event"] = ret["event", "ID"]:nil;
  478.     return ret;
  479. }
  480.  
  481. /**
  482.  * Create rich text description of a device. It can be used for WizardHW::SetContents
  483.  * function for formatting richtext device descriptions
  484.  * @stable
  485.  * @param title header - usually device name
  486.  * @param properties important properties of the device which should be
  487.  *        displayed in the overview dialog
  488.  * @return string rich text string
  489.  */
  490. global define string CreateRichTextDescription(string title, list<string> properties) {
  491.     string items = "";
  492.  
  493.     if (properties != nil && size(properties) > 0)
  494.     {
  495.     foreach(string prop, properties, {
  496.         items = items + "<LI>" + prop + "</LI>";
  497.         }
  498.     );
  499.     }
  500.  
  501.     string ret = "";
  502.  
  503.     if (title != nil && title != "")
  504.     {
  505.     ret = "<P><B>" + title + "</B></P>";
  506.     }
  507.  
  508.     if (items != "")
  509.     {
  510.     ret = ret + "<P><UL>" + items + "</UL></P>";
  511.     }
  512.  
  513.     return ret;
  514. }
  515.  
  516.  
  517. /**
  518.  * Get propertly list of an unconfigured device. Should be used together with
  519.  * device name in CreateRichTextDescription() function.
  520.  * @stable
  521.  * @return a list of strings 
  522.  */
  523. global list<string> UnconfiguredDevice() {
  524.     // translators: message for hardware configuration without any configured
  525.     // device
  526.     return [_("The device is not configured")
  527.     // translators: message for hardware configuration without any configured
  528.     // device
  529.     , _("Press <B>Edit</B> to configure")];
  530. }
  531.  
  532. // EOF
  533. }
  534.