diff --git a/twander.py b/twander.py index 461cec0..f37c2cc 100755 --- a/twander.py +++ b/twander.py @@ -6,7 +6,7 @@ # Program Information PROGNAME = "twander" -RCSID = "$Id: twander.py,v 2.84 2003/01/29 17:45:38 tundra Exp $" +RCSID = "$Id: twander.py,v 2.85 2003/01/30 01:10:03 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information @@ -274,10 +274,13 @@ # Constants -ROOTBORDER = 1 -MENUBORDER = 2 -MENUPADX = 2 -MENUOFFSET = ROOTBORDER + MENUBORDER + MENUPADX +CMDMENU_WIDTH = 16 + + +ROOTBORDER = 1 +MENUBORDER = 2 +MENUPADX = 2 +MENUOFFSET = ROOTBORDER + MENUBORDER + MENUPADX # Key & Button Event Masks @@ -341,7 +344,7 @@ # Size of each of the drive detail fields, including room for trailing space. - SZ_DRIVE_LABEL = 14 # Must be wide enough to hold NODRIVE + 1 + SZ_DRIVE_LABEL = 14 # Must be wide enough to hold NODRIVE + 1 or NOLABEL + 1 SZ_DRIVE_FREE = 13 # In this case there is no trailing space but a trailing '/' SZ_DRIVE_TTL = 13 # so we can have a 'free/total' presentation SZ_DRIVE_TYPE = 20 @@ -387,6 +390,7 @@ FILEGROUP = "group" FILEOWNER = "owner" NODRIVE = "" +NOLABEL = "" SYMPTR = " -> " UNAVAILABLE = "Unavailable" WIN32GROUP = "win32" + FILEGROUP @@ -529,6 +533,15 @@ dOPTVAR = hOPTVBLS dSYMTBL = hUSERVBLS +# Debug Formatting + +dCMDWIDTH = 20 +dINTVARWIDTH = 12 +dKEYWIDTH = 16 +dOPTIONWIDTH = 16 +dSCWIDTH = 6 +dUSRVBLWIDTH = 16 + # List of internal program variables to dump during debug sessions DebugVars = ["RCSID", "OSNAME", "HOSTNAME", "USERNAME", "OPTIONS", "CONF", "HOME", "PSEP", "POLLINT"] @@ -620,6 +633,23 @@ ##### +# Pad A String With Trailing Spaces To Specified Width +# Return either that padded string or, if the passed +# string is too large, truncate it and return a string +# of exactly the specified with whose last character is +# a space. +##### + +def PadString(string, width): + + string = string[:(width-1)] + string += " " * (width - len(string)) + return string + +# End of 'PadString()' + + +##### # Parse & Process The Configuraton File # This is called once at program start time # and again any time someone hits the READCONF key @@ -918,7 +948,7 @@ return else: UI.CmdTable[cmdkey] = [cmdname, cmd] - UI.CmdBtn.menu.add_command(label=cmdname + " " * (15-len(cmdname)) + "(" + cmdkey + ")", + UI.CmdBtn.menu.add_command(label=PadString(cmdname, CMDMENU_WIDTH) + "(" + cmdkey + ")", command=lambda cmd=cmdkey: CommandMenuSelection(cmd)) else: @@ -2332,6 +2362,15 @@ for drive in drivelist: + # Drive Label - Drive Might Not Be Available + try: + label = GetVolumeInformation(drive)[0] + except: + label = NODRIVE + + if not label: + label = NOLABEL + # Type Of Drive - We need this now to get hostname drivetype = GetDriveType(drive) typestring = '' @@ -2340,27 +2379,16 @@ if drivetype == type: typestring = stype - # Starts with hostname in Microsoft naming format - entry = '\\\\' - # Machine Hosting The Drive if drivetype == win32con.DRIVE_REMOTE: - name = WNetGetUniversalName(drive, 1).split('\\')[2].capitalize() + name = WNetGetUniversalName(drive, 1) else: - name = WIN32HOST.capitalize() + name = label - entry += name + "\\" - - # Drive Label - Drive Might Not Be Available - try: - label = GetVolumeInformation(drive)[0] - except: - label = NODRIVE - - entry += label + " " * ((SZ_DRIVE_HOST + SZ_DRIVE_LABEL) - len(entry + label)) + entry = PadString(name, SZ_DRIVE_HOST + SZ_DRIVE_LABEL) # Add the drive type - entry += typestring + " " * (SZ_DRIVE_TYPE - len(typestring)) + entry += PadString(typestring, SZ_DRIVE_TYPE) # Get Drive Space Information - Drive Might Not Be Available try: @@ -2375,7 +2403,7 @@ freespace, totalspace = ('0', '0') sizes = "%s/%s" % (freespace, totalspace) - entry += sizes + " " * ((SZ_DRIVE_FREE + SZ_DRIVE_TTL) - len(sizes)) + entry += PadString(sizes, SZ_DRIVE_FREE + SZ_DRIVE_TTL) # Finally, tack on the drive name entry += drive @@ -2482,11 +2510,10 @@ # Pad the result for column alignment - detlist[index] += mode + (ST_SZMODE - len(mode)) * " " + detlist[index] += PadString(mode, ST_SZMODE) # Number of links to entry - detlist[index] += str(stinfo[ST_NLINK]) + \ - ( ST_SZNLINK - len(str(stinfo[ST_NLINK]))) * " " + detlist[index] += PadString(str(stinfo[ST_NLINK]), ST_SZNLINK) # Get first ST_SZxNAME chars of owner and group names on unix @@ -2549,14 +2576,14 @@ # Add them to the detail - detlist[index] += owner + (ST_SZUNAME - len(owner)) * " " - detlist[index] += group + (ST_SZUNAME - len(group)) * " " + detlist[index] += PadString(owner, ST_SZUNAME) + detlist[index] += PadString(group, ST_SZGNAME) # Length flen = FileLength(stinfo[ST_SIZE]) UI.TotalSize += stinfo[ST_SIZE] - detlist[index] += flen + (ST_SZLEN - len(flen)) * " " + detlist[index] += PadString(flen, ST_SZLEN) # mtime @@ -2574,7 +2601,7 @@ # Turn into a single string ftime = " ".join(ftime) - detlist[index] += ftime + (ST_SZMTIME - len(ftime)) * " " + detlist[index] += PadString(ftime, ST_SZMTIME) # Add the File Name detlist[index] += all[index] @@ -2636,6 +2663,14 @@ # Strip trailing path separators in each case to # give the command author the maximum flexibility possible + # We have to treat built-ins specially if we're in a Drive List View + # Most noteably, there is no meaning to [DIR] in this context + + if UI.CurrentDir == SHOWDRIVES: + currentdir = "" + else: + currentdir = UI.CurrentDir + selection = StripPSEP(UI.LastInSelection()) selections = "" dselections = "" @@ -2643,11 +2678,11 @@ # Fill the various built-ins selected = StripPSEP(selected) - dselections += QUOTECHAR + UI.CurrentDir + selected + QUOTECHAR + " " + dselections += QUOTECHAR + currentdir + selected + QUOTECHAR + " " selections += QUOTECHAR + selected + QUOTECHAR + " " - - cmd = cmd.replace(DIR, QUOTECHAR + StripPSEP(UI.CurrentDir) + QUOTECHAR) - cmd = cmd.replace(DSELECTION, QUOTECHAR + UI.CurrentDir + selection + QUOTECHAR) + + cmd = cmd.replace(DIR, QUOTECHAR + StripPSEP(currentdir) + QUOTECHAR) + cmd = cmd.replace(DSELECTION, QUOTECHAR + currentdir + selection + QUOTECHAR) cmd = cmd.replace(DSELECTIONS, dselections) cmd = cmd.replace(HASH, COMMENT) cmd = cmd.replace(SELECTION, QUOTECHAR + selection + QUOTECHAR) @@ -2963,7 +2998,7 @@ for key in UI.CmdTable.keys(): name = UI.CmdTable[key][0] cmd = UI.CmdTable[key][1] - debuginfo.append(key + " " + name + " " * (16-len(name)) + cmd) + debuginfo.append(PadString(key + " " + name, dCMDWIDTH) + cmd) return debuginfo @@ -2981,7 +3016,7 @@ key = "F" + str(x+1) path = UI.FuncKeys[x] if path: - debuginfo.append(key + " " * (10-len(key)) + path) + debuginfo.append(PadString(key, dSCWIDTH) + path) return debuginfo @@ -2996,7 +3031,7 @@ debuginfo = [] for v in DebugVars: - debuginfo.append(v + " " * (12-len(v)) + (str(eval(v)) or dNULL)) + debuginfo.append(PadString(v, dINTVARWIDTH) + (str(eval(v)) or dNULL)) debuginfo.sort() return debuginfo @@ -3012,7 +3047,7 @@ debuginfo = [] for key in UI.KeyBindings.keys(): - debuginfo.append(key + " " * (10-len(key)) + UI.KeyBindings[key]) + debuginfo.append(PadString(key, dKEYWIDTH) + UI.KeyBindings[key]) debuginfo.sort() return debuginfo @@ -3029,7 +3064,7 @@ debuginfo = [] for l in (UI.OptionsBoolean, UI.OptionsNumeric, UI.OptionsString): for v in l: - debuginfo.append(v + " " * (15-len(v)) + (str(eval(v)) or dNULL)) + debuginfo.append(PadString(v, dOPTIONWIDTH) + (str(eval(v)) or dNULL)) debuginfo.sort() return debuginfo @@ -3045,7 +3080,7 @@ debuginfo = [] for sym in UI.SymTable.keys(): - debuginfo.append(sym + " " * (16-len(sym)) + UI.SymTable[sym]) + debuginfo.append(PadString(sym, dUSRVBLWIDTH) + UI.SymTable[sym]) debuginfo.sort() @@ -3085,13 +3120,13 @@ UI.OptionsBoolean = {"AUTOREFRESH":AUTOREFRESH, "NODETAILS":NODETAILS, "NONAVIGATE":NONAVIGATE, "USETHREADS":USETHREADS, "USEWIN32ALL":USEWIN32ALL, "WARN":WARN} -UI.OptionsNumeric = {"DEBUGLEVEL":DEBUGLEVEL, "FSZ":FSZ, "HEIGHT":HEIGHT, "MAXDIR":MAXDIR, - "MAXDIRBUF":MAXDIRBUF, "MAXHIST":MAXHIST, "MAXHISTBUF":MAXHISTBUF, +UI.OptionsNumeric = {"DEBUGLEVEL":DEBUGLEVEL, "FSZ":FSZ, "MFSZ":MFSZ, "HFSZ":HFSZ, "HEIGHT":HEIGHT, + "MAXDIR":MAXDIR, "MAXDIRBUF":MAXDIRBUF, "MAXHIST":MAXHIST, "MAXHISTBUF":MAXHISTBUF, "MAXNESTING":MAXNESTING, "REFRESHINT":REFRESHINT, "WIDTH":WIDTH} -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 +UI.OptionsString = {"BCOLOR":BCOLOR, "FCOLOR":FCOLOR, "FNAME":FNAME, "FWT":FWT, # Main Font/Colors + "MBCOLOR":MBCOLOR, "MFCOLOR":MFCOLOR, "MFNAME":MFNAME, "MFWT":MFWT, # Menu Font/Colors + "HBCOLOR":HBCOLOR, "HFCOLOR":HFCOLOR, "HFNAME":HFNAME, "HFWT":HFWT, # Help Font/Colors "MBARCOL":MBARCOL, "QUOTECHAR":QUOTECHAR, "STARTDIR":STARTDIR} # Other # Prepare storage for key bindings