Example #1
0
    def showDetailedError(self, message, details, buttons=None):
        from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
        buttons = buttons or [C_("GUI|Detailed Error Dialog", "_Quit")]
        dlg = DetailedErrorDialog(None, buttons=buttons, label=message)

        with self.mainWindow.enlightbox(dlg.window):
            dlg.refresh(details)
            rc = dlg.run()
            dlg.window.destroy()
            return rc
Example #2
0
 def _storageResetHandler(self, exn):
     message = (
         _("There is a problem with your existing storage "
           "configuration: %(errortxt)s\n\n"
           "You must resolve this matter before the installation can "
           "proceed. There is a shell available for use which you "
           "can access by pressing ctrl-alt-f1 and then ctrl-b 2."
           "\n\nOnce you have resolved the issue you can retry the "
           "storage scan. If you do not fix it you will have to exit "
           "the installer.") % {
               "errortxt": exn
           })
     details = _(exn.suggestion)
     buttons = (C_("GUI|Storage Detailed Error Dialog", "_Exit Installer"),
                C_("GUI|Storage Detailed Error Dialog", "_Retry"))
     if self.ui.showDetailedError(message, details, buttons=buttons):
         return ERROR_RETRY
     else:
         return ERROR_RAISE
Example #3
0
 def prompt(self, args=None):
     """ Customize default prompt. """
     prompt = NormalTUISpoke.prompt(self, args)
     prompt.set_message(
         _("Please select the timezone. Use numbers or type names directly")
     )
     # TRANSLATORS: 'b' to go back
     prompt.add_option(C_('TUI|Spoke Navigation|Time Settings', 'b'),
                       _("back to region list"))
     return prompt
Example #4
0
    def prompt(self, args=None):
        """Return the text to be shown as prompt or handle the prompt and return None.

        :param args: optional argument passed from switch_screen calls
        :type args: anything

        :return: returns text to be shown next to the prompt for input or None
                 to skip further input processing
        :rtype: str|None
        """

        return _(u"  Please make your choice from above ['%(quit)s' to quit | '%(continue)s' to continue |\n  '%(refresh)s' to refresh]: ") % {
            # TRANSLATORS: 'q' to quit
            'quit': C_('TUI|Spoke Navigation', 'q'),
            # TRANSLATORS:'c' to continue
            'continue': C_('TUI|Spoke Navigation', 'c'),
            # TRANSLATORS:'r' to refresh
            'refresh': C_('TUI|Spoke Navigation', 'r')
        }
Example #5
0
    def prompt(self, args=None):
        incompleteSpokes = [
            spoke for spoke in self._keys.values()
            if spoke.mandatory and not spoke.completed
        ]

        # do a bit of final sanity checking, make sure pkg selection
        # size < available fs space
        if flags.automatedInstall:
            if self._checker and not self._checker.check():
                print(self._checker.error_message)
            if not incompleteSpokes:
                self.close()
                return None

        if flags.ksprompt:
            for spoke in incompleteSpokes:
                log.info("kickstart installation stopped for info: %s",
                         spoke.title)
        else:
            errtxt = _("The following mandatory spokes are not completed:") + \
                     "\n" + "\n".join(spoke.title for spoke in incompleteSpokes)
            log.error("CmdlineError: %s", errtxt)
            raise CmdlineError(errtxt)

        # if we ever need to halt the flow of a ks install to prompt users for
        # input, flip off the automatedInstall flag -- this way installation
        # does not automatically proceed once all spokes are complete, and a
        # user must confirm they want to begin installation
        flags.automatedInstall = False

        # override the default prompt since we want to offer the 'b' to begin
        # installation option here
        return _(
            "  Please make your choice from above ['%(quit)s' to quit | '%(begin)s' to begin installation |\n  '%(refresh)s' to refresh]: "
        ) % {
            # TRANSLATORS: 'q' to quit
            'quit': C_('TUI|Spoke Navigation', 'q'),
            # TRANSLATORS: 'b' to begin installation
            'begin': C_('TUI|Spoke Navigation', 'b'),
            # TRANSLATORS: 'r' to refresh
            'refresh': C_('TUI|Spoke Navigation', 'r')
        }
Example #6
0
    def on_delete_all_clicked(self, button, *args):
        if button.get_label() == C_("GUI|Reclaim Dialog", "Delete _all"):
            action = DELETE
            button.set_label(C_("GUI|Reclaim Dialog", "Preserve _all"))
        else:
            action = PRESERVE
            button.set_label(C_("GUI|Reclaim Dialog", "Delete _all"))

        itr = self._diskStore.get_iter_first()
        while itr:
            obj = PartStoreRow(*self._diskStore[itr])
            if not obj.editable:
                itr = self._diskStore.iter_next(itr)
                continue

            device = self.storage.devicetree.getDeviceByID(obj.id)
            if device.isDisk:
                self._actionChanged(itr, action)

            itr = self._diskStore.iter_next(itr)
Example #7
0
 def input(self, args, key):
     if self._container is not None and self._container.process_user_input(
             key):
         return InputState.PROCESSED
     # TRANSLATORS: 'c' to continue
     elif key.lower() == C_('TUI|Spoke Navigation', 'c'):
         self.apply()
         self.close()
         return InputState.PROCESSED
     else:
         return super(SelectISOSpoke, self).input(args, key)
Example #8
0
 def input(self, args, key):
     """ Handle user input. """
     if self._container.process_user_input(key):
         return InputState.PROCESSED
     else:
         # TRANSLATORS: 'b' to go back
         if key.lower() == C_("TUI|Spoke Navigation|Language Support", "b"):
             ScreenHandler.replace_screen(self)
             return InputState.PROCESSED
         else:
             return super(LangSpoke, self).input(args, key)
Example #9
0
    def on_info_bar_clicked(self, *args):
        if self.errors:
            label = _(
                "The following errors were encountered when checking your storage "
                "configuration.  You can modify your storage layout or quit the "
                "installer.")

            dialog = DetailedErrorDialog(self.data,
                                         buttons=[
                                             C_("GUI|Storage|Error Dialog",
                                                "_Quit"),
                                             C_("GUI|Storage|Error Dialog",
                                                "_Modify Storage Layout")
                                         ],
                                         label=label)
            with self.main_window.enlightbox(dialog.window):
                errors = "\n".join(self.errors)
                dialog.refresh(errors)
                rc = dialog.run()

            dialog.window.destroy()

            if rc == 0:
                # Quit.
                sys.exit(0)
                iutil.ipmi_report(constants.IPMI_ABORTED)
        elif self.warnings:
            label = _(
                "The following warnings were encountered when checking your storage "
                "configuration.  These are not fatal, but you may wish to make "
                "changes to your storage layout.")

            dialog = DetailedErrorDialog(self.data,
                                         buttons=[_("_OK")],
                                         label=label)
            with self.main_window.enlightbox(dialog.window):
                warnings = "\n".join(self.warnings)
                dialog.refresh(warnings)
                rc = dialog.run()

            dialog.window.destroy()
Example #10
0
    def input(self, args, key):
        """Grab the disk choice and update things"""
        self.errors = []
        if self._container.process_user_input(key):
            self.redraw()
            return InputState.PROCESSED
        else:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                if self.selected_disks:
                    # Is DASD formatting supported?
                    if DasdFormatting.is_supported():
                        # Wait for storage.
                        threadMgr.wait(THREAD_STORAGE)

                        # Get selected disks.
                        disks = getDisksByNames(self.disks, self.selected_disks)

                        # Check if some of the disks should be formatted.
                        dasd_formatting = DasdFormatting()
                        dasd_formatting.search_disks(disks)

                        if dasd_formatting.should_run():
                            # We want to apply current selection before running dasdfmt to
                            # prevent this information from being lost afterward
                            applyDiskSelection(self.storage, self.data, self.selected_disks)

                            # Run the dialog.
                            self.run_dasdfmt_dialog(dasd_formatting)
                            self.redraw()
                            return InputState.PROCESSED

                    # make sure no containers were split up by the user's disk
                    # selection
                    self.errors.extend(checkDiskSelection(self.storage,
                                                          self.selected_disks))
                    if self.errors:
                        # The disk selection has to make sense before we can
                        # proceed.
                        self.redraw()
                        return InputState.PROCESSED

                    self.apply()
                    new_spoke = PartTypeSpoke(self.data, self.storage,
                                              self.payload, self.instclass)
                    ScreenHandler.push_screen_modal(new_spoke)
                    self.apply()
                    self.execute()
                    self.close()

                return InputState.PROCESSED
            else:
                return super(StorageSpoke, self).input(args, key)
Example #11
0
    def _retranslate_one(self, widgetName, context=None):
        widget = self.builder.get_object(widgetName)
        if not widget:
            return

        if not widget in self._origStrings:
            self._origStrings[widget] = widget.get_label()

        before = self._origStrings[widget]
        if context is not None:
            widget.set_label(C_(context, before))
        else:
            widget.set_label(_(before))
Example #12
0
    def input(self, args, key):
        """ Grab the choice and update things. """
        if not self._container.process_user_input(key):
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                self.apply()
                self.close()
                return InputState.PROCESSED
            else:
                return super(PartitionSchemeSpoke, self).input(args, key)

        self.redraw()
        return InputState.PROCESSED
Example #13
0
    def input(self, args, key):
        """Grab the disk choice and update things"""
        self.errors = []
        try:
            keyid = int(key) - 1
            if keyid < 0:
                return key
            self.selection = keyid
            if len(self.disks) > 1 and keyid == len(self.disks):
                self._select_all_disks()
            else:
                self._update_disk_list(self.disks[keyid])
            return INPUT_PROCESSED
        except (ValueError, IndexError):
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                if self.selected_disks:
                    # check selected disks to see if we have any unformatted DASDs
                    # if we're on s390x, since they need to be formatted before we
                    # can use them.
                    if arch.is_s390():
                        _disks = [
                            d for d in self.disks
                            if d.name in self.selected_disks
                        ]
                        to_format = [
                            d for d in _disks if d.type == "dasd"
                            and blockdev.s390.dasd_needs_format(d.busid)
                        ]
                        if to_format:
                            self.run_dasdfmt(to_format)
                            return None

                    # make sure no containers were split up by the user's disk
                    # selection
                    self.errors.extend(
                        checkDiskSelection(self.storage, self.selected_disks))
                    if self.errors:
                        # The disk selection has to make sense before we can
                        # proceed.
                        return None

                    newspoke = AutoPartSpoke(self.app, self.data, self.storage,
                                             self.payload, self.instclass)
                    self.app.switch_screen_modal(newspoke)
                    self.apply()
                    self.execute()
                    self.close()
                return INPUT_PROCESSED
            else:
                return super(StorageSpoke, self).input(args, key)
Example #14
0
    def on_info_bar_clicked(self, *args):
        if not self._errorMsgs:
            return

        label = _(
            "The software marked for installation has the following errors.  "
            "This is likely caused by an error with your installation source.  "
            "You can quit the installer, change your software source, or change "
            "your software selections.")
        dialog = DetailedErrorDialog(
            self.data,
            buttons=[
                C_("GUI|Software Selection|Error Dialog", "_Quit"),
                C_("GUI|Software Selection|Error Dialog",
                   "_Modify Software Source"),
                C_("GUI|Software Selection|Error Dialog", "Modify _Selections")
            ],
            label=label)
        with self.main_window.enlightbox(dialog.window):
            dialog.refresh(self._errorMsgs)
            rc = dialog.run()

        dialog.window.destroy()

        if rc == 0:
            # Quit.
            iutil.ipmi_abort(scripts=self.data.scripts)
            sys.exit(0)
        elif rc == 1:
            # Send the user to the installation source spoke.
            self.skipTo = "SourceSpoke"
            self.window.emit("button-clicked")
        elif rc == 2:
            # Close the dialog so the user can change selections.
            pass
        else:
            pass
Example #15
0
    def initialize(self):
        Hub.initialize(self)

        if flags.livecdInstall:
            continueText = self.builder.get_object("rebootLabel")
            continueText.set_text(
                _("%s is now successfully installed on your system and ready "
                  "for you to use!  When you are ready, reboot your system to start using it!"
                  ))
            continueText.set_line_wrap(True)
            self.window.get_continue_button().set_label(
                C_("GUI|Progress", "_Quit"))

        self._progressBar = self.builder.get_object("progressBar")
        self._progressLabel = self.builder.get_object("progressLabel")
        self._progressNotebook = self.builder.get_object("progressNotebook")
        self._spinner = self.builder.get_object("progressSpinner")

        lbl = self.builder.get_object("configurationLabel")
        lbl.set_text(
            _("%s is now successfully installed, but some configuration still needs to be done.\n"
              "Finish it and then click the Finish configuration button please."
              ) % productName)

        lbl = self.builder.get_object("rebootLabel")
        lbl.set_text(
            _("%s is now successfully installed and ready for you to use!\n"
              "Go ahead and reboot to start using it!") % productName)

        rnotes = self._get_rnotes()
        # Get the start of the pages we're about to add to the notebook
        rnotes_start = self._progressNotebook.get_n_pages()
        if rnotes:
            # Add a new page in the notebook for each ransom note image.
            for f in rnotes:
                img = Gtk.Image.new_from_file(f)
                img.show()
                self._progressNotebook.append_page(img, None)

            # An infinite list of the page numbers containing ransom notes images.
            self._rnotesPages = itertools.cycle(
                range(rnotes_start, self._progressNotebook.get_n_pages()))
        else:
            # Add a blank page to the notebook and we'll just cycle to that
            # over and over again.
            blank = Gtk.Box()
            blank.show()
            self._progressNotebook.append_page(blank, None)
            self._rnotesPages = itertools.cycle([rnotes_start])
Example #16
0
 def input(self, args, key):
     # TRANSLATORS: 'c' to continue
     if key.lower() == C_('TUI|Spoke Navigation', 'c'):
         self.apply()
         self.close()
         return key
     try:
         num = int(key)
         # get the ISO path
         self._current_iso_path = self._isos[num - 1]
         self.apply()
         self.close()
         return True
     except (IndexError, ValueError):
         return key
Example #17
0
    def input(self, args, key):
        try:
            keyid = int(key) - 1
        except ValueError:
            if key.lower().replace("_", " ") in self._lower_zones:
                index = self._lower_zones.index(key.lower().replace("_", " "))
                self._selection = self._zones[index]
                self.apply()
                self.close()
                return INPUT_PROCESSED
            elif key.lower() in self._lower_regions:
                index = self._lower_regions.index(key.lower())
                if len(self._timezones[self._regions[index]]) == 1:
                    self._selection = "%s/%s" % (
                        self._regions[index],
                        self._timezones[self._regions[index]][0])
                    self.apply()
                    self.close()
                else:
                    self.app.switch_screen(self, self._regions[index])
                return INPUT_PROCESSED
            # TRANSLATORS: 'b' to go back
            elif key.lower() == C_('TUI|Spoke Navigation|Time Settings', 'b'):
                self.app.switch_screen(self, None)
                return INPUT_PROCESSED
            else:
                return key

        if keyid < 0:
            return key
        if args:
            if keyid >= len(self._timezones[args]):
                return key
            self._selection = "%s/%s" % (args, self._timezones[args][keyid])
            self.apply()
            self.close()
        else:
            if keyid >= len(self._regions):
                return key
            region = self._regions[keyid]
            selected_timezones = self._timezones[region]
            if len(selected_timezones) == 1:
                self._selection = "%s/%s" % (region, selected_timezones[0])
                self.apply()
                self.close()
            else:
                self.app.switch_screen(self, region)
            return INPUT_PROCESSED
Example #18
0
    def input(self, args, key):
        """Grab the disk choice and update things"""
        self.errors = []
        try:
            keyid = int(key) - 1
            self.selection = keyid
            if len(self.disks) > 1 and keyid == len(self.disks):
                self._select_all_disks()
            else:
                self._update_disk_list(self.disks[keyid])
            return INPUT_PROCESSED
        except (ValueError, IndexError):
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                if self.selected_disks:
                    # check selected disks to see if we have any unformatted or
                    # LDL DASDs if we're on s390x, since they need to be
                    # formatted before we can use them.
                    if arch.isS390():
                        unformatted = make_unformatted_dasd_list(
                            self.selected_disks)
                        ldl = [
                            d for d in self.selected_disks if is_ldl_dasd(d)
                        ]
                        # combine into one nice list
                        dasds = list(set(unformatted + ldl))
                        if dasds:
                            self.run_dasdfmt(dasds)
                            return None

                    # make sure no containers were split up by the user's disk
                    # selection
                    self.errors.extend(
                        checkDiskSelection(self.storage, self.selected_disks))
                    if self.errors:
                        # The disk selection has to make sense before we can
                        # proceed.
                        return None

                    newspoke = AutoPartSpoke(self.app, self.data, self.storage,
                                             self.payload, self.instclass)
                    self.app.switch_screen_modal(newspoke)
                    self.apply()
                    self.execute()
                    self.close()
                return INPUT_PROCESSED
            else:
                return key
Example #19
0
    def input(self, args, key):
        """Grab the disk choice and update things"""
        self.errors = []
        if self._container.process_user_input(key):
            self.redraw()
            return InputState.PROCESSED
        else:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                if self.selected_disks:
                    # check selected disks to see if we have any unformatted DASDs
                    # if we're on s390x, since they need to be formatted before we
                    # can use them.
                    if arch.is_s390():
                        _disks = [
                            d for d in self.disks
                            if d.name in self.selected_disks
                        ]
                        to_format = [
                            d for d in _disks if d.type == "dasd"
                            and blockdev.s390.dasd_needs_format(d.busid)
                        ]
                        if to_format:
                            self.run_dasdfmt(to_format)
                            self.redraw()
                            return InputState.PROCESSED

                    # make sure no containers were split up by the user's disk
                    # selection
                    self.errors.extend(
                        checkDiskSelection(self.storage, self.selected_disks))
                    if self.errors:
                        # The disk selection has to make sense before we can
                        # proceed.
                        self.redraw()
                        return InputState.PROCESSED

                    self.apply()
                    new_spoke = PartTypeSpoke(self.data, self.storage,
                                              self.payload, self.instclass)
                    ScreenHandler.push_screen_modal(new_spoke)
                    self.apply()
                    self.execute()
                    self.close()

                return InputState.PROCESSED
            else:
                return super(StorageSpoke, self).input(args, key)
Example #20
0
    def input(self, args, key):
        """Move along home."""
        try:
            keyid = int(key) - 1
        except ValueError:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                self.apply()
                self.close()
                return INPUT_PROCESSED
            else:
                return key

        if 0 <= keyid < len(self._roots):
            self._selection = keyid
        return INPUT_PROCESSED
Example #21
0
    def input(self, args, key):
        """Grab the choice and update things"""
        if not self._container.process_user_input(key):
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                new_spoke = PartitionSchemeSpoke(self.data, self.storage,
                                                 self.payload, self.instclass)
                ScreenHandler.push_screen_modal(new_spoke)
                self.apply()
                self.close()
                return InputState.PROCESSED
            else:
                return super(AutoPartSpoke, self).input(args, key)

        self.redraw()
        return InputState.PROCESSED
Example #22
0
    def input(self, args, key):
        """ Handle the input; this chooses the desktop environment. """
        try:
            keyid = int(key) - 1
        except ValueError:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_("TUI|Spoke Navigation", "c") and \
                    0 <= self._selection < len(self.payload.environments):
                self.apply()
                self.close()
                return INPUT_PROCESSED
            else:
                return key

        if 0 <= keyid < len(self.payload.environments):
            self._selection = keyid
        return INPUT_PROCESSED
Example #23
0
    def input(self, args, key):
        """ Grab the choice and update things. """

        try:
            keyid = int(key) - 1
        except ValueError:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                self.apply()
                self.close()
                return INPUT_PROCESSED
            else:
                return super(PartitionSchemeSpoke, self).input(args, key)

        if 0 <= keyid < len(self.partschemes):
            self._selection = keyid
        return INPUT_PROCESSED
Example #24
0
    def input(self, args, key):
        """ Handle the input; this chooses the desktop environment. """
        try:
            keyid = int(key) - 1
        except ValueError:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):

                # No environment was selected, close
                if self._selection is None:
                    self.close()

                # The environment was selected, switch screen
                elif args is None:
                    # Get addons for the selected environment
                    environment = self._get_environment(self._selection)
                    environment_id = self._get_environment_id(environment)
                    addons = self._get_available_addons(environment_id)

                    # Switch the screen
                    self.app.switch_screen(self, addons)

                # The addons were selected, apply and close
                else:
                    self.apply()
                    self.close()

                return INPUT_PROCESSED
            else:
                return super(SoftwareSpoke, self).input(args, key)

        # Process the environment selection
        if args is None:
            if 0 <= keyid < len(self.payload.environments):
                self._selection = keyid

        # Process the addons selection
        else:
            if 0 <= keyid < len(args):
                addon = args[keyid]
                if addon not in self._addons_selection:
                    self._addons_selection.add(addon)
                else:
                    self._addons_selection.remove(addon)

        return INPUT_PROCESSED
Example #25
0
 def input(self, args, key):
     """Override input so that we can launch the VNC password spoke"""
     if self._container.process_user_input(key):
         self.apply()
         self.close()
         return InputState.PROCESSED
     else:
         # TRANSLATORS: 'q' to quit
         if key.lower() == C_('TUI|Spoke Navigation', 'q'):
             d = YesNoDialog(_(u"Do you really want to quit?"))
             ScreenHandler.push_screen_modal(d)
             if d.answer:
                 ipmi_abort(scripts=self.data.scripts)
                 if can_touch_runtime_system("Quit and Reboot"):
                     execWithRedirect("systemctl", ["--no-wall", "reboot"])
                 else:
                     sys.exit(1)
         else:
             return super(AskVNCSpoke, self).input(args, key)
Example #26
0
    def input(self, args, key):
        """Handle user input. Numbers are used to show a spoke, the rest is passed
        to the higher level for processing."""

        try:
            number = int(key)
            self.app.switch_screen_with_return(self._keys[number])
            return None

        except (ValueError, KeyError):
            # If we get a continue, check for unfinished spokes.  If unfinished
            # don't continue
            # TRANSLATORS: 'c' to continue
            if key == C_('TUI|Spoke Navigation', 'c'):
                for spoke in self._spokes.values():
                    if not spoke.completed and spoke.mandatory:
                        print(_("Please complete all spokes before continuing"))
                        return False
            return key
Example #27
0
    def input(self, args, key):
        """ Handle user input. """
        try:
            keyid = int(key) - 1
            if args:
                self._selected = args[keyid]
                self.apply()
                self.close()
            else:
                self.app.switch_screen(self, self._locales[self._langs_and_locales[self._langs[keyid]]])
            return True
        except (ValueError, IndexError):
            pass

        # TRANSLATORS: 'b' to go back
        if key.lower() == C_('TUI|Spoke Navigation|Language Support', 'b'):
            self.app.switch_screen(self, None)
            return True
        else:
            return key
Example #28
0
    def input(self, args, key):
        """Grab the choice and update things"""

        try:
            keyid = int(key) - 1
        except ValueError:
            # TRANSLATORS: 'c' to continue
            if key.lower() == C_('TUI|Spoke Navigation', 'c'):
                newspoke = PartitionSchemeSpoke(self.app, self.data, self.storage,
                                                self.payload, self.instclass)
                self.app.switch_screen_modal(newspoke)
                self.apply()
                self.close()
                return INPUT_PROCESSED
            else:
                return super(AutoPartSpoke, self).input(args, key)

        if 0 <= keyid < len(self.parttypelist):
            self.clearPartType = PARTTYPES[self.parttypelist[keyid]]
            self.apply()
        return INPUT_PROCESSED
Example #29
0
    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()
Example #30
0
 def prompt(self, args=None):
     prompt = super(MountPointAssignSpoke, self).prompt(args)
     # TRANSLATORS: 's' to rescan devices
     prompt.add_option(C_('TUI|Spoke Navigation|Partitioning', 's'),
                       _("rescan devices"))
     return prompt