library/wizard/src/modules/Wizard.rb
# ***************************************************************************
#
# Copyright (c) 2002 - 2012 Novell, Inc.
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail,
# you may find current contact information at www.novell.com
#
# ***************************************************************************
# File: Wizard.ycp
# Package: yast2
# Author: Stefan Hundhammer <sh@suse.de>
#
# Provides the wizard dialog (common screen for all YaST2 installation
# modules) and functions to set the contents, to replace and restore
# special widgets.
require "yast"
module Yast
class WizardClass < Module
DEFAULT_ICON_NAME = "yast".freeze
def main
Yast.import "UI"
textdomain "base"
Yast.import "Desktop"
Yast.import "Label"
Yast.import "Popup"
Yast.import "Directory"
Yast.import "OSRelease"
@have_fancy_ui_cache = nil
# this variable is set from Product:: constructor
# to setup correct &product; macro in UI
@product_name = ""
#
# Screenshot Functions
#
# Currently used screenshot name.
# Initially, it must match the UI default, "yast2"
@screenshot_name = "yast2"
# Screenshot names overriden by nested SetScreenShotName calls
@screenshot_name_stack = []
# Handling of relnotes button when creating a wizard over existing one
# Cannot be handled by libyui for NCurses
@relnotes_button_label = ""
@relnotes_button_id = ""
# Current icon name to set.
@icon_name = DEFAULT_ICON_NAME
end
def haveFancyUI
if @have_fancy_ui_cache.nil?
ui_info = UI.GetDisplayInfo
@have_fancy_ui_cache = UI.HasSpecialWidget(:Wizard) == true &&
Ops.greater_or_equal(Ops.get_integer(ui_info, "Depth", 0), 15) &&
Ops.greater_or_equal(Ops.get_integer(ui_info, "DefaultWidth", 0), 800) &&
# some netbooks use such a strange resolution (fate#306298)
Ops.greater_or_equal(
Ops.get_integer(ui_info, "DefaultHeight", 0),
576
)
# have_fancy_ui_cache = false;
UI.SetFunctionKeys(Label.DefaultFunctionKeyMap)
end
@have_fancy_ui_cache
end
# Returns a button box with buttons "Back", "Abort", "Next"
# @return a widget tree
#
def BackAbortNextButtonBox
HBox(
HWeight(
1,
ReplacePoint(
Id(:rep_help),
PushButton(Id(:help), Opt(:key_F1, :helpButton), Label.HelpButton)
)
),
HStretch(),
HWeight(
1,
ReplacePoint(
Id(:rep_back),
PushButton(Id(:back), Opt(:key_F8), Label.BackButton)
)
),
HStretch(),
ReplacePoint(
Id(:rep_abort),
PushButton(Id(:abort), Opt(:key_F9), Label.AbortButton)
),
HStretch(),
HWeight(
1,
ReplacePoint(
Id(:rep_next),
PushButton(Id(:next), Opt(:key_F10, :default), Label.NextButton)
)
)
)
end
# Returns a button box with buttons "Back", "Abort Installation", "Next"
# @return a widget tree
#
def BackAbortInstallationNextButtonBox
HBox(
HWeight(
1,
ReplacePoint(
Id(:rep_help),
PushButton(Id(:help), Opt(:key_F1, :helpButton), Label.HelpButton)
)
),
HStretch(),
HWeight(
1,
ReplacePoint(
Id(:rep_back),
PushButton(Id(:back), Opt(:key_F8), Label.BackButton)
)
),
HStretch(),
ReplacePoint(
Id(:rep_abort),
PushButton(Id(:abort), Opt(:key_F9), Label.AbortInstallationButton)
),
HStretch(),
HWeight(
1,
ReplacePoint(
Id(:rep_next),
PushButton(Id(:next), Opt(:key_F10, :default), Label.NextButton)
)
)
)
end
# Returns a button box with buttons "Back", "Next"
# @return a widget tree
#
def BackNextButtonBox
HBox(
HWeight(
1,
ReplacePoint(
Id(:rep_back),
PushButton(Id(:back), Opt(:key_F8), Label.BackButton)
)
),
HStretch(),
HWeight(
1,
ReplacePoint(
Id(:rep_next),
PushButton(Id(:next), Opt(:key_F10, :default), Label.NextButton)
)
)
)
end
# Returns a button box with buttons "Cancel", "Accept"
# @return a widget tree
#
def CancelAcceptButtonBox
ButtonBox(
PushButton(Id(:cancel), Opt(:key_F9, :cancelButton), Label.CancelButton),
PushButton(
Id(:accept),
Opt(:key_F10, :default, :okButton),
Label.AcceptButton
)
)
end
# Returns a button box with buttons "Cancel", "OK"
# @return a widget tree
#
def CancelOKButtonBox
ButtonBox(
PushButton(Id(:cancel), Opt(:key_F9, :cancelButton), Label.CancelButton),
PushButton(Id(:ok), Opt(:key_F10, :default, :okButton), Label.OKButton)
)
end
# Returns a button box with buttons "Abort", "Accept"
# @return a widget tree
#
def AbortAcceptButtonBox
HBox(
HWeight(1, ReplacePoint(Id(:back_rep), Empty())), # Layout trick to make sure the center button is centered
HStretch(),
HWeight(
1,
ReplacePoint(
Id(:rep_abort), # Make sure HideAbortButton() works (bnc #444176)
PushButton(Id(:abort), Opt(:key_F9), Label.AbortButton)
)
),
HStretch(),
HWeight(
1,
PushButton(Id(:accept), Opt(:key_F10, :default), Label.AcceptButton)
)
)
end
# Returns a button box with buttons "Abort Installation", "Accept"
# @return a widget tree
#
def AbortInstallationAcceptButtonBox
ButtonBox(
PushButton(
Id(:abort),
Opt(:key_F9, :cancelButton),
Label.AbortInstallationButton
),
PushButton(
Id(:accept),
Opt(:key_F10, :okButton, :default),
Label.AcceptButton
)
)
end
# Returns a button box with buttons "Abort", "Apply", "Finish"
# @return a widget tree
#
def AbortApplyFinishButtonBox
ButtonBox(
PushButton(Id(:abort, :cancelButton, :key_F9), Label.AbortButton),
# button text
PushButton(Id(:apply, :applyButton), _("&Apply")),
PushButton(Id(:finish, :okButton, :key_F10), Label.FinishButton)
)
end
# Create a Generic Dialog
#
#
# Returns a term describing a generic wizard dialog with a configurable
# button box.
#
# @note This is a stable API function
#
# @param [Yast::Term] button_box term that contains a `HBox() with buttons in it
# @return [Yast::Term] term describing the dialog.
#
def GenericDialog(button_box)
button_box = deep_copy(button_box)
VBox(
Id(:WizardDialog),
ReplacePoint(Id(:topmenu), Empty()),
VWeight(
1, # Layout trick: Lower layout priority with weight
HBox(
HSpacing(1),
VBox(
VSpacing(0.2),
HBox(
# translators: dialog title to appear before any content is initialized
Heading(Id(:title), Opt(:hstretch), _("Initializing ...")),
HStretch(),
ReplacePoint(Id(:relnotes_rp), Empty())
),
VWeight(
1, # Layout trick: Lower layout priority with weight
HVCenter(Opt(:hvstretch), ReplacePoint(Id(:contents), Empty()))
)
),
HSpacing(1)
)
),
ReplacePoint(Id(:rep_button_box), button_box),
VSpacing(0.2)
)
end
# Create a Generic Tree Dialog
#
#
# Returns a term describing a wizard dialog with left menu tree,
# right contents and a configurable button box.
#
#
# @note This is a stable API function
#
# @param [Yast::Term] button_box term that contains a `HBox() with buttons in it
# @return [Yast::Term] term describing the dialog.
#
def GenericTreeDialog(button_box)
button_box = deep_copy(button_box)
VBox(
Id(:WizardDialog),
ReplacePoint(Id(:topmenu), Empty()),
HBox(
HSpacing(1),
HWeight(
30,
ReplacePoint(
Id(:helpSpace), # `RichText(`id(`HelpText), "")
Empty()
)
),
HSpacing(1),
HWeight(
70,
VBox(
VSpacing(0.2),
HBox(
# translators: dialog title to appear before any content is initialized
Heading(
Id(:title),
Opt(:hstretch),
_("YaST\nInitializing ...\n")
),
HStretch()
),
VWeight(
1, # Layout trick: Lower layout priority with weight
HVCenter(Opt(:hvstretch), ReplacePoint(Id(:contents), Empty()))
)
)
),
HSpacing(1)
),
ReplacePoint(Id(:rep_button_box), button_box),
VSpacing(0.2)
)
end
# Check if the topmost dialog is a wizard dialog
# (i.e. has a widget with `id(`WizardDialog) )
#
# @return [Boolean] True if topmost dialog is a wizard dialog, false otherwise
#
def IsWizardDialog
UI.WidgetExists(Id(:WizardDialog)) == true ||
UI.WidgetExists(:wizard) == true
end
# Open a popup dialog that displays a help text (rich text format).
#
# @note This is a stable API function
#
# @param [String] help_text the text to display
#
def ShowHelp(help_text)
Popup.LongText(
# Heading for help popup window
_("Help"),
RichText(help_text),
50,
20
)
nil
end
# Returns a standard wizard dialog with buttons "Next", "Back", "Abort".
#
# @note This is a stable API function
#
# @return [Yast::Term] describing the dialog.
#
def NextBackDialog
GenericDialog(BackAbortNextButtonBox())
end
# Returns a standard wizard dialog with buttons "Cancel", "Accept"
#
# @note This is a stable API function
#
# @return [Yast::Term] describing the dialog.
#
def AcceptDialog
GenericDialog(CancelAcceptButtonBox())
end
# Returns a standard wizard dialog with buttons "Cancel", "OK"
#
# @note This is a stable API function
#
# @return [Yast::Term] describing the dialog.
#
def OKDialog
GenericDialog(CancelOKButtonBox())
end
# Open any wizard dialog.
#
# @note This is a stable API function
#
# @param [Yast::Term] dialog a wizard dialog, e.g. Wizard::GenericDialog()
#
def OpenDialog(dialog)
dialog = deep_copy(dialog)
set_icon
UI.OpenDialog(Opt(:wizardDialog), dialog)
ShowReleaseNotesButton(@relnotes_button_label, @relnotes_button_id) if !@relnotes_button_id.empty?
nil
end
# Open a dialog with buttons "Next", "Back", "Abort"
# and set the keyboard focus to "Next".
#
def OpenNextBackDialog
if haveFancyUI
open_wizard_dialog(
:back,
Label.BackButton,
:abort,
Label.AbortButton,
:next,
Label.NextButton
)
else
OpenDialog(NextBackDialog())
UI.SetFocus(Id(:next))
end
nil
end
# Open a dialog with "Accept", "Cancel"
# and set the keyboard focus to "Accept".
#
def OpenAcceptDialog
if haveFancyUI
open_wizard_dialog(
:no_back_button,
"",
:cancel,
Label.CancelButton,
:accept,
Label.AcceptButton
)
# Don't let sloppy calls to Wizard::SetContents() disable this button by accident
UI.WizardCommand(term(:ProtectNextButton, true))
else
OpenDialog(AcceptDialog())
UI.SetFocus(Id(:accept))
end
nil
end
# Open a dialog with "OK", "Cancel"
# and set the keyboard focus to "OK".
#
def OpenOKDialog
if haveFancyUI
open_wizard_dialog(
:no_back_button,
"",
:cancel,
Label.CancelButton,
:ok,
Label.OKButton
)
# Don't let sloppy calls to Wizard::SetContents() disable this button by accident
UI.WizardCommand(term(:ProtectNextButton, true))
else
OpenDialog(OKDialog())
UI.SetFocus(Id(:ok))
end
nil
end
# Open a dialog with "Accept", "Cancel"
# and set the keyboard focus to "Accept".
#
def OpenAbortApplyFinishDialog
if haveFancyUI
open_wizard_dialog(
:apply,
_("&Apply"),
:abort,
Label.AbortButton,
:finish,
Label.FinishButton
)
else
OpenDialog(GenericDialog(AbortApplyFinishButtonBox()))
UI.SetFocus(Id(:finish))
end
nil
end
# Open a dialog with "Accept", "Cancel" that will also accept workflow steps.
#
def OpenAcceptStepsDialog
if haveFancyUI
open_wizard_dialog(
Opt(:stepsEnabled),
:no_back_button,
"",
:cancel,
Label.CancelButton,
:accept,
Label.AcceptButton
)
# Don't let sloppy calls to Wizard::SetContents() disable this button by accident
UI.WizardCommand(term(:ProtectNextButton, true))
else
OpenAcceptDialog()
end
nil
end
# Open a dialog with "Accept", "Cancel" that will also accept workflow steps.
#
def OpenAcceptAbortStepsDialog
if haveFancyUI
open_wizard_dialog(
Opt(:stepsEnabled),
:no_back_button,
"",
:abort,
Label.AbortButton,
:accept,
Label.AcceptButton
)
# Don't let sloppy calls to Wizard::SetContents() disable this button by accident
UI.WizardCommand(term(:ProtectNextButton, true))
else
OpenDialog(GenericDialog(AbortAcceptButtonBox()))
end
nil
end
# Open a dialog with "Back", "Next", "Abort" that will also accept workflow steps.
#
def OpenNextBackStepsDialog
if haveFancyUI
open_wizard_dialog(
Opt(:stepsEnabled),
:back,
Label.BackButton,
:abort,
Label.AbortButton,
:next,
Label.NextButton
)
else
OpenNextBackDialog()
end
nil
end
# Open a dialog with "Back", "Next", "Abort"
# that has the title on the left, as wanted by
# the installation visual design
def OpenLeftTitleNextBackDialog
if haveFancyUI
open_wizard_dialog(
Opt(:titleOnLeft),
:back,
Label.BackButton,
:abort,
Label.AbortButton,
:next,
Label.NextButton
)
else
OpenNextBackDialog()
end
nil
end
# Open a new wizard according to the layout configuration
#
# @param layout [::UI::Wizards::Layout]
def OpenWithLayout(layout)
UI.SetProductLogo(layout.banner?)
if layout.mode.steps?
self.OpenNextBackStepsDialog
elsif layout.mode.tree?
self.OpenTreeNextBackDialog
elsif layout.mode.title_on_left?
self.OpenLeftTitleNextBackDialog
elsif layout.mode.title_on_top?
self.OpenNextBackDialog
else
raise "Unknown layout mode: #{layout}"
end
end
# Open a wizard dialog with simple layout
#
# no graphics, no steps,
# only a help widget buttons (by default "Back", "Abort", "Next").
#
# This is the only type of wizard dialog which still allows replacing
# the help space - either already upon opening it or later with
# Wizard::ReplaceCustomHelp().
#
# If help_space_contents is 'nil', the normal help widget will remain.
# If button_box is 'nil', Wizard::BackAbortNextButtonBox() is used.
#
# @see #CloseDialog
#
# @param [Yast::Term] help_space_contents Help space contents
# @param [Yast::Term] button_box Buttom Box
# @return [void]
#
def OpenCustomDialog(help_space_contents, button_box)
help_space_contents = deep_copy(help_space_contents)
button_box = deep_copy(button_box)
button_box = BackAbortNextButtonBox() if button_box.nil?
set_icon
UI.OpenDialog(Opt(:wizardDialog), GenericDialog(button_box))
UI.ReplaceWidget(Id(:helpSpace), help_space_contents) if !help_space_contents.nil?
nil
end
# Replace the help widget for dialogs opened with Wizard::OpenCustomDialog().
# @param [Yast::Term] contents Replace custom help with supplied contents
#
def ReplaceCustomHelp(contents)
contents = deep_copy(contents)
if UI.WidgetExists(Id(:helpSpace))
UI.ReplaceWidget(Id(:helpSpace), contents)
else
Builtins.y2error(
"Wizard::ReplaceHelpSpace() works only for dialogs opened with Wizard::OpenSimpleDialog() !"
)
end
nil
end
# Close a wizard dialog.
#
# @note This is a stable API function
#
def CloseDialog
if IsWizardDialog()
UI.CloseDialog
else
Builtins.y2error(
"Wizard::CloseDialog(): Topmost dialog is not a wizard dialog!"
)
end
nil
end
# Substitute for UI::UserInput
#
# This function transparently handles different variations of the wizard
# layout. Returns `next if `next or `accept were clicked, `back if `back
# or `cancel were clicked. Simply replace
# ret = UI::UserInput()
# with
# ret = Wizard::UserInput()
#
# @return (maybe normalized) widget ID
#
def UserInput
input = UI.UserInput
return :next if input == :accept
return :back if input == :cancel
deep_copy(input)
end
# Substitute for UI::TimeoutUserInput
#
# Analogical to Wizard::UserInput.
#
# @param [Fixnum] timeout_millisec
#
def TimeoutUserInput(timeout_millisec)
input = UI.TimeoutUserInput(timeout_millisec)
return :next if input == :accept
return :back if input == :cancel
deep_copy(input)
end
# Substitute for UI::WaitForEvent
#
# Analog to Wizard::UserInput.
#
def WaitForEvent
input = UI.WaitForEvent
Ops.set(input, "ID", :next) if Ops.get(input, "ID") == :accept
Ops.set(input, "ID", :back) if Ops.get(input, "ID") == :cancel
deep_copy(input)
end
# Substitute for UI::WaitForEvent with timeout
#
# Analog to Wizard::UserInput.
#
def TimeoutWaitForEvent(timeout_millisec)
input = UI.WaitForEvent(timeout_millisec)
Ops.set(input, "ID", :next) if Ops.get(input, "ID") == :accept
Ops.set(input, "ID", :back) if Ops.get(input, "ID") == :cancel
deep_copy(input)
end
# Set a new help text.
# @param [String] help_text Help text
# @example Wizard::SetHelpText("This is a help Text");
#
def SetHelpText(help_text)
UI.ChangeWidget(Id(:WizardDialog), :HelpText, help_text) if UI.WizardCommand(term(:SetHelpText, help_text)) == false
nil
end
# Replace the wizard help subwindow with a custom widget.
#
# @deprecated
# @param [Yast::Term] contents Replace Help with contents
#
def ReplaceHelp(contents)
contents = deep_copy(contents)
if UI.WidgetExists(Id(:helpSpace))
Builtins.y2warning("Wizard::ReplaceHelp() is deprecated!")
UI.ReplaceWidget(Id(:helpSpace), contents)
else
Builtins.y2error(
"Wizard::ReplaceHelp() is not supported by the new Qt wizard!"
)
end
nil
end
# Restore the wizard help subwindow.
# @param [String] help_text Help text
#
def RestoreHelp(help_text)
SetHelpText(help_text)
nil
end
# Create and open a typical installation wizard dialog.
#
# For backwards compatibility only - don't use this any more in new modules.
#
def CreateDialog
# Set productname for help text
@product_name = OSRelease.ReleaseName if @product_name == ""
UI.SetProductName(@product_name)
OpenNextBackDialog()
nil
end
# Set the contents of a wizard dialog and define if to move focus to next button
#
# How the general framework for the installation wizard should
# look like. This function creates and shows a dialog.
#
# @param [String] title Dialog Title
# @param [Yast::Term] contents The Dialog contents
# @param [String] help_text Help text
# @param [Boolean] has_back Is the Back button enabled?
# @param [Boolean] has_next Is the Next button enabled?
# @param [Boolean] set_focus Should the focus be set to Next button?
#
def SetContentsFocus(title, contents, help_text, has_back, has_next, set_focus)
contents = deep_copy(contents)
if UI.WizardCommand(term(:SetDialogHeading, title)) == true
UI.WizardCommand(term(:SetHelpText, help_text))
UI.WizardCommand(term(:EnableNextButton, has_next))
UI.WizardCommand(term(:EnableBackButton, has_back))
UI.WizardCommand(term(:SetFocusToNextButton)) if set_focus
else
if UI.WidgetExists(Id(:next))
UI.ChangeWidget(Id(:next), :Enabled, has_next)
UI.SetFocus(Id(:next))
end
UI.ChangeWidget(Id(:back), :Enabled, has_back) if UI.WidgetExists(Id(:back))
UI.ChangeWidget(Id(:abort), :Enabled, true) if UI.WidgetExists(Id(:abort))
UI.ChangeWidget(Id(:title), :Value, title) if UI.WidgetExists(Id(:title))
UI.SetFocus(Id(:accept)) if set_focus && UI.WidgetExists(Id(:accept))
end
SetHelpText(help_text)
UI.ReplaceWidget(Id(:contents), contents)
nil
end
# Set the contents of a wizard dialog
#
# How the general framework for the installation wizard should
# look like. This function creates and shows a dialog.
#
# @note This is a stable API function
#
# @param [String] title Dialog Title
# @param [Yast::Term] contents The Dialog contents
# @param [String] help_text Help text
# @param [Boolean] has_back Is the Back button enabled?
# @param [Boolean] has_next Is the Next button enabled?
# @see Example file doc/examples/wizard1.rb
# ![screenshots/wizard1.png](../../doc/screenshots/wizard1.png)
#
def SetContents(title, contents, help_text, has_back, has_next)
contents = deep_copy(contents)
SetContentsFocus(title, contents, help_text, has_back, has_next, true)
nil
end
# Clear the wizard contents.
#
# This may sound silly, but it gives much faster feedback to the
# user if used properly: Whenever the user clicks "Next" or
# "Back", call ClearContents() prior to any lengthy
# operation -> the user notices instant response, even though he
# may in fact still have to wait.
#
# @note This is a stable API function
#
def ClearContents
SetContents("", Empty(), "", false, false)
nil
end
# Set the dialog's "Next" button with a new label and a new ID
#
# @note This is a stable API function
#
# @param [Object] id Button ID
# @param [String] label Button Label
#
def SetNextButton(id, label)
id = deep_copy(id)
if UI.WizardCommand(term(:SetNextButtonLabel, label)) == true
UI.WizardCommand(term(:SetNextButtonID, id))
elsif UI.WidgetExists(Id(:rep_next))
UI.ReplaceWidget(
Id(:rep_next),
PushButton(Id(id), Opt(:key_F10, :default), label)
)
end
nil
end
# Set the dialog's "Back" button with a new label and a new ID
#
# @note This is a stable API function
#
# @param [Object] id Button ID
# @param [String] label Button Label
#
def SetBackButton(id, label)
id = deep_copy(id)
if UI.WizardCommand(term(:SetBackButtonLabel, label)) == true
UI.WizardCommand(term(:SetBackButtonID, id))
elsif UI.WidgetExists(Id(:rep_back))
UI.ReplaceWidget(
Id(:rep_back),
PushButton(Id(id), Opt(:key_F8), label)
)
end
nil
end
# Set the dialog's "Abort" button with a new label and a new ID
#
# @note This is a stable API function
#
# @param [Object] id Button ID
# @param [String] label Button Label
#
def SetAbortButton(id, label)
id = deep_copy(id)
if UI.WizardCommand(term(:SetAbortButtonLabel, label)) == true
UI.WizardCommand(term(:SetAbortButtonID, id))
elsif UI.WidgetExists(Id(:rep_abort))
UI.ReplaceWidget(
Id(:rep_abort),
PushButton(Id(id), Opt(:key_F9), label)
)
end
nil
end
# Hide the Wizard's "Next" button.
# Restore it later with RestoreNextButton():
#
# @see #RestoreNextButton
# @note This is a stable API function
#
def HideNextButton
UI.ReplaceWidget(Id(:rep_next), Empty()) if UI.WizardCommand(term(:SetNextButtonLabel, "")) == false && UI.WidgetExists(Id(:rep_next))
nil
end
# Hide the Wizard's "Back" button.
# Restore it later with RestoreBackButton():
#
# @see #RestoreBackButton
# @note This is a stable API function
#
def HideBackButton
UI.ReplaceWidget(Id(:rep_back), Empty()) if UI.WizardCommand(term(:SetBackButtonLabel, "")) == false && UI.WidgetExists(Id(:rep_back))
nil
end
# Overview Dialog
# http://en.opensuse.org/YaST/Style_Guide#Single_Configuration.2FOverview.2FEdit_Dialog
# dialog with Cancel and OK buttons (cancel has function as abort)
#
def OpenCancelOKDialog
if haveFancyUI
open_wizard_dialog(
:back,
Label.BackButton,
:abort,
Label.CancelButton,
:next,
Label.OKButton
)
HideBackButton()
else
OpenDialog(NextBackDialog())
UI.SetFocus(Id(:next))
end
nil
end
# Hide the Wizard's "Abort" button.
# Restore it later with RestoreAbortButton():
#
# @see #RestoreAbortButton
# @note This is a stable API function
#
def HideAbortButton
if UI.WizardCommand(term(:SetAbortButtonLabel, "")) == false
if UI.WidgetExists(Id(:rep_abort))
UI.ReplaceWidget(Id(:rep_abort), Empty())
elsif UI.WidgetExists(Id(:cancel))
UI.ReplaceWidget(Id(:cancel), Empty())
end
end
nil
end
# Restore the wizard 'back' button.
#
# @see #HideBackButton
# @note This is a stable API function
#
def RestoreBackButton
SetBackButton(:back, Label.BackButton)
nil
end
# Restore the wizard 'next' button.
#
# @see #HideNextButton
# @note This is a stable API function
#
def RestoreNextButton
SetNextButton(:next, Label.NextButton)
nil
end
# Restore the wizard 'abort' button.
#
# @see #HideAbortButton
# @note This is a stable API function
#
def RestoreAbortButton
SetAbortButton(:abort, Label.AbortButton)
nil
end
# Set contents and Buttons of wizard dialog
#
# Additionally set its title, help_text and buttons labels. Enables both back and next button.
#
# @params
#
# @param [String] title title of window
# @param [Yast::Term] contents contents of dialog
# @param [String] help_text help text
# @param [String] back_label label of back button
# @param [String] next_label label of next button
#
def SetContentsButtons(title, contents, help_text, back_label, next_label)
contents = deep_copy(contents)
UI.PostponeShortcutCheck
RestoreBackButton()
RestoreNextButton()
if UI.WizardCommand(term(:SetBackButtonLabel, back_label)) == true
UI.WizardCommand(term(:SetNextButtonLabel, next_label))
else
# Set button labels first to avoid geometry problems: SetContents()
# calls ReplaceWidget() wich triggers a re-layout.
UI.ChangeWidget(Id(:back), :Label, back_label) if UI.WidgetExists(Id(:back))
UI.ChangeWidget(Id(:next), :Label, next_label) if UI.WidgetExists(Id(:next))
end
SetContents(title, contents, help_text, true, true)
SetHelpText(help_text)
UI.CheckShortcuts
nil
end
# Sets the dialog title shown in the window manager's title bar.
#
# @param [String] title_text title of the dialog
#
# @example
# SetDialogTitle ("DNS Server Configuration");
#
def SetDialogTitle(title_text)
# backward compatibility with showing just YaST2 in qt
# see bsc#1033161 comment#4
UI.SetApplicationTitle("YaST2") if haveFancyUI
UI.WizardCommand(term(:SetDialogTitle, title_text))
nil
end
# Sets the wizard 'title' icon to the specified icon from the standard icon
# directory.
#
# @note Deprecated. Do nothing.
#
# @param [String] icon_name name (without path) of the new icon
# @see #ClearTitleIcon
#
# @example
# SetTitleIcon ("yast-dns-server");
#
def SetTitleIcon(_icon_name)
nil
end
# Clear the wizard 'title' icon, i.e. replace it with nothing
#
# @note Deprecated. Do nothing.
# @see #SetTitleIcon
#
def ClearTitleIcon
nil
end
# Sets the window title according to the name specified in a .desktop file got as parameter.
# Desktop file is placed in a special directory (/usr/share/applications/YaST2).
# Parameter file is realative to that directory without ".desktop" suffix.
#
# @param [String] file desktop file
# @return [Boolean] true on success
#
# @example
# // Opens /usr/share/applications/YaST2/lan.desktop
# // Reads (localized) "name" entry from there
# // Sets the window title.
# SetDesktopTitle ("lan")
def SetDesktopTitle(file)
description = Desktop.ParseSingleDesktopFile(file)
# fallback name for the dialog title
name = Ops.get(description, "Name", _("Module"))
Builtins.y2debug("Set dialog title: %1", name)
SetDialogTitle(name)
Builtins.haskey(description, "Name")
end
# Sets the icon specified in a .desktop file got as parameter.
# Desktop file is placed in a special directory (/usr/share/applications/YaST2).
# Parameter file is realative to that directory without ".desktop" suffix.
# Warning: There are no desktop files in inst-sys. Use "SetTitleIcon" instead.
#
# @param [String] file Icon name
# @return [Boolean] true on success
#
# @example
# // Opens /usr/share/applications/YaST2/lan.desktop
# // Reads "Icon" entry from there
# // Sets the icon.
# SetDesktopIcon ("lan")
def SetDesktopIcon(file)
description = Desktop.ParseSingleDesktopFile(file)
return false unless description
icon = description["Icon"].to_s
return false if icon.empty?
@icon_name = icon
set_icon
end
# Convenience function to avoid 2 calls if application needs to set
# both dialog title and icon from desktop file specified as parameter.
# Desktop file is placed in a special directory (/usr/share/applications/YaST2).
# Parameter file is realative to that directory without ".desktop" suffix.
# Warning: There are no desktop files in inst-sys.
#
# @param [String] file desktop file name
# @return [Boolean] true on success
#
# @example
# // Opens /usr/share/applications/YaST2/lan.desktop
# // Reads "Icon" and "Name" entries from there
# // Sets the icon, sets the dialog title
# SetDialogTitleAndIcon ("lan")
def SetDesktopTitleAndIcon(file)
description = Desktop.ParseSingleDesktopFile(file)
# fallback name for the dialog title
name = Ops.get(description, "Name", _("Module"))
Builtins.y2debug("Set dialog title: %1", name)
SetDialogTitle(name)
SetDesktopIcon(file)
Builtins.haskey(description, "Name")
end
# PRIVATE - Replace the entire Wizard button box with a new one.
# @param [Yast::Term] button_box Button Box term
# @return [void]
#
def ReplaceButtonBox(button_box)
button_box = deep_copy(button_box)
UI.ReplaceWidget(Id(:rep_button_box), button_box)
nil
end
# Enable the wizard's "Abort" button.
#
# @see #DisableAbortButton
# @note This is a stable API function
#
def EnableAbortButton
UI.ChangeWidget(Id(:abort), :Enabled, true) if UI.WizardCommand(term(:EnableAbortButton, true)) == false
nil
end
# Disable the wizard's "Abort" button.
#
# @see #EnableAbortButton
# @note This is a stable API function
#
def DisableAbortButton
UI.ChangeWidget(Id(:abort), :Enabled, false) if UI.WizardCommand(term(:EnableAbortButton, false)) == false
nil
end
# Disable the wizard's "Next" (or "Accept") button.
#
# @see #EnableNextButton
# @note This is a stable API function
#
def DisableNextButton
if UI.WizardCommand(term(:EnableNextButton, false)) == false
if UI.WidgetExists(Id(:next))
UI.ChangeWidget(Id(:next), :Enabled, false)
elsif UI.WidgetExists(Id(:accept))
UI.ChangeWidget(Id(:accept), :Enabled, false)
else
Builtins.y2error(-1, "Neither `next nor `accept widgets exist")
end
end
nil
end
# Enable the wizard's "Next" (or "Accept") button.
#
# @see #DisableNextButton
# @note This is a stable API function
#
def EnableNextButton
if UI.WizardCommand(term(:EnableNextButton, true)) == false
if UI.WidgetExists(Id(:next))
UI.ChangeWidget(Id(:next), :Enabled, true)
else
UI.ChangeWidget(Id(:accept), :Enabled, true)
end
end
nil
end
# Disable the wizard's "Back" button.
#
# @see #EnableBackButton
# @note This is a stable API function
#
def DisableBackButton
UI.ChangeWidget(Id(:back), :Enabled, false) if UI.WizardCommand(term(:EnableBackButton, false)) == false
nil
end
# Enable the wizard's "Back" button.
#
# @see #DisableBackButton
# @note This is a stable API function
#
def EnableBackButton
UI.ChangeWidget(Id(:back), :Enabled, true) if UI.WizardCommand(term(:EnableBackButton, true)) == false
nil
end
# Disable the wizard's "Cancel" button.
#
# @see #EnableCancelButton
# @note This is a stable API function
#
def DisableCancelButton
UI.ChangeWidget(Id(:cancel), :Enabled, false) if UI.WizardCommand(term(:EnableCancelButton, false)) == false
nil
end
# Enable the wizard's "Cancel" button.
#
# @see #DisableCancelButton
# @note This is a stable API function
#
def EnableCancelButton
UI.ChangeWidget(Id(:cancel), :Enabled, true) if UI.WizardCommand(term(:EnableCancelButton, true)) == false
nil
end
# Returns whether the `Wizard widget is available.
#
# @see bnc #367213.
# @return [Boolean] available
def HasWidgetWizard
if !UI.HasSpecialWidget(:Wizard)
Builtins.y2milestone("no Wizard available")
return false
end
true
end
# Show a "Release Notes" button with the specified label and ID if there is a "steps" panel
#
def ShowReleaseNotesButton(label, id)
# has wizard? continue
# otherwise use dedicated ReplacePoint or reuse the back button
# show-releasenotes-button failed? continue
# use dedicated ReplacePoint or reuse the back button
if HasWidgetWizard() == false ||
UI.WizardCommand(term(:ShowReleaseNotesButton, label, id)) == false
@relnotes_button_label = label
@relnotes_button_id = id
if UI.WidgetExists(Id(:relnotes_rp))
UI.ReplaceWidget(Id(:relnotes_rp), PushButton(Id(id), Opt(:relNotesButton), label))
# Reuse Back button
# TODO: can this situation happen
elsif UI.WidgetExists(Id(:back_rep))
UI.ReplaceWidget(Id(:back_rep), PushButton(Id(id), label))
else
Builtins.y2warning("Widget `back_rep does not exist")
end
end
nil
end
# Hide the "Release Notes" button, if there is any
#
def HideReleaseNotesButton
# has wizard? continue
# otherwise use dedicated ReplacePoint or reuse the back button
# hide-releasenotes-button failed? continue
# reuse use dedicated ReplacePoint or the back button
if HasWidgetWizard() == false ||
UI.WizardCommand(term(:HideReleaseNotesButton)) == false
@relnotes_button_label = ""
@relnotes_button_id = ""
if UI.WidgetExists(Id(:relnotes_rp))
UI.ReplaceWidget(Id(:relnotes_rp), Empty())
elsif UI.WidgetExists(Id(:back_rep))
UI.ReplaceWidget(Id(:back_rep), Empty())
end
end
nil
end
# Retranslate the wizard buttons.
#
# This will revert button labels and IDs
# to the defaults that were used upon Wizard::CreateDialog(),
# Wizard::OpenNextBackDialog(), or Wizard::OpenAcceptDialog().
#
def RetranslateButtons
textdomain "base" # Reload translations
if UI.WidgetExists(Id(:WizardDialog)) == true # NCurses wizard
UI.ChangeWidget(Id(:help), :Label, Label.HelpButton) if UI.WidgetExists(Id(:help))
ReplaceButtonBox(
if UI.WidgetExists(Id(:accept))
AbortAcceptButtonBox()
else
BackAbortNextButtonBox()
end
)
else # Qt wizard
UI.WizardCommand(term(:RetranslateInternalButtons))
if UI.WidgetExists(:accept)
UI.WizardCommand(term(:SetBackButtonLabel, ""))
UI.WizardCommand(term(:SetAbortButtonLabel, Label.AbortButton))
UI.WizardCommand(term(:SetNextButtonLabel, Label.AcceptButton))
else
UI.WizardCommand(term(:SetBackButtonLabel, Label.BackButton))
UI.WizardCommand(term(:SetAbortButtonLabel, Label.AbortButton))
UI.WizardCommand(term(:SetNextButtonLabel, Label.NextButton))
end
end
nil
end
# Set the keyboard focus to the wizard's "Next" (or "Accept") button.
#
# @note This is a stable API function
#
def SetFocusToNextButton
if UI.WizardCommand(term(:SetFocusToNextButton)) == false
UI.SetFocus(UI.WidgetExists(Id(:next)) ? Id(:next) : Id(:accept))
end
nil
end
# Set the keyboard focus to the wizard's "Back" (or "Cancel") button.
#
# @note This is a stable API function
#
def SetFocusToBackButton
if UI.WizardCommand(term(:SetFocusToBackButton)) == false
UI.SetFocus(UI.WidgetExists(Id(:back)) ? Id(:back) : Id(:cancel))
end
nil
end
# Set a name for the current dialog:
#
# Declare a name for the current dialog to ease making screenshots.
# By convention, the name is
# `{rpm-name-without-yast2}-{sorting-prefix}-{description}`
# The calls may be nested.
# @param s eg. "mail-1-conntype"
# @see #RestoreScreenShotName
def SetScreenShotName(name)
@screenshot_name_stack = Builtins.prepend(
@screenshot_name_stack,
@screenshot_name
)
@screenshot_name = name
nil
end
# Restore the screenshot name.
#
# If it does not match a SetScreenShotName, "yast2" is used
# and a y2error logged.
def RestoreScreenShotName
@screenshot_name = Ops.get(@screenshot_name_stack, 0)
if @screenshot_name.nil?
@screenshot_name = "yast2"
Builtins.y2error(1, "No screenshot name to restore!")
else
@screenshot_name_stack = Builtins.remove(@screenshot_name_stack, 0)
end
nil
end
#
# Tree & Menu Wizard functions
#
# Open a Tree dialog with buttons "Next", "Back", "Abort"
# and set the keyboard focus to "Next".
#
def OpenTreeNextBackDialog
if haveFancyUI
open_wizard_dialog(
Opt(:treeEnabled),
:back,
Label.BackButton,
:abort,
Label.AbortButton,
:next,
Label.NextButton
)
else
OpenDialog(GenericTreeDialog(BackAbortNextButtonBox()))
UI.SetFocus(Id(:next))
end
nil
end
# Create and open a Tree wizard dialog.
#
# For backwards compatibility only - don't use this any more in new modules.
#
def CreateTreeDialog
OpenTreeNextBackDialog()
nil
end
# Add Tree Item to tree enabled Wizard
# @param [Array<Hash>] Tree Tree Data
# @param [String] parent Parent of this item
# @param [String] title Item Title
# @param [String] id Item ID
# @return [Array<Hash>] Updated Tree Data
#
def AddTreeItem(tree, parent, title, id)
tree = deep_copy(tree)
if haveFancyUI
UI.WizardCommand(term(:AddTreeItem, parent, title, id))
else
tree = Builtins.add(
tree,
"parent" => parent, "title" => title, "id" => id
)
end
deep_copy(tree)
end
# Create the Tree Items
# @param [Array<Hash>] Tree Tree data
# @param [String] parent Parent of current Item
# @return [Array] Tree Items
#
def CreateTreeInternal(tree, parent)
tree = deep_copy(tree)
m = Builtins.filter(tree) do |c|
Ops.get_string(c, "parent", "") == parent
end
ccbak = nil # #38596, broken recursion for iterators
mm = Builtins.maplist(m) do |cc|
tree_entry = Ops.get_string(cc, "id", "")
ccbak = deep_copy(cc)
items = CreateTreeInternal(tree, tree_entry)
cc = deep_copy(ccbak)
if Ops.greater_than(Builtins.size(items), 0)
next Item(
Id(Ops.get_string(cc, "id", "")),
Ops.get_string(cc, "title", ""),
items
)
else
next Item(
Id(Ops.get_string(cc, "id", "")),
Ops.get_string(cc, "title", "")
)
end
end
Builtins.y2debug("items: %1", mm)
deep_copy(mm)
end
# Query Tree Item
# @return Tree Item
def QueryTreeItem
if haveFancyUI
Convert.to_string(UI.QueryWidget(Id(:wizard), :CurrentItem))
else
Convert.to_string(UI.QueryWidget(Id(:wizardTree), :CurrentItem))
end
end
# Create the tree in the dialog, replaces helpspace with new tree widget
# @param [Array<Hash>] Tree Tree data
# @param [String] title Tree title
#
def CreateTree(tree, title)
tree = deep_copy(tree)
if !haveFancyUI
items = []
Builtins.foreach(tree) do |i|
if Ops.get_string(i, "parent", "") == ""
items = Builtins.add(
items,
Item(
Id(Ops.get_string(i, "id", "")),
Ops.get_string(i, "title", ""),
CreateTreeInternal(tree, Ops.get_string(i, "id", ""))
)
)
end
end
Builtins.y2debug("tree items: %1", items)
ReplaceCustomHelp(
VBox(
term(:Tree, Id(:wizardTree), Opt(:notify, :vstretch), title, items),
VSpacing(1)
)
)
end
nil
end
# Select Tree item
# @param [String] tree_item tree item
def SelectTreeItem(tree_item)
if haveFancyUI
UI.WizardCommand(term(:SelectTreeItem, tree_item))
else
UI.ChangeWidget(Id(:wizardTree), :CurrentItem, tree_item)
end
nil
end
# Delete Tree items
def DeleteTreeItems
if haveFancyUI
UI.WizardCommand(term(:DeleteTreeItems))
else
ReplaceCustomHelp(Empty())
end
nil
end
# Delete Menu items
def DeleteMenus
if haveFancyUI
UI.WizardCommand(term(:DeleteMenus))
else
UI.ReplaceWidget(Id(:topmenu), Empty())
end
nil
end
# Add Menu
# @param [Array<Hash>] Menu Menu data
# @param [String] title Menu Title
# @param [String] id Menu ID
# @return [Array<Hash>] Updated Menu Data
#
def AddMenu(menu, title, id)
menu = deep_copy(menu)
if haveFancyUI
UI.WizardCommand(term(:AddMenu, title, id))
else
menu = Builtins.add(
menu,
"type" => "Menu", "title" => title, "id" => id
)
end
deep_copy(menu)
end
# Add Sub Menu
# @param [Array<Hash>] Menu Menu data
# @param [String] parent_id Menu Parent
# @param [String] title Menu Title
# @param [String] id Menu ID
# @return [Array<Hash>] Updated Menu Data
#
def AddSubMenu(menu, parent_id, title, id)
menu = deep_copy(menu)
if haveFancyUI
UI.WizardCommand(term(:AddSubMenu, parent_id, title, id))
else
menu = Builtins.add(
menu,
"type" => "SubMenu",
"parent" => parent_id,
"title" => title,
"id" => id
)
end
deep_copy(menu)
end
# Add Menu Entry
# @param [Array<Hash>] Menu Menu data
# @param [String] parent_id Menu Parent
# @param [String] title Menu Title
# @param [String] id Menu ID
# @return [Array<Hash>] Updated Menu Data
#
def AddMenuEntry(menu, parent_id, title, id)
menu = deep_copy(menu)
if haveFancyUI
UI.WizardCommand(term(:AddMenuEntry, parent_id, title, id))
else
menu = Builtins.add(
menu,
"type" => "MenuEntry",
"parent" => parent_id,
"title" => title,
"id" => id
)
end
deep_copy(menu)
end
# Create the Menu Items
# @param [Array<Hash>] Menu Menu data
# @param [String] parent Menu Parent
# @return [Array] Menu Items
#
def CreateMenuInternal(menu, parent)
menu = deep_copy(menu)
m = Builtins.filter(menu) do |c|
Ops.get_string(c, "parent", "") == parent
end
mm = Builtins.maplist(m) do |cc|
case Ops.get_string(cc, "type", "")
when "MenuEntry"
menu_entry = Ops.get_string(cc, "id", "")
next Item(Id(menu_entry), Ops.get_string(cc, "title", ""))
when "SubMenu"
sub_menu = Ops.get_string(cc, "id", "")
next term(
:menu,
Ops.get_string(cc, "title", ""),
CreateMenuInternal(menu, sub_menu)
)
end
end
Builtins.y2debug("items: %1", mm)
deep_copy(mm)
end
# Create the menu in the dialog
# @param [Array<Hash>] Menu Menu data
# @return [void]
#
def CreateMenu(menu)
menu = deep_copy(menu)
if !haveFancyUI
menu_term = HBox()
Builtins.foreach(menu) do |m|
if Ops.get_string(m, "type", "") == "Menu"
menu_items = CreateMenuInternal(menu, Ops.get_string(m, "id", ""))
Builtins.y2debug("menu_items: %1", menu_items)
menu_term = Builtins.add(
menu_term,
MenuButton(Ops.get_string(m, "title", ""), menu_items)
)
end
end
Builtins.y2milestone("menu: %1", menu_term)
UI.ReplaceWidget(Id(:topmenu), Left(menu_term))
end
nil
end
# Set the product name for UI
# @param [String] name the product name
# @return [void]
#
def SetProductName(name)
Builtins.y2milestone("Setting product name to '%1'", name)
@product_name = name
UI.SetProductName(@product_name)
nil
end
publish function: :BackAbortNextButtonBox, type: "term ()"
publish function: :BackAbortInstallationNextButtonBox, type: "term ()"
publish function: :BackNextButtonBox, type: "term ()"
publish function: :CancelAcceptButtonBox, type: "term ()"
publish function: :CancelOKButtonBox, type: "term ()"
publish function: :AbortAcceptButtonBox, type: "term ()"
publish function: :AbortInstallationAcceptButtonBox, type: "term ()"
publish function: :AbortApplyFinishButtonBox, type: "term ()"
publish function: :GenericDialog, type: "term (term)"
publish function: :GenericTreeDialog, type: "term (term)"
publish function: :IsWizardDialog, type: "boolean ()"
publish function: :ShowHelp, type: "void (string)"
publish function: :NextBackDialog, type: "term ()"
publish function: :AcceptDialog, type: "term ()"
publish function: :OKDialog, type: "term ()"
publish function: :OpenDialog, type: "void (term)"
publish function: :OpenNextBackDialog, type: "void ()"
publish function: :OpenAcceptDialog, type: "void ()"
publish function: :OpenOKDialog, type: "void ()"
publish function: :OpenAbortApplyFinishDialog, type: "void ()"
publish function: :OpenAcceptStepsDialog, type: "void ()"
publish function: :OpenAcceptAbortStepsDialog, type: "void ()"
publish function: :OpenNextBackStepsDialog, type: "void ()"
publish function: :OpenLeftTitleNextBackDialog, type: "void ()"
publish function: :OpenCustomDialog, type: "void (term, term)"
publish function: :ReplaceCustomHelp, type: "void (term)"
publish function: :CloseDialog, type: "void ()"
publish function: :UserInput, type: "any ()"
publish function: :TimeoutUserInput, type: "any (integer)"
publish function: :WaitForEvent, type: "map ()"
publish function: :TimeoutWaitForEvent, type: "map (integer)"
publish function: :SetHelpText, type: "void (string)"
publish function: :ReplaceHelp, type: "void (term)"
publish function: :RestoreHelp, type: "void (string)"
publish function: :CreateDialog, type: "void ()"
publish function: :SetContentsFocus, type: "void (string, term, string, boolean, boolean, boolean)"
publish function: :SetContents, type: "void (string, term, string, boolean, boolean)"
publish function: :ClearContents, type: "void ()"
publish function: :SetNextButton, type: "void (any, string)"
publish function: :SetBackButton, type: "void (any, string)"
publish function: :SetAbortButton, type: "void (any, string)"
publish function: :HideNextButton, type: "void ()"
publish function: :HideBackButton, type: "void ()"
publish function: :OpenCancelOKDialog, type: "void ()"
publish function: :HideAbortButton, type: "void ()"
publish function: :RestoreBackButton, type: "void ()"
publish function: :RestoreNextButton, type: "void ()"
publish function: :RestoreAbortButton, type: "void ()"
publish function: :SetContentsButtons, type: "void (string, term, string, string, string)"
publish function: :SetDialogTitle, type: "void (string)"
publish function: :SetTitleIcon, type: "void (string)"
publish function: :ClearTitleIcon, type: "void ()"
publish function: :SetDesktopTitle, type: "boolean (string)"
publish function: :SetDesktopIcon, type: "boolean (string)"
publish function: :SetDesktopTitleAndIcon, type: "boolean (string)"
publish function: :EnableAbortButton, type: "void ()"
publish function: :DisableAbortButton, type: "void ()"
publish function: :DisableNextButton, type: "void ()"
publish function: :EnableNextButton, type: "void ()"
publish function: :DisableBackButton, type: "void ()"
publish function: :EnableBackButton, type: "void ()"
publish function: :DisableCancelButton, type: "void ()"
publish function: :EnableCancelButton, type: "void ()"
publish function: :ShowReleaseNotesButton, type: "void (string, string)"
publish function: :HideReleaseNotesButton, type: "void ()"
publish function: :RetranslateButtons, type: "void ()"
publish function: :SetFocusToNextButton, type: "void ()"
publish function: :SetFocusToBackButton, type: "void ()"
publish function: :SetScreenShotName, type: "void (string)"
publish function: :RestoreScreenShotName, type: "void ()"
publish function: :OpenTreeNextBackDialog, type: "void ()"
publish function: :CreateTreeDialog, type: "void ()"
publish function: :AddTreeItem, type: "list <map> (list <map>, string, string, string)"
publish function: :QueryTreeItem, type: "string ()"
publish function: :CreateTree, type: "void (list <map>, string)"
publish function: :SelectTreeItem, type: "void (string)"
publish function: :DeleteTreeItems, type: "void ()"
publish function: :DeleteMenus, type: "void ()"
publish function: :AddMenu, type: "list <map> (list <map>, string, string)"
publish function: :AddSubMenu, type: "list <map> (list <map>, string, string, string)"
publish function: :AddMenuEntry, type: "list <map> (list <map>, string, string, string)"
publish function: :CreateMenu, type: "void (list <map>)"
publish function: :SetProductName, type: "void (string)"
protected
# Sets the icon and opens a wizard dialog with the content specified as
# arguments
def open_wizard_dialog(*args)
set_icon
UI.OpenDialog(
Opt(:wizardDialog),
Wizard(*args)
)
end
# Sets the application icon according to the value of @icon_name
#
# This should be called only immediately before opening a dialog; premature
# UI calls can interfere with the CommandLine mode.
#
# @return [Boolean] true if the application icon was set; false otherwise
def set_icon
UI.SetApplicationIcon(@icon_name)
true
end
end
Wizard = WizardClass.new
Wizard.main
end