diff --git a/twander.py b/twander.py index 21fc81b..43edde6 100755 --- a/twander.py +++ b/twander.py @@ -6,7 +6,7 @@ # Program Information PROGNAME = "twander" -RCSID = "$Id: twander.py,v 2.76 2003/01/20 07:58:10 tundra Exp $" +RCSID = "$Id: twander.py,v 2.77 2003/01/22 02:27:59 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information @@ -72,11 +72,7 @@ #----------------------------------------------------------# ##### -# Defaults -##### - -##### -# Key Assignments +# Default Key Assignments ##### # General Program Commands @@ -128,24 +124,8 @@ MOUSESEL = '' # Select item w/mouse -# Name The Key/Mouse Assignments Which We Do Not Allow To Be Rebound In The Config File - -NOREBIND = ["MOUSECTX", "MOUSEDIR", "MOUSEBACK", "MOUSEUP", "MOUSESEL"] - - ##### -# System-Related Defaults -##### - -# Default startup directory -STARTDIR = os.path.abspath("." + os.sep) - -# Home director -HOME = os.getenv("HOME") or STARTDIR - - -##### -# Program Constants +# GUI Default Size And Colors ##### HEIGHT = 25 @@ -215,16 +195,23 @@ ##### -AUTOREFRESH = TRUE # Automatically refresh the directory display -DEBUGLEVEL = 0 # No debug output -MAXDIRBUF = 250 # Maximum size of UI.AllDirs -MAXHISTBUF = 250 # Maximum size of UI.CmdHist -NODETAILS = FALSE # TRUE means details can never be displayed -NONAVIGATE = FALSE # TRUE means that all directory navigation is prevented -USETHREADS = TRUE # Use threads on Unix -USEWIN32ALL = TRUE # Use win32all features if available -WIN32ALLON = TRUE # Flag for toggling win32all features while running -WARN = TRUE # Warnings on +AUTOREFRESH = TRUE # Automatically refresh the directory display +DEBUGLEVEL = 0 # No debug output +MAXDIR = 32 # Maximum number of directories to track +MAXDIRBUF = 250 # Maximum size of UI.AllDirs +MAXHIST = 32 # Maximum length of Command History +MAXHISTBUF = 250 # Maximum size of UI.CmdHist +MAXNESTING = 32 # Maximum depth of nested variable definitions +NODETAILS = FALSE # TRUE means details can never be displayed +NONAVIGATE = FALSE # TRUE means that all directory navigation is prevented +REFRESHINT = 3000 # Interval (ms) for automatic refresh +QUOTECHAR = '\"' # Character to use when quoting Built-In Variables +USETHREADS = TRUE # Use threads on Unix +USEWIN32ALL = TRUE # Use win32all features if available +WARN = TRUE # Warnings on +WIN32ALLON = TRUE # Flag for toggling win32all features while running +WIN32ENCODING = 'mbcs' # Default Win32 character encoding scheme + ##### # Constants @@ -236,7 +223,19 @@ MB = KB * KB # 1 MB constant GB = MB * KB # 1 GB constant POLLINT = 20 # Interval (ms) the poll routine should run -REFRESHINT = 3000 # Interval (ms) for automatic refresh +PSEP = os.sep # Character separating path components +SHOWDRIVES = '\\\\' # Logical directory name for Win32 Drive Lists + + +##### +# System-Related Defaults +##### + +# Default startup directory +STARTDIR = os.path.abspath("." + os.sep) + +# Home directory +HOME = os.getenv("HOME") or STARTDIR # Get hostname @@ -264,6 +263,19 @@ else: FULLNAME = HOSTNAME + + +##### +# GUI-Related Stuff +##### + +# Constants + +ROOTBORDER = 1 +MENUBORDER = 2 +MENUPADX = 2 +MENUOFFSET = ROOTBORDER + MENUBORDER + MENUPADX + # Key & Button Event Masks ShiftMask = (1<<0) @@ -295,9 +307,16 @@ AltMask = Mod1Mask -# Stat-Related Constants +# Name The Key/Mouse Assignments Which We Do Not Allow To Be Rebound In The Config File -if WIN32ALL and USEWIN32ALL and WIN32ALLON: +NOREBIND = ["MOUSECTX", "MOUSEDIR", "MOUSEBACK", "MOUSEUP", "MOUSESEL"] + + +##### +# Stat-Related Stuff +##### + +if WIN32ALL: # Used with win32all-based permissions logic. # Format for each entry is: (mask to test, symbol if true). @@ -335,41 +354,25 @@ ST_SZLEN + ST_SZMTIME -# String used to separate symlink entry from its real path +# Misc. Stat-Related Strings +FILEGROUP = "group" +FILEOWNER = "owner" SYMPTR = " -> " +UNAVAILABLE = "Unavailable" +WIN32GROUP = "win32" + FILEGROUP +WIN32OWNER = "win32" + FILEOWNER ##### -# General Literals -##### - -PSEP = os.sep # Character separating path components -SHOWDRIVES = '\\\\' # Logical directory name for Win32 Drive Lists - - -##### -# GUI-Related Contsants -#### - -ROOTBORDER = 1 -MENUBORDER = 2 -MENUPADX = 2 -MENUOFFSET = ROOTBORDER + MENUBORDER + MENUPADX - -##### # Configuration File Related Constants ##### ASSIGN = "=" # Assignment for variable definitions - CONF = "" # Config file user selected with -c option COMMENT = r"#" # Comment introducer string ENVVBL = r'$' # Symbol denoting an environment variable -MAXDIR = 32 # Maximum number of directories to track -MAXHIST = 32 # Maximum length of Command History -MAXNESTING = 32 # Maximum depth of nested variable definitions -QUOTECHAR = '\"' # Character to use when quoting Built-In Variables + # Variable Name Pattern Matching Stuff @@ -403,7 +406,10 @@ # Menu, Error, Information, & Warning Messages ##### -# Menu-Related Strings +# Title-Bar Strings + +TTLFILES = " Total Files: " +TTLSIZE = " Total Size: " # Menu Button Titles @@ -414,6 +420,7 @@ # Help Menu-Related +ABOUT = "%s %s\n\nCopyright %s %s\n%s\n\n%s" % (PROGNAME, VERSION, CPRT, DATE, OWNER, RIGHTS) hABOUT = 'About' hCOMMANDS = 'Command Definitions' hDIRSC = 'Directory Shortcuts' @@ -1288,10 +1295,9 @@ def UpdateTitle(self, mainwin): - mainwin.title(PROGNAME + " " + VERSION + " " + FULLNAME + \ - ": "+ UI.CurrentDir + " Total Files: " + \ - str(self.DirList.size()) + \ - " Total Size: " + FileLength(self.TotalSize)) + mainwin.title("%s %s %s: %s %s: %s %s: %s" % + (PROGNAME, VERSION, FULLNAME, UI.CurrentDir, + TTLFILES, str(self.DirList.size()), TTLSIZE, FileLength(self.TotalSize))) # End of method 'twanderUI.UpdateTitle()' @@ -1330,7 +1336,7 @@ x, y = UI.DirList.winfo_pointerxy() # Position near mouse PopupMenu(UI.DirBtn.menu, x, y) # Display Directory Menu -# End Of 'MouseClick() +# End Of 'MouseClick()' ##### @@ -2202,7 +2208,7 @@ win32stat = GetFileAttributes(fn) mode = "" except: - mode = "Unavailable" + mode = UNAVAILABLE if not mode: @@ -2293,8 +2299,8 @@ elif OSNAME == 'nt': # Defaults - owner = 'win32user' - group = 'win32group' + owner = WIN32OWNER + group = WIN32GROUP if WIN32ALL and USEWIN32ALL and WIN32ALLON: try: @@ -2304,16 +2310,14 @@ sidg = hg.GetSecurityDescriptorGroup() owner = LookupAccountSid(WIN32HOST, sido)[0] group = LookupAccountSid(WIN32HOST, sidg)[0] - owner = str(owner[:ST_SZUNAME-1]) - group = str(group[:ST_SZGNAME-1]) except: - owner = 'Unavailable' - group = 'Unavailable' + owner = UNAVAILABLE + group = UNAVAILABLE # Default names for all other OSs else: - owner = OSNAME + 'user' - group = OSNAME + 'group' + owner = OSNAME + FILEOWNER + group = OSNAME + FILEGROUP # Add them to the detail @@ -2344,8 +2348,27 @@ detlist[index] += ftime + (ST_SZMTIME - len(ftime)) * " " - # File name - detlist[index] += all[index] + # Add the File name + + # If we're using win32all, the owner and group names + # we got above came back to us as *unicode* strings. + # This means that detlist[index] got promoted to unicode + # when we added these strings to it. Ordinarily, this + # is no problem. However, if the file name we're about + # to add contains an 8-bit character (which is legal + # in Win32) the concatentation to detlist[index} will + # *fail* because Python has no way of knowing how to + # glue together a unicode string and a binary string. + # The workaround is to promote the filename to unicode + # as well (using the default Win32 encoding scheme) + # in every case where win32all was used to get owner/group names. + + if WIN32ALL and USEWIN32ALL and WIN32ALLON: + detlist[index] += unicode(all[index], WIN32ENCODING ) + + # We're either not using win32all or we're on another OS + else: + detlist[index] += all[index] # Include symlink details as necessary if detlist[index][0] == 'l': @@ -2646,10 +2669,7 @@ # Setup the About item - UI.HelpBtn.menu.add_command(label=hABOUT, command=lambda title=hABOUT, - text="%s %s\n\nCopyright %s %s\n%s\n\n%s" % \ - (PROGNAME, VERSION, CPRT, DATE, OWNER, RIGHTS) \ - : showinfo(title, text)) + UI.HelpBtn.menu.add_command(label=hABOUT, command=lambda title=hABOUT, text=ABOUT : showinfo(title, text)) # Enable the menu content @@ -2869,7 +2889,7 @@ debuginfo = [] for l in (UI.OptionsBoolean, UI.OptionsNumeric, UI.OptionsString): for v in l: - debuginfo.append(v + " " * (12-len(v)) + (str(eval(v)) or dNULL)) + debuginfo.append(v + " " * (15-len(v)) + (str(eval(v)) or dNULL)) debuginfo.sort() return debuginfo @@ -2932,7 +2952,8 @@ UI.OptionsString = {"BCOLOR":BCOLOR, "FCOLOR":FCOLOR, "FNAME":FNAME, "FSZ":HFSZ, "FWT":FWT, # Main Font/Colors "MBCOLOR":MBCOLOR, "MFCOLOR":MFCOLOR, "MFNAME":MFNAME, "MFSZ":MFSZ, "MFWT":MFWT, # Menu Font/Colors "HBCOLOR":HBCOLOR, "HFCOLOR":HFCOLOR, "HFNAME":HFNAME, "HFSZ":HFSZ, "HFWT":HFWT, # Help Font/Colors - "MBARCOL":MBARCOL, "QUOTECHAR":QUOTECHAR, "STARTDIR":STARTDIR} # Other + "MBARCOL":MBARCOL, "QUOTECHAR":QUOTECHAR, "STARTDIR":STARTDIR, # Other + "WIN32ENCODING":WIN32ENCODING} # Prepare storage for key bindings UI.KeyBindings = {}