diff --git a/twander.py b/twander.py index a372879..0655af1 100755 --- a/twander.py +++ b/twander.py @@ -6,7 +6,7 @@ # Program Information PROGNAME = "twander" -RCSID = "$Id: twander.py,v 3.183 2005/01/28 23:18:35 tundra Exp $" +RCSID = "$Id: twander.py,v 3.184 2005/01/29 00:37:38 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information @@ -195,6 +195,7 @@ MOUSEWILD = '' # Pop-up Wildcard Menu FILTERWILD = '' # Filter file list with wildcard SELWILD = '' # Select using wildcards +TOGFILT = '' # Invert the filter wildcard logic ##### @@ -286,6 +287,7 @@ DEBUGLEVEL = 0 # No debug output DEFAULTSEP = "==>" # Default separator in PROMPT and YES definitions FORCEUNIXPATH = False # Force Unix path separators regardless of OS +INVERTFILTER = False # Invert wildcard filtering logic MAXMENU = 32 # Maximum length of displayed menu MAXMENUBUF = 250 # Maximum size of internal menu buffer MAXNESTING = 32 # Maximum depth of nested variable definitions @@ -990,6 +992,34 @@ # End of 'FileLength()' +##### +# Check to see if a passed string matches/does not match the currently +# active filtering wildcard. If there is no active wildcard, everything +# passes. +##### + +def FilterWildcardMatch(matchthis): + + # If there's not active filter, everything matches + + if not UI.FilterWildcard[1]: + matched = True + + elif UI.FilterWildcard[1].match(matchthis): + matched = True + + else: + matched = False + + # Invert the sense of the logic if so dictated, but + # only if there is actually a wildcard active. + + if UI.FilterWildcard[1] and INVERTFILTER: + matched = not matched + + return matched + +# End of 'FilterWildcardMatch()' ##### # Pad A String With Spaces To Specified Width. @@ -1147,6 +1177,7 @@ "MOUSEWILD":MOUSEWILD, "FILTERWILD":FILTERWILD, "SELWILD":SELWILD, + "TOGFILT":TOGFILT, } # Set all the program options to their default values @@ -1668,7 +1699,7 @@ def SetupGUI(): # Start in detailed mode unless details are inhibited - UI.SetDetailedView(~NODETAILS) + UI.SetDetailedView(not NODETAILS) # Rebind all the handlers UI.BindAllHandlers() @@ -2013,9 +2044,6 @@ # Bind handler to invoke Clear Command History self.DirList.bind(self.KeyBindings["CLRHIST"], ClearHistory) - # Bind handler for "Select With Wildcard" - self.DirList.bind(self.KeyBindings["FILTERWILD"], lambda event : KeySelWild(event, FilterWildcard=True)) - # Bind handler to invoke Decrement Font Size self.DirList.bind(self.KeyBindings["FONTDECR"], FontDecr) @@ -2037,9 +2065,6 @@ # Bind handler to invoke Directory Menu self.DirList.bind(self.KeyBindings["MOUSESORT"], MouseClick) - # Bind handler to invoke Directory Menu - self.DirList.bind(self.KeyBindings["MOUSEWILD"], MouseClick) - # Bind handler for individual keystrokes self.DirList.bind(self.KeyBindings["KEYPRESS"], KeystrokeHandler) @@ -2120,8 +2145,6 @@ # Bind handler for "First Item" self.DirList.bind(self.KeyBindings["SELTOP"], KeySelTop) - # Bind handler for "Select With Wildcard" - self.DirList.bind(self.KeyBindings["SELWILD"], KeySelWild) ### # Scrolling Keys @@ -2218,6 +2241,23 @@ self.DirList.bind(self.KeyBindings["SORTSEP"], lambda event : KeySetSortParm(parm=fSEPARATE)) + ##### + # Wildcard Related Keys + ##### + + # Bind handler to invoke Directory Menu + self.DirList.bind(self.KeyBindings["MOUSEWILD"], MouseClick) + + # Bind handler for "Filter With Wildcard" + self.DirList.bind(self.KeyBindings["FILTERWILD"], lambda event : KeySelWild(event, FilterWildcard=True)) + + # Bind handler for "Select With Wildcard" + self.DirList.bind(self.KeyBindings["SELWILD"], KeySelWild) + + # Bind handler for "Toggle Filter By Wildcard" + self.DirList.bind(self.KeyBindings["TOGFILT"], KeyToggleFilter) + + # Give the listbox focus so it gets keystrokes self.DirList.focus() @@ -2379,10 +2419,13 @@ sortedby = "%s %s " % (TTLSORTFLD, srtfld) autostate = YesOrNo[AUTOREFRESH] + refreshing - filter = "%s %s" % (TTLFILTER, UI.FilterWildcard[0]) + filterwc = UI.FilterWildcard[0] + if INVERTFILTER: + filterwc = "NOT " + filterwc + filter = "%s %s" % (TTLFILTER, filterwc) mainwin.title("%s %s %s: %s %s %s %s %s %s %s%s %s %s" % - (PROGNAME, VERSION, FULLNAME, CurrentDir, filter, TTLFILES, + (PROGNAME, VERSION, FULLNAME, CurrentDir, filter, TTLFILES, str(self.DirList.size()), TTLSIZE, FileLength(self.TotalSize), sortedby, sepsort, TTLAUTO, autostate)) # Make sure the titlebar gets updated @@ -2662,6 +2705,24 @@ ##### +# Event Handler: Toggle Wildcard Filter Logic +##### + +def KeyToggleFilter(event): + global INVERTFILTER + + # Only toggle state if there is an active filtering wildcard + + if UI.FilterWildcard[1]: + INVERTFILTER = not INVERTFILTER + RefreshDirList(event) + + return 'break' + +# End of 'KeyToggleFilter()' + + +##### # Event Handler: Toggle Normalized Or Actual File Length Display ##### @@ -3714,16 +3775,14 @@ file += PSEP detail += PSEP - # If wildcard filtering is in effect, only let files through that match + # Check against any active filtering by wildcard. Only allow files through that match. - if UI.FilterWildcard[1]: + matchthis = file + if UI.DetailsOn: + matchthis = detail - matchthis = file - if UI.DetailsOn: - matchthis = detail - - if not UI.FilterWildcard[1].match(matchthis): - continue + if not FilterWildcardMatch(matchthis): + continue # Keep running tally of total files sizes @@ -4478,7 +4537,7 @@ ##### def RefreshDirList(event, ClearFilterWildcard=False): - global UI + global UI, INVERTFILTER # Indicate that we are doing an refresh UI.UpdateTitle(UIroot, refreshing=REFRESHINDI) @@ -4492,6 +4551,8 @@ if ClearFilterWildcard: UI.FilterWildcard = ("None", None) + INVERTFILTER = False + # Get current selection and active @@ -4890,6 +4951,7 @@ "AFTERCLEAR":AFTERCLEAR, "AUTOREFRESH":AUTOREFRESH, "FORCEUNIXPATH":FORCEUNIXPATH, + "INVERTFILTER":INVERTFILTER, "NODETAILS":NODETAILS, "NONAVIGATE":NONAVIGATE, "SORTREVERSE":SORTREVERSE, "SORTSEPARATE":SORTSEPARATE,