Skip to content

Commit

Permalink
Merge pull request #532 from yast/all-in-one-overview
Browse files Browse the repository at this point in the history
All in one overview
  • Loading branch information
jreidinger committed Jan 19, 2017
2 parents f23b545 + b4b4887 commit 431e080
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 7 deletions.
65 changes: 65 additions & 0 deletions library/cwm/examples/replace_point_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Simple example to demonstrate object oriented replace_point widget

require_relative "example_helper"

require "yast"

require "cwm/widget"

Yast.import "UI"
Yast.import "CWM"
Yast.import "Wizard"

class SwitchWidget < CWM::PushButton
def initialize(replace_point, widgets)
@replace_point = replace_point
@widgets = widgets
end

def label
"Switch"
end

def handle
@widgets.rotate!
@replace_point.replace(@widgets.first)
end
end

class PopupButtonWidget < CWM::PushButton
def label
"Popup"
end

def handle
Yast::Popup.Message("Click!")
end
end

class StoreWidget < CWM::InputField
def label
"write here"
end

def validate
return true unless value.empty?

Yast::Popup.Error("Empty value!")
false
end

def store
Yast::Popup.Message(value)
end
end

widgets = [PopupButtonWidget.new, CWM::Empty.new(:empty), StoreWidget.new]
replace_point = CWM::ReplacePoint.new(widget: widgets.first)

content = Yast::Term.new(:VBox,
SwitchWidget.new(replace_point, widgets),
replace_point)

Yast::Wizard.CreateDialog
Yast::CWM.show(content)
Yast::Wizard.CloseDialog
72 changes: 72 additions & 0 deletions library/cwm/src/lib/cwm/widget.rb
Original file line number Diff line number Diff line change
Expand Up @@ -821,4 +821,76 @@ def replace_point
ReplacePoint(Id(replace_point_id), VBox(VStretch(), HStretch()))
end
end

# Placeholder widget that is used to replace content on demand.
# The most important method is {#replace} which allows switching content
class ReplacePoint < CustomWidget
# @param id [Object] id of widget. Needed to redefine only if more than one
# placeholder needed to be in dialog. Parameter type is limited by component
# system
# @param widget [CWM::AbstractWidget] initial widget in placeholder
def initialize(id: :_placeholder, widget: Empty.new(:_initial_placeholder))
self.handle_all_events = true
self.widget_id = id
@widget = widget
end

def contents
ReplacePoint(Id(widget_id), widget_content(@widget))
end

def init
@widget.init if @widget.respond_to?(:init)
end

# Replaces content with different widget. All its events are properly
# handled.
# @param widget [CWM::AbstractWidget] widget to display and process events
def replace(widget)
log.info "replacing with new widget #{widget.inspect}"
Yast::UI.ReplaceWidget(@id, widget_content(widget))
@widget = widget
init
end

def help
@widget.respond_to?(:help) ? @widget.help : ""
end

def handle(event)
return unless @widget.respond_to?(:handle)

if !@widget.handle_all_events
return if event["ID"] != @widget.widget_id
end

m = @widget.method(:handle)
if m.arity == 0
m.call
else
m.call(event)
end
end

def validate
@widget.respond_to?(:validate) ? @widget.validate : true
end

def store
@widget.store if @widget.respond_to?(:store)
end

def cleanup
@widget.cleanup if @widget.respond_to?(:cleanup)
end

private

def widget_content(widget)
definition = widget.cwm_definition
definition["_cwm_key"] = widget.widget_id # a bit hacky way to pass widget id
definition = Yast::CWM.prepareWidget(definition)
definition["widget"]
end
end
end
15 changes: 9 additions & 6 deletions library/cwm/src/modules/CWM.rb
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,8 @@ def handleDebug
# @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
# Useful mainly for non-standard redraw of widgets, like :reset or :redraw
# Useful mainly for non-standard redraw of widgets, like :reset or :redraw. It will skip also
# validation, because it is not needed as nothing is stored.
# @return [Symbol] wizard sequencer symbol
def Run(widgets, functions, skip_store_for: [])
widgets = deep_copy(widgets)
Expand Down Expand Up @@ -855,11 +856,12 @@ def Run(widgets, functions, skip_store_for: [])

next if ret.nil?

ret = nil if save && !validateWidgets(widgets, event_descr)

if ret.nil?
# ok, so what happens here? event want to save widgets, so check that there is no explicit
# skip of storing for this event and there is a widget containing invalid value.
# In such case do not save and clear ret, so we are still in loop
if save && !skip_store_for.include?(ret) && !validateWidgets(widgets, event_descr)
ret = nil
save = false
next
end
end
saveWidgets(widgets, event_descr) if save && !skip_store_for.include?(ret)
Expand Down Expand Up @@ -928,7 +930,8 @@ def SetValidationFailedHandler(handler)
# @param [String] abort_button label for dialog abort button
# @param [Array] skip_store_for list of events for which the value of the widget will not be stored.
# Useful mainly when some widget returns an event that should not trigger the storing,
# like a reset button or a redrawing
# like a reset button or a redrawing. It will skip also validation, because it is not needed
# as nothing is stored.
# @return [Symbol] wizard sequencer symbol
def show(contents, caption: nil, back_button: nil, next_button: nil, abort_button: nil, skip_store_for: [])
widgets = widgets_in_contents(contents)
Expand Down
128 changes: 128 additions & 0 deletions library/cwm/test/widgets_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,131 @@ def contents
end
end
end

describe CWM::ReplacePoint do

class ReplacePointTestWidget < CWM::InputField
def label
"test"
end

def init
end

def handle
end

def help
"help"
end

def validate
false
end

def store
end

def cleanup
end
end

describe ".new" do
it "has widget_id as passed" do
subject = described_class.new(id: "test")
expect(subject.widget_id).to eq "test"
end

it "uses passed widget as initial content" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(widget).to receive(:init)
subject.init
end
end

describe "#contents" do
it "generates contents including current widget UI definition" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)

expect(subject.contents).to eq(
ReplacePoint(
Id(subject.widget_id),
InputField(Id(widget.widget_id), Opt(:hstretch), "test")
)
)
end
end

describe "#init" do
it "passes init to enclosed widget" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(widget).to receive(:init)
subject.init
end
end

describe "#replace" do
it "changes enclosed widget" do
subject = described_class.new(widget: CWM::Empty.new(:initial))
widget = ReplacePointTestWidget.new
expect(widget).to receive(:store)
subject.replace(widget)
subject.store
end
end

describe "#help" do
it "returns help of enclosed widget" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(subject.help).to eq "help"
end
end

class ComplexHandleTest < CWM::Empty
def handle(_event)
nil
end
end

describe "#handle" do
# Cannot test arity based dispatcher, because if we mock expect call of widget.handle, it is
# replaced by rspec method with -1 arity, causing wrong dispatcher functionality

it "do nothing if passed event is not widget_id and enclosed widget do not handle all events" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(widget).to_not receive(:handle)
subject.handle("ID" => "Not mine")
end
end

describe "#validate" do
it "passes validate to enclosed widget" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(subject.validate).to eq false
end
end

describe "#store" do
it "passes store to enclosed widget" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(widget).to receive(:store)
subject.store
end
end

describe "#cleanup" do
it "passes cleanup to enclosed widget" do
widget = ReplacePointTestWidget.new
subject = described_class.new(widget: widget)
expect(widget).to receive(:cleanup)
subject.cleanup
end
end
end
13 changes: 13 additions & 0 deletions package/yast2.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
-------------------------------------------------------------------
Thu Jan 19 13:49:10 UTC 2017 - jreidinger@suse.com

- Added a CWM::ReplacePoint widget
- 3.1.210.4

-------------------------------------------------------------------
Wed Jan 18 13:56:27 UTC 2017 - jreidinger@suse.com

- CWM: when skipping storing of widget values, skip also its
validation (FATE#322328)
- 3.1.210.3

-------------------------------------------------------------------
Tue Dec 20 16:28:45 UTC 2016 - igonzalezsosa@suse.com

Expand Down
2 changes: 1 addition & 1 deletion package/yast2.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2
Version: 3.1.210.2
Version: 3.1.210.4
Release: 0
Summary: YaST2 - Main Package
License: GPL-2.0
Expand Down

0 comments on commit 431e080

Please sign in to comment.