diff --git a/twander.py b/twander.py index 157bae6..8932100 100755 --- a/twander.py +++ b/twander.py @@ -6,12 +6,12 @@ # Program Information PROGNAME = "twander" -RCSID = "$Id: twander.py,v 3.103 2003/02/23 22:50:10 tundra Exp $" -VERSION = RCSID.split()[2] +RCSID = "$Id: twander.py,v 3.104 2003/02/25 00:08:23 tundra Exp $" +VERSION = RCSID.split()[2] # Copyright Information -DATE = "2002-2003" +DATE = "2002-2003" CPRT = chr(169) OWNER = "TundraWare Inc." RIGHTS = "All Rights Reserved." @@ -112,6 +112,7 @@ SELPREV = '' # Select previous item SELEND = '' # Select bottom item SELTOP = '' # Select top item +SELWILD = '' # Select using wildcards # Scrolling Commands @@ -249,14 +250,14 @@ # Symbolic Constants Needed Below ##### -NOCMDSHELL = '""' +CMDSHELLESC = '#' ##### # Defaults ##### AUTOREFRESH = TRUE # Automatically refresh the directory display -CMDSHELL = NOCMDSHELL # Shell definition to use with manual command invocations +CMDSHELL = "" # No CMDSHELL processing DEBUGLEVEL = 0 # No debug output MAXDIR = 32 # Maximum number of directories to track MAXDIRBUF = 250 # Maximum size of UI.AllDirs @@ -287,7 +288,7 @@ POLLINT = 20 # Interval (ms) the poll routine should run PSEP = os.sep # Character separating path components SHOWDRIVES = '\\\\' # Logical directory name for Win32 Drive Lists - +STRICTMATCH = '#' # Tells wildcard system to enforce strict matching ##### # System-Related Defaults @@ -559,8 +560,10 @@ pCHPATH = "Change Path" pENCMD = "Enter Command To Run:" pENPATH = "Enter New Path Desired:" +pENWILD = "Enter Selection Wildcard:" pMANUALCMD = "Manual Command Entry" pRUNCMD = "Run Command" +pWILDSEL = "Selection By Wildcard" # Warnings @@ -580,6 +583,7 @@ wUNDEFVBL = "Ignoring Line %s.\nUndefined Variable %s Referenced:\n\n%s" wVBLTOODEEP = "Ignoring Line %s.\nVariable Definition Nested Too Deeply:\n\n%s" wWARN = "WARNING" +wWILDCOMP = "Cannot Compile Wilcard Expression: %s" ##### @@ -796,6 +800,7 @@ "SELPREV":SELPREV, "SELEND":SELEND, "SELTOP":SELTOP, + "SELWILD":SELWILD, "PGDN":PGDN, "PGUP":PGUP, "PGRT":PGRT, @@ -884,6 +889,8 @@ if DoOptionsProcessing: ProcessOptions() + return 'break' + # End of 'ParseConfFile()' @@ -1032,10 +1039,9 @@ return elif name in UI.OptionsString.keys(): - # RHS cannot be null + # RHS null means line ignored - option left set to default value if not val: - WrnMsg(wBADRHS % (num, line)) - return + pass else: globals()[name] = val @@ -1436,11 +1442,14 @@ # Bind handler for "Previous Item" self.DirList.bind(self.KeyBindings["SELPREV"], KeySelPrev) + # Bind handler for "Last Item" + self.DirList.bind(self.KeyBindings["SELEND"], KeySelEnd) + # Bind handler for "First Item" self.DirList.bind(self.KeyBindings["SELTOP"], KeySelTop) - # Bind handler for "Last Item" - self.DirList.bind(self.KeyBindings["SELEND"], KeySelEnd) + # Bind handler for "Select With Wildcard" + self.DirList.bind(self.KeyBindings["SELWILD"], KeySelWild) ### # Scrolling Keys @@ -1643,7 +1652,7 @@ def UpdateTitle(self, mainwin): mainwin.title("%s %s %s: %s %s %s %s %s" % - (PROGNAME, VERSION[0:3], FULLNAME, UI.CurrentDir, + (PROGNAME, VERSION, FULLNAME, UI.CurrentDir, TTLFILES, str(self.DirList.size()), TTLSIZE, FileLength(self.TotalSize))) # End of method 'twanderUI.UpdateTitle()' @@ -1722,11 +1731,14 @@ UI.LastCmd = "" UI.LastDir = [] UI.LastPathEntered = "" + UI.LastSelWildcard = "" for x in [UI.HistBtn, UI.DirBtn]: x.menu.delete(0,END) x['menu'] = x.menu x.config(state=DISABLED) + + return 'break' # End of 'ClearHistory()' @@ -1746,6 +1758,7 @@ HFSZ -= 1 SetupGUI() + return 'break' # End of 'FontDecr()' @@ -1762,6 +1775,7 @@ HFSZ += 1 SetupGUI() + return 'break' # End of 'FontIncr()' @@ -1861,6 +1875,8 @@ UI.SetDetailedView(not UI.DetailsOn) RefreshDirList(event) + return 'break' + # End of 'KeyToggleDetail()' ##### @@ -1874,6 +1890,8 @@ WIN32ALLON = not WIN32ALLON RefreshDirList(event) + return 'break' + # End of 'KeyToggleWin32All()' @@ -1895,6 +1913,8 @@ KeySelTop(event) UI.DirList.focus() + return 'break' + # End of 'KeyChangeDir()' @@ -1907,6 +1927,8 @@ if HOME: LoadDirList(HOME) + return 'break' + # End of 'KeyHomeDir()' @@ -1925,6 +1947,8 @@ else: pass + return 'break' + # End of 'KeyBackDir()' @@ -1935,6 +1959,8 @@ def KeyRootDir(event): LoadDirList(PSEP) + return 'break' + # End of 'KeyRootDir()' @@ -1945,6 +1971,8 @@ def KeyStartDir(event): LoadDirList(STARTDIR) + return 'break' + # End of 'KeyStartDir()' @@ -1964,6 +1992,8 @@ elif OSNAME == 'nt' and GetWin32Drives(): LoadDirList(SHOWDRIVES) + return 'break' + # End of 'KeyUpDir()' ##### @@ -1978,6 +2008,8 @@ if OSNAME == 'nt' and GetWin32Drives(): LoadDirList(SHOWDRIVES) + return 'break' + # End of 'KeyDriveList() @@ -2004,6 +2036,8 @@ # We never want to select the first item which is ".." UI.DirList.selection_set(1, END) + return 'break' + # End of 'KeySelAll()' @@ -2029,6 +2063,8 @@ if UI.CurrentDir != SHOWDRIVES: UI.DirList.selection_clear(0) + return 'break' + # End of 'KeySelInv()' @@ -2046,6 +2082,8 @@ UI.SetSelection((str(next),), next) + return 'break' + # End of 'KeySelNext()' @@ -2056,6 +2094,8 @@ def KeySelNone(event): UI.DirList.selection_clear(0, END) + return 'break' + # End of 'KeySelNone()' @@ -2072,6 +2112,8 @@ UI.SetSelection((str(prev),), prev) + return 'break' + # End of 'KeySelPrev()' @@ -2087,6 +2129,8 @@ # And setup to last item accordingly UI.SetSelection((str(sz),), sz) + return 'break' + # End of 'KeySelEnd()' @@ -2097,9 +2141,68 @@ def KeySelTop(event): UI.SetSelection(('0',),0) + return 'break' + # End of 'KeySelTop()' +##### +# Event Handler: Select Using Wildcard +##### + +def KeySelWild(event): + + # Ask the user for the wildcard pattern + wc = askstring(pWILDSEL, pENWILD, initialvalue=UI.LastSelWildcard) + + # Return focus to the main interface + UI.DirList.focus() + + # Blank value means to abort + if not wc: + return + + # Save the input - even if it turns out to be + # bogus, its better to have it available for + # subsequent edits since regex's get complicated + + UI.LastSelWildcard = wc + + # Unless the user indicates otherwise, cook the regex so + # a match can occur anywhere on the line + + if wc[0] == STRICTMATCH: + wc = wc[1:] + else: + wc = r".*" + wc + + # Compile it - abort if compilation fails + try: + wild = re.compile(wc) + except: + WrnMsg(wWILDCOMP % wc) + return 'break' + + # Iterate over the current directory listing + # saving the indexes of items which match. + # We start at 1 not 0 because the first entry + # ("..") is never considered when doing wildcard + # matching. + + matches = [] + for x in range(1,UI.DirList.size()): + if wild.match(UI.DirList.get(x)): + matches.append(x) + + # If anything matched, select it + if matches: + UI.SetSelection(matches, matches[0]) + + return 'break' + +# End of 'KeySelWild()' + + #---------------------- Scrolling Keys ---------------------# @@ -2111,6 +2214,8 @@ UI.DirList.yview_scroll(1, "pages") UI.DirList.activate("@0,0") + return 'break' + # End of 'KeyPageDown()' @@ -2122,6 +2227,8 @@ UI.DirList.yview_scroll(-1, "pages") UI.DirList.activate("@0,0") + return 'break' + # End of 'KeyPageUp()' @@ -2132,6 +2239,8 @@ def KeyPageRight(event): UI.DirList.xview_scroll(1, "pages") + return 'break' + # End of 'KeyPageRight()' @@ -2142,6 +2251,8 @@ def KeyPageLeft(event): UI.DirList.xview_scroll(-1, "pages") + return 'break' + # End of 'KeyPageLeft()' @@ -2182,10 +2293,9 @@ # Do CMDSHELL Processing if enabled and requested mycmd = cmd - if CMDSHELL != NOCMDSHELL and DoCmdShell: # See if feature is enabled and requested - if not mycmd.startswith('\\'): # See if user is trying to escape the feature + if CMDSHELL and DoCmdShell: # See if feature is enabled and requested + if not mycmd.startswith(CMDSHELLESC): # See if user is trying to escape the feature mycmd = "%s '%s'" % (CMDSHELL, cmd) - else: # User is escaping the feature mycmd = mycmd[1:] @@ -2202,6 +2312,8 @@ UI.DirList.focus() + return 'break' + # End of 'KeyRunCommand()' @@ -2295,6 +2407,8 @@ elif OSNAME == 'posix': ExecuteCommand(os.path.join(os.path.abspath(UI.CurrentDir), selected), '') + return 'break' + # End of 'DirListHandler()' @@ -2312,6 +2426,7 @@ # Inhibit further processing of key - some Function Keys # have default behavior in Tk which we want to suppress. + return "break" # End of 'DirSCKeyPress()' @@ -3135,6 +3250,8 @@ # Release the mutex UI.DirListMutex.unlock() + return 'break' + # End of 'RefreshDirList() @@ -3488,6 +3605,9 @@ # Initialize storage for last manually entered directory path UI.LastPathEntered = "" +# Initialize storage for last manually entered selection wildcard +UI.LastSelWildcard = "" + # And current location UI.CurrentDir = ""