[or-cvs] r23819: {arm} Usability and functionality improvements for setting config (in arm/trunk: . src/interface)

Damian Johnson atagar1 at gmail.com
Wed Nov 17 18:13:04 UTC 2010


Author: atagar
Date: 2010-11-17 18:13:04 +0000 (Wed, 17 Nov 2010)
New Revision: 23819

Modified:
   arm/trunk/armrc.sample
   arm/trunk/src/interface/configStatePanel.py
   arm/trunk/src/interface/controller.py
Log:
Usability and functionality improvements for setting config values:
- Using a textpad rather than getstr so the entry field isn't so dumb (this has cursor movement, emacs style keybindings, etc).
- Optionally prepopulating the current value in the field.
- Accepting 'true' and 'false' for boolean fields.
- Properly handling LineList entries.
- Cropping off useless parts of the error message.



Modified: arm/trunk/armrc.sample
===================================================================
--- arm/trunk/armrc.sample	2010-11-17 17:05:30 UTC (rev 23818)
+++ arm/trunk/armrc.sample	2010-11-17 18:13:04 UTC (rev 23819)
@@ -65,28 +65,32 @@
 # selectionDetails.height
 #   rows of data for the panel showing details on the current selection, this
 #   is disabled entirely if zero
-# colWidth.*
+# features.config.prepopulateEditValues
+#   when editing config values the current value is prepopulated if true, and
+#   left blank otherwise
+# state.colWidth.*
 #   maximum column content width
+# state.showPrivateOptions
+#   tor provides config options of the form "__<option>" that can be dangerous
+#   to set, if true arm provides these on the config panel
+# state.showVirtualOptions
+#   virtual options are placeholders for other option groups, never having
+#   values or being setable themselves
 # file.showScrollbars
 #   displays scrollbars when the torrc content is longer than the display
 # file.maxLinesPerEntry
 #   max number of lines to display for a single entry in the torrc
-# showPrivateOptions
-#   tor provides config options of the form "__<option>" that can be dangerous
-#   to set, if true arm provides these on the config panel
-# showVirtualOptions
-#   virtual options are placeholders for other option groups, never having
-#   values or being setable themselves
 
 features.config.type 0
 features.config.order 0, 6, 7
 features.config.selectionDetails.height 6
+features.config.prepopulateEditValues true
 features.config.state.colWidth.option 25
 features.config.state.colWidth.value 10
+features.config.state.showPrivateOptions false
+features.config.state.showVirtualOptions false
 features.config.file.showScrollbars true
 features.config.file.maxLinesPerEntry 8
-features.config.showPrivateOptions false
-features.config.showVirtualOptions false
 
 # Descriptions for tor's configuration options can be loaded from its man page
 # to give usage information on the settings page. They can also be persisted to

Modified: arm/trunk/src/interface/configStatePanel.py
===================================================================
--- arm/trunk/src/interface/configStatePanel.py	2010-11-17 17:05:30 UTC (rev 23818)
+++ arm/trunk/src/interface/configStatePanel.py	2010-11-17 18:13:04 UTC (rev 23819)
@@ -9,8 +9,8 @@
 from util import conf, panel, torTools, torConfig, uiTools
 
 DEFAULT_CONFIG = {"features.config.selectionDetails.height": 6,
-                  "features.config.showPrivateOptions": False,
-                  "features.config.showVirtualOptions": False,
+                  "features.config.state.showPrivateOptions": False,
+                  "features.config.state.showVirtualOptions": False,
                   "features.config.state.colWidth.option": 25,
                   "features.config.state.colWidth.value": 10}
 
@@ -145,9 +145,9 @@
         confOption, confType = line.strip().split(" ", 1)
         
         # skips private and virtual entries if not set to show them
-        if not self._config["features.config.showPrivateOptions"] and confOption.startswith("__"):
+        if not self._config["features.config.state.showPrivateOptions"] and confOption.startswith("__"):
           continue
-        elif not self._config["features.config.showVirtualOptions"] and confType == "Virtual":
+        elif not self._config["features.config.state.showVirtualOptions"] and confType == "Virtual":
           continue
         
         manEntry = torConfig.getConfigDescription(confOption)

Modified: arm/trunk/src/interface/controller.py
===================================================================
--- arm/trunk/src/interface/controller.py	2010-11-17 17:05:30 UTC (rev 23818)
+++ arm/trunk/src/interface/controller.py	2010-11-17 18:13:04 UTC (rev 23819)
@@ -10,6 +10,7 @@
 import math
 import time
 import curses
+import curses.textpad
 import socket
 from TorCtl import TorCtl
 from TorCtl import TorUtil
@@ -45,6 +46,7 @@
 
 CONFIG = {"log.torrc.readFailed": log.WARN,
           "features.graph.type": 1,
+          "features.config.prepopulateEditValues": True,
           "queries.refreshRate.rate": 5,
           "log.torEventTypeUnrecognized": log.NOTICE,
           "features.graph.bw.prepopulate": True,
@@ -1563,24 +1565,39 @@
         # makes cursor and typing visible
         try: curses.curs_set(1)
         except curses.error: pass
-        curses.echo()
         
-        # gets user input (this blocks monitor updates)
-        # TODO: can I prepopulate a value?
-        newConfigValue = panels["control"].win.getstr(0, len(titleMsg))
+        # temporary subwindow for user input
+        displayWidth = panels["control"].getPreferredSize()[1]
+        inputSubwindow = panels["control"].parent.subwin(1, displayWidth - len(titleMsg), panels["control"].top, len(titleMsg))
         
+        # prepopulates the current value
+        if CONFIG["features.config.prepopulateEditValues"]:
+          initialValue = selection.get(configStatePanel.FIELD_VALUE)
+          if initialValue != "<none>": inputSubwindow.addstr(0, 0, initialValue)
+        
+        # fetches the user's input for the new config value
+        textbox = curses.textpad.Textbox(inputSubwindow)
+        newConfigValue = textbox.edit().strip()
+        
         # reverts visability settings
         try: curses.curs_set(0)
         except curses.error: pass
-        curses.noecho()
-        curses.halfdelay(REFRESH_RATE * 10) # evidenlty previous tweaks reset this...
+        #curses.halfdelay(REFRESH_RATE * 10) # evidenlty previous tweaks reset this...
         
         # it would be nice to quit on esc, but looks like this might not be possible...
         if newConfigValue != "":
           conn = torTools.getConn()
           
+          # if the value's a boolean then allow for 'true' and 'false' inputs
+          if selection.get(configStatePanel.FIELD_TYPE) == "Boolean":
+            if newConfigValue.lower() == "true": newConfigValue = "1"
+            elif newConfigValue.lower() == "false": newConfigValue = "0"
+          
           try:
-            conn.getTorCtl().set_option(configOption, newConfigValue)
+            if selection.get(configStatePanel.FIELD_TYPE) == "LineList":
+              conn.getTorCtl().set_options([(configOption, val) for val in newConfigValue.split(",")])
+            else:
+              conn.getTorCtl().set_option(configOption, newConfigValue)
             
             # resets the isDefault flag
             setOptions = set()
@@ -1601,12 +1618,17 @@
             excStr = str(exc)
             
             if excStr.startswith("513 Unacceptable option value: "):
-              # common validation error prefix
+              # crops off the common error prefix
               excStr = excStr[31:]
+              
+              # Truncates messages like:
+              # Value 'BandwidthRate la de da' is malformed or out of bounds.
+              # to: Value 'la de da' is malformed or out of bounds.
+              if excStr.startswith("Value '"):
+                excStr = excStr.replace("%s " % configOption, "", 1)
             
             errorMsg = "%s (press any key)" % excStr
-            maxMsgLength = panels["control"].getPreferredSize()[1]
-            panels["control"].setMsg(uiTools.cropStr(errorMsg, maxMsgLength), curses.A_STANDOUT)
+            panels["control"].setMsg(uiTools.cropStr(errorMsg, displayWidth), curses.A_STANDOUT)
             panels["control"].redraw(True)
             
             curses.cbreak() # wait indefinitely for key presses (no timeout)



More information about the tor-commits mailing list