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 / Wizard.ycp < prev    next >
Text File  |  2006-11-29  |  39KB  |  1,497 lines

  1. /**
  2.  * File:    Wizard.ycp
  3.  * Package:    yast2
  4.  * Summary:    Wizard dialog
  5.  * Authors:    Stefan Hundhammer <sh@suse.de>
  6.  *
  7.  * $Id: Wizard.ycp 33164 2006-09-27 08:42:24Z jsrain $
  8.  *
  9.  * Provides the wizard dialog (common screen for all YaST2 installation
  10.  * modules) and functions to set the contents, to replace and restore
  11.  * special widgets.
  12.  */
  13.  
  14. {
  15.  
  16.     module "Wizard";
  17.     textdomain "base";
  18.  
  19.     import "Label";
  20.     import "Popup";
  21.     import "Directory";
  22.     import "SuSERelease";
  23.  
  24.     // keep trailing "/" !!
  25.     string theme_path = Directory::themedir + "/current";
  26.     string icon_path  = theme_path + "/icons/22x22/apps";
  27.  
  28.     boolean have_fancy_ui_cache = nil;
  29.  
  30.     // this variable is set from Product:: constructor
  31.     // to setup correct &product; macro in UI
  32.     string product_name = "";
  33.  
  34.     boolean haveFancyUI()
  35.     {
  36.     if ( have_fancy_ui_cache == nil )
  37.     {
  38.         map ui_info = UI::GetDisplayInfo();
  39.  
  40.         have_fancy_ui_cache = UI::HasSpecialWidget(`Wizard ) == true
  41.         && ui_info[ "Depth" ]:0 >= 15
  42.         && ui_info[ "DefaultWidth" ]:0 >= 800
  43.         && ui_info[ "DefaultHeight"]:0 >= 600;
  44.  
  45.         // have_fancy_ui_cache = false;
  46.  
  47.         UI::SetFunctionKeys( Label::DefaultFunctionKeyMap() );
  48.     }
  49.  
  50.     return have_fancy_ui_cache;
  51.     }
  52.  
  53.  
  54.     /**
  55.      * Returns a button box with buttons "Back", "Abort", "Next"
  56.      * @return a widget tree
  57.      **/
  58.     global term BackAbortNextButtonBox() {
  59.     return `HBox(
  60.              `HWeight(1, `ReplacePoint(`id(`rep_back ), `PushButton(`id(`back ), `opt (`key_F8), Label::BackButton()  ) ) ),
  61.              `HStretch(),
  62.              `ReplacePoint(`id(`rep_abort), `PushButton(`id(`abort), `opt (`key_F9), Label::AbortButton() ) ),
  63.              `HStretch(),
  64.              `HWeight(1, `ReplacePoint(`id(`rep_next ), `PushButton(`id(`next), `opt (`key_F10, `default), Label::NextButton()  ) ) )
  65.              );
  66.     }
  67.  
  68.  
  69.     /**
  70.      * Returns a button box with buttons "Back", "Abort Installation", "Next"
  71.      * @return a widget tree
  72.      **/
  73.     global term BackAbortInstallationNextButtonBox()
  74.     {
  75.     return `HBox(
  76.              `HWeight(1, `ReplacePoint(`id(`rep_back ), `PushButton(`id(`back ), `opt (`key_F8), Label::BackButton()  ) ) ),
  77.              `HStretch(),
  78.              `ReplacePoint(`id(`rep_abort), `PushButton(`id(`abort), `opt (`key_F9), Label::AbortInstallationButton() ) ),
  79.              `HStretch(),
  80.              `HWeight(1, `ReplacePoint(`id(`rep_next ), `PushButton(`id(`next), `opt (`key_F10, `default), Label::NextButton()  ) ) )
  81.              );
  82.     }
  83.  
  84.  
  85.     /**
  86.      * Returns a button box with buttons "Back", "Next"
  87.      * @return a widget tree
  88.      **/
  89.     global term BackNextButtonBox() {
  90.     return `HBox(
  91.              `HWeight(1, `ReplacePoint(`id(`rep_back ), `PushButton(`id(`back ), `opt (`key_F8), Label::BackButton()  ) ) ),
  92.              `HStretch(),
  93.              `HWeight(1, `ReplacePoint(`id(`rep_next ), `PushButton(`id(`next ), `opt (`key_F10, `default), Label::NextButton()  ) ) )
  94.              );
  95.     }
  96.  
  97.  
  98.     /**
  99.      * Returns a button box with buttons "Cancel", "Accept"
  100.      * @return a widget tree
  101.      **/
  102.     global term CancelAcceptButtonBox() {
  103.     return `HBox(
  104.              `HWeight(1, `Empty() ),    // Layout trick to make sure the center button is centered
  105.              `HStretch(),
  106.              `HWeight(1, `PushButton(`id(`cancel ), `opt (`key_F9), Label::CancelButton()  ) ),
  107.              `HStretch(),
  108.              `HWeight(1, `PushButton(`id(`accept ), `opt (`key_F10, `default), Label::AcceptButton()  ) )
  109.              );
  110.     }
  111.  
  112.  
  113.     /**
  114.      * Returns a button box with buttons "Abort", "Accept"
  115.      * @return a widget tree
  116.      **/
  117.     global term AbortAcceptButtonBox() {
  118.     return `HBox(
  119.              `HWeight(1, `ReplacePoint (`id (`back_rep), `Empty())),    // Layout trick to make sure the center button is centered
  120.              `HStretch(),
  121.              `PushButton(`id(`abort ), `opt (`key_F9), Label::AbortButton() ),
  122.              `HStretch(),
  123.              `HWeight(1, `PushButton(`id(`accept ), `opt (`key_F10, `default), Label::AcceptButton()  ) )
  124.              );
  125.     }
  126.  
  127.  
  128.     /**
  129.      * Returns a button box with buttons "Abort Installation", "Accept"
  130.      * @return a widget tree
  131.      **/
  132.     global term AbortInstallationAcceptButtonBox() {
  133.     return `HBox(
  134.              `HWeight(1, `Empty() ),    // Layout trick to make sure the center button is centered
  135.              `HStretch(),
  136.              `PushButton(`id(`abort ), `opt (`key_F9), Label::AbortInstallationButton() ),
  137.              `HStretch(),
  138.              `HWeight(1, `PushButton(`id(`accept ), `opt (`key_F10, `default), Label::AcceptButton()  ) )
  139.              );
  140.     }
  141.  
  142.  
  143.     /**
  144.      * Returns a button box with buttons "Abort", "Apply", "Finish"
  145.      * @return a widget tree
  146.      **/
  147.     global term AbortApplyFinishButtonBox()
  148.     {
  149.     return `HBox(
  150.              `PushButton(`id(`abort ), Label::AbortButton() ),
  151.              `HStretch(),
  152.              // button text
  153.              `PushButton(`id(`apply), _("&Apply") ),
  154.              `HStretch(),
  155.              `PushButton(`id(`finish), Label::FinishButton() )
  156.              );
  157.     }
  158.  
  159.  
  160.     /**
  161.      * @short Create a Generic Dialog
  162.      *
  163.      * @descr Returns a term describing a generic wizard dialog with a configurable
  164.      * button box.
  165.      *
  166.      * @stable
  167.      *
  168.      * @param    button_box term that contains a `HBox() with buttons in it
  169.      * @return    term term describing the dialog.
  170.      **/
  171.     global term GenericDialog( term button_box ) {
  172.     return `VBox( `id(`WizardDialog),
  173.                       `ReplacePoint( `id(`topmenu ), `Empty() ),
  174.               `HBox(
  175.                 `HWeight( 30, `ReplacePoint( `id(`helpSpace), `RichText(`id(`HelpText), ""))),
  176.                 `HSpacing(1),
  177.                 `HWeight( 70, `VBox(
  178.                         `VSpacing(0.2),
  179.                         `HBox(
  180.                               // translators: dialog title to appear before any content is initialized
  181.                               `Heading(`id(`title), `opt (`hstretch), _("YaST2\nInitializing ...")),
  182.                               `HStretch()
  183.                               ),
  184.                         `VWeight( 1, // Layout trick: Lower layout priority with weight
  185.                               `HVCenter(`opt(`hvstretch),
  186.                                     `ReplacePoint(`id(`contents), `Empty() )
  187.                                     )
  188.                               ),
  189.                         `ReplacePoint(`id(`rep_button_box), button_box ),
  190.                         `VSpacing(0.2)
  191.                         )
  192.                       ),
  193.                 `HSpacing(1)
  194.                 )
  195.               );
  196.     }
  197.  
  198.  
  199.  
  200.     /**
  201.      * Check if the topmost dialog is a wizard dialog
  202.      * (i.e. has a widget with `id(`WizardDialog) )
  203.      *
  204.      * @return boolean True if topmost dialog is a wizard dialog, false otherwise
  205.      **/
  206.     global boolean IsWizardDialog() {
  207.     return
  208.         UI::WidgetExists(`id(`WizardDialog) ) == true ||
  209.         UI::WidgetExists(`wizard) == true;
  210.     }
  211.  
  212.  
  213.     /**
  214.      * Open a popup dialog that displays a help text (rich text format).
  215.      *
  216.      * @stable
  217.      *
  218.      * @param help_text the text to display
  219.      **/
  220.     global void ShowHelp( string help_text ) {
  221.     Popup::LongText(
  222.               // Heading for help popup window
  223.               _("Help"),
  224.               `RichText( help_text ),
  225.               50, 20 );
  226.     }
  227.  
  228.  
  229.     /**
  230.      * Returns a standard wizard dialog with buttons "Next", "Back", "Abort".
  231.      *
  232.      * @stable
  233.      *
  234.      * @return term describing the dialog.
  235.      **/
  236.     global term NextBackDialog() {
  237.     return GenericDialog( BackAbortNextButtonBox() );
  238.     }
  239.  
  240.  
  241.     /**
  242.      * Returns a standard wizard dialog with buttons "Cancel", "Accept"
  243.      *
  244.      * @stable
  245.      *
  246.      * @return term describing the dialog.
  247.      **/
  248.     global term AcceptDialog() {
  249.     return GenericDialog( CancelAcceptButtonBox() );
  250.     }
  251.  
  252.  
  253.     /**
  254.      * Open any wizard dialog.
  255.      *
  256.      * @stable
  257.      *
  258.      * @param    dialog    a wizard dialog, e.g. Wizard::GenericDialog()
  259.      **/
  260.     global void OpenDialog( term dialog ) {
  261.     UI::OpenDialog( `opt(`defaultsize), dialog );
  262.     }
  263.  
  264.  
  265.     /**
  266.      * Open a dialog with buttons "Next", "Back", "Abort"
  267.      * and set the keyboard focus to "Next".
  268.      **/
  269.     global void OpenNextBackDialog()
  270.     {
  271.     if ( haveFancyUI() )
  272.     {
  273.         UI::OpenDialog(`opt(`defaultsize ),
  274.                `Wizard(`back,  Label::BackButton(),
  275.                    `abort, Label::AbortButton(),
  276.                    `next,  Label::NextButton() ) );
  277.     }
  278.     else
  279.     {
  280.         Wizard::OpenDialog( NextBackDialog() );
  281.         UI::SetFocus(`id(`next) );
  282.     }
  283.     }
  284.  
  285.  
  286.     /**
  287.      * Open a dialog with "Accept", "Cancel"
  288.      * and set the keyboard focus to "Accept".
  289.      **/
  290.     global void OpenAcceptDialog()
  291.     {
  292.     if ( haveFancyUI() )
  293.     {
  294.         UI::OpenDialog(`opt(`defaultsize ),
  295.                `Wizard(`no_back_button,       "",
  296.                    `cancel,        Label::CancelButton(),
  297.                    `accept,        Label::AcceptButton() ) );
  298.  
  299.         // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
  300.         UI::WizardCommand(`ProtectNextButton( true ) );
  301.     }
  302.     else
  303.     {
  304.         Wizard::OpenDialog( AcceptDialog() );
  305.         UI::SetFocus(`id(`accept) );
  306.     }
  307.     }
  308.  
  309.  
  310.     /**
  311.      * Open a dialog with "Accept", "Cancel"
  312.      * and set the keyboard focus to "Accept".
  313.      **/
  314.     global void OpenAbortApplyFinishDialog()
  315.     {
  316.     if ( haveFancyUI() )
  317.     {
  318.         UI::OpenDialog(`opt(`defaultsize ),
  319.                `Wizard(`apply,    _( "&Apply" ),
  320.                    `abort,    Label::AbortButton(),
  321.                    `finish,    Label::FinishButton() ) );
  322.     }
  323.     else
  324.     {
  325.         Wizard::OpenDialog( GenericDialog( AbortApplyFinishButtonBox() ) );
  326.         UI::SetFocus(`id(`finish ) );
  327.     }
  328.     }
  329.  
  330.  
  331.     /**
  332.      * Open a dialog with "Accept", "Cancel" that will also accept workflow steps.
  333.      **/
  334.     global void OpenAcceptStepsDialog()
  335.     {
  336.     if ( haveFancyUI() )
  337.     {
  338.         UI::OpenDialog(`opt(`defaultsize ),
  339.                `Wizard(`opt(`stepsEnabled),
  340.                    `no_back_button,    "",
  341.                    `cancel,        Label::CancelButton(),
  342.                    `accept,        Label::AcceptButton() ) );
  343.  
  344.         // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
  345.         UI::WizardCommand(`ProtectNextButton( true ) );
  346.     }
  347.     else
  348.     {
  349.         OpenAcceptDialog();
  350.     }
  351.     }
  352.  
  353.  
  354.  
  355.     /**
  356.      * Open a dialog with "Accept", "Cancel" that will also accept workflow steps.
  357.      **/
  358.     global void OpenAcceptAbortStepsDialog()
  359.     {
  360.     if ( haveFancyUI() )
  361.     {
  362.         UI::OpenDialog(`opt(`defaultsize ),
  363.                `Wizard(`opt(`stepsEnabled),
  364.                    `no_back_button,       "",
  365.                    `abort,        Label::AbortButton(),
  366.                    `accept,        Label::AcceptButton() ) );
  367.  
  368.         // Don't let sloppy calls to Wizard::SetContents() disable this button by accident
  369.         UI::WizardCommand(`ProtectNextButton( true ) );
  370.     }
  371.     else
  372.     {
  373.         Wizard::OpenDialog( GenericDialog( AbortAcceptButtonBox() ) );
  374.     }
  375.     }
  376.  
  377.  
  378.     /**
  379.      * Open a dialog with "Back", "Next", "Abort" that will also accept workflow steps.
  380.      **/
  381.     global void OpenNextBackStepsDialog()
  382.     {
  383.     if ( haveFancyUI() )
  384.     {
  385.         UI::OpenDialog(`opt(`defaultsize ),
  386.                `Wizard(`opt(`stepsEnabled),
  387.                    `back,  Label::BackButton(),
  388.                    `abort, Label::AbortButton(),
  389.                    `next,  Label::NextButton() ) );
  390.     }
  391.     else
  392.     {
  393.         OpenNextBackDialog();
  394.     }
  395.     }
  396.  
  397.  
  398.     /**
  399.      * Open a wizard dialog with simple layout
  400.      *
  401.      * no graphics, no steps,
  402.      * only a help widget buttons (by default "Back", "Abort", "Next").
  403.      *
  404.      * This is the only type of wizard dialog which still allows replacing
  405.      * the help space - either already upon opening it or later with
  406.      * Wizard::ReplaceCustomHelp().
  407.      *
  408.      * If help_space_contents is 'nil', the normal help widget will remain.
  409.      * If button_box is 'nil', Wizard::BackAbortNextButtonBox() is used.
  410.      *
  411.      * @see CloseDialog
  412.      *
  413.      * @param help_space_contents Help space contents
  414.      * @param button_box Buttom Box
  415.      * @return void
  416.      **/
  417.     global void OpenCustomDialog( term help_space_contents,
  418.                      term button_box )
  419.     {
  420.     if ( button_box == nil )
  421.         button_box = BackAbortNextButtonBox();
  422.  
  423.     UI::OpenDialog(`opt(`defaultsize),
  424.                GenericDialog( button_box ) );
  425.  
  426.     if ( help_space_contents != nil )
  427.         UI::ReplaceWidget(`id(`helpSpace), help_space_contents );
  428.     }
  429.  
  430.  
  431.     /**
  432.      * Replace the help widget for dialogs opened with Wizard::OpenCustomDialog().
  433.      * @param contents Replace custom help with supplied contents
  434.      **/
  435.     global void ReplaceCustomHelp( term contents )
  436.     {
  437.     if ( UI::WidgetExists( `id(`helpSpace ) ) )
  438.     {
  439.         UI::ReplaceWidget(`id(`helpSpace), contents);
  440.     }
  441.     else
  442.     {
  443.         y2error( "Wizard::ReplaceHelpSpace() works only for dialogs opened with Wizard::OpenSimpleDialog() !" );
  444.     }
  445.     }
  446.  
  447.  
  448.     /**
  449.      * Close a wizard dialog.
  450.      *
  451.      * @stable
  452.      **/
  453.     global void CloseDialog() {
  454.     if ( IsWizardDialog() )
  455.     {
  456.         UI::CloseDialog();
  457.     }
  458.     else
  459.     {
  460.         y2error( "Wizard::CloseDialog(): Topmost dialog is not a wizard dialog!" );
  461.     }
  462.     }
  463.  
  464.  
  465.     /**
  466.      * Substitute for UI::UserInput
  467.      *
  468.      * This function transparently handles different
  469.      * variations of the wizard layout. Returns `next if `next or `accept were
  470.      * clicked, `back if `back or `cancel were clicked. Simply replace
  471.      *    ret = UI::UserInput()
  472.      * with
  473.      *    ret = Wizard::UserInput()
  474.      *
  475.      * @return (maybe normalized) widget ID
  476.      **/
  477.     global any UserInput() {
  478.     any input = UI::UserInput();
  479.  
  480.     if ( input == `accept )    return `next;
  481.     if ( input == `cancel )    return `back;
  482.  
  483.     return input;
  484.     }
  485.  
  486.  
  487.     /**
  488.      * Create and open a typical installation wizard dialog.
  489.      *
  490.      * For backwards compatibility only - don't use this any more in new modules.
  491.      **/
  492.     global void CreateDialog()
  493.     {
  494.         // Set productname for help text
  495.     if (product_name == "")
  496.         product_name = SuSERelease::ReleaseName ();
  497.         UI::SetProductName(product_name);
  498.  
  499.     Wizard::OpenNextBackDialog();
  500.     }
  501.  
  502.  
  503.     /**
  504.      * Set the contents of a wizard dialog
  505.      *
  506.      * How the general framework for the installation wizard should
  507.      * look like. This function creates and shows a dialog.
  508.      *
  509.      * @stable
  510.      *
  511.      * @param title Dialog Title
  512.      * @param contents The Dialog contents
  513.      * @param help_text Help text
  514.      * @param has_back Is the Back button enabled?
  515.      * @param has_next Is the Next button enabled?
  516.      * @example_file ../examples/wizard1.ycp
  517.      * @screenshot screenshots/wizard1.png
  518.      **/
  519.     global void SetContents(string title, term contents, string help_text,
  520.                    boolean has_back, boolean has_next) {
  521.  
  522.     if ( UI::WizardCommand(`SetDialogHeading( title ) ) == true )
  523.     {
  524.         UI::WizardCommand(`SetHelpText( help_text ) );
  525.         UI::WizardCommand(`EnableNextButton( has_next ) );
  526.         UI::WizardCommand(`EnableBackButton( has_back ) );
  527.         UI::WizardCommand(`SetFocusToNextButton() );
  528.     }
  529.     else
  530.     {
  531.         if ( UI::WidgetExists(`id(`next ) ) )
  532.         {
  533.         UI::ChangeWidget(`id(`next), `Enabled, has_next);
  534.         UI::SetFocus( `id(`next) );
  535.         }
  536.  
  537.         if ( UI::WidgetExists(`id(`back    ) ) )    UI::ChangeWidget(`id(`back), `Enabled, has_back);
  538.         if ( UI::WidgetExists(`id(`accept    ) ) )    UI::SetFocus( `id(`accept ) );
  539.         if ( UI::WidgetExists(`id(`abort    ) ) )    UI::ChangeWidget(`id(`abort),`Enabled, true);
  540.         if ( UI::WidgetExists(`id(`HelpText    ) ) )    UI::ChangeWidget(`id(`HelpText), `Value, help_text);
  541.         if ( UI::WidgetExists(`id(`title    ) ) )    UI::ChangeWidget(`id(`title), `Value, title);
  542.     }
  543.  
  544.     UI::ReplaceWidget(`id(`contents), contents);
  545.     }
  546.  
  547.  
  548.     /**
  549.      * Clear the wizard contents.
  550.      *
  551.      * This may sound silly, but it gives much faster feedback to the
  552.      * user if used properly: Whenever the user clicks "Next" or
  553.      * "Back", call ClearContents() prior to any lengthy
  554.      * operation -> the user notices instant response, even though he
  555.      * may in fact still have to wait.
  556.      *
  557.      * @stable
  558.      **/
  559.     global void ClearContents() {
  560.     Wizard::SetContents("", `Empty(), "", false, false);
  561.     }
  562.  
  563.  
  564.     /**
  565.      * Set contents and Buttons of wizard dialog
  566.      *
  567.      * Additionally set its title, help_text and buttons labels. Enables both back and next button.
  568.      *
  569.      * @params
  570.      *
  571.      * @param title title of window
  572.      * @param contents contents of dialog
  573.      * @param help_text help text
  574.      * @param back_label label of back button
  575.      * @param next_label label of next button
  576.      **/
  577.     global void SetContentsButtons (string title,
  578.             term contents,
  579.             string help_text,
  580.             string back_label,
  581.             string next_label)
  582.     {
  583.     UI::PostponeShortcutCheck ();
  584.  
  585.     if ( UI::WizardCommand(`SetBackButtonLabel( back_label ) ) == true )
  586.     {
  587.         UI::WizardCommand(`SetNextButtonLabel( next_label ) );
  588.         Wizard::SetContents( title, contents, help_text, true, true );
  589.     }
  590.     else
  591.     {
  592.         // Set button labels first to avoid geometry problems: SetContents()
  593.         // calls ReplaceWidget() wich triggers a re-layout.
  594.  
  595.         if ( UI::WidgetExists(`id(`back ) ) )    UI::ChangeWidget(`id (`back), `Label, back_label);
  596.         if ( UI::WidgetExists(`id(`next ) ) )    UI::ChangeWidget(`id (`next), `Label, next_label);
  597.         Wizard::SetContents( title, contents, help_text, true, true );
  598.     }
  599.  
  600.     UI::CheckShortcuts ();
  601.     }
  602.  
  603.  
  604.  
  605.     /**
  606.      * Replace the wizard help subwindow with a custom widget.
  607.      *
  608.      * @deprecated
  609.      * @param contents Replace Help with contents
  610.      **/
  611.     global void ReplaceHelp(term contents) {
  612.     if ( UI::WidgetExists( `id(`helpSpace ) ) )
  613.     {
  614.         y2warning( "Wizard::ReplaceHelp() is deprecated!" );
  615.         UI::ReplaceWidget(`id(`helpSpace), contents);
  616.     }
  617.     else
  618.     {
  619.         y2error( "Wizard::ReplaceHelp() is not supported by the new Qt wizard!" );
  620.     }
  621.     }
  622.  
  623.  
  624.  
  625.     /**
  626.      * Set a new help text.
  627.      * @param help_text Help text
  628.      * @example Wizard::SetHelpText("This is a help Text");
  629.      **/
  630.     global void SetHelpText(string help_text)
  631.     {
  632.     if ( UI::WizardCommand(`SetHelpText( help_text ) ) == false )
  633.     {
  634.         if ( UI::WidgetExists( `id(`helpSpace ) ) )
  635.         UI::ReplaceWidget(`id(`helpSpace), `RichText(`id(`HelpText), help_text ) );
  636.     }
  637.     }
  638.  
  639.  
  640.     /**
  641.      * Restore the wizard help subwindow.
  642.      * @param help_text Help text
  643.      **/
  644.     global void RestoreHelp(string help_text)
  645.     {
  646.     Wizard::SetHelpText( help_text );
  647.     }
  648.  
  649.  
  650.     /**
  651.      * Set the dialog's "Next" button with a new label and a new ID
  652.      *
  653.      * @stable
  654.      *
  655.      * @param id Button ID
  656.      * @param label Button Label
  657.      **/
  658.     global void SetNextButton( any id, string label )
  659.     {
  660.     if ( UI::WizardCommand(`SetNextButtonLabel( label ) ) == true )
  661.     {
  662.         UI::WizardCommand(`SetNextButtonID( id ) );
  663.     }
  664.     else
  665.     {
  666.         if ( UI::WidgetExists(`id(`rep_next ) ) )
  667.         {
  668.         UI::ReplaceWidget(`id(`rep_next ),
  669.                   `PushButton( `id( id ), `opt (`key_F10, `default), label ) 
  670.                   );
  671.         }
  672.     }
  673.  
  674.     }
  675.  
  676.  
  677.     /**
  678.      * Set the dialog's "Back" button with a new label and a new ID
  679.      *
  680.      * @stable
  681.      *
  682.      * @param id Button ID
  683.      * @param label Button Label
  684.      **/
  685.     global void SetBackButton( any id, string label )
  686.     {
  687.     if ( UI::WizardCommand(`SetBackButtonLabel( label ) ) == true )
  688.     {
  689.         UI::WizardCommand(`SetBackButtonID( id ) );
  690.     }
  691.     else
  692.     {
  693.         if ( UI::WidgetExists(`id(`rep_back ) ) )
  694.         {
  695.         UI::ReplaceWidget(`id(`rep_back),
  696.                   `PushButton( `id( id ), `opt (`key_F8), label )
  697.                   );
  698.         }
  699.     }
  700.     }
  701.  
  702.  
  703.     /**
  704.      * Set the dialog's "Abort" button with a new label and a new ID
  705.      *
  706.      * @stable
  707.      *
  708.      * @param id Button ID
  709.      * @param label Button Label
  710.      **/
  711.     global void SetAbortButton( any id, string label )
  712.     {
  713.     if ( UI::WizardCommand(`SetAbortButtonLabel( label ) ) == true )
  714.     {
  715.         UI::WizardCommand(`SetAbortButtonID( id ) );
  716.     }
  717.     else
  718.     {
  719.         if ( UI::WidgetExists(`id(`rep_abort ) ) )
  720.         {
  721.         UI::ReplaceWidget(`id(`rep_abort ),
  722.                   `PushButton( `id( id ), `opt (`key_F9), label )
  723.                   );
  724.         }
  725.     }
  726.     }
  727.     /**
  728.      * Hide the Wizard's "Next" button.
  729.      * Restore it later with RestoreNextButton():
  730.      *
  731.      * @see RestoreNextButton
  732.      * @stable
  733.      **/
  734.     global void HideNextButton()
  735.     {
  736.     if ( UI::WizardCommand(`SetNextButtonLabel( "" ) ) == false )
  737.     {
  738.         if ( UI::WidgetExists(`id(`rep_next ) ) )
  739.         UI::ReplaceWidget(`id(`rep_next ), `Empty() );
  740.     }
  741.     }
  742.  
  743.     /**
  744.      * Hide the Wizard's "Back" button.
  745.      * Restore it later with RestoreBackButton():
  746.      *
  747.      * @see RestoreBackButton
  748.      * @stable
  749.      **/
  750.     global void HideBackButton()
  751.     {
  752.     if ( UI::WizardCommand(`SetBackButtonLabel( "" ) ) == false )
  753.     {
  754.         if ( UI::WidgetExists(`id(`rep_back ) ) )
  755.         UI::ReplaceWidget(`id(`rep_back), `Empty() );
  756.     }
  757.     }
  758.  
  759.  
  760.     /**
  761.      * Hide the Wizard's "Abort" button.
  762.      * Restore it later with RestoreAbortButton():
  763.      *
  764.      * @see RestoreAbortButton
  765.      * @stable
  766.      **/
  767.     global void HideAbortButton()
  768.     {
  769.     if ( UI::WizardCommand(`SetAbortButtonLabel( "" ) ) == false )
  770.     {
  771.         if ( UI::WidgetExists(`id(`rep_abort ) ) )
  772.         UI::ReplaceWidget(`id(`rep_abort ), `Empty() );
  773.     }
  774.     }
  775.  
  776.  
  777.     /**
  778.      * Restore the wizard 'back' button.
  779.      *
  780.      * @see HideBackButton
  781.      * @stable
  782.      **/
  783.     global void RestoreBackButton()
  784.     {
  785.     Wizard::SetBackButton( `back, Label::BackButton() );
  786.     }
  787.  
  788.  
  789.     /**
  790.      * Restore the wizard 'next' button.
  791.      *
  792.      * @see HideNextButton
  793.      * @stable
  794.      **/
  795.     global void RestoreNextButton()
  796.     {
  797.     Wizard::SetNextButton( `next, Label::NextButton() );
  798.     }
  799.  
  800.  
  801.     /**
  802.      * Restore the wizard 'abort' button.
  803.      *
  804.      * @see HideAbortButton
  805.      * @stable
  806.      **/
  807.     global void RestoreAbortButton() {
  808.     Wizard::SetAbortButton( `abort, Label::AbortButton() );
  809.     }
  810.  
  811.  
  812.  
  813.     /**
  814.      * Replace the wizard 'next' button with a custom widget.
  815.      * THIS FUNCTION IS DEPRECATED!
  816.      *
  817.      * @deprecated
  818.      * @see SetNextButton
  819.      * @param contents a term describing the new contents
  820.      **/
  821.     global void ReplaceNextButton(term contents) {
  822.     if ( UI::WidgetExists(`id(`rep_next ) ) )
  823.         UI::ReplaceWidget(`id(`rep_next), contents);
  824.  
  825.     y2warning( "Wizard::ReplaceNextButton() is deprecated!" );
  826.     }
  827.  
  828.     /**
  829.      * Replace the wizard 'back' button with a custom widget.
  830.      * THIS FUNCTION IS DEPRECATED!
  831.      *
  832.      * @deprecated
  833.      * @see SetBackButton
  834.      * @param contents a term describing the new contents
  835.      **/
  836.     global void ReplaceBackButton(term contents) {
  837.     if ( UI::WidgetExists(`id(`rep_back ) ) )
  838.         UI::ReplaceWidget(`id(`rep_back), contents);
  839.  
  840.     y2warning( "Wizard::ReplaceBackButton() is deprecated!" );
  841.     }
  842.  
  843.  
  844.     /**
  845.      * Replace the wizard 'abort' button with a custom widget.
  846.      * THIS FUNCTION IS DEPRECATED!
  847.      *
  848.      * @see SetAbortButton
  849.      * @deprecated
  850.      * @param contents a term describing the new contents
  851.      **/
  852.     global void ReplaceAbortButton(term contents) {
  853.     if ( UI::WidgetExists(`id(`rep_abort ) ) )
  854.         UI::ReplaceWidget(`id(`rep_abort), contents);
  855.  
  856.     y2warning( "Wizard::ReplaceAbortButton() is deprecated!" );
  857.     }
  858.  
  859.  
  860.  
  861.     /**
  862.      * Set the wizard 'title' icon
  863.      *
  864.      * Set the wizard 'title' icon to the specified icon from the standard icon
  865.      * directory.
  866.      *
  867.      * @stable
  868.      *
  869.      * @param icon_name name (without path) of the new icon
  870.      * @see ClearTitleIcon
  871.      **/
  872.     global void SetTitleIcon( string icon_name )
  873.     {
  874.     string icon = icon_name == "" ? "" : ( icon_path + "/" + icon_name + ".png" );
  875.  
  876.     // UI::WizardCommand(`SetVerboseCommands( true ) );
  877.     UI::WizardCommand(`SetDialogIcon( icon ) );
  878.     // UI::WizardCommand(`SetVerboseCommands( false ) );
  879.     }
  880.  
  881.  
  882.     /**
  883.      * Clear the wizard 'title' icon, i.e. replace it with nothing
  884.      *
  885.      * @stable
  886.      * @see SetTitleIcon
  887.      **/
  888.     global void ClearTitleIcon()
  889.     {
  890.     UI::WizardCommand(`SetDialogIcon( "" ) );
  891.     }
  892.  
  893.  
  894.     /**
  895.      * Set Desktop Icon
  896.      * @param file Icon name
  897.      * @return boolean true on success
  898.      */
  899.     global boolean SetDesktopIcon( string file )
  900.     {
  901.     string filename = sformat("%1/%2.desktop", Directory::desktopdir, file);
  902.     // Do not use .yast2.desktop.v.$filename, because ini-agent reads
  903.     // all the desktop files anyway which is wasteful for setting one icon.
  904.     // The config is adapted from .yast2.desktop.
  905.     SCR::RegisterAgent (.yast2.desktop1, `ag_ini(
  906.                 `IniAgent( filename,
  907.     $[
  908.         "options"    : [ "read_only" ], // rw works but not needed
  909.         "comments"    : [ "^[ \t]*[;#].*", ";.*", "\\{[^}]*\\}", "^[ \t]*$" ],
  910.         "sections"    : [
  911.         $[ "begin" : [
  912.             "^[ \t]*\\[[ \t]*(.*[^ \t])[ \t]*\\][ \t]*",
  913.             "[%s]",
  914.         ]],
  915.         ],
  916.         "params" : [
  917.         $[ "match" : [
  918.             "^[ \t]*([^=]*[^ \t=])[ \t]*=[ \t]*(.*[^ \t]|)[ \t]*$" ,
  919.             "%s=%s",
  920.         ]],
  921.         ],
  922.     ]
  923.                     )
  924.                 )
  925.         );
  926.     path filepath = .yast2.desktop1.v."Desktop Entry".Icon;
  927.     string icon = (string) SCR::Read(filepath);
  928.     y2debug("icon: %1 (%2)", icon, filepath);
  929.  
  930.     if (icon == nil) 
  931.         return false;
  932.  
  933.     SetTitleIcon(icon);
  934.  
  935.     SCR::UnmountAgent (.yast2.desktop1);
  936.     return true;
  937.     }
  938.  
  939.     /**
  940.      * PRIVATE - Replace the entire Wizard button box with a new one.
  941.      * @param button_box Button Box term
  942.      * @return void
  943.      **/
  944.     void ReplaceButtonBox( term button_box )
  945.     {
  946.     UI::ReplaceWidget(`id(`rep_button_box ), button_box );
  947.     }
  948.  
  949.  
  950.  
  951.     /**
  952.      * Enable the wizard's "Abort" button.
  953.      *
  954.      * @see DisableAbortButton
  955.      * @stable
  956.      **/
  957.     global void EnableAbortButton()
  958.     {
  959.     if ( UI::WizardCommand(`EnableAbortButton( true ) ) == false )
  960.         UI::ChangeWidget(`id(`abort), `Enabled, true );
  961.     }
  962.  
  963.  
  964.     /**
  965.      * Disable the wizard's "Abort" button.
  966.      *
  967.      * @see EnableAbortButton
  968.      * @stable
  969.      **/
  970.     global void DisableAbortButton()
  971.     {
  972.     if ( UI::WizardCommand(`EnableAbortButton( false ) ) == false )
  973.         UI::ChangeWidget(`id(`abort), `Enabled, false );
  974.     }
  975.  
  976.  
  977.     /**
  978.      * Disable the wizard's "Next" (or "Accept") button.
  979.      *
  980.      * @see EnableNextButton
  981.      * @stable
  982.      **/
  983.     global void DisableNextButton()
  984.     {
  985.     if ( UI::WizardCommand(`EnableNextButton( false ) ) == false )
  986.     {
  987.         if ( UI::WidgetExists(`id(`next ) ) )
  988.         UI::ChangeWidget(`id(`next), `Enabled, false );
  989.         else
  990.         UI::ChangeWidget(`id(`accept), `Enabled, false );
  991.     }
  992.     }
  993.  
  994.  
  995.     /**
  996.      * Enable the wizard's "Next" (or "Accept") button.
  997.      *
  998.      * @see DisableNextButton
  999.      * @stable
  1000.      **/
  1001.     global void EnableNextButton()
  1002.     {
  1003.     if ( UI::WizardCommand(`EnableNextButton( true ) ) == false )
  1004.     {
  1005.         if ( UI::WidgetExists(`id(`next ) ) )
  1006.         UI::ChangeWidget(`id(`next), `Enabled, true );
  1007.         else
  1008.         UI::ChangeWidget(`id(`accept), `Enabled, true );
  1009.     }
  1010.     }
  1011.  
  1012.  
  1013.     /**
  1014.      * Disable the wizard's "Back" button.
  1015.      *
  1016.      * @see EnableBackButton
  1017.      * @stable
  1018.      **/
  1019.     global void DisableBackButton()
  1020.     {
  1021.     if ( UI::WizardCommand(`EnableBackButton( false ) ) == false )
  1022.         UI::ChangeWidget(`id(`back ), `Enabled, false );
  1023.     }
  1024.  
  1025.     /**
  1026.      * Enable the wizard's "Back" button.
  1027.      *
  1028.      * @see DisableBackButton
  1029.      * @stable
  1030.      **/
  1031.     global void EnableBackButton()
  1032.     {
  1033.     if ( UI::WizardCommand(`EnableBackButton( true ) ) == false )
  1034.         UI::ChangeWidget(`id(`back ), `Enabled, true );
  1035.     }
  1036.  
  1037.  
  1038.     /**
  1039.      * Disable the wizard's "Cancel" button.
  1040.      *
  1041.      * @see EnableCancelButton
  1042.      * @stable
  1043.      **/
  1044.     global void DisableCancelButton()
  1045.     {
  1046.     if ( UI::WizardCommand(`EnableCancelButton( false ) ) == false )
  1047.         UI::ChangeWidget(`id(`cancel ), `Enabled, false );
  1048.     }
  1049.  
  1050.     /**
  1051.      * Enable the wizard's "Cancel" button.
  1052.      *
  1053.      * @see DisableCancelButton
  1054.      * @stable
  1055.      **/
  1056.     global void EnableCancelButton()
  1057.     {
  1058.     if ( UI::WizardCommand(`EnableCancelButton( true ) ) == false )
  1059.         UI::ChangeWidget(`id(`cancel ), `Enabled, true );
  1060.     }
  1061.  
  1062.     /**
  1063.      * Show a "Release Notes" button with the specified label and ID if there is a "steps" panel
  1064.      **/
  1065.     global void ShowReleaseNotesButton( string label, any id )
  1066.     {
  1067.     if ( UI::WizardCommand(`ShowReleaseNotesButton( label, id ) ) == false )
  1068.     {
  1069.         UI::ReplaceWidget (`id (`back_rep), `PushButton (`id (id), label));
  1070.     }
  1071.     }
  1072.  
  1073.  
  1074.     /**
  1075.      * Hide the "Release Notes" button, if there is any
  1076.      **/
  1077.     global void HideReleaseNotesButton()
  1078.     {
  1079.     if ( UI::WizardCommand(`HideReleaseNotesButton() ) == false )
  1080.     {
  1081.         UI::ReplaceWidget (`id (`back_rep), `Empty ());
  1082.     }
  1083.     }
  1084.  
  1085.  
  1086.     /**
  1087.      * Retranslate the wizard buttons.
  1088.      *
  1089.      * This will revert button labels and IDs
  1090.      * to the default that were used upon Wizard::CreateDialog(),
  1091.      * Wizard::OpenNextBackDialog(), or Wizard::OpenAcceptDialog().
  1092.      **/
  1093.     global void RetranslateButtons()
  1094.     {
  1095.     if ( UI::WidgetExists(`id(`WizardDialog ) ) == true )
  1096.     {
  1097.         ReplaceButtonBox( UI::WidgetExists(`id(`accept ) ) ?
  1098.                   Wizard::AbortAcceptButtonBox() :
  1099.                   Wizard::BackAbortNextButtonBox() );
  1100.     }
  1101.     else // Qt wizard
  1102.     {
  1103.         UI::WizardCommand(`RetranslateInternalButtons() );
  1104.         
  1105.         if ( UI::WidgetExists(`accept) )
  1106.         {
  1107.         UI::WizardCommand(`SetBackButtonLabel ( "" ) );
  1108.         UI::WizardCommand(`SetAbortButtonLabel( Label::AbortButton()  ) );
  1109.         UI::WizardCommand(`SetNextButtonLabel ( Label::AcceptButton() ) );
  1110.         }
  1111.         else
  1112.         {
  1113.         UI::WizardCommand(`SetBackButtonLabel ( Label::BackButton()  ) );
  1114.         UI::WizardCommand(`SetAbortButtonLabel( Label::AbortButton() ) );
  1115.         UI::WizardCommand(`SetNextButtonLabel ( Label::NextButton()  ) );
  1116.         }
  1117.     }
  1118.     }
  1119.  
  1120.  
  1121.     /**
  1122.      * Set the keyboard focus to the wizard's "Next" (or "Accept") button.
  1123.      *
  1124.      * @stable
  1125.      **/
  1126.     global void SetFocusToNextButton()
  1127.     {
  1128.     if ( UI::WizardCommand(`SetFocusToNextButton() ) == false )
  1129.     {
  1130.         UI::SetFocus( UI::WidgetExists(`id(`next) ) ? `id(`next) : `id(`accept ) );
  1131.     }
  1132.     }
  1133.  
  1134.     /**
  1135.      * Set the keyboard focus to the wizard's "Back" (or "Cancel") button.
  1136.      *
  1137.      * @stable
  1138.      **/
  1139.     global void SetFocusToBackButton()
  1140.     {
  1141.     if ( UI::WizardCommand(`SetFocusToBackButton() ) == false )
  1142.     {
  1143.         UI::SetFocus( UI::WidgetExists(`id(`back) ) ? `id(`back) : `id(`cancel ) );
  1144.     }
  1145.     }
  1146.  
  1147.  
  1148.  
  1149.  
  1150.     /* ------------------------------------------------------------ */
  1151.     /*
  1152.      * screenshot functions
  1153.      */
  1154.  
  1155.     /**
  1156.      * Currently used screenshot name.
  1157.      * Initially, it must match the UI default, "yast2"
  1158.      */
  1159.     string screenshot_name = "yast2";
  1160.     /**
  1161.      * Screenshot names overriden by nested SetScreenShotName calls
  1162.      */
  1163.     list<string> screenshot_name_stack = [];
  1164.  
  1165.     /**
  1166.      * Declare a name for the current dialog
  1167.      *
  1168.      * Declare a name for the current dialog to ease making screenshots.
  1169.      * By convention, the name is
  1170.      * {rpm-name-without-yast2}-{sorting-prefix}-{description}
  1171.      * The calls may be nested.
  1172.      * @param s eg. "mail-1-conntype"
  1173.      * @see RestoreScreenShotName
  1174.      */
  1175.     global void SetScreenShotName (string s) {
  1176.     screenshot_name_stack = prepend (screenshot_name_stack, screenshot_name);
  1177.     screenshot_name = s;
  1178.     UI::SetModulename (screenshot_name);
  1179.     }
  1180.  
  1181.     /**
  1182.      * Restore the screenshot name.
  1183.      *
  1184.      * If it does not match a SetScreenShotName, "yast2" is used
  1185.      * and a y2error logged.
  1186.      */
  1187.     global void RestoreScreenShotName () {
  1188.     screenshot_name = screenshot_name_stack[0]:nil;
  1189.     if (screenshot_name == nil)
  1190.     {
  1191.         screenshot_name = "yast2";
  1192.         y2error (1, "No screenshot name to restore!");
  1193.     }
  1194.     else
  1195.     {
  1196.         screenshot_name_stack = remove (screenshot_name_stack, 0);
  1197.     }
  1198.     UI::SetModulename (screenshot_name);
  1199.     }
  1200.  
  1201.     /* ------------------------------------------------------------ */
  1202.     /*
  1203.      * Tree & Menu Wizard functions
  1204.      */
  1205.  
  1206.     /**
  1207.      * Open a Tree  dialog with buttons "Next", "Back", "Abort"
  1208.      * and set the keyboard focus to "Next".
  1209.      **/
  1210.     global void OpenTreeNextBackDialog()
  1211.     {
  1212.         if ( haveFancyUI() )
  1213.         {
  1214.             UI::OpenDialog(`opt(`defaultsize ),
  1215.                     `Wizard(`opt(`treeEnabled),
  1216.                         `back, Label::BackButton(),
  1217.                         `abort, Label::AbortButton(),
  1218.                         `next, Label::NextButton()
  1219.                         )
  1220.                     );
  1221.         }
  1222.         else
  1223.         {
  1224.         Wizard::OpenDialog( NextBackDialog() );
  1225.         UI::SetFocus(`id(`next) );
  1226.         }
  1227.     }
  1228.  
  1229.     /**
  1230.      * Create and open a Tree wizard dialog.
  1231.      *
  1232.      * For backwards compatibility only - don't use this any more in new modules.
  1233.      **/
  1234.     global void CreateTreeDialog()
  1235.     {
  1236.     Wizard::OpenTreeNextBackDialog();
  1237.         return;
  1238.     }
  1239.  
  1240.     /**
  1241.      * Add Tree Item to tree enabled Wizard
  1242.      * @param Tree Tree Data
  1243.      * @param parent Parent of this item
  1244.      * @param title Item Title
  1245.      * @param id Item ID
  1246.      * @return list<map> Updated Tree Data
  1247.      **/
  1248.     global list<map> AddTreeItem(list<map> Tree, string parent , string title, string id) {
  1249.         if ( haveFancyUI() )
  1250.         {
  1251.             UI::WizardCommand(`AddTreeItem( parent, title , id ) );
  1252.         }
  1253.         else
  1254.         {
  1255.             Tree = add(Tree, $[ "parent": parent, "title":title, "id": id]);
  1256.         }
  1257.         return Tree;
  1258.     }
  1259.  
  1260.  
  1261.     /**
  1262.      * Create the Tree Items
  1263.      * @param Tree Tree data
  1264.      * @param parent Parent of current Item
  1265.      * @return list Tree Items
  1266.      **/
  1267.     list CreateTreeInternal(list<map> Tree, string parent) {
  1268.         list<map> m = filter(map c, Tree, ``((c["parent"]:"" == parent )));
  1269.         map ccbak = nil; // #38596, broken recursion for iterators
  1270.         list mm = maplist(map cc, m, ``{
  1271.                     string TreeEntry = cc["id"]:"";
  1272.                     ccbak = cc;
  1273.                     list items = CreateTreeInternal(Tree, TreeEntry);
  1274.                     cc = ccbak;
  1275.                     if (size(items)>0)
  1276.                         return(`item(`id(cc["id"]:""), cc["title"]:"", items));
  1277.                     else
  1278.                         return(`item(`id(cc["id"]:""), cc["title"]:""));
  1279.                 });
  1280.         y2debug("items: %1", mm );
  1281.         return mm;
  1282.     }
  1283.  
  1284.  
  1285.     /**
  1286.      * Query Tree Item
  1287.      * @return Tree Item
  1288.      */
  1289.     global string QueryTreeItem() {
  1290.  
  1291.         if (haveFancyUI() )
  1292.         {
  1293.             return (string)UI::QueryWidget(`id(`wizard), `CurrentItem );
  1294.         }
  1295.         else
  1296.         {
  1297.             return (string)UI::QueryWidget(`id(`wizardTree), `CurrentItem );
  1298.         }
  1299.     }
  1300.  
  1301.     /**
  1302.      * Create the tree in the dialog, replaces helpspace with new tree widget
  1303.      * @param Tree Tree data
  1304.      * @param title Tree title
  1305.      **/
  1306.     global void CreateTree(list<map> Tree, string title) {
  1307.         if ( !haveFancyUI() )
  1308.         {
  1309.             list items = [];
  1310.             foreach(map i, Tree, ``{
  1311.                     if (i["parent"]:"" == "")
  1312.                     {
  1313.                         items=add(items, `item(`id(i["id"]:""), i["title"]:"",
  1314.                                 CreateTreeInternal(Tree, i["id"]:"") ));
  1315.                     }
  1316.                     });
  1317.             y2debug("tree items: %1", items);
  1318.             Wizard::ReplaceCustomHelp(
  1319.                     `VBox(
  1320.                         `Tree(
  1321.                             `id(`wizardTree),
  1322.                             `opt(`notify, `vstretch),
  1323.                             title,
  1324.                             items
  1325.                             ),
  1326.                         `VSpacing(1))
  1327.                     );
  1328.         }
  1329.         return;
  1330.  
  1331.     }
  1332.  
  1333.     /**
  1334.      * Select Tree item
  1335.      * @param tree_item tree item
  1336.      */
  1337.     global void SelectTreeItem(string tree_item) {
  1338.         if ( haveFancyUI() )
  1339.         {
  1340.             UI::WizardCommand(`SelectTreeItem( tree_item ) );
  1341.         }
  1342.         else
  1343.         {
  1344.             UI::ChangeWidget(`id(`wizardTree), `CurrentItem, tree_item);
  1345.         }
  1346.     }
  1347.     /**
  1348.      * Delete Tree items
  1349.      */
  1350.     global void DeleteTreeItems() {
  1351.         if ( haveFancyUI() )
  1352.         {
  1353.             UI::WizardCommand(`DeleteTreeItems() );
  1354.         }
  1355.         else
  1356.         {
  1357.             Wizard::ReplaceCustomHelp(`Empty());
  1358.         }
  1359.     }
  1360.  
  1361.     /**
  1362.      * Delete Menu items
  1363.      */
  1364.     global void DeleteMenus() {
  1365.         if ( haveFancyUI() )
  1366.         {
  1367.             UI::WizardCommand(`DeleteMenus() );
  1368.         }
  1369.         else
  1370.         {
  1371.             UI::ReplaceWidget(`id(`topmenu), `Empty());
  1372.         }
  1373.     }
  1374.     /**
  1375.      * Add Menu
  1376.      * @param Menu  Menu data
  1377.      * @param title Menu Title
  1378.      * @param id Menu ID
  1379.      * @return list<map> Updated Menu Data
  1380.      **/
  1381.     global list<map> AddMenu(list<map> Menu, string title, string id) {
  1382.         if ( haveFancyUI() )
  1383.         {
  1384.             UI::WizardCommand(`AddMenu( title, id ) );
  1385.         }
  1386.         else
  1387.         {
  1388.             Menu = add(Menu, $["type":"Menu", "title":title, "id": id]);
  1389.         }
  1390.         return Menu;
  1391.     }
  1392.  
  1393.     /**
  1394.      * Add Sub Menu
  1395.      * @param Menu Menu data
  1396.      * @param parent_id Menu Parent
  1397.      * @param title Menu Title
  1398.      * @param id Menu ID
  1399.      * @return list<map> Updated Menu Data
  1400.      **/
  1401.     global list<map>  AddSubMenu(list<map> Menu, string parent_id, string title, string id) {
  1402.         if ( haveFancyUI() )
  1403.         {
  1404.             UI::WizardCommand(`AddSubMenu( parent_id, title, id ) );
  1405.         }
  1406.         else
  1407.         {
  1408.             Menu = add(Menu, $["type":"SubMenu", "parent": parent_id, "title":title, "id": id]);
  1409.         }
  1410.         return Menu;
  1411.     }
  1412.  
  1413.     /**
  1414.      * Add Menu Entry
  1415.      * @param Menu Menu data
  1416.      * @param parent_id Menu Parent
  1417.      * @param title Menu Title
  1418.      * @param id Menu ID
  1419.      * @return list<map> Updated Menu Data
  1420.      **/
  1421.     global list<map> AddMenuEntry(list<map> Menu, string parent_id, string title, string id) {
  1422.         if ( haveFancyUI() )
  1423.         {
  1424.             UI::WizardCommand(`AddMenuEntry( parent_id, title, id ) );
  1425.         }
  1426.         else
  1427.         {
  1428.             Menu = add(Menu, $["type":"MenuEntry", "parent": parent_id, "title":title, "id": id]);
  1429.         }
  1430.         return Menu;
  1431.     }
  1432.  
  1433.     /**
  1434.      * Create the Menu Items
  1435.      * @param Menu Menu data
  1436.      * @param parent Menu Parent
  1437.      * @return list Menu Items
  1438.      **/
  1439.     list CreateMenuInternal(list<map> Menu, string parent) {
  1440.         list<map> m = filter(map c, Menu, ``((c["parent"]:"" == parent )));
  1441.  
  1442.         list mm = maplist(map cc, m, ``{
  1443.                 if(cc["type"]:"" == "MenuEntry")
  1444.                 {
  1445.                     string MenuEntry = cc["id"]:"";
  1446.                     return(`item(`id(MenuEntry), cc["title"]:""));
  1447.                 }
  1448.                 else if (cc["type"]:"" == "SubMenu")
  1449.                 {
  1450.                     string SubMenu = cc["id"]:"";
  1451.                     return(`menu( cc["title"]:"", CreateMenuInternal(Menu,
  1452.                                 SubMenu)));
  1453.                 }
  1454.                 });
  1455.         y2debug("items: %1", mm );
  1456.         return mm;
  1457.     }
  1458.  
  1459.     /**
  1460.      * Create the menu in the dialog
  1461.      * @param Menu Menu data
  1462.      * @return void
  1463.      **/
  1464.     global void CreateMenu(list<map> Menu) {
  1465.         if (!haveFancyUI() )
  1466.         {
  1467.             term menu_term = `HBox();
  1468.             foreach(map m, Menu, ``{
  1469.                     if (m["type"]:"" == "Menu")
  1470.                     {
  1471.                         list menu_items = CreateMenuInternal(Menu, m["id"]:"");
  1472.                         y2debug("menu_items: %1", menu_items );
  1473.                         menu_term=add(menu_term, `MenuButton( m["title"]:"",
  1474.                                 menu_items));
  1475.                     }
  1476.                     });
  1477.             y2milestone("menu: %1", menu_term );
  1478.             UI::ReplaceWidget(`id(`topmenu), `Left(menu_term));
  1479.         }
  1480.         return;
  1481.     }
  1482.  
  1483.  
  1484.     /**
  1485.      * Set the product name for UI
  1486.      * @param name the product name
  1487.      * @return void
  1488.      **/
  1489.     global void SetProductName (string name) {
  1490.         y2milestone ("Setting product name to '%1'", name);
  1491.         product_name = name;
  1492.     }
  1493.  
  1494.  
  1495. /* EOF */
  1496. }
  1497.