-
Notifications
You must be signed in to change notification settings - Fork 19
/
addon_selection_dialog.rb
226 lines (183 loc) · 6.42 KB
/
addon_selection_dialog.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
require "yast"
require "registration/addon"
require "registration/addon_sorter"
module Registration
module UI
class AddonSelectionDialog
include Yast::Logger
include Yast::I18n
include Yast::UIShortcuts
include Yast
Yast.import "Mode"
Yast.import "GetInstArgs"
Yast.import "Popup"
Yast.import "Report"
Yast.import "UI"
Yast.import "Wizard"
Yast.import "Stage"
# create a new dialog for accepting importing a SSL certificate and run it
def self.run(registration)
dialog = AddonSelectionDialog.new(registration)
dialog.run
end
def initialize(registration)
textdomain "registration"
@addons = Addon.find_all(registration)
# sort the addons
@addons.sort!(&::Registration::ADDON_SORTER)
log.info "Available addons: #{@addons}"
end
# display the extension selection dialog and wait for a button click
# @return [Symbol] user input (:import, :cancel)
def run
Wizard.SetContents(
# dialog title
_("Extension and Module Selection"),
content,
# help text (1/3)
_("<p>Here you can select available extensions and modules for your"\
"system.</p>") +
# help text (2/3)
_("<p>Please note, that some extensions or modules might need "\
"specific registration code.</p>") +
# help text (3/3)
_("<p>If you want to remove any extension or module you need to log"\
"into the SUSE Customer Center and remove them manually there.</p>"),
# always enable Back/Next, the dialog cannot be the first in workflow
true,
true
)
@old_selection = Addon.selected.dup
reactivate_dependencies
handle_dialog
end
private
def content
VBox(
VStretch(),
Left(Heading(_("Available Extensions and Modules"))),
addons_box,
Left(Label(_("Details"))),
MinHeight(8,
VWeight(25, RichText(Id(:details), Opt(:disabled), "<small>" +
_("Select an extension or a module to show details here") + "</small>")),
),
VStretch()
)
end
def addons_box
lines = Yast::UI.TextMode ? 9 : 14
if @addons.size <= lines
content = addon_selection_items(@addons)
else
box2 = addon_selection_items(@addons[lines..(2*lines - 1)])
box2.params << VStretch() # just UI tweak
content = HBox(
addon_selection_items(@addons[0..(lines - 1)]),
HSpacing(1),
box2
)
end
VWeight(75, MarginBox(2, 1, content))
end
def addon_selection_items(addons)
box = VBox()
# whether to add extra spacing in the UI
if Yast::UI.TextMode
add_extra_spacing = addons.size < 5
else
add_extra_spacing = true
end
addons.each do |addon|
box.params.concat(addon_checkbox(addon, add_extra_spacing))
end
box
end
# @return [Array] Return array with one or two elements for VBox
def addon_checkbox(addon, extra_spacing)
checkbox = Left(addon_checkbox_element(addon))
# usability help. If addon depends on something, then we get it
# immediatelly after parent, so indent it slightly, so it is easier visible
if addon.depends_on
checkbox = HBox(HSpacing(2.5), checkbox)
end
res = [checkbox]
# add extra spacing when there are just few addons, in GUI always
res << VSpacing(0.7) if extra_spacing
return res
end
def addon_checkbox_element(addon)
# checkbox label for an unavailable extension
# (%s is an extension name)
label = addon.available? ? addon.label : (_("%s (not available)") % addon.label)
CheckBox(Id(addon.identifier),
Opt(:notify),
label,
addon.selected? || addon.registered?)
end
def handle_dialog
ret = nil
continue_buttons = [:next, :back, :abort, :skip]
while !continue_buttons.include?(ret) do
ret = Yast::UI.UserInput
case ret
when :next
ret = handle_next_button
when :cancel, :abort
ret = Stage.initial && !Popup.ConfirmAbort(:painless) ? nil : :abort
# when canceled switch to old selection
Addon.selected.replace(@old_selection) if ret == :abort
else
handle_addon_selection(ret)
end
end
ret
end
def handle_next_button
if !supported_addon_count?
return nil
end
log.info "Selected addons: #{Addon.selected.map(&:name)}"
Addon.selected.empty? ? :skip : :next
end
def handle_addon_selection(id)
# check whether it's an add-on ID (checkbox clicked)
addon = @addons.find{|addon| addon.identifier == id}
return unless addon
show_addon_details(addon)
if Yast::UI.QueryWidget(Id(addon.identifier), :Value)
addon.selected
else
addon.unselected
end
reactivate_dependencies
end
# update addon details after changing the current addon in the UI
def show_addon_details(addon)
# addon description is a rich text
Yast::UI.ChangeWidget(Id(:details), :Value, addon.description)
Yast::UI.ChangeWidget(Id(:details), :Enabled, true)
end
def reactivate_dependencies
@addons.each do |addon|
Yast::UI.ChangeWidget(Id(addon.identifier), :Enabled, addon.selectable?)
end
end
# the maximum number of reg. codes displayed vertically,
# this is the limit for 80x25 textmode UI
MAX_REGCODES_PER_COLUMN = 8
# check for the maximum amount of reg. codes supported by Yast
def supported_addon_count?
need_regcode = Addon.selected.reject(&:registered?).reject(&:free)
# maximum number or reg codes which can be displayed in two column layout
max_supported = 2*MAX_REGCODES_PER_COLUMN
# check the addons requiring a reg. code
if need_regcode.size > max_supported
Report.Error(_("YaST allows to select at most %s extensions or modules.") % max_supported)
return false
end
return true
end
end
end
end