commit 93875272baf20437578a4b3e18e4b39a8a9efb9e Author: Damian Johnson atagar@torproject.org Date: Sun Jun 12 14:08:31 2011 -0700
Binding handlers for the configuration submenu --- src/cli/configPanel.py | 232 ++++++++++++++++++++++++++--------------------- src/cli/menu/actions.py | 34 +++++-- 2 files changed, 153 insertions(+), 113 deletions(-)
diff --git a/src/cli/configPanel.py b/src/cli/configPanel.py index c2e290d..4647286 100644 --- a/src/cli/configPanel.py +++ b/src/cli/configPanel.py @@ -6,7 +6,7 @@ and the resulting configuration files saved. import curses import threading
-import controller +import cli.controller import popups
from util import conf, enum, panel, sysTools, torConfig, torTools, uiTools @@ -242,6 +242,17 @@ class ConfigPanel(panel.Panel):
return self.scroller.getCursorSelection(self._getConfigOptions())
+ def setFiltering(self, isFiltered): + """ + Sets if configuration options are filtered or not. + + Arguments: + isFiltered - if true then only relatively important options will be + shown, otherwise everything is shown + """ + + self.showAll = not isFiltered + def setSortOrder(self, ordering = None): """ Sets the configuration attributes we're sorting by and resorts the @@ -258,6 +269,24 @@ class ConfigPanel(panel.Panel): self.confImportantContents.sort(key=lambda i: (i.getAll(self.sortOrdering))) self.valsLock.release()
+ def showSortDialog(self): + """ + Provides the sort dialog for our configuration options. + """ + + # set ordering for config options + cli.controller.getController().requestRedraw(True) + titleLabel = "Config Option Ordering:" + options = [FIELD_ATTR[field][0] for field in Field.values()] + oldSelection = [FIELD_ATTR[field][0] for field in self.sortOrdering] + optionColors = dict([FIELD_ATTR[field] for field in Field.values()]) + results = popups.showSortDialog(titleLabel, options, oldSelection, optionColors) + + if results: + # converts labels back to enums + resultEnums = [getFieldFromLabel(label) for label in results] + self.setSortOrder(resultEnums) + def handleKey(self, key): self.valsLock.acquire() isKeystrokeConsumed = True @@ -313,118 +342,117 @@ class ConfigPanel(panel.Panel): self.showAll = not self.showAll self.redraw(True) elif key == ord('s') or key == ord('S'): - # set ordering for config options - titleLabel = "Config Option Ordering:" - options = [FIELD_ATTR[field][0] for field in Field.values()] - oldSelection = [FIELD_ATTR[field][0] for field in self.sortOrdering] - optionColors = dict([FIELD_ATTR[field] for field in Field.values()]) - results = popups.showSortDialog(titleLabel, options, oldSelection, optionColors) - - if results: - # converts labels back to enums - resultEnums = [getFieldFromLabel(label) for label in results] - self.setSortOrder(resultEnums) + self.showSortDialog() elif key == ord('w') or key == ord('W'): - # display a popup for saving the current configuration - configLines = torConfig.getCustomOptions(True) - popup, width, height = popups.init(len(configLines) + 2) - if not popup: return + self.showWriteDialog() + else: isKeystrokeConsumed = False + + self.valsLock.release() + return isKeystrokeConsumed + + def showWriteDialog(self): + """ + Provies an interface to confirm if the configuration is saved and, if so, + where. + """ + + # display a popup for saving the current configuration + cli.controller.getController().requestRedraw(True) + configLines = torConfig.getCustomOptions(True) + popup, width, height = popups.init(len(configLines) + 2) + if not popup: return + + try: + # displayed options (truncating the labels if there's limited room) + if width >= 30: selectionOptions = ("Save", "Save As...", "Cancel") + else: selectionOptions = ("Save", "Save As", "X")
- try: - # displayed options (truncating the labels if there's limited room) - if width >= 30: selectionOptions = ("Save", "Save As...", "Cancel") - else: selectionOptions = ("Save", "Save As", "X") + # checks if we can show options beside the last line of visible content + isOptionLineSeparate = False + lastIndex = min(height - 2, len(configLines) - 1) + + # if we don't have room to display the selection options and room to + # grow then display the selection options on its own line + if width < (30 + len(configLines[lastIndex])): + popup.setHeight(height + 1) + popup.redraw(True) # recreates the window instance + newHeight, _ = popup.getPreferredSize()
- # checks if we can show options beside the last line of visible content - isOptionLineSeparate = False - lastIndex = min(height - 2, len(configLines) - 1) + if newHeight > height: + height = newHeight + isOptionLineSeparate = True + + key, selection = 0, 2 + while not uiTools.isSelectionKey(key): + # if the popup has been resized then recreate it (needed for the + # proper border height) + newHeight, newWidth = popup.getPreferredSize() + if (height, width) != (newHeight, newWidth): + height, width = newHeight, newWidth + popup.redraw(True)
- # if we don't have room to display the selection options and room to - # grow then display the selection options on its own line - if width < (30 + len(configLines[lastIndex])): - popup.setHeight(height + 1) - popup.redraw(True) # recreates the window instance - newHeight, _ = popup.getPreferredSize() - - if newHeight > height: - height = newHeight - isOptionLineSeparate = True + # if there isn't room to display the popup then cancel it + if height <= 2: + selection = 2 + break
- key, selection = 0, 2 - while not uiTools.isSelectionKey(key): - # if the popup has been resized then recreate it (needed for the - # proper border height) - newHeight, newWidth = popup.getPreferredSize() - if (height, width) != (newHeight, newWidth): - height, width = newHeight, newWidth - popup.redraw(True) - - # if there isn't room to display the popup then cancel it - if height <= 2: - selection = 2 - break - - popup.win.erase() - popup.win.box() - popup.addstr(0, 0, "Configuration being saved:", curses.A_STANDOUT) + popup.win.erase() + popup.win.box() + popup.addstr(0, 0, "Configuration being saved:", curses.A_STANDOUT) + + visibleConfigLines = height - 3 if isOptionLineSeparate else height - 2 + for i in range(visibleConfigLines): + line = uiTools.cropStr(configLines[i], width - 2)
- visibleConfigLines = height - 3 if isOptionLineSeparate else height - 2 - for i in range(visibleConfigLines): - line = uiTools.cropStr(configLines[i], width - 2) - - if " " in line: - option, arg = line.split(" ", 1) - popup.addstr(i + 1, 1, option, curses.A_BOLD | uiTools.getColor("green")) - popup.addstr(i + 1, len(option) + 2, arg, curses.A_BOLD | uiTools.getColor("cyan")) - else: - popup.addstr(i + 1, 1, line, curses.A_BOLD | uiTools.getColor("green")) + if " " in line: + option, arg = line.split(" ", 1) + popup.addstr(i + 1, 1, option, curses.A_BOLD | uiTools.getColor("green")) + popup.addstr(i + 1, len(option) + 2, arg, curses.A_BOLD | uiTools.getColor("cyan")) + else: + popup.addstr(i + 1, 1, line, curses.A_BOLD | uiTools.getColor("green")) + + # draws selection options (drawn right to left) + drawX = width - 1 + for i in range(len(selectionOptions) - 1, -1, -1): + optionLabel = selectionOptions[i] + drawX -= (len(optionLabel) + 2)
- # draws selection options (drawn right to left) - drawX = width - 1 - for i in range(len(selectionOptions) - 1, -1, -1): - optionLabel = selectionOptions[i] - drawX -= (len(optionLabel) + 2) - - # if we've run out of room then drop the option (this will only - # occure on tiny displays) - if drawX < 1: break - - selectionFormat = curses.A_STANDOUT if i == selection else curses.A_NORMAL - popup.addstr(height - 2, drawX, "[") - popup.addstr(height - 2, drawX + 1, optionLabel, selectionFormat | curses.A_BOLD) - popup.addstr(height - 2, drawX + len(optionLabel) + 1, "]") - - drawX -= 1 # space gap between the options + # if we've run out of room then drop the option (this will only + # occure on tiny displays) + if drawX < 1: break
- popup.win.refresh() + selectionFormat = curses.A_STANDOUT if i == selection else curses.A_NORMAL + popup.addstr(height - 2, drawX, "[") + popup.addstr(height - 2, drawX + 1, optionLabel, selectionFormat | curses.A_BOLD) + popup.addstr(height - 2, drawX + len(optionLabel) + 1, "]")
- key = controller.getController().getScreen().getch() - if key == curses.KEY_LEFT: selection = max(0, selection - 1) - elif key == curses.KEY_RIGHT: selection = min(len(selectionOptions) - 1, selection + 1) + drawX -= 1 # space gap between the options
- if selection in (0, 1): - loadedTorrc, promptCanceled = torConfig.getTorrc(), False - try: configLocation = loadedTorrc.getConfigLocation() - except IOError: configLocation = "" - - if selection == 1: - # prompts user for a configuration location - configLocation = popups.inputPrompt("Save to (esc to cancel): ", configLocation) - if not configLocation: promptCanceled = True + popup.win.refresh() + + key = cli.controller.getController().getScreen().getch() + if key == curses.KEY_LEFT: selection = max(0, selection - 1) + elif key == curses.KEY_RIGHT: selection = min(len(selectionOptions) - 1, selection + 1) + + if selection in (0, 1): + loadedTorrc, promptCanceled = torConfig.getTorrc(), False + try: configLocation = loadedTorrc.getConfigLocation() + except IOError: configLocation = "" + + if selection == 1: + # prompts user for a configuration location + configLocation = popups.inputPrompt("Save to (esc to cancel): ", configLocation) + if not configLocation: promptCanceled = True + + if not promptCanceled: + try: + torConfig.saveConf(configLocation, configLines) + msg = "Saved configuration to %s" % configLocation + except IOError, exc: + msg = "Unable to save configuration (%s)" % sysTools.getFileErrorMsg(exc)
- if not promptCanceled: - try: - torConfig.saveConf(configLocation, configLines) - msg = "Saved configuration to %s" % configLocation - except IOError, exc: - msg = "Unable to save configuration (%s)" % sysTools.getFileErrorMsg(exc) - - popups.showMsg(msg, 2) - finally: popups.finalize() - else: isKeystrokeConsumed = False - - self.valsLock.release() - return isKeystrokeConsumed + popups.showMsg(msg, 2) + finally: popups.finalize()
def getHelp(self): options = [] diff --git a/src/cli/menu/actions.py b/src/cli/menu/actions.py index 2827742..2072ead 100644 --- a/src/cli/menu/actions.py +++ b/src/cli/menu/actions.py @@ -28,17 +28,8 @@ def makeMenu(): baseMenu.add(makeLogMenu(pagePanel)) elif pagePanel.getName() == "connections": baseMenu.add(makeConnectionsMenu(pagePanel)) - - configurationMenu = cli.menu.item.Submenu("Configuration") - - commentsSubmenu = cli.menu.item.Submenu("Comments") - commentsSubmenu.add(cli.menu.item.MenuItem("Hidden", None)) - commentsSubmenu.add(cli.menu.item.MenuItem("Visible", None)) - configurationMenu.add(commentsSubmenu) - - configurationMenu.add(cli.menu.item.MenuItem("Reload", None)) - configurationMenu.add(cli.menu.item.MenuItem("Reset Tor", None)) - baseMenu.add(configurationMenu) + elif pagePanel.getName() == "configuration": + baseMenu.add(makeConfigurationMenu(pagePanel))
return baseMenu
@@ -226,3 +217,24 @@ def makeConnectionsMenu(connPanel):
return connectionsMenu
+def makeConfigurationMenu(configPanel): + """ + Submenu for the configuration panel, consisting of... + Save Config... + Sorting... + Filter / Unfilter Options + + Arguments: + configPanel - instance of the configuration panel + """ + + configMenu = cli.menu.item.Submenu("Configuration") + configMenu.add(cli.menu.item.MenuItem("Save Config...", configPanel.showWriteDialog)) + configMenu.add(cli.menu.item.MenuItem("Sorting...", configPanel.showSortDialog)) + + if configPanel.showAll: label, arg = "Filter", True + else: label, arg = "Unfilter", False + configMenu.add(cli.menu.item.MenuItem("%s Options" % label, functools.partial(configPanel.setFiltering, arg))) + + return configMenu +
tor-commits@lists.torproject.org