From 7e4ada6370bed16d29ee13de0e55a9d7480223a5 Mon Sep 17 00:00:00 2001 From: Knut Anderssen Date: Wed, 17 Nov 2021 09:51:19 +0000 Subject: [PATCH] Added format dialogs --- src/lib/y2s390/dialogs/dasd_format.rb | 167 ++++++++++++++++++++++++ src/lib/y2s390/dialogs/format.rb | 3 + src/lib/y2s390/dialogs/format_dialog.rb | 70 ++++++++++ src/lib/y2s390/dialogs/format_disks.rb | 36 +++++ 4 files changed, 276 insertions(+) create mode 100644 src/lib/y2s390/dialogs/dasd_format.rb create mode 100644 src/lib/y2s390/dialogs/format.rb create mode 100644 src/lib/y2s390/dialogs/format_dialog.rb create mode 100644 src/lib/y2s390/dialogs/format_disks.rb diff --git a/src/lib/y2s390/dialogs/dasd_format.rb b/src/lib/y2s390/dialogs/dasd_format.rb new file mode 100644 index 00000000..41266aa1 --- /dev/null +++ b/src/lib/y2s390/dialogs/dasd_format.rb @@ -0,0 +1,167 @@ +require "yast" +require "y2s390/format_process" +require "ui/dialog" +require "ui/event_dispatcher" + +Yast.import "UI" +Yast.import "Label" + +module Y2S390 + module Dialogs + # Class for displaying progress while formatting one or several DASDs. + class DasdFormat < ::UI::Dialog + include Yast::Logger + include ::UI::EventDispatcher + attr_accessor :fmt_process + + TIMEOUT_MILLISEC = 10 + + # Constructor + # + # @param dasds [Array] list of DASDs to be formatted + def initialize(dasds) + textdomain "s390" + @dasds = dasds + @fmt_process = FormatProcess.new(dasds) + end + + def should_open_dialog? + true + end + + def dialog_content + MarginBox( + 1, # left and right margin + 0.45, # top and bottom margin; NCurses rounds this down to 0 + VBox( + Heading(_("Formatting DASDs")), + MinHeight(7, tables), + VSpacing(1), + ProgressBar(Id(:progress_bar), _("Total Progress"), 100, 0), + VSpacing(1) + ) + ) + end + + def run + fmt_process.start + sleep(0.2) + fmt_process.initialize_summary + create_dialog + loop do + break if update_progress == :break + end + close_dialog + :refresh + end + + def user_input + Yast::UI.TimeoutUserInput(1000) + end + + private + + def tables + HBox( + MinWidth( + 38, + VBox( + Left(Label(_("In Progress"))), + in_progress_table + ) + ), + HSpacing(4), + MinWidth( + 26, + VBox( + Left(Label(_("Done"))), + done_table + ) + ) + ) + end + + def in_progress_table + Table( + Id(:in_progress_table), + Header( + Right(_("Channel ID")), + "Device", + Right(_("Cyl.") + " " * 6) # reserve some space for more digits + ), + in_progress_items + ) + end + + def in_progress_items + @fmt_process.summary.values.reject(&:done?).map { |s| in_progress_item_for(s) } + end + + def id_for(dasd) + Id(dasd.device_name.to_sym) + end + + def in_progress_item_for(status) + d = status.dasd + Item(id_for(d), d.id, d.device_name, format_cyl(status.progress, status.cylinders)) + end + + def done_item_for(status) + d = status.dasd + Item(id_for(d), d.id, "/dev/#{d.device_name}") + end + + def format_cyl(current_cyl, total_cyl) + "#{current_cyl}/#{total_cyl}" + end + + def done_table + Table( + Id(:done_table), + Header(Right(_("Channel ID")), _("Device")), + done_items + ) + end + + def done_items + fmt_process.summary.values.select(&:done?).map { |s| done_item_for(s) } + end + + def update_progress + fmt_process.update_summary + sleep(0.2) + progress = fmt_process.progress + cylinders = fmt_process.cylinders + update_progress_percent(100 * progress / cylinders) if cylinders > 0 + fmt_process.updated.values.each { |s| s.done? ? refresh_tables : update_cyl_cell(s) } + + fmt_process.running? ? :continue : :break + end + + def refresh_tables + Yast::UI.ChangeWidget(Id(:in_progress_table), :Items, in_progress_items) + Yast::UI.ChangeWidget(Id(:done_table), :Items, done_items) + end + + def update_progress_percent(percent) + @progress = percent + Yast::UI.ChangeWidget(Id(:progress_bar), :Value, @progress) + end + + # Update the cylinder cell for one item of the "In Progress" table. + # + # @param item_id [Term] ID of the table item to update + # @param cyl [Integer] Current cylinder of that DASD + # @param total_cyl [Integer] Total number of cylinders of that DASD + # + def update_cyl_cell(status) + item_id = id_for(status.dasd) + cyl = status.progress + total_cyl = status.cylinders + return if cyl <= 0 || cyl > total_cyl + + Yast::UI.ChangeWidget(Id(:in_progress_table), Cell(item_id, 2), format_cyl(cyl, total_cyl)) + end + end + end +end diff --git a/src/lib/y2s390/dialogs/format.rb b/src/lib/y2s390/dialogs/format.rb new file mode 100644 index 00000000..7d6fd3d2 --- /dev/null +++ b/src/lib/y2s390/dialogs/format.rb @@ -0,0 +1,3 @@ +require "y2s390/format_process" +require "y2s390/dialogs/dasd_format" +require "y2s390/dialogs/format_disks" diff --git a/src/lib/y2s390/dialogs/format_dialog.rb b/src/lib/y2s390/dialogs/format_dialog.rb new file mode 100644 index 00000000..d2a4697c --- /dev/null +++ b/src/lib/y2s390/dialogs/format_dialog.rb @@ -0,0 +1,70 @@ +require "yast" +require "y2s390/format_process" +require "ui/dialog" +require "ui/event_dispatcher" + +Yast.import "UI" +Yast.import "Label" +Yast.import "Report" + +module Y2S390 + module Dialogs + # Class for displaying progress while formatting one or several DASDs. + class FormatDialog < ::UI::Dialog + include Yast::Logger + include ::UI::EventDispatcher + attr_accessor :fmt_process + attr_accessor :progress + attr_accessor :cylinders + attr_accessor :dasds + + abstract_method :dialog_content, :update_progress + + TIMEOUT_MILLISEC = 10 + + # Constructor + # + # @param dasds [Array] list of DASDs to be formatted + def initialize(dasds) + textdomain "s390" + @dasds = dasds + @fmt_process = FormatProcess.new(dasds) + end + + def should_open_dialog? + true + end + + def run + fmt_process.start + sleep(0.2) + return report_format_failed(fmt_process) unless fmt_process.running? + + fmt_process.initialize_summary + create_dialog + while fmt_process.running? + fmt_process.update_summary + sleep(0.2) + update_progress + end + close_dialog + return report_format_failed(fmt_process) if fmt_process.status.to_i != 0 + + :refresh + end + + def user_input + Yast::UI.TimeoutUserInput(1000) + end + + private + + def report_format_failed(process) + Yast::Report.Error(format(_("Disks formatting failed. Exit code: %s.\nError output:%s"), + process.status, process.error)) + + nil + end + end + end +end diff --git a/src/lib/y2s390/dialogs/format_disks.rb b/src/lib/y2s390/dialogs/format_disks.rb new file mode 100644 index 00000000..8a4088d6 --- /dev/null +++ b/src/lib/y2s390/dialogs/format_disks.rb @@ -0,0 +1,36 @@ +require "y2s390/dialogs/format_dialog" + +module Y2S390 + module Dialogs + class FormatDisks < FormatDialog + def dialog_content + VBox( + HSpacing(70), + *dasds_progress_bars + ) + end + + private + + def dasds_progress_bars + dasds.map.with_index { |d, i| ProgressBar(Id(i), format(_("Formatting %s:"), d), 100, 0) } + end + + def update_progress + fmt_process.updated.each do |index, status| + Yast::UI.ChangeWidget( + Id(index), + :Label, + # progress bar, %1 is device name, %2 and %3 + # integers, + # eg. Formatting /dev/dasda: cylinder 123 of 12334 done + format(_("Formatting %s: cylinder %s of %s done"), + status.dasd.id, status.progress, status.cylinders) + ) + Yast::UI.ChangeWidget(Id(index), :Value, (100 * status.progress) / status.cylinders) + Yast::UI.ChangeWidget(Id(index), :Enabled, true) + end + end + end + end +end