[tor-commits] [arm/release] Configuration confirmation page for setup wizard

atagar at torproject.org atagar at torproject.org
Sun Jul 17 06:08:30 UTC 2011


commit 1bb80486d2a8c9221c1e1cf7084d6245f43a24fd
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Jul 6 17:51:00 2011 -0700

    Configuration confirmation page for setup wizard
    
    This provides a dialog in the relay setup wizard with the torrc that'll be
    created (with syntax hilighing, scrolling, etc).
---
 src/cli/wizard.py |  110 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/util/panel.py |   11 +++--
 2 files changed, 114 insertions(+), 7 deletions(-)

diff --git a/src/cli/wizard.py b/src/cli/wizard.py
index 8ad7208..946ecd1 100644
--- a/src/cli/wizard.py
+++ b/src/cli/wizard.py
@@ -264,8 +264,19 @@ def showWizard():
       if selection == BACK: relayType = None
       elif selection == NEXT:
         generatedTorrc = getTorrc(relayType, config)
-        log.log(log.NOTICE, "Resulting torrc:\n%s" % generatedTorrc)
-        break # TODO: implement next screen
+        
+        dataDir = CONFIG["startup.dataDirectory"]
+        if not dataDir.endswith("/"): dataDir += "/"
+        torrcLocation = os.path.expanduser(dataDir) + "torrc"
+        
+        cli.controller.getController().requestRedraw(True)
+        confirmationSelection = showConfirmationDialog(generatedTorrc, torrcLocation)
+        
+        if confirmationSelection == NEXT:
+          log.log(log.NOTICE, "Resulting torrc:\n%s" % generatedTorrc)
+          break # TODO: implement next screen
+        elif confirmationSelection == CANCEL:
+          break
     
     # redraws screen to clear away the dialog we just showed
     cli.controller.getController().requestRedraw(True)
@@ -507,6 +518,101 @@ def getTorrc(relayType, config):
   
   return torConfig.renderTorrc(template, templateOptions)
 
+def showConfirmationDialog(torrcContents, torrcLocation):
+  """
+  Shows a confirmation dialog with the given torrc contents, returning CANCEL,
+  NEXT, or BACK based on the selection.
+  
+  Arguments:
+    torrcContents - lines of torrc contents to be presented
+    torrcLocation - path where the torrc will be placed
+  """
+  
+  torrcLines = torrcContents.split("\n")
+  options = ["Cancel", "Back to Setup", "Start Tor"]
+  
+  control = cli.controller.getController()
+  screenHeight = control.getScreen().getmaxyx()[0]
+  stickyHeight = sum([stickyPanel.getHeight() for stickyPanel in control.getStickyPanels()])
+  isScrollbarVisible = len(torrcLines) + stickyHeight + 5 > screenHeight
+  
+  xOffset = 3 if isScrollbarVisible else 0
+  popup, width, height = cli.popups.init(len(torrcLines) + 5, 84 + xOffset)
+  if not popup: return False
+  
+  try:
+    scroll, selection = 0, 2
+    curses.cbreak()
+    
+    while True:
+      popup.win.erase()
+      popup.win.box()
+      
+      # renders the scrollbar
+      if isScrollbarVisible:
+        popup.addScrollBar(scroll, scroll + height - 5, len(torrcLines), 1, height - 4, 1)
+      
+      # shows the path where the torrc will be placed
+      titleMsg = "The following will be placed at '%s':" % torrcLocation
+      popup.addstr(0, 0, titleMsg, curses.A_STANDOUT)
+      
+      # renders the torrc contents
+      for i in range(scroll, min(len(torrcLines), height - 5 + scroll)):
+        # parses the argument and comment from options
+        option, arg, comment = uiTools.cropStr(torrcLines[i], width - 4 - xOffset), "", ""
+        
+        div = option.find("#")
+        if div != -1: option, comment = option[:div], option[div:]
+        
+        div = option.find(" ")
+        if div != -1: option, arg = option[:div], option[div:]
+        
+        drawX = 2 + xOffset
+        popup.addstr(i + 1 - scroll, drawX, option, curses.A_BOLD | uiTools.getColor("green"))
+        drawX += len(option)
+        popup.addstr(i + 1 - scroll, drawX, arg, curses.A_BOLD | uiTools.getColor("cyan"))
+        drawX += len(arg)
+        popup.addstr(i + 1 - scroll, drawX, comment, uiTools.getColor("white"))
+      
+      # divider between the torrc and the options
+      popup.addch(height - 4, 0, curses.ACS_LTEE)
+      popup.addch(height - 4, width, curses.ACS_RTEE)
+      popup.hline(height - 4, 1, width - 1)
+      if isScrollbarVisible: popup.addch(height - 4, 2, curses.ACS_BTEE)
+      
+      # renders the selection options
+      confirmationMsg = "Run tor with the above configuration?"
+      popup.addstr(height - 3, width - len(confirmationMsg) - 1, confirmationMsg, uiTools.getColor("green") | curses.A_BOLD)
+      
+      drawX = width - 1
+      for i in range(len(options) - 1, -1, -1):
+        optionLabel = " %s " % options[i]
+        drawX -= (len(optionLabel) + 4)
+        
+        selectionFormat = curses.A_STANDOUT if i == selection else curses.A_NORMAL
+        popup.addstr(height - 2, drawX, "[", uiTools.getColor("green"))
+        popup.addstr(height - 2, drawX + 1, optionLabel, uiTools.getColor("green") | selectionFormat | curses.A_BOLD)
+        popup.addstr(height - 2, drawX + len(optionLabel) + 1, "]", uiTools.getColor("green"))
+        
+        drawX -= 1 # space gap between the options
+      
+      popup.win.refresh()
+      key = cli.controller.getController().getScreen().getch()
+      
+      if key == curses.KEY_LEFT:
+        selection = (selection - 1) % len(options)
+      elif key == curses.KEY_RIGHT:
+        selection = (selection + 1) % len(options)
+      elif uiTools.isScrollKey(key):
+        scroll = uiTools.getScrollPosition(key, scroll, height - 5, len(torrcLines))
+      elif uiTools.isSelectionKey(key):
+        if selection == 0: return CANCEL
+        elif selection == 1: return BACK
+        else: return NEXT
+      elif key == 27: return CANCEL
+  finally:
+    cli.popups.finalize()
+
 def _splitStr(msg, width):
   """
   Splits a string into substrings of a given length.
diff --git a/src/util/panel.py b/src/util/panel.py
index 1be2306..5a96623 100644
--- a/src/util/panel.py
+++ b/src/util/panel.py
@@ -628,7 +628,7 @@ class Panel():
     
     return userInput
   
-  def addScrollBar(self, top, bottom, size, drawTop = 0, drawBottom = -1):
+  def addScrollBar(self, top, bottom, size, drawTop = 0, drawBottom = -1, drawLeft = 0):
     """
     Draws a left justified scroll bar reflecting position within a vertical
     listing. This is shorted if necessary, and left undrawn if no space is
@@ -649,6 +649,7 @@ class Panel():
       drawTop    - starting row where the scroll bar should be drawn
       drawBottom - ending row where the scroll bar should end, -1 if it should
                    span to the bottom of the panel
+      drawLeft   - left offset at which to draw the scroll bar
     """
     
     if (self.maxY - drawTop) < 2: return # not enough room
@@ -673,12 +674,12 @@ class Panel():
     # draws scrollbar slider
     for i in range(scrollbarHeight):
       if i >= sliderTop and i <= sliderTop + sliderSize:
-        self.addstr(i + drawTop, 0, " ", curses.A_STANDOUT)
+        self.addstr(i + drawTop, drawLeft, " ", curses.A_STANDOUT)
     
     # draws box around the scroll bar
-    self.win.vline(drawTop, 1, curses.ACS_VLINE, self.maxY - 2)
-    self.win.addch(drawBottom, 1, curses.ACS_LRCORNER)
-    self.win.addch(drawBottom, 0, curses.ACS_HLINE)
+    self.vline(drawTop, drawLeft + 1, drawBottom - 1)
+    self.addch(drawBottom, drawLeft + 1, curses.ACS_LRCORNER)
+    self.addch(drawBottom, drawLeft, curses.ACS_HLINE)
   
   def _resetSubwindow(self):
     """





More information about the tor-commits mailing list