Exemplo n.º 1
0
    def messageWindow(self, title, text, ty="ok", default=None,
                      custom_icon=None, custom_buttons=None):
        if custom_buttons is None:
            custom_buttons = []

        if ty == "ok":
            ButtonChoiceWindow(self.screen, title, text, buttons=[TEXT_OK_BUTTON])
        elif ty == "yesno":
            if default and default == "no":
                btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
            else:
                btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
            rc = ButtonChoiceWindow(self.screen, title, text, buttons=btnlist)
            if rc == "yes":
                return 1
            else:
                return 0
        elif ty == "custom":
            tmpbut = []
            for but in custom_buttons:
                tmpbut.append(but.replace("_", ""))

            rc = ButtonChoiceWindow(self.screen, title, text, width=60, buttons=tmpbut)

            idx = 0
            for b in tmpbut:
                if b.lower() == rc:
                    return idx
                idx += 1
            return 0
        else:
            return OkCancelWindow(self.screen, title, text)
Exemplo n.º 2
0
 def action(self):
     self.ncs.screen.setColor("BUTTON", "black", "red")
     self.ncs.screen.setColor("ACTBUTTON", "blue", "white")
     if self.root_password_1.value() != "" and self.root_password_2.value(
     ) != "" and self.root_password_1.value() == self.root_password_2.value(
     ):
         set_password(self.root_password_1.value(), "root")
         augtool("set", "/files/etc/ssh/sshd_config/PasswordAuthentication",
                 "yes")
         dn = file('/dev/null', 'w+')
         subprocess.Popen(['/sbin/service', 'sshd', 'restart'],
                          stdout=dn,
                          stderr=dn)
     if len(self.rhevm_server.value()) > 0:
         deployUtil.nodeCleanup()
         if self.verify_rhevm_cert.selected():
             if deployUtil.getRhevmCert(self.rhevm_server.value(),
                                        self.rhevm_server_port.value()):
                 path, dontCare = deployUtil.certPaths('')
                 fp = deployUtil.generateFingerPrint(path)
                 approval = ButtonChoiceWindow(
                     self.ncs.screen,
                     "Certificate Fingerprint:",
                     fp,
                     buttons=['Approve', 'Reject'])
                 if 'reject' == approval:
                     ButtonChoiceWindow(self.ncs.screen,
                                        "Fingerprint rejected",
                                        "RHEV-M Configuration Failed",
                                        buttons=['Ok'])
                     return False
                 else:
                     ovirt_store_config(path)
                     self.ncs.reset_screen_colors()
             else:
                 ButtonChoiceWindow(self.ncs.screen,
                                    "RHEV-M Configuration",
                                    "Failed downloading RHEV-M certificate",
                                    buttons=['Ok'])
                 self.ncs.reset_screen_colors()
         # Stopping vdsm-reg may fail but its ok - its in the case when the menus are run after installation
         deployUtil._logExec([constants.EXT_SERVICE, 'vdsm-reg', 'stop'])
         if write_vdsm_config(self.rhevm_server.value(),
                              self.rhevm_server_port.value()):
             deployUtil._logExec(
                 [constants.EXT_SERVICE, 'vdsm-reg', 'start'])
             ButtonChoiceWindow(self.ncs.screen,
                                "RHEV-M Configuration",
                                "RHEV-M Configuration Successfully Updated",
                                buttons=['Ok'])
             self.ncs.reset_screen_colors()
             return True
         else:
             ButtonChoiceWindow(self.ncs.screen,
                                "RHEV-M Configuration",
                                "RHEV-M Configuration Failed",
                                buttons=['Ok'])
             self.ncs.reset_screen_colors()
             return False
 def _run_create(self):
     from snack import ListboxChoiceWindow, ButtonChoiceWindow, EntryWindow
     templatetypes = self.controller.getCompleteConfigTemplateSetNames()
     if len(templatetypes) != 0:
         _res = ListboxChoiceWindow(self.screen,
                                    "Configuration Types",
                                    "Select type of new configuration set",
                                    templatetypes,
                                    buttons=('Create', 'Cancel'),
                                    width=40,
                                    scroll=1,
                                    height=-1,
                                    default=None,
                                    help=None)
     else:
         _res = [
             ButtonChoiceWindow(
                 self.screen,
                 "Error",
                 "No valid configurationset templates defined",
                 buttons=['Cancel'])
         ]
     if _res[0] != "create": return
     type = templatetypes[_res[1]]
     _res = EntryWindow(self.screen,
                        "New Configuration",
                        "Name of the new configuration set", ['Name'],
                        allowCancel=1,
                        width=40,
                        entryWidth=20,
                        buttons=['Ok', 'Cancel'],
                        help=None)
     if _res[0] != "ok": return
     name = _res[1][0]
     self.controller.createConfigSet(name, type)
Exemplo n.º 4
0
def check_memory(opts, display_mode=None):

    if not display_mode:
        display_mode = opts.display_mode

    reason = ''
    needed_ram = isys.MIN_RAM
    if not within_available_memory(needed_ram):
        from snack import SnackScreen, ButtonChoiceWindow
        screen = SnackScreen()
        ButtonChoiceWindow(screen,
                           _('Fatal Error'),
                           _('You do not have enough RAM to install %s '
                             'on this machine%s.\n'
                             '\n'
                             'Press <return> to reboot your system.\n') %
                           (product.productName, reason),
                           buttons=(_("OK"), ))
        screen.finish()
        sys.exit(0)

    # override display mode if machine cannot nicely run X
    if display_mode not in ('t', 'c') and not flags.usevnc:
        needed_ram = isys.MIN_GUI_RAM

        if not within_available_memory(needed_ram):
            stdoutLog.warning(
                _("You do not have enough RAM to use the graphical "
                  "installer.  Starting text mode."))
            opts.display_mode = 't'
            time.sleep(2)
Exemplo n.º 5
0
def display_selection(screen,
                      title,
                      list_of_items,
                      subtitle,
                      default=None,
                      buttons=[('Back', 'back', 'F12'), 'Ok']):
    """Display a list of items, return selected one or None, if nothing was selected"""
    #if len(list_of_items) == 1:
    # shortcut if there's only one item for choosing
    #    return list_of_items[0]

    if len(list_of_items) > 0:
        if not isinstance(list_of_items[0], types.TupleType):
            # if we have a list of strings, we'd prefer to get these strings as the selection result
            list_of_items = zip(list_of_items, list_of_items)
        height = 10
        scroll = 1 if len(list_of_items) > height else 0
        action, selection = ListboxChoiceWindow(screen,
                                                title,
                                                subtitle,
                                                list_of_items,
                                                buttons,
                                                scroll=scroll,
                                                height=height,
                                                default=default)
        if buttons == [('Back', 'back', 'F12'), 'Ok'
                       ] or buttons == [('Menu', 'back', 'F12'), 'Ok']:
            if action != 'back':
                return selection
        else:
            return (action, selection)  # customized buttons
    else:
        ButtonChoiceWindow(screen, title,
                           'Sorry, there are no items to choose from.',
                           ['Back'])
Exemplo n.º 6
0
 def valid_rhevm_server_port_callback(self):
     if not is_valid_port(self.rhevm_server_port.value()):
         self.ncs.screen.setColor("BUTTON", "black", "red")
         self.ncs.screen.setColor("ACTBUTTON", "blue", "white")
         ButtonChoiceWindow(self.ncs.screen,
                            "Configuration Check",
                            "Invalid RHEV-M Server Port",
                            buttons=['Ok'])
         self.ncs.reset_screen_colors()
Exemplo n.º 7
0
 def valid_rhevm_server_callback(self):
     if not is_valid_host_or_ip(self.rhevm_server.value()):
         self.ncs.screen.setColor("BUTTON", "black", "red")
         self.ncs.screen.setColor("ACTBUTTON", "blue", "white")
         ButtonChoiceWindow(self.ncs.screen,
                            "Configuration Check",
                            "Invalid RHEV-M Hostname or Address",
                            buttons=['Ok'])
         self.ncs.reset_screen_colors()
 def _run_warning(self, warning):
     from snack import ButtonChoiceWindow
     _rec = ButtonChoiceWindow(self.screen,
                               "Are you sure ?",
                               warning,
                               buttons=['Ok', 'Back'])
     if _rec == "ok":
         return self.OK
     else:
         return self.CANCEL
Exemplo n.º 9
0
 def __init__(self, screen, title, text):
     rc = ButtonChoiceWindow(screen,
                             title,
                             text,
                             buttons=[TEXT_OK_BUTTON,
                                      _("Cancel")])
     if rc == _("Cancel").lower():
         self.rc = 1
     else:
         self.rc = 0
    def run(self, warning=None):
        ''' @returns [name, type, direction] '''
        #items=["a", "b"]
        from snack import ListboxChoiceWindow, ButtonChoiceWindow
        result = None
        while True:
            self.confignames = self.controller.getCompleteConfigSetNames()
            names = self.confignames.keys()
            names.sort()
            if len(names) != 0:
                _res = ListboxChoiceWindow(self.screen,
                                           "Configuration Sets",
                                           "Select configuration set",
                                           names,
                                           buttons=('Next', 'New', 'Rename',
                                                    'Delete', 'Cancel'),
                                           width=40,
                                           scroll=1,
                                           height=-1,
                                           default=None,
                                           help=None)
            else:
                _res = [
                    ButtonChoiceWindow(self.screen,
                                       "Configuration Sets",
                                       "No Configuration sets defined",
                                       buttons=['New', 'Cancel'],
                                       width=40,
                                       help=None)
                ]

            if _res[0] == "cancel": break
            if _res[0] == "new":
                self._run_create()
            if _res[0] == "rename":
                _name = names[_res[1]]
                _type = self.confignames.get(_name)
                _newname = self._run_rename(_name)
                if _newname:
                    self.controller.renameConfigSet(_name, _type, _newname)
            if _res[0] == "delete":
                self._run_delete(names[_res[1]])
            if _res[0] == "next":
                _name = names[_res[1]]
                _type = self.confignames.get(_name)
                set = self.controller.getConfigStore(
                ).getConfigTypeStoreByName(_type).getConfigset(_name)
                direction = self._run_direction(
                    _name, set.getDirections(ordered=True))
                if direction == None: continue
                result = [_name, _type, direction]
                break
        self.cleanup()
        return result
Exemplo n.º 11
0
def display_checkbox_selection(screen, title, list_of_items, subtitle):
    if len(list_of_items) > 0:
        action, selection = create_select_checkbox(screen,
                                                   title,
                                                   subtitle,
                                                   list_of_items,
                                                   ['Ok', 'Back'],
                                                   height=10)
        if action != 'back':
            return selection
    else:
        ButtonChoiceWindow(screen, title,
                           'Sorry, there are no items to choose from',
                           ['Back'])
Exemplo n.º 12
0
#!/usr/bin/python
from snack import SnackScreen, ButtonChoiceWindow
screen = SnackScreen()
ButtonChoiceWindow(screen, ('Fatal Error'),
					('You do not have enough RAM to install %s '
					  'on this machine.\n'
					  '\n'
					  'Press <return> to reboot your system.\n')
				   %("wenshuna",),
				   buttons = (("OK"),))
screen.finish()
Exemplo n.º 13
0
    def show_menu(self, title, top_node):
        selection = 0

        while True:
            items = Menuconfig.menu_node_strings(top_node, 0)

            height = len(items)
            scroll = 0
            if height > self.screen.height - 13:
                height = self.screen.height - 13
                scroll = 1

            buttons = [('Save & Build', 'build', 'B'),
                       ('Save & Exit', 'save', 'S'), (' Help ', 'help', 'h'),
                       (' Exit ', 'exit', 'ESC')]
            buttonbar = ButtonBar(self.screen, buttons)
            listbox = Listbox(height, scroll=scroll, returnExit=1)
            count = 0
            for string, _ in items:
                listbox.append(string, count)
                if (selection == count):
                    listbox.setCurrent(count)
                count = count + 1

            grid = GridFormHelp(self.screen, title, None, 1, 2)
            grid.add(listbox, 0, 0, padding=(0, 0, 0, 1))
            grid.add(buttonbar, 0, 1, growx=1)
            grid.addHotKey(' ')

            rc = grid.runOnce()

            action = buttonbar.buttonPressed(rc)
            if action and action != 'help':
                return action

            if count == 0:
                continue

            selection = listbox.current()
            _, selected_node = items[selection]
            sym = selected_node.item

            if action == 'help':
                prompt, _ = selected_node.prompt
                if hasattr(selected_node, 'help') and selected_node.help:
                    help = selected_node.help
                else:
                    help = 'No help available.'
                ButtonChoiceWindow(screen=self.screen,
                                   title="Help on '{}'".format(prompt),
                                   text=help,
                                   width=60,
                                   buttons=['  Ok  '])
                continue

            show_submenu = False

            if type(sym) == Symbol:
                if rc == ' ':
                    if sym.type == BOOL:
                        sym.set_value('n' if sym.tri_value > 0 else 'y')
                else:
                    if selected_node.is_menuconfig:
                        show_submenu = True
                    elif sym.type in (STRING, INT, HEX):
                        action, values = EntryWindow(
                            screen=self.screen,
                            title=sym.name,
                            text='Enter a %s value:' % TYPE_TO_STR[sym.type],
                            prompts=[('', sym.str_value)],
                            buttons=[('  Ok  ', 'Ok'), ('Cancel', '', 'ESC')])
                        if action == 'Ok':
                            self.kconf.warnings = []
                            val = values[0]
                            if sym.type == HEX and not val.startswith('0x'):
                                val = '0x' + val
                            sym.set_value(val)
                            # only fetching triggers range check - how ugly...
                            sym.str_value
                            if len(self.kconf.warnings) > 0:
                                ButtonChoiceWindow(screen=self.screen,
                                                   title="Invalid entry",
                                                   text="\n".join(
                                                       self.kconf.warnings),
                                                   width=60,
                                                   buttons=['  Ok  '])
                                self.kconf.warnings = []
            elif selected_node.is_menuconfig and type(sym) != Choice:
                show_submenu = True

            if show_submenu:
                submenu_title, _ = selected_node.prompt
                action = self.show_menu(submenu_title, selected_node.list)
                if action != 'exit':
                    return action
Exemplo n.º 14
0
def doRescue(intf, rescue_mount, ksdata):
    import blivet

    # XXX: hook the exception handler wrapper that turns off snack first
    orig_hook = sys.excepthook
    sys.excepthook = lambda ty, val, tb: _exception_handler_wrapper(
        orig_hook, intf.screen, ty, val, tb)

    for f in [
            "services", "protocols", "group", "joe", "man.config",
            "nsswitch.conf", "selinux", "mke2fs.conf"
    ]:
        try:
            os.symlink('/mnt/runtime/etc/' + f, '/etc/' + f)
        except OSError:
            pass

    # Early shell access with no disk access attempts
    if not rescue_mount:
        # the %post should be responsible for mounting all needed file systems
        # NOTE: 1st script must be bash or simple python as nothing else might be available in the rescue image
        if flags.automatedInstall and ksdata.scripts:
            runPostScripts(ksdata.scripts)
        else:
            runShell()

        sys.exit(0)

    if flags.automatedInstall:
        readOnly = ksdata.rescue.romount
    else:
        # prompt to see if we should try and find root filesystem and mount
        # everything in /etc/fstab on that root
        while True:
            rc = ButtonChoiceWindow(
                intf.screen, _("Rescue"),
                _("The rescue environment will now attempt to find your "
                  "Linux installation and mount it under the directory "
                  "%s.  You can then make any changes required to your "
                  "system.  If you want to proceed with this step choose "
                  "'Continue'.  You can also choose to mount your file systems "
                  "read-only instead of read-write by choosing 'Read-Only'.  "
                  "\n\n"
                  "If for some reason this process fails you can choose 'Skip' "
                  "and this step will be skipped and you will go directly to a "
                  "command shell.\n\n") % (ROOT_PATH, ),
                [_("Continue"), _("Read-Only"),
                 _("Skip")])

            if rc == _("Skip").lower():
                runShell(intf.screen)
                sys.exit(0)
            else:
                readOnly = rc == _("Read-Only").lower()

            break

    sto = blivet.Blivet(ksdata=ksdata)
    blivet.storageInitialize(sto, ksdata, [])
    _unlock_devices(intf, sto)
    roots = blivet.findExistingInstallations(sto.devicetree)

    if not roots:
        root = None
    elif len(roots) == 1:
        root = roots[0]
    else:
        height = min(len(roots), 12)
        if height == 12:
            scroll = 1
        else:
            scroll = 0

        lst = []
        for root in roots:
            lst.append("%s" % root.name)

        (button, choice) = \
            ListboxChoiceWindow(intf.screen, _("System to Rescue"),
                                _("Which device holds the root partition "
                                  "of your installation?"), lst,
                                [ _("OK"), _("Exit") ], width = 30,
                                scroll = scroll, height = height,
                                help = "multipleroot")

        if button == _("Exit").lower():
            root = None
        else:
            root = roots[choice]

    rootmounted = False

    if root:
        try:
            # TODO: add a callback to warn about dirty filesystems
            mountExistingSystem(sto.fsset,
                                root.device,
                                allowDirty=True,
                                readOnly=readOnly)

            if not flags.imageInstall:
                msg = _("The system will reboot automatically when you exit "
                        "from the shell.")
            else:
                msg = _("Run %s to unmount the system "
                        "when you are finished.") % ANACONDA_CLEANUP

            if rc == -1:
                if flags.automatedInstall:
                    log.error(
                        "System had dirty file systems which you chose not to mount"
                    )
                else:
                    ButtonChoiceWindow(
                        intf.screen,
                        _("Rescue"),
                        _("Your system had dirty file systems which you chose not "
                          "to mount.  Press return to get a shell from which "
                          "you can fsck and mount your partitions. %s") % msg,
                        [_("OK")],
                        width=50)
                rootmounted = False
            else:
                if flags.automatedInstall:
                    log.info("System has been mounted under: %s", ROOT_PATH)
                else:
                    ButtonChoiceWindow(
                        intf.screen, _("Rescue"),
                        _("Your system has been mounted under %(rootPath)s.\n\n"
                          "Press <return> to get a shell. If you would like to "
                          "make your system the root environment, run the command:\n\n"
                          "\tchroot %(rootPath)s\n\n%(msg)s") % {
                              'rootPath': ROOT_PATH,
                              'msg': msg
                          }, [_("OK")])
                rootmounted = True

                # now turn on swap
                if not readOnly:
                    try:
                        sto.turnOnSwap()
                    except StorageError:
                        log.error("Error enabling swap")

                # and selinux too
                if flags.selinux:
                    # we have to catch the possible exception
                    # because we support read-only mounting
                    try:
                        fd = open("%s/.autorelabel" % ROOT_PATH, "w+")
                        fd.close()
                    except IOError:
                        log.warning("cannot touch /.autorelabel")

                # set a library path to use mounted fs
                libdirs = os.environ.get("LD_LIBRARY_PATH", "").split(":")
                mounted = map(lambda dir: "/mnt/sysimage%s" % dir, libdirs)
                os.environ["LD_LIBRARY_PATH"] = ":".join(libdirs + mounted)

                # find groff data dir
                gversion = None
                try:
                    glst = os.listdir("/mnt/sysimage/usr/share/groff")
                except OSError:
                    pass
                else:
                    # find a directory which is a numeral, its where
                    # data files are
                    for gdir in glst:
                        if re.match(r'\d[.\d]+\d$', gdir):
                            gversion = gdir
                            break

                if gversion is not None:
                    gpath = "/mnt/sysimage/usr/share/groff/" + gversion
                    os.environ["GROFF_FONT_PATH"] = gpath + '/font'
                    os.environ[
                        "GROFF_TMAC_PATH"] = "%s:/mnt/sysimage/usr/share/groff/site-tmac" % (
                            gpath + '/tmac', )

                # do we have bash?
                try:
                    if os.access("/usr/bin/bash", os.R_OK):
                        os.symlink("/usr/bin/bash", "/bin/bash")
                except OSError:
                    pass
        except (ValueError, LookupError, SyntaxError, NameError):
            raise
        except Exception as e:
            log.error("doRescue caught exception: %s", e)
            if flags.automatedInstall:
                log.error(
                    "An error occurred trying to mount some or all of your system"
                )
            else:
                if not flags.imageInstall:
                    msg = _("The system will reboot automatically when you "
                            "exit from the shell.")
                else:
                    msg = _("Run %s to unmount the system "
                            "when you are finished.") % ANACONDA_CLEANUP

                ButtonChoiceWindow(
                    intf.screen, _("Rescue"),
                    _("An error occurred trying to mount some or all of your "
                      "system. Some of it may be mounted under %s.\n\n"
                      "Press <return> to get a shell.") % ROOT_PATH + msg,
                    [_("OK")])
    else:
        if flags.automatedInstall and ksdata.reboot.action in [
                KS_REBOOT, KS_SHUTDOWN
        ]:
            log.info("No Linux partitions found")
            intf.screen.finish()
            print(_("You don't have any Linux partitions.  Rebooting.\n"))
            sys.exit(0)
        else:
            if not flags.imageInstall:
                msg = _(" The system will reboot automatically when you exit "
                        "from the shell.")
            else:
                msg = ""
            ButtonChoiceWindow(intf.screen,
                               _("Rescue Mode"),
                               _("You don't have any Linux partitions. Press "
                                 "return to get a shell.%s") % msg, [_("OK")],
                               width=50)

    msgStr = ""

    if rootmounted and not readOnly:
        sto.makeMtab()
        try:
            makeResolvConf(ROOT_PATH)
        except (OSError, IOError) as e:
            log.error("error making a resolv.conf: %s", e)
        msgStr = _("Your system is mounted under the %s directory.") % (
            ROOT_PATH, )
        ButtonChoiceWindow(intf.screen, _("Rescue"), msgStr, [_("OK")])

    # we do not need ncurses anymore, shut them down
    intf.shutdown()

    #create /etc/fstab in ramdisk, so it is easier to work with RO mounted filesystems
    makeFStab()

    # run %post if we've mounted everything
    if rootmounted and not readOnly and flags.automatedInstall:
        runPostScripts(ksdata.scripts)

    # start shell if reboot wasn't requested
    if not flags.automatedInstall or not ksdata.reboot.action in [
            KS_REBOOT, KS_SHUTDOWN
    ]:
        runShell(msg=msgStr)

    sys.exit(0)
class AssistantTui(object):
    OK = 0
    NEXT = 1
    MODIFY = 2
    SAVE = 3
    RUN = 4
    CANCEL = -1

    def __init__(self, controller, title="Com-EC Assistant"):
        """
        @param: controller, a list of AssistantControllers
        """
        from snack import SnackScreen
        self.title = title
        self.controller = controller
        self.infodict = self._build_infodict()
        self.screen = SnackScreen()

    def getInfoList(self):
        return self.infodict.values()

    def getInfoDict(self):
        return self.infodict

    def run(self, warning=None):
        step = self.OK
        try:
            while True:
                _ret = self._run_confirmation()
                if _ret == self.SAVE:
                    self._run_save()
                if _ret == self.MODIFY:
                    self._run_collector()
                if _ret == self.RUN:
                    if warning:
                        _rc = self._run_warning(warning)
                        if _rc == self.CANCEL:
                            continue
                    self.cleanup()
                    return True
        except CancelException:
            self.cleanup()
            return False

    def _build_infodict(self):
        from comoonics import odict
        _dict = odict.Odict()
        for _controller in self.controller:
            _tdict = _controller.getInfoDict()
            for _key in _tdict.iterkeys():
                if not _dict.has_key(_key):
                    _dict[_key] = _tdict.get(_key)[0]
                else:
                    for elem in _tdict.get(_key):
                        elem.setValue(_dict.get(_key).getValue())
        return _dict

    def _run_warning(self, warning):
        from snack import ButtonChoiceWindow
        _rec = ButtonChoiceWindow(self.screen,
                                  "Are you sure ?",
                                  warning,
                                  buttons=['Ok', 'Back'])
        if _rec == "ok":
            return self.OK
        else:
            return self.CANCEL

    def _run_confirmation(self):
        _button = ConfirmationWindow(self.screen, self.title,
                                     self.getInfoList())
        if _button == "start":
            return self.RUN
        if _button == "modify":
            return self.MODIFY
        if _button == "save":
            return self.SAVE
        if _button == "exit":
            raise CancelException()

    def _run_collector(self, page=0):
        _list = self.getInfoList()
        i = page
        while i < len(_list):
            _info = _list[i]
            if i == 0:
                _buttons = ['Next', 'Return']
            else:
                _buttons = ['Next', 'Previous', 'Return']
            _button, _value = AssistantWindow(self.screen,
                                              self.title,
                                              _info,
                                              buttons=_buttons)
            if _button == "next":
                i = i + 1
                self._set_info_value(_info.getName(), _value)
            if _button == "previous":
                i = i - 1
                self._set_info_value(_info.getName(), _value)
            if _button == "return":
                return self.CANCEL
        return self.NEXT

    def _run_save(self):
        from snack import ButtonChoiceWindow
        try:
            for _controller in self.controller:
                _controller.save()
            _msg = "Save complete"
        except Exception, e:
            _msg = "An error occured:%s" % e
        ButtonChoiceWindow(self.screen, "Save", _msg, buttons=['Ok'])