Skip to content

Commit

Permalink
Merge pull request #576 from yast/cwm-term-kinds
Browse files Browse the repository at this point in the history
Document the 3 kind of Terms used in CWM
  • Loading branch information
mvidner committed May 17, 2017
2 parents d2ad7da + 1d14813 commit 7b26e54
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 31 deletions.
30 changes: 28 additions & 2 deletions library/cwm/src/lib/cwm/abstract_widget.rb
@@ -1,6 +1,32 @@
require "abstract_method"

module CWM
# A Yast::Term that can be passed as is to Yast::UI methods
# (OpenDialog, ReplaceWidget)
#
# The normal workflow is that a {WidgetTerm} becomes a {StringTerm}
# which becomes a {UITerm}.
class UITerm < Yast::Term; end

# A Yast::Term that contains strings
# which identify the old style hash based CWM widgets.
# Can be passed to {Yast::CWMClass#ShowAndRun Yast::CWM.ShowAndRun}
#
# The normal workflow is that a {WidgetTerm} becomes a {StringTerm}
# which becomes a {UITerm}.
class StringTerm < Yast::Term; end

# A Yast::Term that contains instances of {CWM::AbstractWidget}.
# Can be passed to {Yast::CWMClass#show Yast::CWM.show}
#
# The normal workflow is that a {WidgetTerm} becomes a {StringTerm}
# which becomes a {UITerm}.
class WidgetTerm < Yast::Term; end

# A {Hash{String=>Object}} that {Yast::CWMClass} knows to handle.
# TODO: document the members
class WidgetHash < Hash; end

# Represent base for any widget used in CWM. It can be passed as "widget"
# argument. For more details about usage
# see {Yast::CWMClass#show Yast::CWM.show}
Expand All @@ -9,7 +35,7 @@ module CWM
#
# The call sequence is:
#
# - {#initialize} is called by the Ruby constructor {.new}
# - `#initialize` is called by the Ruby constructor {.new}
# - CWM#show builds a widget tree, using
# - the AbstractWidget concrete class
# - {#opt} widget options: `[:notify]` is needed if {#handle} is defined
Expand Down Expand Up @@ -106,7 +132,7 @@ def self.widget_type=(type)
# It refers to
# {#help}, {#label}, {#opt}
# {#validate}, {#init}, {#handle}, {#store}, {#cleanup}.
# @return [Hash{String => Object}]
# @return [WidgetHash]
# @raise [RuntimeError] if a required method is not implemented
# or widget_type is not set.
def cwm_definition
Expand Down
4 changes: 3 additions & 1 deletion library/cwm/src/lib/cwm/custom_widget.rb
Expand Up @@ -33,9 +33,10 @@ class CustomWidget < AbstractWidget

# @!method contents
# Must be defined by subclasses
# @return [Yast::Term] a UI term; {AbstractWidget} are not allowed inside
# @return [UITerm] a UI term; {AbstractWidget} are not allowed inside
abstract_method :contents

# @return [WidgetHash]
def cwm_definition
res = { "custom_widget" => cwm_contents }

Expand All @@ -56,6 +57,7 @@ def nested_widgets

# return contents converted to format understandable by CWM module
# Basically it replace instance of AbstractWidget by its widget_id
# @return [StringTerm]
def cwm_contents
Yast.import "CWM"

Expand Down
4 changes: 3 additions & 1 deletion library/cwm/src/lib/cwm/tabs.rb
Expand Up @@ -5,11 +5,12 @@ class Tab < CustomWidget
# @return [Boolean] is this the initially selected tab
attr_accessor :initial

# @return [Yast::Term] contents of the tab, can contain {AbstractWidget}s
# @return [WidgetTerm] contents of the tab, can contain {AbstractWidget}s
abstract_method :contents
# @return [String] label defines name of tab header
abstract_method :label

# @return [WidgetHash]
def cwm_definition
super.merge(
"widgets" => cwm_widgets,
Expand All @@ -19,6 +20,7 @@ def cwm_definition

# get cwm style of widget definitions
# @note internal api only used as gate to communicate with CWM
# @return [Array<WidgetHash>]
def cwm_widgets
return @cwm_widgets if @cwm_widgets

Expand Down
7 changes: 7 additions & 0 deletions library/cwm/src/lib/cwm/widget.rb
Expand Up @@ -57,6 +57,7 @@ def items
[]
end

# @return [WidgetHash]
def cwm_definition
super.merge(
"items" => items
Expand Down Expand Up @@ -248,6 +249,8 @@ class IntField < AbstractWidget

# The definition for IntField additionally supports
# `minimum` and `maximum` methods.
#
# @return [WidgetHash]
# @example minimum and maximum methods
# def minimum
# 50
Expand Down Expand Up @@ -294,6 +297,7 @@ def value=(val)
# In addition to the base definition, this honors possible
# `vspacing` and `hspacing` methods
#
# @return [WidgetHash]
# @example defining additional space between the options
# def vspacing
# 1
Expand Down Expand Up @@ -369,6 +373,7 @@ def initialize(id: "_placeholder", widget: Empty.new("_initial_placeholder"))
@widget = widget
end

# @return [UITerm]
def contents
ReplacePoint(Id(widget_id), widget_content(@widget))
end
Expand Down Expand Up @@ -420,6 +425,8 @@ def cleanup

private

# @param widget [AbstractWidget]
# @return [UITerm]
def widget_content(widget)
definition = widget.cwm_definition
definition["_cwm_key"] = widget.widget_id # a bit hacky way to pass widget id
Expand Down
58 changes: 31 additions & 27 deletions library/cwm/src/modules/CWM.rb
Expand Up @@ -107,9 +107,9 @@ def PopSettings

# Process term with the dialog, replace strings in the term with
# appropriate widgets
# @param [Yast::Term] t term dialog containing strings
# @param [Hash <String, Hash{String => Object>}] widgets map of widget name -> widget description map
# @return [Yast::Term] updated term ready to be used as a dialog
# @param t [::CWM::StringTerm] term dialog containing strings
# @param widgets [Hash{String => ::CWM::WidgetHash}] widget name -> widget description
# @return [::CWM::UITerm] updated term ready to be used as a dialog
def ProcessTerm(t, widgets)
t = deep_copy(t)
widgets = deep_copy(widgets)
Expand Down Expand Up @@ -155,8 +155,8 @@ def ProcessTerm(t, widgets)

# Process term with the dialog, return all strings.
# To be used as an argument for widget_names until they are obsoleted.
# @param [Yast::Term] t term dialog containing strings
# @return [String]s found in the term
# @param t [::CWM::StringTerm] term dialog containing strings
# @return [Array<String>] found in the term
def StringsOfTerm(t)
t = deep_copy(t)
rets = []
Expand Down Expand Up @@ -305,7 +305,7 @@ def GetLowestTimeout(widgets)

# Add fallback functions to a widget
# global only because of testsuites
# @param [Array<Hash{String => Object>}] widgets a list of widget desctiption maps
# @param [Array<::CWM::WidgetHash>] widgets a list of widget desctiption maps
# @param [Hash] functions map of functions
# @return a list of modified widget description maps
def mergeFunctions(widgets, functions)
Expand All @@ -328,7 +328,7 @@ def mergeFunctions(widgets, functions)

# Set widgets according to internally stored settings
# global only because of testsuites
# @param [Array<Hash{String => Object>}] widgets list of maps representing widgets
# @param [Array<::CWM::WidgetHash>] widgets list of maps representing widgets
def initWidgets(widgets)
widgets = deep_copy(widgets)
Builtins.foreach(widgets) do |w|
Expand Down Expand Up @@ -356,7 +356,7 @@ def initWidgets(widgets)

# Handle change of widget after event generated
# global only because of testsuites
# @param [Array<Hash{String => Object>}] widgets list of maps represenging widgets
# @param [Array<::CWM::WidgetHash>] widgets list of maps represenging widgets
# @param [Hash] event_descr map event that occured
# @return [Symbol] modified action (sometimes may be needed) or nil
def handleWidgets(widgets, event_descr)
Expand Down Expand Up @@ -385,7 +385,7 @@ def handleWidgets(widgets, event_descr)
# Save changes of widget after event generated
# global only because of testsuites
# CWMTab uses it too
# @param [Array<Hash{String => Object>}] widgets list of maps represenging widgets
# @param [Array<::CWM::WidgetHash>] widgets list of maps represenging widgets
# @param [Hash] event map event that occured
def saveWidgets(widgets, event)
widgets = deep_copy(widgets)
Expand All @@ -405,7 +405,7 @@ def saveWidgets(widgets, event)

# Cleanup after dialog was finished (independently on what event)
# global only because of testsuites
# @param [Array<Hash{String => Object>}] widgets list of maps represenging widgets
# @param [Array<::CWM::WidgetHash>] widgets list of maps represenging widgets
def cleanupWidgets(widgets)
widgets = deep_copy(widgets)
Builtins.foreach(widgets) do |w|
Expand All @@ -430,7 +430,7 @@ def GetProcessedWidget
end

# Create a term with OK and Cancel buttons placed horizontally
# @return the term (HBox)
# @return [::CWM::UITerm] the term (HBox)
def OkCancelBox
ButtonBox(
PushButton(
Expand All @@ -448,7 +448,7 @@ def OkCancelBox

# Validate widget description map, check for maps structure
# Also checks option description maps if present
# @param [Hash <String, Hash{String => Object>}] widgets map widgets description map
# @param [Hash{String => ::CWM::WidgetHash}] widgets map widgets description map
# @return [Boolean] true on success
def ValidateMaps(widgets)
widgets = deep_copy(widgets)
Expand Down Expand Up @@ -501,8 +501,9 @@ def ValidateMaps(widgets)
end

# Prepare a widget for usage
# @param [Hash{String => Object}] widget_descr map widget description map
# @return [Hash] modified widget description map
# @param [::CWM::WidgetHash] widget_descr map widget description map
# @return [::CWM::WidgetHash] modified widget description map
# where "widget" key is a {::CWM::UITerm}
def prepareWidget(widget_descr)
widget_descr = deep_copy(widget_descr)
w = deep_copy(widget_descr)
Expand Down Expand Up @@ -646,7 +647,7 @@ def prepareWidget(widget_descr)
end

# Validate single widget
# @param [Hash{String => Object}] widget widget description map
# @param [::CWM::WidgetHash] widget widget description map
# @param [Hash] event map event that caused validation
# @param [String] key widget key for validation by function
# @return true if validation succeeded
Expand Down Expand Up @@ -697,7 +698,7 @@ def validateWidget(widget, event, key)
end

# Validate dialog contents for allow it to be saved
# @param [Array<Hash{String => Object>}] widgets list of widgets to validate
# @param [Array<::CWM::WidgetHash>] widgets list of widgets to validate
# @param [Hash] event map event that caused validation
# @return [Boolean] true if everything is OK, false if something is wrong
def validateWidgets(widgets, event)
Expand All @@ -716,8 +717,8 @@ def validateWidgets(widgets, event)

# Read widgets with listed names
# @param [Array<String>] names a list of strings/symbols names of widgets
# @param [Hash <String, Hash{String => Object>}] source a map containing the widgets
# @return [Array] of maps representing widgets
# @param [Hash <String, ::CWM::WidgetHash] source a map containing the widgets
# @return [Array<::CWM::WidgetHash>] of maps representing widgets
def CreateWidgets(names, source)
names = deep_copy(names)
source = deep_copy(source)
Expand All @@ -735,7 +736,7 @@ def CreateWidgets(names, source)
end

# Merge helps from the widgets
# @param [Array<Hash{String => Object>}] widgets a list of widget description maps
# @param [Array<::CWM::WidgetHash>] widgets a list of widget description maps
# @return [String] merged helps of the widgets
def MergeHelps(widgets)
widgets = deep_copy(widgets)
Expand All @@ -746,9 +747,9 @@ def MergeHelps(widgets)

# Prepare the dialog, replace strings in the term with appropriate
# widgets
# @param [Yast::Term] dialog term dialog containing strings
# @param [Array<Hash{String => Object>}] widgets list of widget description maps
# @return updated term ready to be used as a dialog
# @param dialog [::CWM::StringTerm] term dialog containing strings
# @param widgets [Array<::CWM::WidgetHash>] list of widget description maps
# @return [::CWM::UITerm] updated term ready to be used as a dialog
def PrepareDialog(dialog, widgets)
dialog = deep_copy(dialog)
widgets = deep_copy(widgets)
Expand Down Expand Up @@ -783,7 +784,7 @@ def handleDebug
end

# Generic function to create dialog and handle it's events
# @param [Array<Hash{String => Object>}] widgets list of widget maps
# @param [Array<::CWM::WidgetHash>] widgets list of widget maps
# @param [Hash] functions map initialize/save/handle fallbacks if not specified
# with the widgets.
# @param [Array<Object>] skip_store_for list of events for which the value of the widget will not be stored
Expand Down Expand Up @@ -923,7 +924,7 @@ def SetValidationFailedHandler(handler)
end

# Display the dialog and run its event loop using new widget API
# @param [Yast::Term] contents is UI term including instances of {CWM::AbstractWidget}
# @param [::CWM::WidgetTerm] contents is UI term including instances of {CWM::AbstractWidget}
# @param [String] caption of dialog
# @param [String] back_button label for dialog back button
# @param [String] next_button label for dialog next button
Expand Down Expand Up @@ -951,7 +952,7 @@ def show(contents, caption: nil, back_button: nil, next_button: nil, abort_butto

# Display the dialog and run its event loop
# @param [Hash<String, Object>] settings a map of all settings needed to run the dialog
# @option settings [AbstractWidget] "widgets" list of widgets used in CWM,
# @option settings [Array<CWM::AbstractWidget>] "widgets" list of widgets used in CWM,
# it is auto added to `"widget_names"` and `"widget_descr"`
def ShowAndRun(settings)
settings = deep_copy(settings)
Expand Down Expand Up @@ -997,8 +998,8 @@ def ShowAndRun(settings)
# Display the dialog and run its event loop
# @param [Array<String>] widget_names list of names of widgets that will be used in the
# dialog
# @param [Hash <String, Hash{String => Object>}] widget_descr map description map of all widgets
# @param [Yast::Term] contents term contents of the dialog, identifiers instead of
# @param [Hash{String => ::CWM::WidgetHash}] widget_descr map description map of all widgets
# @param contents [::CWM::StringTerm] contents of the dialog, identifiers instead of
# widgets
# @param [String] caption string dialog caption
# @param [String] back_button string label of the back button
Expand Down Expand Up @@ -1083,6 +1084,7 @@ def validate_current_widgets(event)
publish function: :InitNull, type: "void (string)"
publish function: :StoreNull, type: "void (string, map)"

# @return [Array<::CWM::AbstractWidget>]
def widgets_in_contents(contents)
contents.each_with_object([]) do |arg, res|
case arg
Expand All @@ -1093,6 +1095,8 @@ def widgets_in_contents(contents)
end
end

# @param [::CWM::WidgetTerm] contents
# @return [::CWM::StringTerm]
def widgets_contents(contents)
res = contents.clone

Expand Down

0 comments on commit 7b26e54

Please sign in to comment.