Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/SLE-15-SP3' into huha-merge-15…
Browse files Browse the repository at this point in the history
…-sp3-to-master
  • Loading branch information
shundhammer committed Jul 15, 2021
2 parents 6565a53 + fd561fe commit 1bf0026
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 16 deletions.
37 changes: 22 additions & 15 deletions library/wizard/src/modules/Progress.rb
Expand Up @@ -20,11 +20,6 @@
#
# ***************************************************************************
# File: modules/Progress.ycp
# Module: Progress
# Summary: Progress bar
# Authors: Petr Blahos <pblahos@suse.cz>
#
# $Id$
#
# Functions for progress bar.<br>
# <pre>
Expand Down Expand Up @@ -88,6 +83,8 @@

module Yast
class ProgressClass < Module
include Yast::Logger

def main
Yast.import "UI"

Expand Down Expand Up @@ -143,8 +140,7 @@ def IsRunning
# Check if any progress bar exists. If it does not, we're not running
# (querying progress counter is not enough, a module ran previously
# might have failed to reset the counter properly)
Ops.greater_than(@progress_running, 0) &&
UI.WidgetExists(:progress_replace_point) == true
@progress_running > 0 && UI.WidgetExists(:progress_replace_point)
end

# push the current progress into the stack
Expand Down Expand Up @@ -226,7 +222,7 @@ def PopState
pb_value = Ops.add(pb_value.nil? ? 0 : pb_value, 1)

# refresh the progress widget, add one step for the embedded progress
UI.ReplaceWidget(
try_replace_widget(
Id(:progress_replace_point),
ProgressBar(
Id(:pb),
Expand Down Expand Up @@ -384,14 +380,13 @@ def New(window_title, progress_title, length, stg, tits, help_text)
end

# set the maximum value of the progress bar
UI.ReplaceWidget(
try_replace_widget(
Id(:progress_replace_point),
ProgressBar(Id(:pb), progress_title, @progress_max, @progress_val)
)
Builtins.y2debug("New progress: %1/%2", @progress_val, @progress_max)

# increase the reference counter
@progress_running = Ops.add(@progress_running, 1)
@progress_running += 1
return
else
@progress_max = @steps
Expand Down Expand Up @@ -451,7 +446,7 @@ def New(window_title, progress_title, length, stg, tits, help_text)
end

# patch from Michal Srb https://bugzilla.novell.com/show_bug.cgi?id=406890#c7
UI.ReplaceWidget(Id(:contents), bar) if !Mode.test && UI.WidgetExists(Id(:contents))
try_replace_widget(Id(:contents), bar) unless Mode.test

if !UI.WizardCommand(term(:SetDialogHeading, window_title))
UI.ChangeWidget(Id(:title), :Value, window_title)
Expand All @@ -461,7 +456,7 @@ def New(window_title, progress_title, length, stg, tits, help_text)
Wizard.DisableBackButton
Wizard.DisableNextButton

@progress_running = Ops.add(@progress_running, 1)
@progress_running += 1

nil
end
Expand Down Expand Up @@ -547,7 +542,7 @@ def SubprogressType(type, max_value)
end

Builtins.y2debug("widget: %1", widget)
UI.ReplaceWidget(Id(:subprogress_replace_point), widget)
try_replace_widget(Id(:subprogress_replace_point), widget)

# remember the max. value
@last_subprogress_max = max_value
Expand Down Expand Up @@ -785,7 +780,7 @@ def Finish
return if !@visible || Mode.commandline

# decrease the reference counter
@progress_running = Ops.subtract(@progress_running, 1)
@progress_running -= 1

# set the previous state
if Ops.greater_than(StackSize(), 0)
Expand Down Expand Up @@ -898,6 +893,18 @@ def StepSuperior
nil
end

# Try replacing a ReplacePoint widget's content with new content, but only
# if the ReplacePoint actually exists: It might be hidden by another dialog
# that was opened on top of the current one (bsc#1187676).
def try_replace_widget(widget_id, new_content)
if UI.WidgetExists(widget_id)
UI.ReplaceWidget(widget_id, new_content)
else
log.warn("No widget with ID #{widget_id} in the current dialog")
UI.DumpWidgetTree
end
end

publish function: :IsRunning, type: "boolean ()"
publish function: :CurrentSubprogressType, type: "symbol ()"
publish function: :SubprogressTitle, type: "void (string)"
Expand Down
264 changes: 264 additions & 0 deletions library/wizard/test/manual/progress_demo.rb
@@ -0,0 +1,264 @@
#!/usr/bin/env ruby

# Copyright (c) [2021] SUSE LLC
#
# 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 SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

#---------------------------------------------------------------------------
#
# Manual demo and testing client for the Progress.rb module
#
# Start with
#
# yast2 ./progress_demo
#
# and click though the application. Use the "Next Step", "Next Stage", "Next
# Stage Step" buttons to trigger the progress update methods of the Progress
# module directly.
#
# Use "Open Popup" to open a popup like in the libzypp callbacks (you can open
# several of them) and "Close Popup" to close the toplevel layer of popups
# again. Use the "Next XZ" buttons from there to check what happens if the
# progress is updated while one of those popups is open: It shouldn't crash
# with a UI error (bsc#1187676), though it may leave the progress somewhat
# disturbed visually afterwards.
#
# Implementation details: This uses a normal UI dialog, not, as the Progress
# module expects, a wizard dialog: It would completely exchange the content of
# the wizard dialog, removing the buttons that we added for the purpose of this
# test, which would make the test unusable.

require "yast"

module Yast
class ProgressDemo < Client
include Yast::Logger

attr_accessor :progress_type

def initialize
Yast.import "UI"
Yast.import "Progress"

@popup_count = 0
@progress_type = :simple
end

def run
UI.OpenDialog(content)
add_progress
handle_events
UI.CloseDialog
end

def content
MinSize(
Id(:main_dialog),
80, 20,
MarginBox(
2, 0.45,
HBox(
HVCenter(
# This emulates the inner part of a wizard dialog
# which we can't use to avoid our buttons being removed
ReplacePoint(Id(:contents), Empty())
),
HSpacing(3),
main_buttons
)
)
)
end

def add_progress
case @progress_type
when :simple
simple_progress
when :complex, nil
complex_progress
end
end

def simple_progress
window_title = "" # unused
progress_title = "Some Progress..."
progress_len = 7
help_text = ""

Progress.Simple(
window_title,
progress_title,
progress_len,
help_text
)
end

def complex_progress
window_title = "" # unused
progress_title = "Complex Progress..."
help_text = ""

stages = ["Stage 1", "Stage 2", "Stage 3", "Stage 4"]
titles = ["Title 1", "Title 2", "Title 3", "Title 4"]
progress_len = 3 * stages.size

Progress.New(
window_title,
progress_title,
progress_len,
stages,
titles,
help_text
)
Progress.NextStage
end

def main_buttons
HSquash(
VBox(
VStretch(),
*common_buttons,
VStretch(),
PushButton(Id(:quit), Opt(:hstretch), "&Quit")
)
)
end

def common_buttons
# Opt(:hstretch) makes all buttons the same width if put in a vertical
# column (as used in the main dialog). It has no effect if they are put
# in a horizontal row (as used in the popup dialog).
opt = Opt(:hstretch)

[
PushButton(Id(:next_step), opt, "&Next Step"),
PushButton(Id(:next_stage), opt, "Next &Stage"),
PushButton(Id(:next_stage_step), opt, "Next Stage St&ep"),
PushButton(Id(:open_popup), opt, "&Open Popup")
]
end

def open_popup
@popup_count += 1
UI.OpenDialog(popup_content)
end

def popup?
UI.WidgetExists(:popup_dialog)
end

def close_popup
if popup?
UI.CloseDialog
@popup_count -= 1
else
log.warn("No popup dialog to close")
end
end

def popup_content
MarginBox(
Id(:popup_dialog),
2, 0.45,
VBox(
HVCenter(
Label("Popup dialog ##{@popup_count} that gets in the way")
),
popup_buttons
)
)
end

def popup_buttons
HBox(
HStretch(),
*common_buttons,
PushButton(Id(:close_popup), "&Close Popup"),
HStretch()
)
end

# Event handler for the main dialog as well as for any open popups
#
# rubocop:disable Style/GuardClause
def handle_events
loop do
input = UI.UserInput
log.info("Input: \"#{input}\"")

case input
when :quit
break # leave event loop
when :open_popup
open_popup
when :close_popup
close_popup
when :cancel # :cancel is WM_CLOSE
if popup?
close_popup
else
break # leave event loop
end
when :next_step
Progress.NextStep
when :next_stage
Progress.NextStage
when :next_stage_step
Progress.NextStageStep(1)
end

input
end
end
# rubocop:enable Style/GuardClause

# Open a dialog to ask the user which progress type to use and set the
# internal @progress_type member variable accordingly.
def select_progress_type
UI.OpenDialog(
MarginBox(
1, 0.45,
MinWidth(
20,
VBox(
SelectionBox(
Id(:progress_type),
"Progress &Type",
[
Item(Id(:simple), "Simple", true),
Item(Id(:complex), "Complex")
]
),
Right(PushButton("C&ontinue"))
)
)
)
)
UI.UserInput
# Query the widget as long as the dialog is still open
@progress_type = UI.QueryWidget(Id(:progress_type), :Value)
UI.CloseDialog
@progress_type
end
end
end

client = Yast::ProgressDemo.new
# Comment the next line out to avoid the initial question
client.select_progress_type
client.run
7 changes: 7 additions & 0 deletions package/yast2.changes
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Wed Jul 14 16:06:50 UTC 2021 - Stefan Hundhammer <shundhammer@suse.com>

- Don't crash with UI exception in Progress.rb if a popup is in the way
(bsc#1187676)
- 4.4.15

-------------------------------------------------------------------
Wed Jun 23 13:24:04 UTC 2021 - Ancor Gonzalez Sosa <ancor@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2
Version: 4.4.14
Version: 4.4.15
Release: 0
Summary: YaST2 Main Package
License: GPL-2.0-only
Expand Down

0 comments on commit 1bf0026

Please sign in to comment.