def _runSpoke(self, action): from gi.repository import Gtk # This duplicates code in widgets/src/BaseWindow.c, but we want to make sure # maximize gets called every time a spoke is displayed to prevent the 25% # UI from showing up. action.window.maximize() action.window.set_property("expand", True) action.refresh() action.window.set_beta(self.window.get_beta()) action.window.set_property("distribution", distributionText().upper()) action.window.set_transient_for(self.window) action.window.show_all() # Start a recursive main loop for this spoke, which will prevent # signals from going to the underlying (but still displayed) Hub and # prevent the user from switching away. It's up to the spoke's back # button handler to kill its own layer of main loop. Gtk.main() action.window.set_transient_for(None) action._visitedSinceApplied = True # Don't take _visitedSinceApplied into account here. It will always be # True from the line above. if action.changed and (not action.skipTo or (action.skipTo and action.applyOnSkip)): action.apply() action.execute() action._visitedSinceApplied = False
def retranslate(self): # Change the translations on labels and buttons that do not have # substitution text. for name in ["pickLanguageLabel", "betaWarnTitle", "betaWarnDesc"]: self._retranslate_one(name) # It would be nice to be able to read the translation context from the # widget, but we live in an imperfect world. # See also: https://bugzilla.gnome.org/show_bug.cgi?id=729066 for name in ["quitButton", "continueButton"]: self._retranslate_one(name, "GUI|Welcome|Beta Warn Dialog") # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") welcomeLabel.set_text( _("WELCOME TO %(name)s %(version)s.") % { "name": productName.upper(), "version": productVersion }) # Retranslate the language (filtering) entry's placeholder text languageEntry = self.builder.get_object("languageEntry") if not languageEntry in self._origStrings: self._origStrings[ languageEntry] = languageEntry.get_placeholder_text() languageEntry.set_placeholder_text(_(self._origStrings[languageEntry])) # And of course, don't forget the underlying window. self.window.set_property("distribution", distributionText().upper()) self.window.retranslate()
def retranslate(self, lang): # Change the translations on labels and buttons that do not have # substitution text. for name in ["pickLanguageLabel", "betaWarnTitle", "betaWarnDesc", "quitButton", "continueButton"]: self._retranslate_one(name) # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") if not welcomeLabel in self._origStrings: self._origStrings[welcomeLabel] = welcomeLabel.get_label() before = self._origStrings[welcomeLabel] # pylint: disable-msg=E1103 xlated = _(before) % {"name" : productName.upper(), "version" : productVersion} welcomeLabel.set_label(xlated) # Retranslate the language (filtering) entry's placeholder text languageEntry = self.builder.get_object("languageEntry") if not languageEntry in self._origStrings: self._origStrings[languageEntry] = languageEntry.get_placeholder_text() languageEntry.set_placeholder_text(_(self._origStrings[languageEntry])) # And of course, don't forget the underlying window. self.window.set_property("distribution", distributionText().upper()) self.window.retranslate(lang)
def retranslate(self): # Change the translations on labels and buttons that do not have # substitution text. for name in ["pickLanguageLabel", "betaWarnTitle", "betaWarnDesc"]: self._retranslate_one(name) # It would be nice to be able to read the translation context from the # widget, but we live in an imperfect world. # See also: https://bugzilla.gnome.org/show_bug.cgi?id=729066 for name in ["quitButton", "continueButton"]: self._retranslate_one(name, "GUI|Welcome|Beta Warn Dialog") # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") welcomeLabel.set_text( _("WELCOME TO %(name)s %(version)s.") % {"name": productName.upper(), "version": productVersion} ) # Retranslate the language (filtering) entry's placeholder text languageEntry = self.builder.get_object("languageEntry") if not languageEntry in self._origStrings: self._origStrings[languageEntry] = languageEntry.get_placeholder_text() languageEntry.set_placeholder_text(_(self._origStrings[languageEntry])) # And of course, don't forget the underlying window. self.window.set_property("distribution", distributionText().upper()) self.window.retranslate()
def retranslate(self, lang): # Change the translations on labels and buttons that do not have # substitution text. for name in ["pickLanguageLabel", "betaWarnTitle", "betaWarnDesc", "quitButton", "continueButton", "setKeyboardCheckButton"]: self._retranslate_one(name) # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") if not welcomeLabel in self._origStrings: self._origStrings[welcomeLabel] = welcomeLabel.get_label() before = self._origStrings[welcomeLabel] xlated = _(before) % (productName.upper(), productVersion) welcomeLabel.set_label(xlated) # And of course, don't forget the underlying window. #nkwin7 add by yuwan #self.window.set_property("distribution", distributionText().upper()) #self.window.set_property("distribution", distributionText().upper()) self.window.set_property("distribution", distributionText()) #nkwin7 done self.window.retranslate(lang)
def retranslate(self, lang): # Change the translations on labels and buttons that do not have # substitution text. for name in [ "pickLanguageLabel", "betaWarnTitle", "betaWarnDesc", "quitButton", "continueButton" ]: self._retranslate_one(name) # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") if not welcomeLabel in self._origStrings: self._origStrings[welcomeLabel] = welcomeLabel.get_label() before = self._origStrings[welcomeLabel] # pylint: disable-msg=E1103 xlated = _(before) % { "name": productName.upper(), "version": productVersion } welcomeLabel.set_label(xlated) # Retranslate the language (filtering) entry's placeholder text languageEntry = self.builder.get_object("languageEntry") if not languageEntry in self._origStrings: self._origStrings[ languageEntry] = languageEntry.get_placeholder_text() languageEntry.set_placeholder_text(_(self._origStrings[languageEntry])) # And of course, don't forget the underlying window. self.window.set_property("distribution", distributionText().upper()) self.window.retranslate(lang)
def retranslate(self): # Change the translations on labels and buttons that do not have # substitution text. for name in ["pickLanguageLabel", "betaWarnTitle", "betaWarnDesc"]: self._retranslate_one(name) # It would be nice to be able to read the translation context from the # widget, but we live in an imperfect world. # See also: https://bugzilla.gnome.org/show_bug.cgi?id=729066 for name in ["quitButton", "continueButton"]: self._retranslate_one(name, "GUI|Welcome|Beta Warn Dialog") # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") welcomeLabel.set_text( _("WELCOME TO %(name)s %(version)s.") % { "name": productName.upper(), "version": productVersion }) # pylint: disable=no-member # Retranslate the language (filtering) entry's placeholder text languageEntry = self.builder.get_object("languageEntry") if not languageEntry in self._origStrings: self._origStrings[ languageEntry] = languageEntry.get_placeholder_text() languageEntry.set_placeholder_text(_(self._origStrings[languageEntry])) # And of course, don't forget the underlying window. self.window.set_property("distribution", distributionText().upper()) self.window.retranslate() # Retranslate the window title text # - it looks like that the main window object is not yet # properly initialized during the first run of the # retranslate method (it is always triggered at startup) # so make sure the object is actually what we think it is # - ignoring this run is OK as the initial title is # already translated to the initial language if isinstance(self.main_window, Gtk.Window): self.main_window.set_title(_(WINDOW_TITLE_TEXT)) # Correct the language attributes for labels self.main_window.reapply_language()
def retranslate(self): # Change the translations on labels and buttons that do not have # substitution text. for name in ["pickLanguageLabel", "betaWarnTitle", "betaWarnDesc"]: self._retranslate_one(name) # It would be nice to be able to read the translation context from the # widget, but we live in an imperfect world. # See also: https://bugzilla.gnome.org/show_bug.cgi?id=729066 for name in ["quitButton", "continueButton"]: self._retranslate_one(name, "GUI|Welcome|Beta Warn Dialog") # The welcome label is special - it has text that needs to be # substituted. welcomeLabel = self.builder.get_object("welcomeLabel") welcomeLabel.set_text(_("WELCOME TO %(name)s %(version)s.") % {"name" : productName.upper(), "version" : productVersion}) # pylint: disable=no-member # Retranslate the language (filtering) entry's placeholder text languageEntry = self.builder.get_object("languageEntry") if not languageEntry in self._origStrings: self._origStrings[languageEntry] = languageEntry.get_placeholder_text() languageEntry.set_placeholder_text(_(self._origStrings[languageEntry])) # And of course, don't forget the underlying window. self.window.set_property("distribution", distributionText().upper()) self.window.retranslate() # Retranslate the window title text # - it looks like that the main window object is not yet # properly initialized during the first run of the # retranslate method (it is always triggered at startup) # so make sure the object is actually what we think it is # - ignoring this run is OK as the initial title is # already translated to the initial language if isinstance(self.main_window, Gtk.Window): self.main_window.set_title(_(WINDOW_TITLE_TEXT)) # Correct the language attributes for labels self.main_window.reapply_language()
def _createBox(self): gi.require_version("Gtk", "3.0") gi.require_version("AnacondaWidgets", "3.3") from gi.repository import Gtk, AnacondaWidgets cats_and_spokes = self._collectCategoriesAndSpokes() categories = cats_and_spokes.keys() grid = Gtk.Grid(row_spacing=6, column_spacing=6, column_homogeneous=True, margin_bottom=12) row = 0 for c in sorted(categories, key=lambda c: c.title): obj = c() selectors = [] for spokeClass in sorted(cats_and_spokes[c], key=lambda s: s.title): # Check if this spoke is to be shown in the supported environments if not any( spokeClass.should_run(environ, self.data) for environ in flags.environs): continue # Create the new spoke and populate its UI with whatever data. # From here on, this Spoke will always exist. spoke = spokeClass(self.data, self.storage, self.payload, self.instclass) spoke.window.set_beta(self.window.get_beta()) spoke.window.set_property("distribution", distributionText().upper()) # If a spoke is not showable, it is unreachable in the UI. We # might as well get rid of it. # # NOTE: Any kind of spoke can be unshowable. if not spoke.showable: del (spoke) continue # This allows being able to jump between two spokes without # having to directly involve the hub. self._spokes[spokeClass.__name__] = spoke # If a spoke is indirect, it is reachable but not directly from # a hub. This is for things like the custom partitioning spoke, # which you can only get to after going through the initial # storage configuration spoke. # # NOTE: This only makes sense for NormalSpokes. Other kinds # of spokes do not involve a hub. if spoke.indirect: spoke.initialize() continue spoke.selector = AnacondaWidgets.SpokeSelector( C_("GUI|Spoke", spoke.title), spoke.icon) # Set all selectors to insensitive before initialize runs. The call to # _updateCompleteness later will take care of setting it straight. spoke.selector.set_sensitive(False) spoke.initialize() if not spoke.ready: self._notReadySpokes.append(spoke) # Set some default values on the associated selector that # affect its display on the hub. self._updateCompleteness(spoke, update_continue=False) spoke.selector.connect("button-press-event", self._on_spoke_clicked, spoke) spoke.selector.connect("key-release-event", self._on_spoke_clicked, spoke) # If this is a kickstart install, attempt to execute any provided ksdata now. if flags.automatedInstall and spoke.ready and spoke.changed and \ spoke.visitedSinceApplied: spoke.execute() spoke.visitedSinceApplied = False selectors.append(spoke.selector) if not selectors: continue label = Gtk.Label(label="<span font-desc=\"Sans 14\">%s</span>" % escape_markup(_(obj.title)), use_markup=True, halign=Gtk.Align.START, margin_top=12, margin_bottom=12) grid.attach(label, 0, row, 2, 1) row += 1 col = 0 for selector in selectors: selector.set_margin_start(12) grid.attach(selector, col, row, 1, 1) col = int(not col) if col == 0: row += 1 # If this category contains an odd number of selectors, the above # row += 1 will not have run for the last row, which puts the next # category's title in the wrong place. if len(selectors) % 2: row += 1 # initialization of all expected spokes has been started, so notify the controller hub_controller = lifecycle.get_controller_by_name( self.__class__.__name__) if hub_controller: hub_controller.all_modules_added() else: log.error( "Initialization controller for hub %s expected but missing.", self.__class__.__name__) spokeArea = self.window.get_spoke_area() viewport = Gtk.Viewport() viewport.add(grid) spokeArea.add(viewport) self._updateContinue()
def _createBox(self): """Create and fill the list of categories and spokes.""" import gi gi.require_version("Gtk", "3.0") gi.require_version("AnacondaWidgets", "3.3") from gi.repository import Gtk, AnacondaWidgets cats_and_spokes = self._collectCategoriesAndSpokes() categories = cats_and_spokes.keys() grid = Gtk.Grid(row_spacing=18, column_spacing=18, column_homogeneous=True, margin_bottom=12, margin_left=12, margin_right=12, halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER, row_homogeneous=True) col = 0 row_in_column = [-1] * self._gridColumns for category in common.sort_categories(categories): selectors = [] for spokeClass in sorted(cats_and_spokes[category], key=lambda s: s.title): # Check if this spoke is to be shown in the supported environments if not any( spokeClass.should_run(environ, self.data) for environ in flags.environs): continue # Create the new spoke and populate its UI with whatever data. # From here on, this Spoke will always exist. spoke = spokeClass(self.data, self.storage, self.payload) spoke.window.set_beta(self.window.get_beta()) spoke.window.set_property("distribution", distributionText()) # If a spoke is not showable, it is unreachable in the UI. We # might as well get rid of it. # # NOTE: Any kind of spoke can be unshowable. if not spoke.showable: del (spoke) continue # This allows being able to jump between two spokes without # having to directly involve the hub. self._spokes[spokeClass.__name__] = spoke # If a spoke is indirect, it is reachable but not directly from # a hub. This is for things like the custom partitioning spoke, # which you can only get to after going through the initial # storage configuration spoke. # # NOTE: This only makes sense for NormalSpokes. Other kinds # of spokes do not involve a hub. if spoke.indirect: spoke.initialize() continue spoke.selector = AnacondaWidgets.SpokeSelector( C_("GUI|Spoke", spoke.title), spoke.icon) # Set all selectors to insensitive before initialize runs. The call to # _updateCompleteness later will take care of setting it straight. spoke.selector.set_sensitive(False) spoke.initialize() if not spoke.ready: self._notReadySpokes.append(spoke) # Set some default values on the associated selector that # affect its display on the hub. self._updateCompleteness(spoke, update_continue=False) spoke.selector.connect("button-press-event", self._on_spoke_clicked, spoke) spoke.selector.connect("key-release-event", self._on_spoke_clicked, spoke) selectors.append(spoke.selector) if not selectors: continue # category handling # excape unwanted markup cat_title = escape_markup(category.get_title()) # generate pango markup cat_label = '<span size="larger" weight="bold">{}</span>'.format( cat_title) # setup the category label label = Gtk.Label(label=cat_label, use_markup=True, halign=Gtk.Align.START, valign=Gtk.Align.END, margin_bottom=6, wrap=True, xalign=0.0) grid.attach(label, col, row_in_column[col], 1, 1) row_in_column[col] += 1 for selector in selectors: grid.attach(selector, col, row_in_column[col], 1, 1) row_in_column[col] += 1 col = (col + 1) % self._gridColumns # initialization of all expected spokes has been started, so notify the controller hub_controller = lifecycle.get_controller_by_name( self.__class__.__name__) if hub_controller: hub_controller.all_modules_added() else: log.error( "Initialization controller for hub %s expected but missing.", self.__class__.__name__) spokeArea = self.window.get_spoke_area() viewport = Gtk.Viewport() viewport.add(grid) spokeArea.add(viewport) self._updateContinue()
def _createBox(self): gi.require_version("Gtk", "3.0") gi.require_version("AnacondaWidgets", "3.3") from gi.repository import Gtk, AnacondaWidgets cats_and_spokes = self._collectCategoriesAndSpokes() categories = cats_and_spokes.keys() grid = Gtk.Grid(row_spacing=6, column_spacing=6, column_homogeneous=True, margin_bottom=12) row = 0 for c in sorted(categories, key=lambda c: c.title): obj = c() selectors = [] for spokeClass in sorted(cats_and_spokes[c], key=lambda s: s.title): # Check if this spoke is to be shown in the supported environments if not any(spokeClass.should_run(environ, self.data) for environ in self._environs): continue # Create the new spoke and populate its UI with whatever data. # From here on, this Spoke will always exist. spoke = spokeClass(self.data, self.storage, self.payload, self.instclass) spoke.window.set_beta(self.window.get_beta()) spoke.window.set_property("distribution", distributionText().upper()) # If a spoke is not showable, it is unreachable in the UI. We # might as well get rid of it. # # NOTE: Any kind of spoke can be unshowable. if not spoke.showable: del(spoke) continue # This allows being able to jump between two spokes without # having to directly involve the hub. self._spokes[spokeClass.__name__] = spoke # If a spoke is indirect, it is reachable but not directly from # a hub. This is for things like the custom partitioning spoke, # which you can only get to after going through the initial # storage configuration spoke. # # NOTE: This only makes sense for NormalSpokes. Other kinds # of spokes do not involve a hub. if spoke.indirect: spoke.initialize() continue spoke.selector = AnacondaWidgets.SpokeSelector(C_("GUI|Spoke", spoke.title), spoke.icon) # Set all selectors to insensitive before initialize runs. The call to # _updateCompleteness later will take care of setting it straight. spoke.selector.set_sensitive(False) spoke.initialize() if not spoke.ready: self._notReadySpokes.append(spoke) # Set some default values on the associated selector that # affect its display on the hub. self._updateCompleteness(spoke, update_continue=False) spoke.selector.connect("button-press-event", self._on_spoke_clicked, spoke) spoke.selector.connect("key-release-event", self._on_spoke_clicked, spoke) # If this is a kickstart install, attempt to execute any provided ksdata now. if flags.automatedInstall and spoke.ready and spoke.changed and \ spoke.visitedSinceApplied: spoke.execute() spoke.visitedSinceApplied = False selectors.append(spoke.selector) if not selectors: continue label = Gtk.Label(label="<span font-desc=\"Sans 14\">%s</span>" % escape_markup(_(obj.title)), use_markup=True, halign=Gtk.Align.START, margin_top=12, margin_bottom=12) grid.attach(label, 0, row, 2, 1) row += 1 col = 0 for selector in selectors: selector.set_margin_left(12) grid.attach(selector, col, row, 1, 1) col = int(not col) if col == 0: row += 1 # If this category contains an odd number of selectors, the above # row += 1 will not have run for the last row, which puts the next # category's title in the wrong place. if len(selectors) % 2: row += 1 spokeArea = self.window.get_spoke_area() viewport = Gtk.Viewport() viewport.add(grid) spokeArea.add(viewport) self._updateContinue()
def _createBox(self): from gi.repository import Gtk, AnacondaWidgets from pyanaconda.ui.gui.utils import setViewportBackground cats_and_spokes = self._collectCategoriesAndSpokes() categories = cats_and_spokes.keys() grid = Gtk.Grid() grid.set_row_spacing(6) grid.set_column_spacing(6) grid.set_column_homogeneous(True) grid.set_margin_bottom(12) row = 0 for c in sorted(categories, key=lambda c: c.title): obj = c() selectors = [] for spokeClass in sorted(cats_and_spokes[c], key=lambda s: s.title): # Check if this spoke is to be shown in the supported environments if not any(spokeClass.should_run(environ, self.data) for environ in self._environs): continue # Create the new spoke and populate its UI with whatever data. # From here on, this Spoke will always exist. spoke = spokeClass(self.data, self.storage, self.payload, self.instclass) spoke.window.set_beta(self.window.get_beta()) spoke.window.set_property("distribution", distributionText().upper()) # If a spoke is not showable, it is unreachable in the UI. We # might as well get rid of it. # # NOTE: Any kind of spoke can be unshowable. if not spoke.showable: del(spoke) continue # This allows being able to jump between two spokes without # having to directly involve the hub. self._spokes[spokeClass.__name__] = spoke # If a spoke is indirect, it is reachable but not directly from # a hub. This is for things like the custom partitioning spoke, # which you can only get to after going through the initial # storage configuration spoke. # # NOTE: This only makes sense for NormalSpokes. Other kinds # of spokes do not involve a hub. if spoke.indirect: spoke.initialize() continue # Hubs and spokes might be used outside of Anaconda # (for example in initial-setup) and individual spokes might # also have different translation domains (usually spokes # taken from Anaconda will have the "anaconda" domain and # external spokes will have their own). # Therefore we need to forward the domain of the spoke to # gettext to properly translate its title. spoke.selector = AnacondaWidgets.SpokeSelector( gettext.ldgettext(spoke.translationDomain, spoke.title), spoke.icon ) # Set all selectors to insensitive before initialize runs. The call to # _updateCompleteness later will take care of setting it straight. spoke.selector.set_sensitive(False) spoke.initialize() if not spoke.ready: self._notReadySpokes.append(spoke) # Set some default values on the associated selector that # affect its display on the hub. self._updateCompleteness(spoke) spoke.selector.connect("button-press-event", self._on_spoke_clicked, spoke) spoke.selector.connect("key-release-event", self._on_spoke_clicked, spoke) # If this is a kickstart install, attempt to execute any provided ksdata now. if flags.automatedInstall and spoke.ready and spoke.changed and \ spoke._visitedSinceApplied: spoke.execute() spoke._visitedSinceApplied = False selectors.append(spoke.selector) if not selectors: continue label = Gtk.Label("<span font-desc=\"Sans 14\">%s</span>" % escape_markup(_(obj.title))) label.set_use_markup(True) label.set_halign(Gtk.Align.START) label.set_margin_top(12) label.set_margin_bottom(12) grid.attach(label, 0, row, 2, 1) row += 1 col = 0 for selector in selectors: selector.set_margin_left(12) grid.attach(selector, col, row, 1, 1) col = int(not col) if col == 0: row += 1 # If this category contains an odd number of selectors, the above # row += 1 will not have run for the last row, which puts the next # category's title in the wrong place. if len(selectors) % 2: row += 1 spokeArea = self.window.get_spoke_area() viewport = Gtk.Viewport() viewport.add(grid) spokeArea.add(viewport) setViewportBackground(viewport)
def _createBox(self): import gi gi.require_version("Gtk", "3.0") gi.require_version("AnacondaWidgets", "3.3") from gi.repository import Gtk, AnacondaWidgets cats_and_spokes = self._collectCategoriesAndSpokes() categories = cats_and_spokes.keys() grid = Gtk.Grid(row_spacing=18, column_spacing=18, column_homogeneous=True, margin_bottom=12, margin_left=12, margin_right=12, halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER, row_homogeneous=True) max_row = category_row = 0 col = 0 for c in sorted(categories, key=lambda c: c.sortOrder): obj = c() selectors = [] for spokeClass in sorted(cats_and_spokes[c], key=lambda s: s.title): # Check if this spoke is to be shown in the supported environments if not any(spokeClass.should_run(environ, self.data) for environ in flags.environs): continue # Create the new spoke and populate its UI with whatever data. # From here on, this Spoke will always exist. spoke = spokeClass(self.data, self.storage, self.payload) spoke.window.set_beta(self.window.get_beta()) spoke.window.set_property("distribution", distributionText().upper()) # If a spoke is not showable, it is unreachable in the UI. We # might as well get rid of it. # # NOTE: Any kind of spoke can be unshowable. if not spoke.showable: del(spoke) continue # This allows being able to jump between two spokes without # having to directly involve the hub. self._spokes[spokeClass.__name__] = spoke # If a spoke is indirect, it is reachable but not directly from # a hub. This is for things like the custom partitioning spoke, # which you can only get to after going through the initial # storage configuration spoke. # # NOTE: This only makes sense for NormalSpokes. Other kinds # of spokes do not involve a hub. if spoke.indirect: spoke.initialize() continue spoke.selector = AnacondaWidgets.SpokeSelector(C_("GUI|Spoke", spoke.title), spoke.icon) # Set all selectors to insensitive before initialize runs. The call to # _updateCompleteness later will take care of setting it straight. spoke.selector.set_sensitive(False) spoke.initialize() if not spoke.ready: self._notReadySpokes.append(spoke) # Set some default values on the associated selector that # affect its display on the hub. self._updateCompleteness(spoke, update_continue=False) spoke.selector.connect("button-press-event", self._on_spoke_clicked, spoke) spoke.selector.connect("key-release-event", self._on_spoke_clicked, spoke) # If this is a kickstart install, attempt to execute any provided ksdata now. if flags.automatedInstall and spoke.ready and spoke.changed and \ spoke.visitedSinceApplied: spoke.execute() spoke.visitedSinceApplied = False selectors.append(spoke.selector) if not selectors: continue row = category_row label = Gtk.Label(label="<span size=\"larger\" weight=\"bold\">%s</span>" % escape_markup(_(obj.title)), use_markup=True, halign=Gtk.Align.START, valign=Gtk.Align.END, margin_bottom=6, wrap=True, xalign=0.0) grid.attach(label, col, category_row, 1, 1) row += 1 for selector in selectors: grid.attach(selector, col, row, 1, 1) row += 1 max_row = max(row, max_row) col = (col + 1) % self._gridColumns if col == 0: category_row = max_row # initialization of all expected spokes has been started, so notify the controller hub_controller = lifecycle.get_controller_by_name(self.__class__.__name__) if hub_controller: hub_controller.all_modules_added() else: log.error("Initialization controller for hub %s expected but missing.", self.__class__.__name__) spokeArea = self.window.get_spoke_area() viewport = Gtk.Viewport() viewport.add(grid) spokeArea.add(viewport) self._updateContinue()