/** * File: modules/Popup.ycp * Package: yast2 * Summary: Commonly used popup dialogs * Authors: Gabriele Strattner * Stefan Hundhammer * Arvin Schnell * Flags: Stable * * $Id: Popup.ycp 31242 2006-06-01 12:59:16Z locilka $ * * Contains commonly used popup dialogs * for general usage, e.g. Popup::YesNo(), Popup::ContinueCancel(). *
* See also README.popups */ { module "Popup"; textdomain "base"; import "Label"; import "Mode"; import "Directory"; import "String"; boolean feedback_open = false; // default size of the richtext widget in richtext popups integer default_width = 60; integer default_height = 10; /** * Internal function that returns a popup dialog with an additional label. * * @param headline headline to show or Popup::NoHeadline() * @param message message text to show * @param icon_name icon name (with full path) or Popup::NoIcon() * @param button_box term with one or more buttons * @param label second label with id `label which can be used e.g. for time out value displaying * * @return term the layout contents as a term */ define term popupLayoutInternalTypeWithLabel( string headline, string message, string icon_name, term button_box, string label, boolean richtext, integer width, integer height ) { term content = `Empty(); term heading = `VSpacing(0.2); term icon = `Empty(); if ( size( icon_name ) > 0 ) { map ui_capabilities = UI::GetDisplayInfo(); if ( ui_capabilities[ "HasLocalImageSupport" ]:false ) { icon = `Image( icon_name, "" ); } } term rt = `VWeight(1, `VBox( `HSpacing(width), `HBox( `VSpacing(height), // display the message in the widget "as is": // escape all tags, replace new lines by
tag `RichText(mergestring(splitstring(String::EscapeTags(message), "\n"), "
")) ) ) ); if ( size( headline ) > 0 ) { content = `VBox( `HBox( `VCenter( icon ), `HSpacing(1), `VCenter(`Heading( headline ) ), `HStretch() ), `VSpacing(0.2), richtext ? rt : `Left( `Label( message ) ), `VSpacing(0.2), (label != nil && label != "") ? `Label(`id(`label), label ) : `Empty() ); } else // no headline { content = `VBox( `HBox( `Top( icon ), `HSpacing(1), richtext ? rt : `VCenter (`Label( message ) ) ), `VSpacing(0.2), (label != nil && label != "") ? `Label(`id(`label), label ) : `Empty() ); } term dialog = `HBox( `HSpacing(1), `VBox( `VSpacing(0.2), content, richtext ? `Empty() : `VStretch(), button_box, richtext ? `Empty() : `VStretch(), `VSpacing(0.2) ), `HSpacing(1) ); return dialog; } /** * Internal function - wrapper for popupLayoutInternalTypeWithLabel call */ define term popupLayoutInternal( string headline, string message, string icon_name, term button_box ) { return popupLayoutInternalTypeWithLabel(headline, message, icon_name, button_box, nil, false, 0, 0); } /** * Internal function - wrapper for popupLayoutInternalTypeWithLabel call */ define term popupLayoutInternalRich( string headline, string message, string icon_name, term button_box, integer width, integer height ) { return popupLayoutInternalTypeWithLabel(headline, message, icon_name, button_box, nil, true, width, height); } /** * Internal version of AnyTimedMessage * * Show a message with optional headline above and * wait until user clicked "OK" or until a timeout runs out. * * @param headline optional headline or Popup::NoHeadline() * @param message the message (maybe multi-line) to display. * @param icon_name icon name (with full path) or Popup::NoIcon() * @param timeout After timeout seconds dialog will be automatically closed * * @return void **/ define void anyTimedMessageTypeInternal(string headline, string message, string icon_name, integer timeout, boolean richtext, integer width, integer height ) { term button_box = `HBox( `HStretch(), `HWeight(1, `PushButton( `id(`stop), Label::StopButton())), `HSpacing(2), `HWeight(1, `PushButton( `id(`ok_msg), `opt(`default, `key_F10), Label::OKButton())), `HStretch() ); UI::OpenDialog( `opt(`decorated), popupLayoutInternalTypeWithLabel( headline, message, icon_name, button_box, sformat("%1", timeout), richtext, width, height ) ); UI::SetFocus(`id(`ok_msg)); symbol button = nil; while ( timeout > 0 && button != `ok_msg) { button = (symbol) UI::TimeoutUserInput( 1000 ); if (button == `stop) { while(UI::UserInput() != `ok_msg){}; break; } timeout = timeout - 1; UI::ChangeWidget(`id(`label), `Value, sformat("%1", timeout )); } UI::CloseDialog(); } /** * Internal function - wrapper for anyTimedMessageTypeInternal call */ define void anyTimedMessageInternal(string headline, string message, string icon_name, integer timeout ) { anyTimedMessageTypeInternal(headline, message, icon_name, timeout, false, 0, 0); } /** * Internal function - wrapper for anyTimedMessageTypeInternal call */ define void anyTimedRichMessageInternal(string headline, string message, string icon_name, integer timeout, integer width, integer height ) { anyTimedMessageTypeInternal(headline, message, icon_name, timeout, true, width, height); } /** * Returns the full icon path for a icon with the specified base name. * "warning.png" -> "/usr/lib/YaST2/theme/icons/32x32/apps/warning.png" **/ define string popupIcon( string icon_base_name ) { return Directory::icondir + "32x32/apps/" + icon_base_name; } /** * Indicator for empty headline for popups that can optionally have one * * This is really just an alias for the empty string "", but it is * slightly better readable. * * @return empty string ("") */ global define string NoHeadline() { return ""; } /** * Indicator for empty icon for popups that can have one - for code readability. **/ global define string NoIcon() { return ""; } /** * Button box for the AnyQuestion Dialog (internal function). * * @param yes_button_message label on affirmative buttons (on left side) * @param no_button_message label on negating button (on right side) * @param focus `focus_yes (first button) or `focus_no (second button) * * @return term button box */ define term AnyQuestionButtonBox ( string yes_button_message, string no_button_message, symbol focus ) { term yes_button = `Empty(); term no_button = `Empty(); if ( focus == `focus_no ) { yes_button = `PushButton( `id(`yes), `opt (`key_F10), yes_button_message ); no_button = `PushButton( `id(`no_button), `opt(`default, `key_F9), no_button_message ); } else { yes_button = `PushButton( `id(`yes), `opt(`default, `key_F10), yes_button_message); no_button = `PushButton( `id(`no_button), `opt (`key_F9), no_button_message ); } term button_box = `HBox( `HStretch (), `HWeight( 1, yes_button), `HSpacing(2), `HWeight( 1, no_button ), `HStretch () ); return button_box; } /** * Generic question popup with two buttons. * * Style guide hint: The first button has to have the semantics of "yes", * "OK", "continue" etc., the second its opposite ("no", "cancel", ...). * NEVER use this generic question popup to simply exchange the order of * yes/no, continue/cancel or ok/cancel buttons! * * @param headline headline or Popup::NoHeadline() * @param message message string * @param yes_button_message label on affirmative buttons (on left side) * @param no_button_message label on negating button (on right side) * @param focus `focus_yes (first button) or `focus_no (second button) * @screenshot screenshots/AnyQuestion.png * * @return true: first button has been clicked * false: second button has been clicked * * @see YesNo * @see ContinueCancel * * @example Popup::AnyQuestion( Label::WarningMsg(), "Do really want to ...?", "Install", "Don't do it", `focus_no ); */ global define boolean AnyQuestion( string headline, string message, string yes_button_message, string no_button_message, symbol focus ) { term button_box = AnyQuestionButtonBox ( yes_button_message, no_button_message, focus); UI::OpenDialog( `opt(`decorated), popupLayoutInternal( headline, message, NoIcon(), button_box ) ); any ret = UI::UserInput(); UI::CloseDialog(); return ret == `yes; } /** * Timed question popup with two buttons and time display * * @param headline headline or Popup::NoHeadline() * @param message message string * @param yes_button_message label on affirmative buttons (on left side) * @param no_button_message label on negating button (on right side) * @param focus `focus_yes (first button) or `focus_no (second button) * @param timeout_seconds timeout, if 0, normal behaviour * @return boolean True if Yes, False if no * @see AnyQuestion */ global define boolean TimedAnyQuestion( string headline, string message, string yes_button_message, string no_button_message, symbol focus , integer timeout_seconds) { term button_box = AnyQuestionButtonBox ( yes_button_message, no_button_message, focus); term timed = `ReplacePoint(`id(`replace_buttons) , `VBox( `HCenter( `Label(`id(`remaining_time), "" + timeout_seconds) ), `HBox( `PushButton(`id(`timed_stop), Label::StopButton() ), `HSpacing(2), `PushButton(`id(`timed_ok), `opt(`default, `key_F10), Label::OKButton() ) ), `VSpacing(0.2) ) ); UI::OpenDialog( `opt(`decorated), popupLayoutInternal( headline, message, NoIcon(), timed ) ); any which_input = nil; while (timeout_seconds > 0) { which_input = UI::TimeoutUserInput( 1000 ); if (which_input == `timed_ok) break; if (which_input == `timed_stop) { UI::ReplaceWidget(`id(`replace_buttons), button_box); while (which_input == `timed_stop) which_input = UI::UserInput(); break; } timeout_seconds = timeout_seconds - 1; UI::ChangeWidget (`id(`remaining_time), `Value, ""+timeout_seconds); } UI::CloseDialog(); return which_input == `yes; } /** * Dialog which displays the "message" and has a Continue * and a Cancel button. * * This popup should be used to confirm possibly dangerous actions and if * it's useful to display a short headline (without headline * Popup::ContinueCancel() can be used). * The default button is Continue. * * Returns true if Continue is clicked. * * @screenshot screenshot/ContinueCancelHeadline.png * * @param headline short headline or Popup::NoHeadline() * @param message message string * @return boolean * * @example Popup::ContinueCancelHeadline ( "Short Header", "Going on with action....?" ); * * @see ContinueCancel * @see YesNo * @see AnyQuestion */ global define boolean ContinueCancelHeadline (string headline, string message) { boolean ret = AnyQuestion( headline, message, Label::ContinueButton(), Label::CancelButton(), `focus_yes ); y2debug("ContinueCancelHeadline returned: %1", ret ); return ret; } /** * Dialog which displays the "message" and has a Continue * and a Cancel button. * * This popup should be used to confirm possibly dangerous actions. * The default button is Continue. * Returns true if Continue is clicked. * * @screenshot screenshots/ContinueCancel.png * * @param message message string * @return boolean * * @example Popup::ContinueCancel ( "Please insert required CD-ROM." ); * * @see AnyQuestion */ global define boolean ContinueCancel (string message) { boolean ret = ContinueCancelHeadline( NoHeadline(), message ); y2debug("ContinueCancel returned: %1", ret ); return ret; } /** * This dialog displays "message" (a question) and has a Yes and * a No button. * * It should be used for decisions about two about equivalent paths, * not for simple confirmation - use "Popup::ContinueCancel()" for those. * A short headline can be displayed (without headline you can use Popup::YesNo()). * * The default button is Yes. * * Returns true if Yes is clicked. * * @screenshot screenshots/YesNoHeadline.png * * @param headline short headline or Popup::NoHeadline() * @param message message string * @return boolean true if [Yes] has been pressed * * @example Popup::YesNoHeadline ( "Resize Windows Partition?", "... explanation of dangers ..." ); * * @see YesNo * @see AnyQuestion */ global define boolean YesNoHeadline(string headline, string message) { boolean ret = AnyQuestion( headline, message, Label::YesButton(), Label::NoButton(), `focus_yes ); y2debug("YesNoHeadline returned: %1", ret ); return ret; } /** * Display a yes/no question and wait for answer. * * Should be used for decisions about two about equivalent paths, * not for simple confirmation - use "Popup::ContinueCancel()" for those. * The default button is Yes. * Returns true if Yes is clicked. * * @screenshot screenshots/YesNo.png * * @param message message string * @return boolean true if [Yes] has been pressed * * @example Popup::YesNo ( "Create a backup of the config files?" ); * * @see YesNoHeadline * @see ContinueCancel * @see AnyQuestion */ global define boolean YesNo(string message) { boolean ret = YesNoHeadline( NoHeadline(), message); y2debug("YesNo returned: %1", ret ); return ret; } /** * Show a long text that might need scrolling. * * Pass a RichText widget with the parameters appropriate for your text - * i.e. without special parameters for HTML-like text or with * `opt(`plainText) for plain ASCII text without HTML tags. * * @screenshot screenshots/LongText.png * * @param headline short headline * @param richtext text input is `Richtext() * @param hdim initial horizontal dimension of the popup * @param vdim initial vertical dimension of the popup * * @example Popup::LongText ( "Package description", `Richtext("

Hello, this is a long description .....

"), 50, 20 ); */ global define void LongText( string headline, term richtext, integer hdim, integer vdim ) { UI::OpenDialog( `opt( `decorated ), `HBox( `VSpacing(vdim), `VBox (`HSpacing(hdim), `Left(`Heading( headline )), `VSpacing(0.2), richtext, // scrolled text `PushButton( `id(`ok), `opt(`default, `key_F10), Label::OKButton() ) ) ) ); UI::SetFocus(`id(`ok ) ); UI::UserInput(); UI::CloseDialog(); } /** * Show a question that might need scrolling. * * @param headline short headline * @param richtext text input as a rich text * @param hdim initial horizontal dimension of the popup * @param vdim initial vertical dimension of the popup * @param yes_button_message message on the left/true button * @param no_button_message message on the right/false button * @param focus `focus_yes, `focus_no, `focus_none * @return left button pressed? */ global define boolean AnyQuestionRichText (string headline, string richtext, integer hdim, integer vdim, string yes_button_message, string no_button_message, symbol focus) { term yes_button = `PushButton ( `id (`ok), ( focus == `focus_yes ? `opt (`default, `key_F10) : `opt (`key_F10) ), yes_button_message); term no_button = `PushButton ( `id (`cancel), ( focus == `focus_no ? `opt (`default, `key_F9) : `opt (`key_F9) ), no_button_message); term d = `HBox ( `VSpacing (vdim), `VBox ( `HSpacing (hdim), size (headline) > 0 ? `Left(`Heading( headline )) : `Empty (), `VSpacing(0.2), `RichText (richtext), `HBox ( yes_button, no_button ) ) ); UI::OpenDialog (`opt (`decorated), d); any ui = UI::UserInput (); UI::CloseDialog (); return ui == `ok; } /** * Confirmation for "Abort" button during installation. * * According to the "severity" parameter an appropriate text will be * displayed indicating what the user has to expect when he really aborts now. * * @screenshot screenshots/ConfirmAbort.png * * @param severity `painless, `incomplete, `unusable * * @return boolean * * @example Popup::ConfirmAbort ( `painless ); */ global define boolean ConfirmAbort( symbol severity ) { string what_will_happen = ""; // Confirm user request to abort installation string abort_label = _("Really abort the installation?"); // Button that will really abort the installation string abort_button = _("&Abort Installation"); // Button that will continue with the installation string continue_button = _("&Continue Installation"); if ( severity == `painless ) { if (Mode::repair ()) { // Confirm user request to abort System Repair abort_label = _("Really abort YaST System Repair?"); // Button that will really abort the repair abort_button = _("Abort System Repair"); // Button that will continue with the repair continue_button = _("&Continue System Repair"); } else { // Warning text for aborting an installation before anything is installed what_will_happen = _("If you abort the installation now, Linux will not be installed. Your hard disk will remain untouched."); } } else if ( severity == `incomplete ) { // Warning text for aborting an installation during the install process // - After some installation steps have been performed - e.g. // disks formatted / some packages already installed what_will_happen = _("If you abort the installation now, you will have an incomplete Linux system that might or might not be usable. You might need to reinstall. "); } else if ( severity == `unusable ) { // Warning text for aborting an installation during the install process // right in the middle of some critical process (e.g. formatting) what_will_happen = _("If you abort the installation now, Linux will be unusable. You will need to reinstall."); } else { y2error ("Unknown symbol for ConfirmAbort"); } string message = abort_label + "\n\n" + what_will_happen; boolean ret = AnyQuestion (NoHeadline (), message, abort_button, continue_button, `focus_no); y2debug("ConfirmAbort returned: %1", ret); return ret; } /** * Confirmation popup when user clicked "Abort". * * Set "have changes" to "true" when there are changes that will be lost. * Note: If there are none, it is good policy to ask for confirmation * anyway, but of course with "have_changes" set to "false" so the user * isn't warned about changes that might be lost. * * @param have_changes true: There are changes that will be lost * false: No changes * * @return true: "abort" confirmed; * false: don't abort */ global define boolean ReallyAbort( boolean have_changes ) { symbol focus = `focus_yes; // Confirm aborting the program string message = _("Really abort?"); if ( have_changes ) { focus = `focus_no; // Additional hint when trying to abort program in spite of changes message = message + "\n" + _("All changes will be lost!"); } boolean ret = AnyQuestion( NoHeadline(), message, Label::YesButton(), Label::NoButton(), `focus_no ); y2debug("ReallyAbort returned: %1", ret ); return ret; } /** * Generic message popup - internal * * Show a message with optional headline above and * wait until user clicked "OK". * * @param headline optional headline or Popup::NoHeadline() * @param message the message (maybe multi-line) to display. */ define void anyMessageInternalType(string headline, string message, string icon_name, boolean richtext, integer width, integer height ) { term button_box = `PushButton( `id(`ok_msg), `opt(`default, `key_F10), Label::OKButton() ); UI::OpenDialog( `opt(`decorated), richtext ? popupLayoutInternalRich(headline, message, icon_name, button_box, width, height) : popupLayoutInternal( headline, message, icon_name, button_box ) ); UI::SetFocus(`id(`ok_msg) ); UI::UserInput(); UI::CloseDialog(); } /** * Internal function - wrapper for anyMessageInternal call */ define void anyMessageInternal(string headline, string message, string icon_name ) { anyMessageInternalType(headline, message, icon_name, false, 0, 0); } /** * Internal function - wrapper for anyMessageInternal call */ define void anyMessageInternalRich(string headline, string message, string icon_name, integer width, integer height) { anyMessageInternalType(headline, message, icon_name, true, width, height); } /** * Generic message popup - internal * * Show a message with optional headline above and * wait until user clicked "OK". * * @param headline optional headline or Popup::NoHeadline() * @param message the message (maybe multi-line) to display. */ define void anyRichMessageInternal(string headline, string message, string icon_name, integer width, integer height ) { term button_box = `PushButton( `id(`ok_msg), `opt(`default, `key_F10), Label::OKButton() ); UI::OpenDialog( `opt(`decorated), popupLayoutInternalRich( headline, message, icon_name, button_box, width, height ) ); UI::SetFocus(`id(`ok_msg) ); UI::UserInput(); UI::CloseDialog(); } /** * Generic message popup * * Show a message with optional headline above and * wait until user clicked "OK". * * @param headline optional headline or Popup::NoHeadline() * @param message the message (maybe multi-line) to display. * @param icon_name icon name (with full path) or Popup::NoIcon() */ global define void AnyMessage(string headline, string message) { anyMessageInternal( headline, message, NoIcon() ); } /** * Clear feedback message * @return void */ global define void ClearFeedback() { if ( feedback_open ) UI::CloseDialog(); feedback_open = false; } /** * Show popup with a headline and a message for feedback * @param headline headline of Feedback popup * @param message the feedback message * @return void */ global define void ShowFeedback(string headline, string message) { if (feedback_open) { UI::CloseDialog(); } term button_box = `Empty(); UI::BusyCursor(); UI::OpenDialog( `opt(`decorated), popupLayoutInternal( headline, message, NoIcon(), button_box ) ); feedback_open = true; } /** * Show a simple message and wait until user clicked "OK". * * * @param message message string * * @example Popup::Message("This is an information about ... ." ); * * @screenshot screenshots/Message.png * @see AnyMessage * @see Notify * @see Warning * @see Error */ global define void Message(string message) { anyMessageInternal(NoHeadline(), message, NoIcon()); } /** * Show a long message and wait until user clicked "OK". * * @param message message string (may contain rich text tags) */ global define void LongMessage(string message) { anyMessageInternalRich(NoHeadline(), message, NoIcon(), default_width, default_height); } /** * Show a long message and wait until user clicked "OK". Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param width width of the popup window * @param height height of the popup window */ global define void LongMessageGeometry(string message, integer width, integer height) { anyMessageInternalRich(NoHeadline(), message, NoIcon(), width, height); } /** * Show a message and wait until user clicked "OK" or time is out * * @param message message string * @param timeout_seconds time out in seconds */ global define void TimedMessage(string message, integer timeout_seconds) { anyTimedMessageInternal(NoHeadline(), message, NoIcon(), timeout_seconds); } /** * Show a long message and wait until user clicked "OK" or time is out. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds */ global define void TimedLongMessage(string message, integer timeout_seconds) { anyTimedRichMessageInternal(NoHeadline(), message, NoIcon(), timeout_seconds, default_width, default_height); } /** * Show a long message and wait until user clicked "OK" or time is out. Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds * @param width width of the popup window * @param height height of the popup window */ global define void TimedLongMessageGeometry(string message, integer timeout_seconds, integer width, integer height) { anyTimedRichMessageInternal(NoHeadline(), message, NoIcon(), timeout_seconds, width, height ); } /** * Show a warning message and wait until user clicked "OK". * * * @param message warning message string * * @example Popup::Warning("Something is wrong. Please check your configuration." ); * * @screenshot screenshots/Warning.png * @see Message * @see Notify * @see Error * @see AnyMessage */ global define void Warning(string message) { anyMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ) ); } /** * Show a long warning and wait until user clicked "OK". * * @param message message string (may contain rich text tags) */ global define void LongWarning(string message) { anyMessageInternalRich( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), default_width, default_height ); } /** * Show a long warning and wait until user clicked "OK". Size of the popup window is adjustable * * @param message message string (may contain rich text tags) * @param width width of the popup window * @param height height of the popup window */ global define void LongWarningGeometry(string message, integer width, integer height) { anyMessageInternalRich( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), width, height ); } /** * Show a warning message and wait specified amount of time or until user clicked "OK". * * @screenshot screenshots/TimedWarningPopup.png * * @param message warning message string * @param timeout_seconds time out in seconds * * @return void * * @see Warning */ global define void TimedWarning(string message, integer timeout_seconds) { anyTimedMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), timeout_seconds ); } /** * Show a long warning message and wait until user clicked "OK" or time is out. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds */ global define void TimedLongWarning(string message, integer timeout_seconds) { anyTimedRichMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), timeout_seconds, default_width, default_height ); } /** * Show a long warning and wait until user clicked "OK" or time is out. Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds * @param width width of the popup window * @param height height of the popup window */ global define void TimedLongWarningGeometry(string message, integer timeout_seconds, integer width, integer height) { anyTimedRichMessageInternal( Label::WarningMsg(), message, popupIcon( "msg_warning.png" ), timeout_seconds, width, height ); } /** * Show an error message and wait until user clicked "OK". * * @param message error message string * * @example Popup::Error("The configuration was not succesful." ); * @screenshot screenshots/Error.png * * @see Message * @see Notify * @see Warning * @see AnyMessage */ global define void Error(string message) { anyMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ) ); } /** * Show a long error and wait until user clicked "OK". * * @param message message string (may contain rich text tags) */ global define void LongError(string message) { anyMessageInternalRich( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), default_width, default_height ); } /** * Show a long error message and wait until user clicked "OK". Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param width width of the popup window * @param height height of the popup window */ global define void LongErrorGeometry(string message, integer width, integer height) { anyMessageInternalRich( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), width, height); } /** * Show an error message and wait specified amount of time or until user clicked "OK". * * @screenshot screenshots/TimedErrorPopup.png * * @param message error message string * @param timeout_seconds time out in seconds * * @return void * * @see Error */ global define void TimedError(string message, integer timeout_seconds) { anyTimedMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), timeout_seconds ); } /** * Show a long error message and wait until user clicked "OK" or time is out. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds */ global define void TimedLongError(string message, integer timeout_seconds) { anyTimedRichMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), timeout_seconds, default_width, default_height ); } /** * Show a long error message and wait until user clicked "OK" or time is out. Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds * @param width width of the popup window * @param height height of the popup window */ global define void TimedLongErrorGeometry(string message, integer timeout_seconds, integer width, integer height) { anyTimedRichMessageInternal( Label::ErrorMsg(), message, popupIcon( "msg_error.png" ), timeout_seconds, width, height ); } /** * Show a notification message and wait until user clicked "OK". * * @screenshot screenshots/Notify.png * * @param message notify message string * * @example Popup::Notify("Your printer is ready for use." ); * * @see Message * @see AnyMessage */ global define void Notify(string message) { anyMessageInternal( "", message, popupIcon( "msg_info.png" ) ); } /** * Show a long notify message and wait until user clicked "OK". * * @param message message string (may contain rich text tags) */ global define void LongNotify(string message) { anyMessageInternalRich( NoHeadline(), message, popupIcon( "msg_info.png" ), default_width, default_height ); } /** * Show a long notify message and wait until user clicked "OK". Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param width width of the popup window * @param height height of the popup window */ global define void LongNotifyGeometry(string message, integer width, integer height) { anyMessageInternalRich( NoHeadline(), message, popupIcon( "msg_info.png" ), width, height); } /** * Show a long notify message and wait until user clicked "OK" or the time is out. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds */ global define void TimedNotify(string message, integer timeout_seconds) { anyTimedMessageInternal( NoHeadline(), message, popupIcon( "msg_info.png" ), timeout_seconds ); } /** * Show a long error message and wait until user clicked "OK" or time is out. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds */ global define void TimedLongNotify(string message, integer timeout_seconds) { anyTimedRichMessageInternal( NoHeadline(), message, popupIcon( "msg_info.png" ), timeout_seconds, default_width, default_height ); } /** * Show a long notify message and wait until user clicked "OK" or time is out. Size of the popup window is adjustable. * * @param message message string (may contain rich text tags) * @param timeout_seconds time out in seconds * @param width width of the popup window * @param height height of the popup window */ global define void TimedLongNotifyGeometry(string message, integer timeout_seconds, integer width, integer height) { anyTimedRichMessageInternal( NoHeadline(), message, popupIcon( "msg_info.png" ), timeout_seconds, width, height ); } /** * Display a message with a timeout * * Display a message with a timeout and return when the user clicks "OK", "Cancel" * or when the timeout expires ("OK" is assumed then). * * There is also a "stop" button that will stop the countdown. If the * user clicks that, the popup will wait forever (or until "OK" or "Cancel" is * clicked, of course). * * @param message message to display * @param timeout_seconds the timeout in seconds * * @return true --> "OK" or timer expired
* false --> "Cancel" * * @example boolean ret = Popup::TimedOKCancel("This is a timed message", 2 ); */ global define boolean TimedOKCancel(string message, integer timeout_seconds) { UI::OpenDialog( `opt(`decorated), `HBox( `HSpacing(1), `VBox( `VSpacing(0.2), `Label(message), `HCenter( `Label(`id(`remaining_time), "" + timeout_seconds) ), `HBox( `PushButton(`id(`timed_stop), Label::StopButton() ), `HSpacing(2), `PushButton(`id(`timed_ok), `opt(`default, `key_F10), Label::OKButton() ), `HSpacing(2), `PushButton(`id(`timed_cancel), `opt (`key_F9), Label::CancelButton() ) ), `VSpacing(0.2) ) ) ); any which_input = nil; while (timeout_seconds > 0) { which_input = UI::TimeoutUserInput( 1000 ); if (which_input == `timed_ok) break; if (which_input == `timed_cancel) break; if (which_input == `timed_stop) { while (which_input == `timed_stop) which_input = UI::UserInput(); break; } timeout_seconds = timeout_seconds - 1; UI::ChangeWidget (`id(`remaining_time), `Value, ""+timeout_seconds); } UI::CloseDialog(); return which_input != `timed_cancel; } /** * Generic question popup with three buttons. * * @param headline headline or Popup::NoHeadline() * @param message message string * @param yes_button_message label on affirmative button (on left side) * @param no_button_message label on negating button (middle) * @param retry_button_message label on retry button (on right side) * @param focus `focus_yes (first button), `focus_no (second button) or * `focus_retry (third button) * * @return - `yes: first button has been clicked * - `no: second button has been clicked * - `retry: third button has been clicked * * @see AnyQuestion * * @example Popup::AnyQuestion3( Label::WarningMsg(), _("... failed"), _("Continue"), _("Cancel"), _("Retry"), `focus_yes ); */ global define symbol AnyQuestion3( string headline, string message, string yes_button_message, string no_button_message, string retry_button_message, symbol focus ) { term yes_button = `Empty(); term no_button = `Empty(); term retry_button = `Empty(); if ( focus == `focus_no ) { yes_button = `PushButton( `id(`yes), `opt (`key_F10), yes_button_message ); no_button = `PushButton( `id(`no), `opt(`default, `key_F9), no_button_message ); retry_button = `PushButton( `id(`retry), `opt (`key_F6), retry_button_message ); } else if ( focus == `focus_yes ) { yes_button = `PushButton(`id(`yes), `opt(`default, `key_F10), yes_button_message); no_button = `PushButton( `id(`no), `opt (`key_F9), no_button_message ); retry_button = `PushButton( `id(`retry), `opt (`key_F6), retry_button_message ); } else { yes_button = `PushButton(`id(`yes), `opt (`key_F10), yes_button_message); no_button = `PushButton( `id(`no), `opt (`key_F9), no_button_message ); retry_button = `PushButton( `id(`retry), `opt(`default, `key_F6), retry_button_message ); } term button_box = `HBox( `HWeight( 1, yes_button), `HSpacing(2), `HWeight( 1, no_button ), `HSpacing(2), `HWeight( 1, retry_button ) ); UI::OpenDialog( `opt(`decorated), popupLayoutInternal( headline, message, NoIcon(), button_box ) ); symbol ret = (symbol)UI::UserInput(); UI::CloseDialog(); return ret; } /** * Special error popup for YCP modules that don't work. * * The user can choose one of: * - "back" - go back to the previous module * - "next" - skip this faulty module and directly go to the next one * - "again" - try it again (after fixing something in the code, of course) * - "cancel" - exit program * * @screenshot screenshots/ModuleError.png * * @param text string * @return symbol `back, `again, `cancel, `next * * @example Popup::ModuleError( "The module " + symbolof(argterm) + " does not work." ); */ global define symbol ModuleError(string text) { UI::OpenDialog( `opt(`decorated, `warncolor), `HBox( `HSpacing(1), `VBox( `VSpacing(0.2), `Heading(text), `HBox( `PushButton(`id(`back), `opt (`key_F8), Label::BackButton() ), `PushButton(`id(`again), `opt (`key_F6), Label::RetryButton() ), `PushButton(`id(`cancel), `opt (`key_F9), Label::QuitButton() ), `PushButton(`id(`next), `opt (`key_F10), Label::NextButton() ) ), `VSpacing(0.2) ), `HSpacing(1) ) ); symbol ret = (symbol)UI::UserInput(); UI::CloseDialog(); return ret; } /** * Generic message popup * * Show a message with optional headline above and * wait until user clicked "OK" or until a timeout runs out. * * @param headline optional headline or Popup::NoHeadline() * @param message the message (maybe multi-line) to display. * @param timeout After timeout seconds dialog will be automatically closed * * @return void * */ global define void AnyTimedMessage(string headline, string message, integer timeout) { anyTimedMessageInternal( headline, message, nil, timeout ); } global define void AnyTimedRichMessage(string headline, string message, integer timeout) { anyTimedRichMessageInternal( headline, message, nil, timeout, default_width, default_height ); } // it is misaligned because there used to be UI() around it /** * Show the contents of an entire file in a popup. * * @param headline headline text * @param text text to show * @param timeout text to show * * @example Popup::ShowText ("Boot Messages", "kernel panic"); */ global define void ShowTextTimed (string headline, string text, integer timeout) { term heading = `Empty( ); if ( size(headline) == 0 ) { heading = `VSpacing(0.2); } else { heading = `Heading( headline ); } UI::OpenDialog( `opt(`decorated ), `VBox( `HSpacing( 70 ), // force width heading, `VWeight( 1, `HBox( `VSpacing( 18 ), // force height `HSpacing( 0.7 ), `RichText(`id(`text), `opt(`plainText), text), `HSpacing( 0.7 ) ) ), `VSpacing( 0.3 ), `Label(`id(`label), sformat("%1", timeout)), `VSpacing(0.2), `PushButton(`id(`ok_msg), `opt(`default, `key_F10), Label::OKButton() ), `VSpacing( 0.3 ) ) ); symbol button = nil; while ( timeout > 0 && button != `ok_msg) { button = (symbol) UI::TimeoutUserInput( 1000 ); timeout = timeout - 1; UI::ChangeWidget(`id(`label), `Value, sformat("%1", timeout )); } UI::CloseDialog(); } /** * Show the contents of an entire file in a popup. * * @param headline headline text * @param text text to show * * @example Popup::ShowText ("Boot Messages", "kernel panic"); */ global define void ShowText (string headline, string text) { term heading = `Empty( ); if ( size(headline) == 0 ) { heading = `VSpacing(0.2); } else { heading = `Heading( headline ); } UI::OpenDialog( `opt(`decorated ), `VBox( `HSpacing( 70 ), // force width heading, `VWeight( 1, `HBox( `VSpacing( 18 ), // force height `HSpacing( 0.7 ), `RichText(`id(`text), `opt(`plainText), text), `HSpacing( 0.7 ) ) ), `VSpacing( 0.3 ), `PushButton( `opt(`default, `key_F10), Label::OKButton() ), `VSpacing( 0.3 ) ) ); UI::UserInput(); UI::CloseDialog(); } /** * Show the contents of an entire file in a popup. * * Notice: This is a WFM function, NOT an UI function! * * @param headline headline text * @param filename filename with path of the file to show * * @example Popup::ShowFile ("Boot Messages", "/var/log/boot.msg"); */ global define void ShowFile (string headline, string filename) { string text = (string)SCR::Read (.target.string, filename); ShowText (headline, text); } } /* EOF */