[tor-commits] [arm/master] Mapped menu items to respective actions.

atagar at torproject.org atagar at torproject.org
Sat Jun 4 21:12:30 UTC 2011


commit 2a6916e1fbcc6fc6a60563e969d0ddc448ece1fd
Author: Kamran Riaz Khan <krkhan at inspirated.com>
Date:   Tue May 31 14:02:49 2011 +0500

    Mapped menu items to respective actions.
    
    There are three kinds of menu items:
     * The ones which are directly mapped to a panel action via
       Menu._callbackPressKey()
     * "State-ful" menu items which are enabled/disabled depending on their
       panel's states. These are taken care of via the
       Menu._callbackGetEnabled() and Menu._callbackSet() methods. For
       example, the "Duplicates" submenu in "Logs" changes its state
       depending on log.showDuplicates.
     * View menu items, which change controller state. Supported via
       Menu._callbackView()
    
    Launching a panel action switches view to that panel, e.g., if we're
    on configuration panel and graph bounds are changed the controller
    is traversed through pages until one with graph panel is found.
    Otherwise, an error is logged.
    
    File->Exit and Configuration->Reset Tor items are unimplemented as of
    yet. Possible approaches include factoring out a handleKey() in
    controller or duplicating the same code in callbacks.
---
 src/cli/menu.py      |  198 +++++++++++++++++++++++++++++++++++---------------
 src/util/menuItem.py |   11 +++-
 2 files changed, 149 insertions(+), 60 deletions(-)

diff --git a/src/cli/menu.py b/src/cli/menu.py
index 5a51797..9aadf8d 100644
--- a/src/cli/menu.py
+++ b/src/cli/menu.py
@@ -6,6 +6,8 @@ import curses
 
 import cli.controller
 import popups
+
+from cli.graphing.graphPanel import Bounds as GraphBounds
 from util import log, panel, uiTools, menuItem
 
 PARENTLEVEL, TOPLEVEL = (-1, 0)
@@ -15,70 +17,78 @@ class Menu():
 
   def __init__(self, item=None):
     DEFAULT_ROOT = menuItem.MenuItem(label="Root", children=(
-      menuItem.MenuItem(label="File"          , children=(
-        menuItem.MenuItem(label="Exit"                , callback=self._callbackDefault),)),
-      menuItem.MenuItem(label="Logs"          , children=(
-        menuItem.MenuItem(label="Events"              , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Clear"               , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Save"                , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Filter"              , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Duplicates"          , children=(
-          menuItem.MenuItem(label="Hidden"            , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Visible"           , callback=self._callbackDefault),))
-        )),
-      menuItem.MenuItem(label="View"          , children=(
-        menuItem.MenuItem(label="Graph"               , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Connections"         , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Configuration"       , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Configuration File"  , callback=self._callbackDefault),)),
-      menuItem.MenuItem(label="Graph"         , children=(
-        menuItem.MenuItem(label="Stats"               , children=(
-          menuItem.MenuItem(label="Bandwidth"         , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Connections"       , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Resources"         , callback=self._callbackDefault),
-        )),
-        menuItem.MenuItem(label="Size"                , children=(
-          menuItem.MenuItem(label="Increase"          , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Decrease"          , callback=self._callbackDefault),
-        )),
-        menuItem.MenuItem(label="Update Interval"     , children=(
-          menuItem.MenuItem(label="Each second"       , callback=self._callbackDefault),
-          menuItem.MenuItem(label="5 seconds"         , callback=self._callbackDefault),
-          menuItem.MenuItem(label="30 seconds"        , callback=self._callbackDefault),
-          menuItem.MenuItem(label="1 minute"          , callback=self._callbackDefault),
-          menuItem.MenuItem(label="30 minutes"        , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Hourly"            , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Daily"             , callback=self._callbackDefault),
+      menuItem.MenuItem(label="File", children=(
+        menuItem.MenuItem(label="Exit",
+                          callback=self._callbackDefault),)),
+      menuItem.MenuItem(label="Logs", children=(
+        menuItem.MenuItem(label="Events",
+                          callback=lambda item: self._callbackPressKey('log', ord('e'))),
+        menuItem.MenuItem(label="Clear",
+                          callback=lambda item: self._callbackPressKey('log', ord('c'))),
+        menuItem.MenuItem(label="Save",
+                          callback=lambda item: self._callbackPressKey('log', ord('a'))),
+        menuItem.MenuItem(label="Filter",
+                          callback=lambda item: self._callbackPressKey('log', ord('f'))),
+        menuItem.MenuItem(label="Duplicates", children=(
+          menuItem.MenuItem(label="Hidden",
+                            callback=lambda item: self._callbackSet('log', 'showDuplicates', False, ord('u')),
+                            enabled=lambda: self._getItemEnabled('log', 'showDuplicates', False)),
+          menuItem.MenuItem(label="Visible",
+                            callback=lambda item: self._callbackSet('log', 'showDuplicates', True, ord('u')),
+                            enabled=lambda: self._getItemEnabled('log', 'showDuplicates', True)),
+          )))),
+      menuItem.MenuItem(label="View", children=(
+        menuItem.MenuItem(label="Graph",
+                          callback=lambda item: self._callbackView('graph')),
+        menuItem.MenuItem(label="Connections",
+                          callback=lambda item: self._callbackView('conn')),
+        menuItem.MenuItem(label="Configuration",
+                          callback=lambda item: self._callbackView('configState')),
+        menuItem.MenuItem(label="Configuration File",
+                          callback=lambda item: self._callbackView('configFile')),)),
+      menuItem.MenuItem(label="Graph", children=(
+        menuItem.MenuItem(label="Stats",
+                          callback=lambda item: self._callbackPressKey('graph', ord('s'))),
+        menuItem.MenuItem(label="Size", children=(
+          menuItem.MenuItem(label="Increase",
+                            callback=lambda item: self._callbackPressKey('graph', ord('m'))),
+          menuItem.MenuItem(label="Decrease",
+                            callback=lambda item: self._callbackPressKey('graph', ord('n'))),
         )),
-        menuItem.MenuItem(label="Bounds"              , children=(
-          menuItem.MenuItem(label="Local Max"         , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Global Max"        , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Tight"             , callback=self._callbackDefault),
+        menuItem.MenuItem(label="Update Interval",
+                            callback=lambda item: self._callbackPressKey('graph', ord('i'))),
+        menuItem.MenuItem(label="Bounds", children=(
+          menuItem.MenuItem(label="Local Max",
+                            callback=lambda item: self._callbackSet('graph', 'bounds', GraphBounds.LOCAL_MAX, ord('b')),
+                            enabled=lambda: self._getItemEnabled('graph', 'bounds', GraphBounds.LOCAL_MAX)),
+          menuItem.MenuItem(label="Global Max",
+                            callback=lambda item: self._callbackSet('graph', 'bounds', GraphBounds.GLOBAL_MAX, ord('b')),
+                            enabled=lambda: self._getItemEnabled('graph', 'bounds', GraphBounds.GLOBAL_MAX)),
+          menuItem.MenuItem(label="Tight",
+                            callback=lambda item: self._callbackSet('graph', 'bounds', GraphBounds.TIGHT, ord('b')),
+                            enabled=lambda: self._getItemEnabled('graph', 'bounds', GraphBounds.TIGHT)),
         )),)),
-      menuItem.MenuItem(label="Connections"   , children=(
-        menuItem.MenuItem(label="Identity"            , children=(
-          menuItem.MenuItem(label="IP"                , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Fingerprints"      , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Nicknames"             , callback=self._callbackDefault),
+      menuItem.MenuItem(label="Connections", children=(
+        menuItem.MenuItem(label="Identity",
+                            callback=lambda item: self._callbackPressKey('conn', ord('l'))),
+        menuItem.MenuItem(label="Resolver",
+                            callback=lambda item: self._callbackPressKey('conn', ord('u'))),
+        menuItem.MenuItem(label="Sort Order",
+                            callback=lambda item: self._callbackPressKey('conn', ord('s'))),
         )),
-        menuItem.MenuItem(label="Resolver"            , children=(
-          menuItem.MenuItem(label="auto"              , callback=self._callbackDefault),
-          menuItem.MenuItem(label="proc"              , callback=self._callbackDefault),
-          menuItem.MenuItem(label="netstat"           , callback=self._callbackDefault),
-          menuItem.MenuItem(label="ss"                , callback=self._callbackDefault),
-          menuItem.MenuItem(label="lsof"              , callback=self._callbackDefault),
-          menuItem.MenuItem(label="sockstat"          , callback=self._callbackDefault),
-          menuItem.MenuItem(label="sockstat (bsd)"    , callback=self._callbackDefault),
-          menuItem.MenuItem(label="procstat (bsd)"    , callback=self._callbackDefault),
-        )),
-        menuItem.MenuItem(label="Sort Order"          , callback=self._callbackDefault),)),
       menuItem.MenuItem(label="Configuration" , children=(
-        menuItem.MenuItem(label="Comments"            , children=(
-          menuItem.MenuItem(label="Hidden"            , callback=self._callbackDefault),
-          menuItem.MenuItem(label="Visible"           , callback=self._callbackDefault),
+        menuItem.MenuItem(label="Comments", children=(
+          menuItem.MenuItem(label="Hidden",
+                            callback=lambda item: self._callbackSet('configFile', 'stripComments', True, ord('s')),
+                            enabled=lambda: self._getItemEnabled('configFile', 'stripComments', True)),
+          menuItem.MenuItem(label="Visible",
+                            callback=lambda item: self._callbackSet('configFile', 'stripComments', False, ord('s')),
+                            enabled=lambda: self._getItemEnabled('configFile', 'stripComments', False)),
         )),
-        menuItem.MenuItem(label="Reload"              , callback=self._callbackDefault),
-        menuItem.MenuItem(label="Reset Tor"           , callback=self._callbackDefault),))
+        menuItem.MenuItem(label="Reload",
+                          callback=lambda item: self._callbackPressKey('configFile', ord('r'))),
+        menuItem.MenuItem(label="Reset Tor",
+                          callback=self._callbackDefault),))
       ))
 
     self._first = [0]
@@ -111,6 +121,8 @@ class Menu():
           elif key == curses.KEY_DOWN:
             self._showNLevel()
             break
+          elif key == 27:
+            break
           elif uiTools.isSelectionKey(key):
             self._handleEvent()
             break
@@ -238,6 +250,9 @@ class Menu():
 
     popup, width, height = popups.init(height=printable+2, width=labelwidth+2, top=2, left=left)
 
+    while self._getCurrentItem().isEnabled() == False:
+      self._moveNLevelDown(height)
+
     if popup.win:
       try:
         while True:
@@ -258,6 +273,10 @@ class Menu():
           elif key == curses.KEY_RIGHT:
             self._showNLevel()
             break
+          elif key == 27:
+            self._first.pop()
+            self._selection.pop()
+            break
           elif uiTools.isSelectionKey(key):
             self._handleEvent()
             self._first.pop()
@@ -277,6 +296,9 @@ class Menu():
     for (index, item) in enumerate(children):
       labelformat = curses.A_STANDOUT if index == self._selection[PARENTLEVEL] else curses.A_NORMAL
 
+      if not item.isEnabled():
+        labelformat = labelformat | uiTools.getColor('yellow')
+
       popup.addstr(top, left, item.getLabel(), labelformat)
       top = top + 1
 
@@ -295,6 +317,9 @@ class Menu():
       self._first[PARENTLEVEL] = 0
       self._selection[PARENTLEVEL] = 0
 
+    while self._getCurrentItem().isEnabled() == False:
+      self._moveNLevelDown(height)
+
   def _moveNLevelUp(self, height):
     printable = self._calculateNLevelHeights(level=PARENTLEVEL)
     parent = self._getCurrentItem(level=PARENTLEVEL)
@@ -311,6 +336,9 @@ class Menu():
     if self._selection[PARENTLEVEL] > printable:
       self._selection[PARENTLEVEL] = printable - 1
 
+    while self._getCurrentItem().isEnabled() == False:
+      self._moveNLevelUp(height)
+
   def _handleEvent(self):
     item = self._getCurrentItem()
 
@@ -322,3 +350,55 @@ class Menu():
   def _callbackDefault(self, item):
     log.log(log.NOTICE, "%s selected" % item.getLabel())
 
+  def _callbackView(self, panelname):
+    control = cli.controller.getController()
+
+    start = control.getPage()
+    panels = control.getDisplayPanels(includeSticky=False)
+    panelnames = [panel.getName() for panel in panels]
+    while not panelname in panelnames:
+      control.nextPage()
+      panels = control.getDisplayPanels(includeSticky=False)
+      panelnames = [panel.getName() for panel in panels]
+
+      if control.getPage() == start:
+        log.log(log.ERR, "Panel %s not found" % panelname)
+        break
+
+  def _getItemEnabled(self, panel, attr, value):
+    control = cli.controller.getController()
+    if control:
+      panel = control.getPanel(panel)
+
+      if panel:
+        return getattr(panel, attr, None) != value
+
+      return False
+
+  def _callbackSet(self, panel, attr, value, key=None):
+    self._callbackView(panel)
+
+    control = cli.controller.getController()
+    panel = control.getPanel(panel)
+
+    panelattr = getattr(panel, attr, None)
+
+    if panelattr != None:
+      if hasattr(panelattr, '__call__'):
+        panelattr(value)
+      elif panelattr != value and key != None:
+        start = panelattr
+        while panelattr != value:
+          panel.handleKey(key)
+          panelattr = getattr(panel, attr, None)
+          if panelattr == start:
+            log.log(log.ERR, "Could not set %s.%s" % (panel, attr))
+            break
+
+  def _callbackPressKey(self, panel, key):
+    self._callbackView(panel)
+
+    control = cli.controller.getController()
+    panel = control.getPanel(panel)
+    panel.handleKey(key)
+
diff --git a/src/util/menuItem.py b/src/util/menuItem.py
index 3dbf922..6868db6 100644
--- a/src/util/menuItem.py
+++ b/src/util/menuItem.py
@@ -5,10 +5,11 @@ Menu Item class, used by the drop-down menus
 class MenuItem():
   """Contains title, callback handler and possible children"""
 
-  def __init__(self, label=None, callback=None, children=[]):
+  def __init__(self, label=None, callback=None, children=[], enabled=None):
     self._label = label
     self._callback = callback
     self._children = children
+    self._enabled = enabled
 
   def getLabel(self):
     return self._label
@@ -19,6 +20,14 @@ class MenuItem():
   def isParent(self):
     return self._children != []
 
+  def isEnabled(self):
+    if self._enabled == None:
+      return True
+    elif hasattr(self._enabled, '__call__'):
+      return self._enabled()
+    else:
+      return self._enabled
+
   def getChildren(self):
     return self._children
 





More information about the tor-commits mailing list