diff --git a/twander.py b/twander.py index f4e2753..a0ef3d1 100755 --- a/twander.py +++ b/twander.py @@ -4,7 +4,7 @@ # For Updates See: http://www.tundraware.com/Software/twander PROGNAME = "twander" -RCSID = "$Id: twander.py,v 2.11 2002/12/14 21:18:15 tundra Exp $" +RCSID = "$Id: twander.py,v 2.12 2002/12/15 21:38:14 tundra Exp $" VERSION = RCSID.split()[2] @@ -58,7 +58,6 @@ QUITPROG = '' # Quit the program READCONF = '' # Re-read the configuration file REFRESH = '' # Refresh screen -RUNCMD = '' # Run arbitrary user command TOGDETAIL = '' # Toggle detail view # Directory Navigation @@ -79,24 +78,28 @@ SELPREV = '' # Select previous item SELEND = '' # Select bottom item SELTOP = '' # Select top item -SELKEY = '' # Select item w/keyboard -SELMOUSE = '' # Select item w/mouse # Intra-Display Movement PGDN = '' # Move page down PGUP = '' # Move page up +# Execute Commands + +RUNCMD = '' # Run arbitrary user command +SELKEY = '' # Select item w/keyboard +SELMOUSE = '' # Select item w/mouse + ##### # System-Related Defaults ##### # Default startup directory -STARTDIR = "." + os.sep +STARTDIR = os.path.abspath("." + os.sep) # Home director -HOME = os.getenv("HOME") or os.path.abspath(STARTDIR) +HOME = os.getenv("HOME") or STARTDIR ##### @@ -231,9 +234,17 @@ ##### -# Error, Information, & Warning Messages +# Debug, Error, Information, & Warning Messages ##### +# Debug Strings + +dCMD = "COMMAND: " +dCMDTBL = "" +dINTVAR = "" +dKEYBINDS = "" +dSYMTBL = "" + # Errors eBADCFGLINE = "Bogus Configuration Entry In Line %s: %s" @@ -345,6 +356,47 @@ def ParseConfFile(event): global CONF, UI + # Cleanout any old configuration data + UI.CmdTable = {} + UI.SymTable = {} + linenum = 0 + + # Unbind all existing key bindings + for x in UI.KeyBindings.keys(): + UI.DirList.unbind(UI.KeyBindings[x]) + + # Initialize keyboard binding variables to their defaults + # These may be overriden in the configuration file + # parsing process. + + UI.KeyBindings = {"KEYPRESS":KEYPRESS, + "QUITPROG":QUITPROG, + "READCONF":READCONF, + "REFRESH":REFRESH, + "TOGDETAIL":TOGDETAIL, + "CHANGEDIR":CHANGEDIR, + "DIRHOME":DIRHOME, + "DIRBACK":DIRBACK, + "DIRSTART":DIRSTART, + "DIRUP":DIRUP, + "MSEBACK":MSEBACK, + "MSEUP":MSEUP, + "SELALL":SELALL, + "SELNEXT":SELNEXT, + "SELNONE":SELNONE, + "SELPREV":SELPREV, + "SELEND":SELEND, + "SELTOP":SELTOP, + "PGDN":PGDN, + "PGUP":PGUP, + "RUNCMD":RUNCMD, + "SELKEY":SELKEY, + "SELMOUSE":SELMOUSE + } + + # Initialize the command menu + UI.CmdBtn.menu.delete(0,END) + # If user specified a config file, try that # Otherwise use HOME == either $HOME or ./ @@ -354,20 +406,10 @@ cf = open(CONF) except: WrnMsg(wCONFOPEN % (CONF, wNOCMDS)) - UI.CmdTable = {} - UI.Symtable = {} return # Successful open of config file - Begin processing it - # Cleanout any old configuration data - UI.CmdTable = {} - UI.SymTable = {} - linenum = 0 - - # Initialize the command menu - UI.CmdBtn.menu.delete(0,END) - # Process and massage the configuration file for line in cf.read().splitlines(): linenum += 1 @@ -382,6 +424,11 @@ if line: ParseLine(line, linenum) + + # Rebind all the handlers + UI.BindAllHandlers() + + # Close the config file cf.close() # Set the Command Menu Contents @@ -389,15 +436,22 @@ # Dump tables if we're debugging if DEBUG: - print "SYMBOL TABLE:\n" + print dSYMTBL + "\n" for sym in UI.SymTable.keys(): print sym + " " * (16-len(sym)) + UI.SymTable[sym] + print - print"\nCOMMAND TABLE:\n" + print dCMDTBL + "\n" for key in UI.CmdTable.keys(): name = UI.CmdTable[key][0] cmd = UI.CmdTable[key][1] print key + " " + name + " " * (16-len(name)) + cmd + print + + print dKEYBINDS + "\n" + for key in UI.KeyBindings.keys(): + print key + " " * (10-len(key)) + UI.KeyBindings[key] + print # End of 'ParseConfFile()' @@ -410,7 +464,7 @@ def ParseLine(line, num): - global UI + global UI, PGUP revar = re.compile(reVAR) # Get rid of trailing newline, if any @@ -466,7 +520,13 @@ ErrMsg(eREDEFVAR % (name, num, line)) sys.exit(1) - UI.SymTable[name] = val + # Distinguish between internal program variables and + # user-defined variables and act accordingly + + if name in UI.KeyBindings.keys(): + UI.KeyBindings[name] = val + else: + UI.SymTable[name] = val ##### # Command Definitions @@ -651,95 +711,104 @@ self.vSB.pack(side=RIGHT, fill=Y) self.DirList.pack(side=LEFT, fill=BOTH, expand=1) - ##### - # Bind the relevant event handlers - ##### + # End if method 'twanderUI.__init__()' + + + ##### + # Bind the relevant event handlers + ##### + def BindAllHandlers(self): + # General Program Commands # Bind handler for individual keystrokes - self.DirList.bind(KEYPRESS, KeystrokeHandler) + self.DirList.bind(self.KeyBindings["KEYPRESS"], KeystrokeHandler) # Bind handler for "Quit Program" - self.DirList.bind(QUITPROG, KeyQuitProg) + self.DirList.bind(self.KeyBindings["QUITPROG"], KeyQuitProg) # Bind handler for "Read Config File" - self.DirList.bind(READCONF, ParseConfFile) + self.DirList.bind(self.KeyBindings["READCONF"], ParseConfFile) # Bind handler for "Refresh Screen" - self.DirList.bind(REFRESH, RefreshDirList) - - # Bind handler for "Run Command" - self.DirList.bind(RUNCMD, KeyRunCommand) + self.DirList.bind(self.KeyBindings["REFRESH"], RefreshDirList) # Bind handler for "Toggle Detail" - self.DirList.bind(TOGDETAIL, KeyToggleDetail) + self.DirList.bind(self.KeyBindings["TOGDETAIL"], KeyToggleDetail) # Directory Navigation # Bind handler for "Change Directory" - self.DirList.bind(CHANGEDIR, ChangeDir) + self.DirList.bind(self.KeyBindings["CHANGEDIR"], ChangeDir) # Bind handler for "Home Dir" - self.DirList.bind(DIRHOME, KeyHomeDir) + self.DirList.bind(self.KeyBindings["DIRHOME"], KeyHomeDir) # Bind handler for "Previous Dir" - self.DirList.bind(DIRBACK, KeyBackDir) + self.DirList.bind(self.KeyBindings["DIRBACK"], KeyBackDir) # Bind handler for "Starting Dir" - self.DirList.bind(DIRSTART, KeyStartDir) + self.DirList.bind(self.KeyBindings["DIRSTART"], KeyStartDir) # Bind handler for "Up Dir" - self.DirList.bind(DIRUP, KeyUpDir) + self.DirList.bind(self.KeyBindings["DIRUP"], KeyUpDir) # Bind handler for "Mouse Back Dir" - self.DirList.bind(MSEBACK, KeyBackDir) + self.DirList.bind(self.KeyBindings["MSEBACK"], KeyBackDir) # Bind handler for "Mouse Up Dir" - self.DirList.bind(MSEUP, KeyUpDir) + self.DirList.bind(self.KeyBindings["MSEUP"], KeyUpDir) # Selection Keys # Bind handler for "Select All" - self.DirList.bind(SELALL, KeySelAll) + self.DirList.bind(self.KeyBindings["SELALL"], KeySelAll) # Bind handler for "Next Item" - self.DirList.bind(SELNEXT, KeySelNext) + self.DirList.bind(self.KeyBindings["SELNEXT"], KeySelNext) # Bind handler for "Select No Items" - self.DirList.bind(SELNONE, KeySelNone) + self.DirList.bind(self.KeyBindings["SELNONE"], KeySelNone) # Bind handler for "Previous Item" - self.DirList.bind(SELPREV, KeySelPrev) + self.DirList.bind(self.KeyBindings["SELPREV"], KeySelPrev) # Bind handler for "First Item" - self.DirList.bind(SELTOP, KeySelTop) + self.DirList.bind(self.KeyBindings["SELTOP"], KeySelTop) # Bind handler for "Last Item" - self.DirList.bind(SELEND, KeySelEnd) - - # Bind handler for "Item Select" - self.DirList.bind(SELKEY, DirListHandler) - - # Bind handler for "Mouse Select" - self.DirList.bind(SELMOUSE, DirListHandler) - + self.DirList.bind(self.KeyBindings["SELEND"], KeySelEnd) # Intra-display movement # Bind Handler for "Move Page Down - self.DirList.bind(PGDN, KeyPageDown) + self.DirList.bind(self.KeyBindings["PGDN"], KeyPageDown) # Bind Handler for "Move Page Up" - self.DirList.bind(PGUP, KeyPageUp) + self.DirList.bind(self.KeyBindings["PGUP"], KeyPageUp) + + + # Execute commands + + # Bind handler for "Run Command" + self.DirList.bind(self.KeyBindings["RUNCMD"], KeyRunCommand) + + # Bind handler for "Item Select" + self.DirList.bind(self.KeyBindings["SELKEY"], DirListHandler) + + # Bind handler for "Mouse Select" + self.DirList.bind(self.KeyBindings["SELMOUSE"], DirListHandler) # Give the listbox focus so it gets keystrokes self.DirList.focus() - # End if method 'twanderUI.__init__()' + # End Of method 'twanderUI.BindAllHandlers() + + ##### @@ -906,7 +975,7 @@ # Just dump command if we're debugging if DEBUG: - print cmd + print dCMD, cmd # Otherwise,actually execute the command else: @@ -1574,7 +1643,7 @@ if opt == "-b": BCOLOR = val if opt == "-c": - CONF = val + CONF = os.path.abspath(val) if opt == "-d": DEBUG = TRUE if opt == "-f": @@ -1603,6 +1672,19 @@ HEIGHT = val +# List of internal program variables to dump during debug sessions + +DebugVars = ["OSNAME", "STARTDIR", "HOME", "CONF", "HEIGHT", "WIDTH", + "BCOLOR", "FCOLOR", "FNAME", "FSZ", "FWT", + "AUTOREFRESH", "DEBUG", "WARN"] + +# Dump program variable during debug sessions +if DEBUG: + print dINTVAR + "\n" + for v in DebugVars: + print v + " " * (12-len(v)) + str(eval(v)) + print + # Create an instance of the UI UIroot = Tk() UI = twanderUI(UIroot) @@ -1639,9 +1721,15 @@ UI.BuiltIns = {DIR:"", SELECTION:"", SELECTIONS:"", DSELECTION:"", DSELECTIONS:"", PROMPT:""} +# Prepare storage for key bindings +UI.KeyBindings = {} + # Parse the and store configuration file, if any ParseConfFile(None) +# Setup event handlers +UI.BindAllHandlers() + # Initialize directory stack UI.LastDir = []