Skip to content

Commit

Permalink
WIP: add master-detail widget, dialog and controller
Browse files Browse the repository at this point in the history
  • Loading branch information
dgdavid committed Feb 20, 2020
1 parent 5b863fb commit 8b406ee
Show file tree
Hide file tree
Showing 6 changed files with 560 additions and 0 deletions.
146 changes: 146 additions & 0 deletions src/lib/registration/controllers/addons_selection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Copyright (c) [2020] 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.

require "yast"
require "registration/addon"
require "registration/addon_sorter"

module Registration
module Controllers
class AddonsSelection
include Yast::I18n

# @return [Array<Addon>] List of previous selected addons
attr_reader :previous_selected_addons

# Constructor
def initialize(registration)
textdomain "registration"

@registartion = registration
@addons = Addon.find_all(registration).sort(&::Registration::ADDON_SORTER)
@previous_selected_addons = Addon.selected.dup

preselect_recommended
end

def items
# FIXME
@items || @addons
end

def selected_items
selected_addons = Addon.selected

log.info "Selected addons: #{selected_addons.map(&:name)}"

selected_addons
end

def restore_selection
Addon.selected.replace(previous_selected_addons)
end

def find(id)
@addons.find { |addon| addon.id.to_s == id }
end

def toggle_selection_for(addon)
return unless addon

addon.toggle_selected
end

def details_for(addon)
return unless addon

addon.description
end

def details_placeholder
_("Select an extension or a module to show details here")
end

def include_heading?
true
end

def heading
_("Available Extensions and Modules")
end

def include_filter?
development_addons = @addons.reject { |addon| addon.registered? || addon.released? }

!development_addons.empty?
end

def filter(enabled)
@items = enabled ? filtered_addons : @addons
end

def filter_label
_("&Hide Development Versions")
end

# FIXME: still relevant?

# the maximum number of reg. codes displayed vertically,
# this is the limit for 80x25 textmode UI
MAX_REGCODES_PER_COLUMN = 8

# check the number of required reg. codes
# @return [Boolean] true if the number of the required reg. codes fits
# the maximum limit
def supported_addon_count?
# maximum number or reg codes which can be displayed in two column layout
max_supported = 2 * MAX_REGCODES_PER_COLUMN

# check if the count of addons requiring a reg. code fits two columns
if Addon.selected.count { |a| a.registered? && a.free } > max_supported
Report.Error(_("YaST allows to select at most %s extensions or modules.") % max_supported)
return false
end

true
end

private

attr_reader :registration

def filtered_addons
@addons.select do |addon|
addon.registered? || addon.selected? || addon.auto_selected? || addon.released?
end
end

def preselect_recommended
# something is already selected/registered, keep the user selection unchanged
return if !Addon.selected.empty? || !Addon.registered.empty?

@addons.each do |a|
next unless a.recommended
log.info("Preselecting a default addon: #{a.friendly_name}")
a.selected
end
end
end
end
end
110 changes: 110 additions & 0 deletions src/lib/registration/dialogs/addons_selection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright (c) [2020] 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.

require "yast"
require "cwm/dialog"
require "registration/ui/abort_confirmation"
require "registration/widgets/master_detail_selector"
require "registration/controllers/addons_selection"

module Registration
module Dialogs
class AddonsSelection < CWM::Dialog
Yast.import "Stage"

attr_reader :registration

# Constructor
def initialize(registration)
textdomain "registration"

@registration = registration

super()
end

# @macro seeAbstractWidget
def title
_("Extension and Module Selection")
end

# @macro seeAbstractWidget
def contents
addons_selector_widget
end

# @macro seeAbstractWidget
def run
ret = nil

until continue_actions.include?(ret)
ret = super
end

case ret
when :next
ret = handle_next_action
when :cancel, :abort
ret = handle_cancel_action
end

ret
end

def handle_cancel_action
return nil if Yast::Stage.initial && !UI::AbortConfirmation.run

controller.restore_selection
:abort
end

def handle_next_action
return nil unless controller.supported_addon_count?

controller.selected_items.empty? ? :skip : :next
end

def continue_actions
@continue_actions ||= [:next, :back, :cancel, :abort, :skip]
end

# @macro seeDialog
def help
# TODO
_("<p>Here you can select available extensions and modules for your system.</p>")
end

private

# Addons selector widget
#
# @return [Registration::Widgets::MasterDetailSelector]
def addons_selector_widget
@addons_selector_widget ||= ::Registration::Widgets::MasterDetailSelector.new(controller)
end

# Addons selection controller
#
# @return [Registration::Controllers::AddonsSelection]
def controller
@controller ||= ::Registration::Controllers::AddonsSelection.new(registration)
end
end
end
end
108 changes: 108 additions & 0 deletions src/lib/registration/widgets/checkbox_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright (c) [2020] 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.

require "yast"

module Registration
module Widgets
class CheckboxItem
IMAGES = {
"inst:[a]:enabled" => "auto-selected.svg",
"inst:[x]:enabled" => "inst_checkbox-on.svg",
"inst:[ ]:enabled" => "inst_checkbox-off.svg",
"inst:[x]disabled" => "inst_checkbox-on-disabled.svg",
"inst:[ ]:disabled" => "inst_checkbox-off-disabled.svg",
"normal:[a]:enabled" => "auto-selected.svg",
"normal:[x]:enabled" => "checkbox-on.svg",
"normal:[ ]:enabled" => "checkbox-off.svg",
# NOTE: Normal theme has no special images for disabled checkboxes
"normal:[x]:disabled" => "checkbox-on.svg",
"normal:[ ]:disabled" => "checkbox-off.svg",
}.freeze
private_constant :IMAGES

IMAGES_DIR = "/usr/share/YaST2/theme/current/wizard".freeze
private_constant :IMAGES_DIR

def initialize(id, text, status)
@id = id
@text = text
@status = status
end

def content
"#{checkbox} #{label}"
end

private

attr_reader :id, :text, :status

def checkbox
"<a href=\"#{id}#checkbox#input\" style=\"text-decoration: none; color: #{color}\">#{icon}</a>"
end

def label
styles = "text-decoration: none; color: #{color}"

"<a href=\"#{id}#checkbox#label\" style=\"#{styles}\">#{text}</a>"
end

def icon
if Yast::UI.TextMode
value
else
image_key = [mode, value, "enabled"].join(':')

"<img src=\"#{IMAGES_DIR}/#{IMAGES[image_key]}\">"
end
end

def value
case status
when :selected, :registered
'[x]'
when :auto_selected
'[a]'
else
'[ ]'
end
end

def mode
installation? ? "inst" : "normal"
end

def color
# TODO: fix this
!installation? ? "white" : "black"
end

# Determines whether running in installation mode
#
# We do not use Stage.initial because of firstboot, which runs in 'installation' mode
# but in 'firstboot' stage.
#
# @return [Boolean] Boolean if running in installation or update mode
def installation?
Yast::Mode.installation || Yast::Mode.update
end
end
end
end

0 comments on commit 8b406ee

Please sign in to comment.