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 / Popup.ycp < prev    next >
Text File  |  2006-11-29  |  42KB  |  1,524 lines

  1. /**
  2.  * File:    modules/Popup.ycp
  3.  * Package:    yast2
  4.  * Summary:    Commonly used popup dialogs
  5.  * Authors:    Gabriele Strattner <gs@suse.de>
  6.  *        Stefan Hundhammer <sh@suse.de>
  7.  *        Arvin Schnell <arvin@suse.de>
  8.  * Flags:    Stable
  9.  *
  10.  * $Id: Popup.ycp 31242 2006-06-01 12:59:16Z locilka $
  11.  *
  12.  * Contains commonly used popup dialogs
  13.  * for general usage, e.g. Popup::YesNo(), Popup::ContinueCancel().
  14.  * <br>
  15.  * See also <a href="../wizard/README.popups">README.popups</a>
  16.  */
  17.  
  18. {
  19.  
  20. module "Popup";
  21.  
  22. textdomain "base";
  23.  
  24. import "Label";
  25. import "Mode";
  26. import "Directory";
  27. import "String";
  28.  
  29. boolean feedback_open = false;
  30.  
  31. // default size of the richtext widget in richtext popups
  32. integer default_width = 60;
  33. integer default_height = 10;
  34.  
  35.  
  36.  
  37. /**
  38.  * Internal function that returns a popup dialog with an additional label.
  39.  *
  40.  * @param headline    headline to show or Popup::NoHeadline()
  41.  * @param message    message text to show
  42.  * @param icon_name    icon name (with full path) or Popup::NoIcon()
  43.  * @param button_box    term with one or more buttons
  44.  * @param label        second label with id `label which can be used e.g. for time out value displaying
  45.  *
  46.  * @return term the layout contents as a term
  47.  */
  48. define term popupLayoutInternalTypeWithLabel( string headline,
  49.                       string message,
  50.                       string icon_name,
  51.                       term button_box,
  52.                       string label,
  53.                       boolean richtext,
  54.                       integer width,
  55.                       integer height )
  56. {
  57.     term content = `Empty();
  58.     term heading = `VSpacing(0.2);
  59.     term icon    = `Empty();
  60.  
  61.     if ( size( icon_name ) > 0 )
  62.     {
  63.     map ui_capabilities = UI::GetDisplayInfo();
  64.  
  65.     if ( ui_capabilities[ "HasLocalImageSupport" ]:false )
  66.     {
  67.         icon = `Image( icon_name, "" );
  68.     }
  69.     }
  70.  
  71.     term rt = `VWeight(1,
  72.     `VBox(
  73.         `HSpacing(width),
  74.         `HBox(
  75.         `VSpacing(height),
  76.         // display the message in the widget "as is":
  77.         // escape all tags, replace new lines by <br> tag
  78.         `RichText(mergestring(splitstring(String::EscapeTags(message), "\n"), "<br>"))
  79.         )
  80.     )
  81.     );
  82.  
  83.  
  84.     if ( size( headline ) > 0 )
  85.     {
  86.     content =
  87.         `VBox(
  88.           `HBox(
  89.             `VCenter( icon ),
  90.             `HSpacing(1),
  91.             `VCenter(`Heading( headline ) ),
  92.             `HStretch()
  93.             ),
  94.           `VSpacing(0.2),
  95.           richtext ? rt : `Left( `Label( message ) ),
  96.           `VSpacing(0.2),
  97.           (label != nil && label != "") ? `Label(`id(`label), label ) : `Empty()
  98.           );
  99.     }
  100.     else // no headline
  101.     {
  102.     content =
  103.         `VBox(
  104.           `HBox(
  105.             `Top( icon ),
  106.             `HSpacing(1),
  107.             richtext ? rt : `VCenter (`Label( message ) )
  108.             ),
  109.           `VSpacing(0.2),
  110.           (label != nil && label != "") ? `Label(`id(`label), label ) : `Empty()
  111.           );
  112.     }
  113.  
  114.     term dialog =
  115.     `HBox(
  116.           `HSpacing(1),
  117.           `VBox(
  118.             `VSpacing(0.2),
  119.             content,
  120.             richtext ? `Empty() : `VStretch(),
  121.             button_box,
  122.             richtext ? `Empty() : `VStretch(),
  123.             `VSpacing(0.2)
  124.             ),
  125.           `HSpacing(1)
  126.           );
  127.  
  128.     return dialog;
  129. }
  130.  
  131. /**
  132.  * Internal function - wrapper for popupLayoutInternalTypeWithLabel call
  133.  */
  134. define term popupLayoutInternal( string headline, string message, string icon_name, term button_box ) {
  135.     return popupLayoutInternalTypeWithLabel(headline, message, icon_name, button_box, nil, false, 0, 0);
  136. }
  137.  
  138. /**
  139.  * Internal function - wrapper for popupLayoutInternalTypeWithLabel call
  140.  */
  141. define term popupLayoutInternalRich( string headline, string message, string icon_name, term button_box, integer width, integer height ) {
  142.     return popupLayoutInternalTypeWithLabel(headline, message, icon_name, button_box, nil, true, width, height);
  143. }
  144.  
  145.  
  146. /**
  147.  * Internal version of AnyTimedMessage
  148.  *
  149.  * Show a message with optional headline above and
  150.  * wait until user clicked "OK" or until a timeout runs out.
  151.  *
  152.  * @param headline    optional headline or Popup::NoHeadline()
  153.  * @param message    the message (maybe multi-line) to display.
  154.  * @param icon_name    icon name (with full path) or Popup::NoIcon()
  155.  * @param timeout    After timeout seconds dialog will be automatically closed
  156.  *
  157.  * @return void
  158.  **/
  159. define void anyTimedMessageTypeInternal(string headline,
  160.                     string message,
  161.                     string icon_name,
  162.                     integer timeout,
  163.                     boolean richtext,
  164.                     integer width,
  165.                     integer height )
  166. {
  167.     term button_box = `HBox(
  168.     `HStretch(),
  169.     `HWeight(1, `PushButton( `id(`stop), Label::StopButton())),
  170.     `HSpacing(2),
  171.     `HWeight(1, `PushButton( `id(`ok_msg), `opt(`default, `key_F10), Label::OKButton())),
  172.     `HStretch()
  173.     );
  174.     UI::OpenDialog(
  175.            `opt(`decorated),
  176.            popupLayoutInternalTypeWithLabel( headline, message, icon_name,
  177.                          button_box, sformat("%1", timeout), richtext, width, height )
  178.            );
  179.  
  180.     UI::SetFocus(`id(`ok_msg));
  181.  
  182.  
  183.     symbol button = nil;
  184.  
  185.     while ( timeout > 0 && button != `ok_msg)
  186.     {
  187.     button = (symbol) UI::TimeoutUserInput( 1000 );
  188.  
  189.     if (button == `stop)
  190.     {
  191.         while(UI::UserInput() != `ok_msg){};
  192.         break;
  193.     }
  194.  
  195.     timeout = timeout - 1;
  196.  
  197.     UI::ChangeWidget(`id(`label), `Value, sformat("%1", timeout ));
  198.     }
  199.  
  200.     UI::CloseDialog();
  201. }
  202.  
  203. /**
  204.  * Internal function - wrapper for anyTimedMessageTypeInternal call
  205.  */
  206. define void anyTimedMessageInternal(string headline,
  207.                     string message,
  208.                     string icon_name,
  209.                     integer timeout )
  210. {
  211.     anyTimedMessageTypeInternal(headline, message, icon_name, timeout, false, 0, 0);
  212. }
  213.  
  214. /**
  215.  * Internal function - wrapper for anyTimedMessageTypeInternal call
  216.  */
  217. define void anyTimedRichMessageInternal(string headline,
  218.                     string message,
  219.                     string icon_name,
  220.                     integer timeout,
  221.                     integer width,
  222.                     integer height )
  223. {
  224.     anyTimedMessageTypeInternal(headline, message, icon_name, timeout, true, width, height);
  225. }
  226.  
  227.  
  228. /**
  229.  * Returns the full icon path for a icon with the specified base name.
  230.  * "warning.png" -> "/usr/lib/YaST2/theme/icons/32x32/apps/warning.png"
  231.  **/
  232. define string popupIcon( string icon_base_name )
  233. {
  234.     return Directory::icondir + "32x32/apps/" + icon_base_name;
  235. }
  236.  
  237.  
  238. /**
  239.  * Indicator for empty headline for popups that can optionally have one
  240.  *
  241.  * This is really just an alias for the empty string "", but it is
  242.  * slightly better readable.
  243.  *
  244.  * @return empty string ("")
  245.  */
  246. global define string NoHeadline()
  247. {
  248.     return "";
  249. }
  250.  
  251.  
  252. /**
  253.  * Indicator for empty icon for popups that can have one - for code readability.
  254.  **/
  255. global define string NoIcon()
  256. {
  257.     return "";
  258. }
  259.  
  260. /**
  261.  * Button box for the AnyQuestion Dialog (internal function).
  262.  *
  263.  * @param yes_button_message    label on affirmative buttons (on left side)
  264.  * @param no_button_message    label on negating button (on right side)
  265.  * @param focus            `focus_yes (first button) or `focus_no (second button)
  266.  *
  267.  * @return term button box
  268.  */
  269. define term AnyQuestionButtonBox (
  270.     string yes_button_message,
  271.     string no_button_message,
  272.     symbol focus )
  273. {
  274.     term yes_button = `Empty();
  275.     term no_button = `Empty();
  276.  
  277.     if ( focus == `focus_no )
  278.     {
  279.     yes_button = `PushButton( `id(`yes),
  280.                   `opt (`key_F10),
  281.                   yes_button_message );
  282.     no_button  = `PushButton( `id(`no_button),
  283.                   `opt(`default, `key_F9),
  284.                   no_button_message );
  285.     }
  286.     else
  287.     {
  288.     yes_button = `PushButton( `id(`yes),
  289.                   `opt(`default, `key_F10),
  290.                   yes_button_message);
  291.     no_button  = `PushButton( `id(`no_button),
  292.                   `opt (`key_F9),
  293.                   no_button_message );
  294.     }
  295.  
  296.     term button_box =  `HBox(
  297.                  `HStretch (),
  298.                  `HWeight( 1, yes_button),
  299.                  `HSpacing(2),
  300.                  `HWeight( 1, no_button ),
  301.                  `HStretch ()
  302.                  );
  303.     return button_box;
  304. }
  305.  
  306.  
  307. /**
  308.  * Generic question popup with two buttons.
  309.  *
  310.  * Style guide hint: The first button has to have the semantics of "yes",
  311.  * "OK", "continue" etc., the second its opposite ("no", "cancel", ...).
  312.  * NEVER use this generic question popup to simply exchange the order of
  313.  * yes/no, continue/cancel or ok/cancel buttons!
  314.  *
  315.  * @param headline        headline or Popup::NoHeadline()
  316.  * @param message        message string
  317.  * @param yes_button_message    label on affirmative buttons (on left side)
  318.  * @param no_button_message    label on negating button (on right side)
  319.  * @param focus            `focus_yes (first button) or `focus_no (second button)
  320.  * @screenshot screenshots/AnyQuestion.png
  321.  *
  322.  * @return true:  first button has been clicked
  323.  *     false: second button has been clicked
  324.  *
  325.  * @see YesNo
  326.  * @see ContinueCancel
  327.  *
  328.  * @example Popup::AnyQuestion( Label::WarningMsg(), "Do really want to ...?", "Install", "Don't do it", `focus_no );
  329.  */
  330. global define boolean AnyQuestion( string headline,
  331.                    string message,
  332.                    string yes_button_message,
  333.                    string no_button_message,
  334.                    symbol focus )
  335. {
  336.     term button_box = AnyQuestionButtonBox ( yes_button_message, no_button_message, focus);
  337.     UI::OpenDialog( 
  338.            `opt(`decorated),
  339.            popupLayoutInternal( headline, message, NoIcon(), button_box )
  340.            );
  341.  
  342.     any ret = UI::UserInput();
  343.     UI::CloseDialog();
  344.  
  345.     return ret == `yes;
  346. }
  347.  
  348.  
  349. /**
  350.  * Timed question popup with two buttons and time display
  351.  *
  352.  * @param headline        headline or Popup::NoHeadline()
  353.  * @param message        message string
  354.  * @param yes_button_message    label on affirmative buttons (on left side)
  355.  * @param no_button_message    label on negating button (on right side)
  356.  * @param focus            `focus_yes (first button) or `focus_no (second button)
  357.  * @param timeout_seconds    timeout, if 0, normal behaviour
  358.  * @return boolean              True if Yes, False if no
  359.  * @see AnyQuestion
  360.  */
  361. global define boolean TimedAnyQuestion( string headline,
  362.                    string message,
  363.                    string yes_button_message,
  364.                    string no_button_message,
  365.                    symbol focus ,
  366.                    integer timeout_seconds)
  367. {
  368.     term button_box = AnyQuestionButtonBox ( yes_button_message, no_button_message, focus);
  369.     term timed =
  370.     `ReplacePoint(`id(`replace_buttons) ,
  371.               `VBox(
  372.                 `HCenter(
  373.                      `Label(`id(`remaining_time), "" + timeout_seconds)
  374.                      ),
  375.                 `HBox(
  376.                   `PushButton(`id(`timed_stop), Label::StopButton() ),
  377.                   `HSpacing(2),
  378.                   `PushButton(`id(`timed_ok), `opt(`default, `key_F10), Label::OKButton() )
  379.                   ),
  380.                 `VSpacing(0.2)
  381.                 )
  382.               );
  383.  
  384.  
  385.     UI::OpenDialog(
  386.            `opt(`decorated),
  387.            popupLayoutInternal( headline, message, NoIcon(), timed )
  388.            );
  389.  
  390.     any which_input = nil;
  391.  
  392.     while (timeout_seconds > 0) {
  393.     which_input = UI::TimeoutUserInput( 1000 );
  394.     if (which_input == `timed_ok)
  395.         break;
  396.     if (which_input == `timed_stop)
  397.     {
  398.         UI::ReplaceWidget(`id(`replace_buttons), button_box);
  399.         while (which_input == `timed_stop)
  400.         which_input = UI::UserInput();
  401.         break;
  402.     }
  403.     timeout_seconds = timeout_seconds - 1;
  404.     UI::ChangeWidget (`id(`remaining_time), `Value, ""+timeout_seconds);
  405.     }
  406.     UI::CloseDialog();
  407.  
  408.     return which_input == `yes;
  409. }
  410.  
  411.  
  412. /**
  413.  * Dialog which displays the "message" and has a <b>Continue</b>
  414.  * and a <b>Cancel</b> button.
  415.  *
  416.  * This popup should be used to confirm possibly dangerous actions and if
  417.  * it's useful to display a short headline (without headline
  418.  * Popup::ContinueCancel() can be used).
  419.  * The default button is Continue.
  420.  *
  421.  * Returns true if Continue is clicked.
  422.  *
  423.  * @screenshot screenshot/ContinueCancelHeadline.png
  424.  *
  425.  * @param  headline short headline or Popup::NoHeadline()
  426.  * @param  message  message string
  427.  * @return boolean
  428.  *
  429.  * @example Popup::ContinueCancelHeadline ( "Short Header", "Going on with action....?" );
  430.  *
  431.  * @see    ContinueCancel
  432.  * @see    YesNo
  433.  * @see    AnyQuestion
  434.  */
  435. global define boolean ContinueCancelHeadline (string headline, string message)
  436. {
  437.     boolean ret = AnyQuestion( headline,
  438.                    message,
  439.                    Label::ContinueButton(),
  440.                    Label::CancelButton(),
  441.                    `focus_yes
  442.                    );
  443.  
  444.     y2debug("ContinueCancelHeadline returned: %1", ret );
  445.  
  446.     return ret;
  447. }
  448.  
  449.  
  450. /**
  451.  * Dialog which displays the "message" and has a <b>Continue</b>
  452.  * and a <b>Cancel</b> button.
  453.  *
  454.  * This popup should be used to confirm possibly dangerous actions.
  455.  * The default button is Continue.
  456.  * Returns true if Continue is clicked.
  457.  *
  458.  * @screenshot screenshots/ContinueCancel.png
  459.  *
  460.  * @param  message  message string
  461.  * @return boolean
  462.  *
  463.  * @example Popup::ContinueCancel ( "Please insert required CD-ROM." );
  464.  *
  465.  * @see    AnyQuestion
  466.  */
  467. global define boolean ContinueCancel (string message)
  468. {
  469.  
  470.     boolean ret = ContinueCancelHeadline( NoHeadline(), message );
  471.     y2debug("ContinueCancel returned: %1", ret );
  472.  
  473.     return ret;
  474. }
  475.  
  476.  
  477. /**
  478.  * This dialog displays "message" (a question) and has a <b>Yes</b> and
  479.  * a <b>No</b> button.
  480.  *
  481.  * It should be used for decisions about two about equivalent paths,
  482.  * not for simple confirmation - use "Popup::ContinueCancel()" for those.
  483.  * A short headline can be displayed (without headline you can use Popup::YesNo()).
  484.  *
  485.  * The default button is Yes.
  486.  *
  487.  * Returns true if <b>Yes</b> is clicked.
  488.  *
  489.  * @screenshot screenshots/YesNoHeadline.png
  490.  *
  491.  * @param  headline    short headline or Popup::NoHeadline()
  492.  * @param  message    message string
  493.  * @return boolean    true if [Yes] has been pressed
  494.  *
  495.  * @example  Popup::YesNoHeadline ( "Resize Windows Partition?", "... explanation of dangers ..." );
  496.  *
  497.  * @see    YesNo
  498.  * @see    AnyQuestion
  499.  */
  500. global define boolean YesNoHeadline(string headline, string message)
  501. {
  502.  
  503.     boolean ret = AnyQuestion( headline,
  504.                    message,
  505.                    Label::YesButton(),
  506.                    Label::NoButton(),
  507.                    `focus_yes
  508.                    );
  509.  
  510.     y2debug("YesNoHeadline returned: %1", ret );
  511.  
  512.     return ret;
  513. }
  514.  
  515.  
  516. /**
  517.  * Display a yes/no question and wait for answer.
  518.  *
  519.  * Should be used for decisions about two about equivalent paths,
  520.  * not for simple confirmation - use "Popup::ContinueCancel()" for those.
  521.  * The default button is Yes.
  522.  * Returns true if <b>Yes</b> is clicked.
  523.  *
  524.  * @screenshot screenshots/YesNo.png
  525.  *
  526.  * @param  message    message string
  527.  * @return boolean    true if [Yes] has been pressed
  528.  *
  529.  * @example  Popup::YesNo ( "Create a backup of the config files?" );
  530.  *
  531.  * @see    YesNoHeadline
  532.  * @see    ContinueCancel
  533.  * @see    AnyQuestion
  534.  */
  535. global define boolean YesNo(string message)
  536. {
  537.     boolean ret = YesNoHeadline( NoHeadline(), message);
  538.  
  539.     y2debug("YesNo returned: %1", ret );
  540.  
  541.     return ret;
  542. }
  543.  
  544.  
  545. /**
  546.  * Show a long text that might need scrolling.
  547.  *
  548.  * Pass a RichText widget with the parameters appropriate for your text -
  549.  * i.e. without special parameters for HTML-like text or with
  550.  * `opt(`plainText) for plain ASCII text without HTML tags.
  551.  *
  552.  * @screenshot screenshots/LongText.png
  553.  *
  554.  * @param  headline short headline
  555.  * @param  richtext  text input is `Richtext()
  556.  * @param  hdim  initial horizontal dimension of the popup
  557.  * @param  vdim  initial vertical dimension of the popup
  558.  *
  559.  * @example Popup::LongText ( "Package description", `Richtext("<p>Hello, this is a long description .....</p>"), 50, 20 );
  560.  */
  561. global define void LongText( string headline, term richtext,
  562.                  integer hdim, integer vdim )
  563. {
  564.     UI::OpenDialog( `opt( `decorated ),
  565.             `HBox( `VSpacing(vdim),
  566.                `VBox (`HSpacing(hdim),
  567.                   `Left(`Heading( headline )),
  568.                   `VSpacing(0.2),
  569.                   richtext,    // scrolled text
  570.                   `PushButton( `id(`ok), `opt(`default, `key_F10), Label::OKButton() )
  571.                   )
  572.                )
  573.             );
  574.  
  575.     UI::SetFocus(`id(`ok ) );
  576.  
  577.     UI::UserInput();
  578.     UI::CloseDialog();
  579. }
  580.  
  581.  
  582. /**
  583.  * Show a question that might need scrolling.
  584.  *
  585.  * @param  headline short headline
  586.  * @param  richtext  text input as a rich text
  587.  * @param  hdim  initial horizontal dimension of the popup
  588.  * @param  vdim  initial vertical dimension of the popup
  589.  * @param  yes_button_message message on the left/true button
  590.  * @param  no_button_message message on the right/false button
  591.  * @param  focus `focus_yes, `focus_no, `focus_none
  592.  * @return left button pressed?
  593.  */
  594. global define boolean AnyQuestionRichText (string headline,
  595.                        string richtext,
  596.                        integer hdim, integer vdim,
  597.                        string yes_button_message,
  598.                        string no_button_message,
  599.                        symbol focus)
  600. {
  601.     term yes_button = `PushButton (
  602.     `id (`ok),
  603.     ( focus == `focus_yes ?
  604.       `opt (`default, `key_F10) :
  605.       `opt (`key_F10) ),
  606.     yes_button_message);
  607.  
  608.     term no_button = `PushButton (
  609.     `id (`cancel),
  610.     ( focus == `focus_no ?
  611.       `opt (`default, `key_F9) :
  612.       `opt (`key_F9) ),
  613.     no_button_message);
  614.  
  615.     term d = `HBox (
  616.     `VSpacing (vdim),
  617.     `VBox (
  618.         `HSpacing (hdim),
  619.         size (headline) > 0 ? `Left(`Heading( headline )) : `Empty (),
  620.         `VSpacing(0.2),
  621.         `RichText (richtext),
  622.         `HBox (
  623.         yes_button,
  624.         no_button
  625.         )
  626.         )
  627.     );
  628.     UI::OpenDialog (`opt (`decorated), d);
  629.     any ui = UI::UserInput ();
  630.     UI::CloseDialog ();
  631.     return ui == `ok;
  632. }
  633.  
  634.  
  635. /**
  636.  * Confirmation for "Abort" button during installation.
  637.  *
  638.  * According to the "severity" parameter an appropriate text will be
  639.  * displayed indicating what the user has to expect when he really aborts now.
  640.  *
  641.  * @screenshot screenshots/ConfirmAbort.png
  642.  *
  643.  * @param severity        `painless, `incomplete, `unusable
  644.  *
  645.  * @return boolean
  646.  *
  647.  * @example Popup::ConfirmAbort ( `painless );
  648.  */
  649. global define boolean ConfirmAbort( symbol severity )
  650. {
  651.     string what_will_happen = "";
  652.  
  653.     // Confirm user request to abort installation
  654.     string abort_label = _("Really abort the installation?");
  655.     // Button that will really abort the installation
  656.     string abort_button = _("&Abort Installation");
  657.     // Button that will continue with the installation
  658.     string continue_button = _("&Continue Installation");
  659.  
  660.     if ( severity == `painless )
  661.     {
  662.     if (Mode::repair ())
  663.     {
  664.         // Confirm user request to abort System Repair
  665.         abort_label = _("Really abort YaST System Repair?");
  666.         // Button that will really abort the repair
  667.         abort_button = _("Abort System Repair");
  668.         // Button that will continue with the repair
  669.         continue_button = _("&Continue System Repair");
  670.     }
  671.     else
  672.     {
  673.         // Warning text for aborting an installation before anything is installed
  674.         what_will_happen = _("If you abort the installation now,
  675. Linux will not be installed.
  676. Your hard disk will remain untouched.");
  677.     }
  678.     }
  679.     else if ( severity == `incomplete )
  680.     {
  681.     // Warning text for aborting an installation during the install process
  682.     // - After some installation steps have been performed - e.g.
  683.     // disks formatted / some packages already installed
  684.     what_will_happen = _("If you abort the installation now, you will
  685. have an incomplete Linux system
  686. that might or might not be usable.
  687. You might need to reinstall.
  688. ");
  689.     }
  690.     else if ( severity == `unusable )
  691.     {
  692.     // Warning text for aborting an installation during the install process
  693.     // right in the middle of some critical process (e.g. formatting)
  694.     what_will_happen = _("If you abort the installation now,
  695. Linux will be unusable.
  696. You will need to reinstall.");
  697.     }
  698.     else
  699.     {
  700.     y2error ("Unknown symbol for ConfirmAbort");
  701.     }
  702.  
  703.     string message = abort_label + "\n\n" + what_will_happen;
  704.  
  705.     boolean ret = AnyQuestion (NoHeadline (), message, abort_button,
  706.                continue_button, `focus_no);
  707.  
  708.     y2debug("ConfirmAbort returned: %1", ret);
  709.  
  710.     return ret;
  711. }
  712.  
  713.  
  714. /**
  715.  * Confirmation popup when user clicked "Abort".
  716.  *
  717.  * Set "have changes" to "true" when there are changes that will be lost.
  718.  * Note: If there are none, it is good policy to ask for confirmation
  719.  * anyway, but of course with "have_changes" set to "false" so the user
  720.  * isn't warned about changes that might be lost.
  721.  *
  722.  * @param have_changes    true:  There are changes that will be lost
  723.  *            false: No changes
  724.  *
  725.  * @return    true: "abort" confirmed;
  726.  *        false: don't abort
  727.  */
  728. global define boolean ReallyAbort( boolean have_changes )
  729. {
  730.     symbol focus = `focus_yes;
  731.  
  732.     // Confirm aborting the program
  733.     string message = _("Really abort?");
  734.  
  735.     if ( have_changes )
  736.     {
  737.     focus = `focus_no;
  738.  
  739.     // Additional hint when trying to abort program in spite of changes
  740.     message = message + "\n" + _("All changes will be lost!");
  741.     }
  742.  
  743.     boolean ret = AnyQuestion( NoHeadline(),
  744.                message,
  745.                Label::YesButton(),
  746.                Label::NoButton(),
  747.                `focus_no );
  748.  
  749.     y2debug("ReallyAbort returned: %1", ret );
  750.  
  751.     return ret;
  752. }
  753.  
  754.  
  755.  
  756.  
  757. /**
  758.  * Generic message popup - internal
  759.  *
  760.  * Show a message with optional headline above and
  761.  * wait until user clicked "OK".
  762.  *
  763.  * @param headline    optional headline or Popup::NoHeadline()
  764.  * @param message    the message (maybe multi-line) to display.
  765.  */
  766. define void anyMessageInternalType(string headline, string message, string icon_name, boolean richtext, integer width, integer height )
  767. {
  768.     term button_box =  `PushButton( `id(`ok_msg), `opt(`default, `key_F10), Label::OKButton() );
  769.     UI::OpenDialog(
  770.            `opt(`decorated),
  771.            richtext ? popupLayoutInternalRich(headline, message, icon_name, button_box, width, height) :
  772.             popupLayoutInternal( headline, message, icon_name, button_box )
  773.            );
  774.  
  775.     UI::SetFocus(`id(`ok_msg) );
  776.  
  777.     UI::UserInput();
  778.     UI::CloseDialog();
  779. }
  780.  
  781. /**
  782.  * Internal function - wrapper for anyMessageInternal call
  783.  */
  784. define void anyMessageInternal(string headline, string message, string icon_name ) {
  785.     anyMessageInternalType(headline, message, icon_name, false, 0, 0);
  786. }
  787.  
  788. /**
  789.  * Internal function - wrapper for anyMessageInternal call
  790.  */
  791. define void anyMessageInternalRich(string headline, string message, string icon_name, integer width, integer height) {
  792.     anyMessageInternalType(headline, message, icon_name, true, width, height);
  793. }
  794.  
  795.  
  796. /**
  797.  * Generic message popup - internal
  798.  *
  799.  * Show a message with optional headline above and
  800.  * wait until user clicked "OK".
  801.  *
  802.  * @param headline    optional headline or Popup::NoHeadline()
  803.  * @param message    the message (maybe multi-line) to display.
  804.  */
  805. define void anyRichMessageInternal(string headline, string message, string icon_name, integer width, integer height )
  806. {
  807.     term button_box =  `PushButton( `id(`ok_msg), `opt(`default, `key_F10), Label::OKButton() );
  808.     UI::OpenDialog(
  809.            `opt(`decorated),
  810.            popupLayoutInternalRich( headline, message, icon_name, button_box, width, height )
  811.            );
  812.  
  813.     UI::SetFocus(`id(`ok_msg) );
  814.  
  815.     UI::UserInput();
  816.     UI::CloseDialog();
  817. }
  818.  
  819.  
  820. /**
  821.  * Generic message popup
  822.  *
  823.  * Show a message with optional headline above and
  824.  * wait until user clicked "OK".
  825.  *
  826.  * @param headline    optional headline or Popup::NoHeadline()
  827.  * @param message    the message (maybe multi-line) to display.
  828.  * @param icon_name    icon name (with full path) or Popup::NoIcon()
  829.  */
  830. global define void AnyMessage(string headline, string message)
  831. {
  832.     anyMessageInternal( headline, message, NoIcon() );
  833. }
  834.     
  835.  
  836. /**
  837.  * Clear feedback message
  838.  * @return void
  839.  */
  840. global define void ClearFeedback()
  841. {
  842.     if ( feedback_open )
  843.     UI::CloseDialog();
  844.     feedback_open = false;
  845. }
  846.  
  847.  
  848. /**
  849.  * Show popup with a headline and a message for feedback
  850.  * @param headline headline of Feedback popup
  851.  * @param message the feedback message
  852.  * @return void
  853.  */
  854. global define void ShowFeedback(string headline, string message)
  855. {
  856.     if (feedback_open)
  857.     {
  858.     UI::CloseDialog();
  859.     }
  860.     term button_box =  `Empty();
  861.     UI::BusyCursor();
  862.     UI::OpenDialog(
  863.            `opt(`decorated),
  864.            popupLayoutInternal( headline, message, NoIcon(), button_box )
  865.            );
  866.  
  867.     feedback_open = true;
  868. }
  869.  
  870. /**
  871.  * Show a simple message and wait until user clicked "OK".
  872.  *
  873.  *
  874.  * @param message message string
  875.  *
  876.  * @example  Popup::Message("This is an information about ... ." );
  877.  *
  878.  * @screenshot screenshots/Message.png
  879.  * @see AnyMessage
  880.  * @see Notify
  881.  * @see Warning
  882.  * @see Error
  883.  */
  884. global define void Message(string message)
  885. {
  886.     anyMessageInternal(NoHeadline(), message, NoIcon());
  887. }
  888.  
  889. /**
  890.  * Show a long message and wait until user clicked "OK".
  891.  *
  892.  * @param message message string (may contain rich text tags)
  893.  */
  894. global define void LongMessage(string message)
  895. {
  896.     anyMessageInternalRich(NoHeadline(), message, NoIcon(), default_width, default_height);
  897. }
  898.  
  899. /**
  900.  * Show a long message and wait until user clicked "OK". Size of the popup window is adjustable.
  901.  *
  902.  * @param message message string (may contain rich text tags)
  903.  * @param width width of the popup window
  904.  * @param height height of the popup window
  905.  */
  906. global define void LongMessageGeometry(string message, integer width, integer height)
  907. {
  908.     anyMessageInternalRich(NoHeadline(), message, NoIcon(), width, height);
  909. }
  910.  
  911. /**
  912.  * Show a message and wait until user clicked "OK" or time is out
  913.  *
  914.  * @param message message string
  915.  * @param timeout_seconds time out in seconds
  916.  */
  917. global define void TimedMessage(string message, integer timeout_seconds) {
  918.     anyTimedMessageInternal(NoHeadline(), message, NoIcon(), timeout_seconds);
  919. }
  920.  
  921. /**
  922.  * Show a long message and wait until user clicked "OK" or time is out.
  923.  *
  924.  * @param message message string (may contain rich text tags)
  925.  * @param timeout_seconds time out in seconds
  926.  */
  927. global define void TimedLongMessage(string message, integer timeout_seconds)
  928. {
  929.     anyTimedRichMessageInternal(NoHeadline(), message, NoIcon(), timeout_seconds, default_width, default_height);
  930. }
  931.  
  932. /**
  933.  * Show a long message and wait until user clicked "OK" or time is out. Size of the popup window is adjustable.
  934.  *
  935.  * @param message message string (may contain rich text tags)
  936.  * @param timeout_seconds time out in seconds
  937.  * @param width width of the popup window
  938.  * @param height height of the popup window
  939.  */
  940. global define void TimedLongMessageGeometry(string message, integer timeout_seconds, integer width, integer height)
  941. {
  942.     anyTimedRichMessageInternal(NoHeadline(), message, NoIcon(), timeout_seconds, width, height );
  943. }
  944.  
  945. /**
  946.  * Show a warning message and wait until user clicked "OK".
  947.  *
  948.  *
  949.  * @param message warning message string
  950.  *
  951.  * @example Popup::Warning("Something is wrong. Please check your configuration." );
  952.  *
  953.  * @screenshot screenshots/Warning.png
  954.  * @see Message
  955.  * @see Notify
  956.  * @see Error
  957.  * @see AnyMessage
  958.  */
  959. global define void Warning(string message)
  960. {
  961.     anyMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ) );
  962. }
  963.  
  964. /**
  965.  * Show a long warning and wait until user clicked "OK".
  966.  *
  967.  * @param message message string (may contain rich text tags)
  968.  */
  969. global define void LongWarning(string message)
  970. {
  971.     anyMessageInternalRich( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), default_width, default_height );
  972. }
  973.  
  974. /**
  975.  * Show a long warning and wait until user clicked "OK". Size of the popup window is adjustable
  976.  *
  977.  * @param message message string (may contain rich text tags)
  978.  * @param width width of the popup window
  979.  * @param height height of the popup window
  980.  */
  981. global define void LongWarningGeometry(string message, integer width, integer height)
  982. {
  983.     anyMessageInternalRich( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), width, height );
  984. }
  985.  
  986. /**
  987.  * Show a warning message and wait specified amount of time or until user clicked "OK".
  988.  *
  989.  * @screenshot screenshots/TimedWarningPopup.png
  990.  *
  991.  * @param message warning message string
  992.  * @param timeout_seconds time out in seconds
  993.  *
  994.  * @return void
  995.  *
  996.  * @see Warning
  997.  */
  998. global define void TimedWarning(string message, integer timeout_seconds)
  999. {
  1000.     anyTimedMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), timeout_seconds );
  1001. }
  1002.  
  1003. /**
  1004.  * Show a long warning message and wait until user clicked "OK" or time is out.
  1005.  *
  1006.  * @param message message string (may contain rich text tags)
  1007.  * @param timeout_seconds time out in seconds
  1008.  */
  1009. global define void TimedLongWarning(string message, integer timeout_seconds)
  1010. {
  1011.     anyTimedRichMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), timeout_seconds, default_width, default_height );
  1012. }
  1013.  
  1014. /**
  1015.  * Show a long warning and wait until user clicked "OK" or time is out. Size of the popup window is adjustable.
  1016.  *
  1017.  * @param message message string (may contain rich text tags)
  1018.  * @param timeout_seconds time out in seconds
  1019.  * @param width width of the popup window
  1020.  * @param height height of the popup window
  1021.  */
  1022. global define void TimedLongWarningGeometry(string message, integer timeout_seconds, integer width, integer height) {
  1023.     anyTimedRichMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), timeout_seconds, width, height );
  1024. }
  1025.  
  1026.  
  1027. /**
  1028.  * Show an error message and wait until user clicked "OK".
  1029.  *
  1030.  * @param message    error message string
  1031.  *
  1032.  * @example  Popup::Error("The configuration was not succesful." );
  1033.  * @screenshot screenshots/Error.png
  1034.  *
  1035.  * @see Message
  1036.  * @see Notify
  1037.  * @see Warning
  1038.  * @see AnyMessage
  1039.  */
  1040. global define void Error(string message)
  1041. {
  1042.     anyMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ) );
  1043. }
  1044.  
  1045. /**
  1046.  * Show a long error and wait until user clicked "OK".
  1047.  *
  1048.  * @param message message string (may contain rich text tags)
  1049.  */
  1050. global define void LongError(string message)
  1051. {
  1052.     anyMessageInternalRich( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), default_width, default_height );
  1053. }
  1054.  
  1055. /**
  1056.  * Show a long error message and wait until user clicked "OK". Size of the popup window is adjustable.
  1057.  *
  1058.  * @param message message string (may contain rich text tags)
  1059.  * @param width width of the popup window
  1060.  * @param height height of the popup window
  1061.  */
  1062. global define void LongErrorGeometry(string message, integer width, integer height)
  1063. {
  1064.     anyMessageInternalRich( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), width, height);
  1065. }
  1066.  
  1067. /**
  1068.  * Show an error message and wait specified amount of time or until user clicked "OK".
  1069.  *
  1070.  * @screenshot screenshots/TimedErrorPopup.png
  1071.  *
  1072.  * @param message    error message string
  1073.  * @param timeout_seconds time out in seconds
  1074.  *
  1075.  * @return void
  1076.  *
  1077.  * @see Error
  1078.  */
  1079. global define void TimedError(string message, integer timeout_seconds)
  1080. {
  1081.     anyTimedMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), timeout_seconds );
  1082. }
  1083.  
  1084. /**
  1085.  * Show a long error message and wait until user clicked "OK" or time is out.
  1086.  *
  1087.  * @param message message string (may contain rich text tags)
  1088.  * @param timeout_seconds time out in seconds
  1089.  */
  1090. global define void TimedLongError(string message, integer timeout_seconds)
  1091. {
  1092.     anyTimedRichMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), timeout_seconds, default_width, default_height );
  1093. }
  1094.  
  1095. /**
  1096.  * Show a long error message and wait until user clicked "OK" or time is out. Size of the popup window is adjustable.
  1097.  *
  1098.  * @param message message string (may contain rich text tags)
  1099.  * @param timeout_seconds time out in seconds
  1100.  * @param width width of the popup window
  1101.  * @param height height of the popup window
  1102.  */
  1103. global define void TimedLongErrorGeometry(string message, integer timeout_seconds, integer width, integer height)
  1104. {
  1105.     anyTimedRichMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), timeout_seconds, width, height );
  1106. }
  1107.  
  1108.  
  1109.  
  1110. /**
  1111.  * Show a notification message and wait until user clicked "OK".
  1112.  *
  1113.  * @screenshot screenshots/Notify.png
  1114.  *
  1115.  * @param  message notify message string
  1116.  *
  1117.  * @example  Popup::Notify("Your printer is ready for use." );
  1118.  *
  1119.  * @see Message
  1120.  * @see AnyMessage
  1121.  */
  1122. global define void Notify(string message)
  1123. {
  1124.     anyMessageInternal( "", message, popupIcon( "msg_info.png" ) );
  1125. }
  1126.  
  1127. /**
  1128.  * Show a long notify message and wait until user clicked "OK".
  1129.  *
  1130.  * @param message message string (may contain rich text tags)
  1131.  */
  1132. global define void LongNotify(string message)
  1133. {
  1134.     anyMessageInternalRich( NoHeadline(), message, popupIcon( "msg_info.png" ), default_width, default_height );
  1135. }
  1136.  
  1137. /**
  1138.  * Show a long notify message and wait until user clicked "OK". Size of the popup window is adjustable.
  1139.  *
  1140.  * @param message message string (may contain rich text tags)
  1141.  * @param width width of the popup window
  1142.  * @param height height of the popup window
  1143.  */
  1144. global define void LongNotifyGeometry(string message, integer width, integer height)
  1145. {
  1146.     anyMessageInternalRich( NoHeadline(), message, popupIcon( "msg_info.png" ), width, height);
  1147. }
  1148.  
  1149. /**
  1150.  * Show a long notify message and wait until user clicked "OK" or the time is out.
  1151.  *
  1152.  * @param message message string (may contain rich text tags)
  1153.  * @param timeout_seconds time out in seconds
  1154.  */
  1155. global define void TimedNotify(string message, integer timeout_seconds)
  1156. {
  1157.     anyTimedMessageInternal( NoHeadline(), message, popupIcon( "msg_info.png" ), timeout_seconds );
  1158. }
  1159.  
  1160. /**
  1161.  * Show a long error message and wait until user clicked "OK" or time is out.
  1162.  *
  1163.  * @param message message string (may contain rich text tags)
  1164.  * @param timeout_seconds time out in seconds
  1165.  */
  1166. global define void TimedLongNotify(string message, integer timeout_seconds)
  1167. {
  1168.     anyTimedRichMessageInternal( NoHeadline(), message, popupIcon( "msg_info.png" ), timeout_seconds, default_width, default_height );
  1169. }
  1170.  
  1171. /**
  1172.  * Show a long notify message and wait until user clicked "OK" or time is out. Size of the popup window is adjustable.
  1173.  *
  1174.  * @param message message string (may contain rich text tags)
  1175.  * @param timeout_seconds time out in seconds
  1176.  * @param width width of the popup window
  1177.  * @param height height of the popup window
  1178.  */
  1179. global define void TimedLongNotifyGeometry(string message, integer timeout_seconds, integer width, integer height)
  1180. {
  1181.     anyTimedRichMessageInternal( NoHeadline(), message, popupIcon( "msg_info.png" ), timeout_seconds, width, height );
  1182. }
  1183.  
  1184.  
  1185. /**
  1186.  * Display a message with a timeout
  1187.  *
  1188.  * Display a message with a timeout and return when the user clicks "OK", "Cancel"
  1189.  * or when the timeout expires ("OK" is assumed then).
  1190.  *
  1191.  * There is also a "stop" button that will stop the countdown. If the
  1192.  * user clicks that, the popup will wait forever (or until "OK" or "Cancel" is
  1193.  * clicked, of course).
  1194.  *
  1195.  * @param message        message to display
  1196.  * @param timeout_seconds        the timeout in seconds
  1197.  *
  1198.  * @return true    --> "OK" or timer expired<br>
  1199.  *     false  --> "Cancel"
  1200.  *
  1201.  * @example boolean ret = Popup::TimedOKCancel("This is a timed message", 2 );
  1202.  */
  1203. global define boolean TimedOKCancel(string message, integer timeout_seconds)
  1204. {
  1205.     UI::OpenDialog(
  1206.            `opt(`decorated),
  1207.            `HBox(
  1208.              `HSpacing(1),
  1209.              `VBox(
  1210.                    `VSpacing(0.2),
  1211.                    `Label(message),
  1212.                    `HCenter(
  1213.                     `Label(`id(`remaining_time), "" + timeout_seconds)
  1214.                     ),
  1215.                    `HBox(
  1216.                      `PushButton(`id(`timed_stop), Label::StopButton() ),
  1217.                      `HSpacing(2),
  1218.                      `PushButton(`id(`timed_ok), `opt(`default, `key_F10), Label::OKButton() ),
  1219.                      `HSpacing(2),
  1220.                      `PushButton(`id(`timed_cancel), `opt (`key_F9), Label::CancelButton() )
  1221.                      ),
  1222.                    `VSpacing(0.2)
  1223.                    )
  1224.              )
  1225.            );
  1226.  
  1227.     any which_input = nil;
  1228.  
  1229.     while (timeout_seconds > 0) {
  1230.     which_input = UI::TimeoutUserInput( 1000 );
  1231.     if (which_input == `timed_ok)
  1232.         break;
  1233.     if (which_input == `timed_cancel)
  1234.         break;
  1235.     if (which_input == `timed_stop) {
  1236.         while (which_input == `timed_stop)
  1237.         which_input = UI::UserInput();
  1238.         break;
  1239.     }
  1240.     timeout_seconds = timeout_seconds - 1;
  1241.     UI::ChangeWidget (`id(`remaining_time), `Value, ""+timeout_seconds);
  1242.     }
  1243.     UI::CloseDialog();
  1244.  
  1245.     return which_input != `timed_cancel;
  1246. }
  1247.  
  1248.  
  1249. /**
  1250.  * Generic question popup with three buttons.
  1251.  *
  1252.  * @param headline        headline or Popup::NoHeadline()
  1253.  * @param message            message string
  1254.  * @param yes_button_message    label on affirmative button (on left side)
  1255.  * @param no_button_message    label on negating button (middle)
  1256.  * @param retry_button_message    label on retry button (on right side)
  1257.  * @param focus            `focus_yes (first button), `focus_no (second button) or
  1258.  *                `focus_retry (third button)
  1259.  *
  1260.  * @return - `yes:  first button has been clicked
  1261.  *       - `no: second button has been clicked
  1262.  *       - `retry: third button has been clicked
  1263.  *
  1264.  * @see AnyQuestion
  1265.  *
  1266.  * @example Popup::AnyQuestion3( Label::WarningMsg(), _("... failed"), _("Continue"), _("Cancel"), _("Retry"), `focus_yes );
  1267.  */
  1268. global define symbol AnyQuestion3( string headline,
  1269.                    string message,
  1270.                    string yes_button_message,
  1271.                    string no_button_message,
  1272.                    string retry_button_message,
  1273.                    symbol focus )
  1274. {
  1275.     term yes_button = `Empty();
  1276.     term no_button = `Empty();
  1277.     term retry_button = `Empty();
  1278.  
  1279.     if ( focus == `focus_no )
  1280.     {
  1281.     yes_button = `PushButton( `id(`yes),
  1282.                   `opt (`key_F10),
  1283.                   yes_button_message );
  1284.     no_button  = `PushButton( `id(`no),
  1285.                   `opt(`default, `key_F9),
  1286.                   no_button_message );
  1287.     retry_button  = `PushButton( `id(`retry),
  1288.                      `opt (`key_F6),
  1289.                      retry_button_message );
  1290.     }
  1291.     else if ( focus == `focus_yes )
  1292.     {
  1293.     yes_button = `PushButton(`id(`yes),
  1294.                  `opt(`default, `key_F10),
  1295.                  yes_button_message);
  1296.     no_button  = `PushButton( `id(`no),
  1297.                   `opt (`key_F9),
  1298.                   no_button_message );
  1299.     retry_button  = `PushButton( `id(`retry),
  1300.                      `opt (`key_F6),
  1301.                      retry_button_message );
  1302.     }
  1303.     else
  1304.     {
  1305.     yes_button = `PushButton(`id(`yes),
  1306.                  `opt (`key_F10),
  1307.                  yes_button_message);
  1308.     no_button  = `PushButton( `id(`no),
  1309.                   `opt (`key_F9),
  1310.                   no_button_message );
  1311.     retry_button  = `PushButton( `id(`retry),
  1312.                      `opt(`default, `key_F6),
  1313.                      retry_button_message );
  1314.     }
  1315.  
  1316.     term button_box =  `HBox(
  1317.                  `HWeight( 1, yes_button),
  1318.                  `HSpacing(2),
  1319.                  `HWeight( 1, no_button ),
  1320.                  `HSpacing(2),
  1321.                  `HWeight( 1, retry_button )
  1322.                  );
  1323.  
  1324.     UI::OpenDialog(
  1325.            `opt(`decorated),
  1326.            popupLayoutInternal( headline, message, NoIcon(), button_box )
  1327.            );
  1328.  
  1329.     symbol ret = (symbol)UI::UserInput();
  1330.     UI::CloseDialog();
  1331.  
  1332.     return ret;
  1333. }
  1334.  
  1335.  
  1336. /**
  1337.  * Special error popup for YCP modules that don't work.
  1338.  *
  1339.  * The user can choose one of:
  1340.  * - "back" - go back to the previous module
  1341.  * - "next" - skip this faulty module and directly go to the next one
  1342.  * - "again" - try it again (after fixing something in the code, of course)
  1343.  * - "cancel" - exit program
  1344.  *
  1345.  * @screenshot screenshots/ModuleError.png
  1346.  *
  1347.  * @param text     string
  1348.  * @return symbol `back, `again, `cancel, `next
  1349.  *
  1350.  * @example Popup::ModuleError( "The module " + symbolof(argterm) + " does not work." );
  1351.  */
  1352. global define symbol ModuleError(string text)
  1353. {
  1354.     UI::OpenDialog(
  1355.            `opt(`decorated, `warncolor),
  1356.            `HBox(
  1357.              `HSpacing(1),
  1358.              `VBox(
  1359.                    `VSpacing(0.2),
  1360.                    `Heading(text),
  1361.                    `HBox(
  1362.                      `PushButton(`id(`back),   `opt (`key_F8),  Label::BackButton()  ),
  1363.                      `PushButton(`id(`again),  `opt (`key_F6),  Label::RetryButton() ),
  1364.                      `PushButton(`id(`cancel), `opt (`key_F9),  Label::QuitButton()  ),
  1365.                      `PushButton(`id(`next),   `opt (`key_F10), Label::NextButton()  )
  1366.                      ),
  1367.                    `VSpacing(0.2)
  1368.                    ),
  1369.              `HSpacing(1)
  1370.              )
  1371.            );
  1372.     symbol ret = (symbol)UI::UserInput();
  1373.     UI::CloseDialog();
  1374.     return ret;
  1375. }
  1376.  
  1377.  
  1378. /**
  1379.  * Generic message popup
  1380.  *
  1381.  * Show a message with optional headline above and
  1382.  * wait until user clicked "OK" or until a timeout runs out.
  1383.  *
  1384.  * @param headline    optional headline or Popup::NoHeadline()
  1385.  * @param message    the message (maybe multi-line) to display.
  1386.  * @param timeout    After timeout seconds dialog will be automatically closed
  1387.  *
  1388.  * @return void
  1389.  *
  1390.  */
  1391. global define void AnyTimedMessage(string headline, string message, integer timeout)
  1392. {
  1393.     anyTimedMessageInternal( headline, message, nil, timeout );
  1394. }
  1395.  
  1396. global define void AnyTimedRichMessage(string headline, string message, integer timeout)
  1397. {
  1398.     anyTimedRichMessageInternal( headline, message, nil, timeout, default_width, default_height );
  1399. }
  1400.  
  1401.  
  1402.  
  1403. // it is misaligned because there used to be UI() around it
  1404.  
  1405. /**
  1406.  * Show the contents of an entire file in a popup.
  1407.  *
  1408.  * @param headline    headline text
  1409.  * @param text    text to show
  1410.  * @param timeout    text to show
  1411.  *
  1412.  * @example Popup::ShowText ("Boot Messages", "kernel panic");
  1413.  */
  1414. global define void ShowTextTimed (string headline, string text,
  1415.                   integer timeout)
  1416. {
  1417.     term heading = `Empty( );
  1418.  
  1419.     if ( size(headline) == 0 )
  1420.     {
  1421.     heading = `VSpacing(0.2);
  1422.     }
  1423.     else
  1424.     {
  1425.     heading = `Heading( headline );
  1426.     }
  1427.  
  1428.     UI::OpenDialog( `opt(`decorated ),
  1429.             `VBox(
  1430.               `HSpacing( 70 ),    // force width
  1431.               heading,
  1432.               `VWeight( 1,
  1433.                     `HBox(
  1434.                       `VSpacing( 18 ),    // force height
  1435.                       `HSpacing( 0.7 ),
  1436.                       `RichText(`id(`text), `opt(`plainText), text),
  1437.                       `HSpacing( 0.7 )
  1438.                       )
  1439.                     ),
  1440.                           `VSpacing( 0.3 ),
  1441.                           `Label(`id(`label), sformat("%1", timeout)),
  1442.                           `VSpacing(0.2),
  1443.                           `PushButton(`id(`ok_msg),  `opt(`default, `key_F10), Label::OKButton() ),
  1444.               `VSpacing( 0.3 )
  1445.               )
  1446.             );
  1447.  
  1448.     symbol button = nil;
  1449.  
  1450.     while ( timeout > 0 && button != `ok_msg)
  1451.     {
  1452.     button = (symbol) UI::TimeoutUserInput( 1000 );
  1453.     timeout = timeout - 1;
  1454.  
  1455.     UI::ChangeWidget(`id(`label), `Value, sformat("%1", timeout ));
  1456.     }
  1457.  
  1458.     UI::CloseDialog();
  1459. }
  1460.  
  1461.  
  1462. /**
  1463.  * Show the contents of an entire file in a popup.
  1464.  *
  1465.  * @param headline    headline text
  1466.  * @param text    text to show
  1467.  *
  1468.  * @example Popup::ShowText ("Boot Messages", "kernel panic");
  1469.  */
  1470. global define void ShowText (string headline, string text)
  1471. {
  1472.     term heading = `Empty( );
  1473.  
  1474.     if ( size(headline) == 0 )
  1475.     {
  1476.     heading = `VSpacing(0.2);
  1477.     }
  1478.     else
  1479.     {
  1480.     heading = `Heading( headline );
  1481.     }
  1482.  
  1483.     UI::OpenDialog( `opt(`decorated ),
  1484.             `VBox(
  1485.               `HSpacing( 70 ),    // force width
  1486.               heading,
  1487.               `VWeight( 1,
  1488.                     `HBox(
  1489.                       `VSpacing( 18 ),    // force height
  1490.                       `HSpacing( 0.7 ),
  1491.                       `RichText(`id(`text), `opt(`plainText), text),
  1492.                       `HSpacing( 0.7 )
  1493.                       )
  1494.                     ),
  1495.               `VSpacing( 0.3 ),
  1496.               `PushButton( `opt(`default, `key_F10), Label::OKButton() ), `VSpacing( 0.3 )
  1497.               )
  1498.             );
  1499.  
  1500.     UI::UserInput();
  1501.     UI::CloseDialog();
  1502. }
  1503.  
  1504. /**
  1505.  * Show the contents of an entire file in a popup.
  1506.  *
  1507.  * Notice: This is a WFM function, NOT an UI function!
  1508.  *
  1509.  * @param headline    headline text
  1510.  * @param filename    filename with path of the file to show
  1511.  *
  1512.  * @example Popup::ShowFile ("Boot Messages", "/var/log/boot.msg");
  1513.  */
  1514. global define void ShowFile (string headline, string filename)
  1515. {
  1516.     string text = (string)SCR::Read (.target.string, filename);
  1517.  
  1518.     ShowText (headline, text);
  1519. }
  1520.  
  1521.  
  1522. }
  1523. /* EOF */
  1524.