def promptConfigOptions(relayType, config, disabledOpt): """ Prompts the user for the configuration of an internal relay. """ topContent = _splitStr( CONFIG.get("wizard.message.%s" % relayType.lower(), ""), 54) options = [ config[opt] for opt in RelayOptions[relayType] if not opt in disabledOpt ] options.append(Options.DIVIDER) options.append(ConfigOption(BACK, "general", "(to role selection)")) options.append(ConfigOption(NEXT, "general", "(to confirm options)")) popupHeight = len(topContent) + len(options) + DESC_SIZE + 5 popup, _, _ = cli.popups.init(popupHeight, 58) if not popup: return control = cli.controller.getController() key, selection = 0, 0 try: curses.cbreak() while True: popup.win.erase() popup.win.box() # provides the description for the relay type for i in range(len(topContent)): popup.addstr(i + 1, 2, topContent[i], curses.A_BOLD | uiTools.getColor(MSG_COLOR)) y, offset = len(topContent) + 1, 0 for opt in options: if opt == Options.DIVIDER: offset += 1 continue optionFormat = opt.getDisplayAttr() if opt == options[selection]: optionFormat |= curses.A_STANDOUT offset, indent = offset + 1, 0 if opt.getKey() in CONFIG["wizard.suboptions"]: # If the next entry is also a suboption then show a 'T', otherwise # end the bracketing. bracketChar, nextIndex = curses.ACS_LLCORNER, options.index( opt) + 1 if nextIndex < len(options) and isinstance( options[nextIndex], ConfigOption): if options[nextIndex].getKey( ) in CONFIG["wizard.suboptions"]: bracketChar = curses.ACS_LTEE popup.addch(y + offset, 3, bracketChar, opt.getDisplayAttr()) popup.addch(y + offset, 4, curses.ACS_HLINE, opt.getDisplayAttr()) indent = 3 labelFormat = " %%-%is%%s" % (30 - indent) label = labelFormat % (opt.getLabel(), opt.getDisplayValue()) popup.addstr(y + offset, 2 + indent, uiTools.padStr(label, 54 - indent), optionFormat) # little hack to make "Block" policies red if opt != options[selection] and not opt.getValue( ) and opt.getKey() in CUSTOM_POLICIES: optionFormat = curses.A_BOLD | uiTools.getColor("red") popup.addstr(y + offset, 33, opt.getDisplayValue(), optionFormat) # divider between the options and description offset += 2 popup.addch(y + offset, 0, curses.ACS_LTEE) popup.addch(y + offset, popup.getWidth() - 1, curses.ACS_RTEE) popup.hline(y + offset, 1, popup.getWidth() - 2) # description for the currently selected option for line in options[selection].getDescription(54, " "): offset += 1 popup.addstr(y + offset, 1, line, uiTools.getColor(MSG_COLOR)) popup.win.refresh() key = control.getScreen().getch() if key in (curses.KEY_UP, curses.KEY_DOWN): posOffset = -1 if key == curses.KEY_UP else 1 selection = (selection + posOffset) % len(options) # skips disabled options and dividers while options[selection] == Options.DIVIDER or not options[ selection].isEnabled(): selection = (selection + posOffset) % len(options) elif uiTools.isSelectionKey(key): if selection == len(options) - 2: return BACK # selected back elif selection == len(options) - 1: return NEXT # selected next elif isinstance(options[selection], ToggleConfigOption): options[selection].toggle() else: newValue = popup.getstr( y + selection + 1, 33, options[selection].getValue(), curses.A_STANDOUT | uiTools.getColor(OPTION_COLOR), 23) if newValue: try: options[selection].setValue(newValue.strip()) except ValueError, exc: cli.popups.showMsg(str(exc), 3) cli.controller.getController().redraw() elif key in (27, ord('q'), ord('Q')): return CANCEL
def promptConfigOptions(relayType, config, disabledOpt): """ Prompts the user for the configuration of an internal relay. """ topContent = _splitStr(CONFIG.get("wizard.message.%s" % relayType.lower(), ""), 54) options = [config[opt] for opt in RelayOptions[relayType] if not opt in disabledOpt] options.append(Options.DIVIDER) options.append(ConfigOption(BACK, "general", "(to role selection)")) options.append(ConfigOption(NEXT, "general", "(to confirm options)")) popupHeight = len(topContent) + len(options) + DESC_SIZE + 5 popup, _, _ = cli.popups.init(popupHeight, 58) if not popup: return control = cli.controller.getController() key, selection = 0, 0 try: curses.cbreak() while True: popup.win.erase() popup.win.box() # provides the description for the relay type for i in range(len(topContent)): popup.addstr(i + 1, 2, topContent[i], curses.A_BOLD | uiTools.getColor(MSG_COLOR)) y, offset = len(topContent) + 1, 0 for opt in options: if opt == Options.DIVIDER: offset += 1 continue optionFormat = opt.getDisplayAttr() if opt == options[selection]: optionFormat |= curses.A_STANDOUT offset, indent = offset + 1, 0 if opt.getKey() in CONFIG["wizard.suboptions"]: # If the next entry is also a suboption then show a 'T', otherwise # end the bracketing. bracketChar, nextIndex = curses.ACS_LLCORNER, options.index(opt) + 1 if nextIndex < len(options) and isinstance(options[nextIndex], ConfigOption): if options[nextIndex].getKey() in CONFIG["wizard.suboptions"]: bracketChar = curses.ACS_LTEE popup.addch(y + offset, 3, bracketChar, opt.getDisplayAttr()) popup.addch(y + offset, 4, curses.ACS_HLINE, opt.getDisplayAttr()) indent = 3 labelFormat = " %%-%is%%s" % (30 - indent) label = labelFormat % (opt.getLabel(), opt.getDisplayValue()) popup.addstr(y + offset, 2 + indent, uiTools.padStr(label, 54 - indent), optionFormat) # little hack to make "Block" policies red if opt != options[selection] and not opt.getValue() and opt.getKey() in CUSTOM_POLICIES: optionFormat = curses.A_BOLD | uiTools.getColor("red") popup.addstr(y + offset, 33, opt.getDisplayValue(), optionFormat) # divider between the options and description offset += 2 popup.addch(y + offset, 0, curses.ACS_LTEE) popup.addch(y + offset, popup.getWidth() - 1, curses.ACS_RTEE) popup.hline(y + offset, 1, popup.getWidth() - 2) # description for the currently selected option for line in options[selection].getDescription(54, " "): offset += 1 popup.addstr(y + offset, 1, line, uiTools.getColor(MSG_COLOR)) popup.win.refresh() key = control.getScreen().getch() if key in (curses.KEY_UP, curses.KEY_DOWN): posOffset = -1 if key == curses.KEY_UP else 1 selection = (selection + posOffset) % len(options) # skips disabled options and dividers while options[selection] == Options.DIVIDER or not options[selection].isEnabled(): selection = (selection + posOffset) % len(options) elif uiTools.isSelectionKey(key): if selection == len(options) - 2: return BACK # selected back elif selection == len(options) - 1: return NEXT # selected next elif isinstance(options[selection], ToggleConfigOption): options[selection].toggle() else: newValue = popup.getstr(y + selection + 1, 33, options[selection].getValue(), curses.A_STANDOUT | uiTools.getColor(OPTION_COLOR), 23) if newValue: try: options[selection].setValue(newValue.strip()) except ValueError, exc: cli.popups.showMsg(str(exc), 3) cli.controller.getController().redraw() elif key in (27, ord('q'), ord('Q')): return CANCEL finally: cli.popups.finalize()
def promptRelayType(initialSelection): """ Provides a prompt for selecting the general role we'd like Tor to run with. This returns a RelayType enumeration for the selection, or CANCEL if the dialog was canceled. """ options = [ConfigOption(opt, "role", opt) for opt in RelayType.values()] options.append(ConfigOption(CANCEL, "general", CANCEL)) selection = RelayType.indexOf(initialSelection) height = 28 # drops the resume option if it isn't applicable control = cli.controller.getController() if not control.getTorManager().isTorrcAvailable(): options.pop(0) height -= 3 selection -= 1 popup, _, _ = cli.popups.init(height, 58) if not popup: return try: popup.win.box() curses.cbreak() # provides the welcoming message topContent = _splitStr(CONFIG["wizard.message.role"], 54) for i in range(len(topContent)): popup.addstr(i + 1, 2, topContent[i], curses.A_BOLD | uiTools.getColor(MSG_COLOR)) while True: y, offset = len(topContent) + 1, 0 for opt in options: optionFormat = uiTools.getColor(MSG_COLOR) if opt == options[selection]: optionFormat |= curses.A_STANDOUT # Curses has a weird bug where there's a one-pixel alignment # difference between bold and regular text, so it looks better # to render the whitespace here as not being bold. offset += 1 label = opt.getLabel(" ") popup.addstr(y + offset, 2, label, optionFormat | curses.A_BOLD) popup.addstr(y + offset, 2 + len(label), " " * (54 - len(label)), optionFormat) offset += 1 for line in opt.getDescription(52, " "): popup.addstr(y + offset, 2, uiTools.padStr(line, 54), optionFormat) offset += 1 popup.win.refresh() key = control.getScreen().getch() if key == curses.KEY_UP: selection = (selection - 1) % len(options) elif key == curses.KEY_DOWN: selection = (selection + 1) % len(options) elif uiTools.isSelectionKey(key): return options[selection].getValue() elif key in (27, ord('q'), ord('Q')): return CANCEL # esc or q - cancel finally: cli.popups.finalize()