diff options
Diffstat (limited to 'Mac/Tools/twit/mactwit_browser.py')
-rw-r--r-- | Mac/Tools/twit/mactwit_browser.py | 429 |
1 files changed, 0 insertions, 429 deletions
diff --git a/Mac/Tools/twit/mactwit_browser.py b/Mac/Tools/twit/mactwit_browser.py deleted file mode 100644 index 070de43..0000000 --- a/Mac/Tools/twit/mactwit_browser.py +++ /dev/null @@ -1,429 +0,0 @@ -"""A simple Mac-only browse utility to peek at the inner data structures of Python.""" -# Minor modifications by Jack to facilitate incorporation in twit. - -# june 1996 -# Written by Just van Rossum <just@knoware.nl>, please send comments/improvements. -# Loosely based on Jack Jansens's PICTbrowse.py, but depends on his fabulous FrameWork.py -# XXX Some parts are *very* poorly solved. Will fix. Guido has to check if all the -# XXX "python-peeking" is done correctly. I kindof reverse-engineered it ;-) - -# disclaimer: although I happen to be the brother of Python's father, programming is -# not what I've been trained to do. So don't be surprised if you find anything that's not -# as nice as it could be... - -# XXX to do: -# Arrow key support -# Copy & Paste? -# MAIN_TEXT item should not contain (type); should be below or something. -# MAIN_TEXT item should check if a string is binary or not: convert to '/000' style -# or convert newlines. - -version = "1.0" - -import FrameWork -import EasyDialogs -import Dlg -import Res -import Qd -import List -import sys -from Types import * -from QuickDraw import * -import string -import time -import os - -# The initial object to start browsing with. Can be anything, but 'sys' makes kindof sense. -start_object = sys - -# Resource definitions -ID_MAIN = 503 -NUM_LISTS = 4 # the number of lists used. could be changed, but the dlg item numbers should be consistent -MAIN_TITLE = 3 # this is only the first text item, the other three ID's should be 5, 7 and 9 -MAIN_LIST = 4 # this is only the first list, the other three ID's should be 6, 8 and 10 -MAIN_TEXT = 11 -MAIN_LEFT = 1 -MAIN_RIGHT = 2 -MAIN_RESET = 12 -MAIN_CLOSE = 13 -MAIN_LINE = 14 - -def Initialize(): - # this bit ensures that this module will also work as an applet if the resources are - # in the resource fork of the applet - # stolen from Jack, so it should work(?!;-) - try: - # if this doesn't raise an error, we are an applet containing the necessary resources - # so we don't have to bother opening the resource file - dummy = Res.GetResource('DLOG', ID_MAIN) - except Res.Error: - savewd = os.getcwd() - ourparentdir = os.path.split(openresfile.func_code.co_filename)[0] - os.chdir(ourparentdir) - try: - Res.FSpOpenResFile("mactwit_browse.rsrc", 1) - except Res.Error, arg: - EasyDialogs.Message("Cannot open mactwit_browse.rsrc: "+arg[1]) - sys.exit(1) - os.chdir(savewd) - -def main(): - Initialize() - PythonBrowse() - -# this is all there is to it to make an application. -class PythonBrowse(FrameWork.Application): - def __init__(self): - FrameWork.Application.__init__(self) - VarBrowser(self).open(start_object) - self.mainloop() - - def do_about(self, id, item, window, event): - EasyDialogs.Message(self.__class__.__name__ + " version " + version + "\rby Just van Rossum") - - def quit(self, *args): - raise self - -class MyList: - def __init__(self, wid, rect, itemnum): - # wid is the window (dialog) where our list is going to be in - # rect is it's item rectangle (as in dialog item) - # itemnum is the itemnumber in the dialog - self.rect = rect - rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1 # Scroll bar space, that's 15 + 1, Jack! - self.list = List.LNew(rect2, (0, 0, 1, 0), (0,0), 0, wid, - 0, 1, 0, 1) - self.wid = wid - self.active = 0 - self.itemnum = itemnum - - def setcontent(self, content, title = ""): - # first, gather some stuff - keylist = [] - valuelist = [] - thetype = type(content) - if thetype == DictType: - keylist = content.keys() - keylist.sort() - for key in keylist: - valuelist.append(content[key]) - elif thetype == ListType: - keylist = valuelist = content - elif thetype == TupleType: - - keylist = valuelist = [] - for i in content: - keylist.append(i) - else: - # XXX help me! is all this correct? is there more I should consider??? - # XXX is this a sensible way to do it in the first place???? - # XXX I'm not familiar enough with Python's guts to be sure. GUIDOOOOO!!! - if hasattr(content, "__dict__"): - keylist = keylist + content.__dict__.keys() - if hasattr(content, "__methods__"): - keylist = keylist + content.__methods__ - if hasattr(content, "__members__"): - keylist = keylist + content.__members__ - if hasattr(content, "__class__"): - keylist.append("__class__") - if hasattr(content, "__bases__"): - keylist.append("__bases__") - if hasattr(content, "__name__"): - title = content.__name__ - if "__name__" not in keylist: - keylist.append("__name__") - keylist.sort() - for key in keylist: - valuelist.append(getattr(content, key)) - if content <> None: - title = title + "\r" + cleantype(content) - # now make that list! - tp, h, rect = self.wid.GetDialogItem(self.itemnum - 1) - Dlg.SetDialogItemText(h, title[:255]) - self.list.LDelRow(0, 1) - self.list.LSetDrawingMode(0) - self.list.LAddRow(len(keylist), 0) - for i in range(len(keylist)): - self.list.LSetCell(str(keylist[i]), (0, i)) - self.list.LSetDrawingMode(1) - self.list.LUpdate(self.wid.GetWindowPort().visRgn) - self.content = content - self.keylist = keylist - self.valuelist = valuelist - self.title = title - - # draw a frame around the list, List Manager doesn't do that - def drawframe(self): - Qd.SetPort(self.wid) - Qd.FrameRect(self.rect) - rect2 = Qd.InsetRect(self.rect, -3, -3) - save = Qd.GetPenState() - Qd.PenSize(2, 2) - if self.active: - Qd.PenPat(Qd.qd.black) - else: - Qd.PenPat(Qd.qd.white) - # draw (or erase) an extra frame to indicate this is the acive list (or not) - Qd.FrameRect(rect2) - Qd.SetPenState(save) - - - -class VarBrowser(FrameWork.DialogWindow): - def open(self, start_object, title = ""): - FrameWork.DialogWindow.open(self, ID_MAIN) - if title <> "": - windowtitle = self.wid.GetWTitle() - self.wid.SetWTitle(windowtitle + " >> " + title) - else: - if hasattr(start_object, "__name__"): - windowtitle = self.wid.GetWTitle() - self.wid.SetWTitle(windowtitle + " >> " + str(getattr(start_object, "__name__")) ) - - self.SetPort() - Qd.TextFont(3) - Qd.TextSize(9) - self.lists = [] - self.listitems = [] - for i in range(NUM_LISTS): - self.listitems.append(MAIN_LIST + 2 * i) # dlg item numbers... have to be consistent - for i in self.listitems: - tp, h, rect = self.wid.GetDialogItem(i) - list = MyList(self.wid, rect, i) - self.lists.append(list) - self.leftover = [] - self.rightover = [] - self.setup(start_object, title) - - def close(self): - self.lists = [] - self.listitems = [] - self.do_postclose() - - def setup(self, start_object, title = ""): - # here we set the starting point for our expedition - self.start = start_object - self.lists[0].setcontent(start_object, title) - for list in self.lists[1:]: - list.setcontent(None) - - def do_listhit(self, event, item): - (what, message, when, where, modifiers) = event - Qd.SetPort(self.wid) - where = Qd.GlobalToLocal(where) - for list in self.lists: - list.active = 0 - list = self.lists[self.listitems.index(item)] - list.active = 1 - for l in self.lists: - l.drawframe() - - point = (0,0) - ok, point = list.list.LGetSelect(1, point) - if ok: - oldsel = point[1] - else: - oldsel = -1 - # This should be: list.list.LClick(where, modifiers) - # Since the selFlags field of the list is not accessible from Python I have to do it like this. - # The effect is that you can't select more items by using shift or command. - list.list.LClick(where, 0) - - index = self.listitems.index(item) + 1 - point = (0,0) - ok, point = list.list.LGetSelect(1, point) - if oldsel == point[1]: - return # selection didn't change, do nothing. - if not ok: - for i in range(index, len(self.listitems)): - self.lists[i].setcontent(None) - self.rightover = [] - return - - if point[1] >= len(list.keylist): - return # XXX is this still necessary? is ok really true? - key = str(list.keylist[point[1]]) - value = list.valuelist[point[1]] - - self.settextitem("") - thetype = type(value) - if thetype == ListType or \ - thetype == TupleType or \ - thetype == DictType or \ - hasattr(value, "__dict__") or \ - hasattr(value, "__methods__") or \ - hasattr(value, "__members__"): # XXX or, or... again: did I miss something? - if index >= len(self.listitems): - # we've reached the right side of our dialog. move everything to the left - # (by pushing the rightbutton...) - self.do_rightbutton(1) - index = index - 1 - newlist = self.lists[index] - newlist.setcontent(value, key) - else: - index = index - 1 - self.settextitem( str(value) + "\r" + cleantype(value)) - for i in range(index + 1, len(self.listitems)): - self.lists[i].setcontent(None) - self.rightover = [] - - # helper to set the big text item at the bottom of the dialog. - def settextitem(self, text): - tp, h, rect = self.wid.GetDialogItem(MAIN_TEXT) - Dlg.SetDialogItemText(h, text[:255]) - - def do_rawupdate(self, window, event): - Qd.SetPort(self.wid) - iType, iHandle, iRect = window.GetDialogItem(MAIN_LINE) - Qd.FrameRect(iRect) - for list in self.lists: - Qd.FrameRect(list.rect) - if list.active: - # see MyList.drawframe - rect2 = Qd.InsetRect(list.rect, -3, -3) - save = Qd.GetPenState() - Qd.PenSize(2, 2) - Qd.FrameRect(rect2) - Qd.SetPenState(save) - for list in self.lists: - list.list.LUpdate(self.wid.GetWindowPort().visRgn) - - def do_activate(self, activate, event): - for list in self.lists: - list.list.LActivate(activate) - - # scroll everything one 'unit' to the left - # XXX I don't like the way this works. Too many 'manual' assignments - def do_rightbutton(self, force = 0): - if not force and self.rightover == []: - return - self.scroll(-1) - point = (0, 0) - ok, point = self.lists[0].list.LGetSelect(1, point) - self.leftover.append((point, self.lists[0].content, self.lists[0].title, self.lists[0].active)) - for i in range(len(self.lists)-1): - point = (0, 0) - ok, point = self.lists[i+1].list.LGetSelect(1, point) - self.lists[i].setcontent(self.lists[i+1].content, self.lists[i+1].title) - self.lists[i].list.LSetSelect(ok, point) - self.lists[i].list.LAutoScroll() - self.lists[i].active = self.lists[i+1].active - self.lists[i].drawframe() - if len(self.rightover) > 0: - point, content, title, active = self.rightover[-1] - self.lists[-1].setcontent(content, title) - self.lists[-1].list.LSetSelect(1, point) - self.lists[-1].list.LAutoScroll() - self.lists[-1].active = active - self.lists[-1].drawframe() - del self.rightover[-1] - else: - self.lists[-1].setcontent(None) - self.lists[-1].active = 0 - for list in self.lists: - list.drawframe() - - # scroll everything one 'unit' to the right - def do_leftbutton(self): - if self.leftover == []: - return - self.scroll(1) - if self.lists[-1].content <> None: - point = (0, 0) - ok, point = self.lists[-1].list.LGetSelect(1, point) - self.rightover.append((point, self.lists[-1].content, self.lists[-1].title, self.lists[-1].active )) - for i in range(len(self.lists)-1, 0, -1): - point = (0, 0) - ok, point = self.lists[i-1].list.LGetSelect(1, point) - self.lists[i].setcontent(self.lists[i-1].content, self.lists[i-1].title) - self.lists[i].list.LSetSelect(ok, point) - self.lists[i].list.LAutoScroll() - self.lists[i].active = self.lists[i-1].active - self.lists[i].drawframe() - if len(self.leftover) > 0: - point, content, title, active = self.leftover[-1] - self.lists[0].setcontent(content, title) - self.lists[0].list.LSetSelect(1, point) - self.lists[0].list.LAutoScroll() - self.lists[0].active = active - self.lists[0].drawframe() - del self.leftover[-1] - else: - self.lists[0].setcontent(None) - self.lists[0].active = 0 - - # create some visual feedback when 'scrolling' the lists to the left or to the right - def scroll(self, leftright): # leftright should be 1 or -1 - # first, build a region containing all list rectangles - myregion = Qd.NewRgn() - mylastregion = Qd.NewRgn() - for list in self.lists: - AddRect2Rgn(list.rect, myregion) - AddRect2Rgn(list.rect, mylastregion) - # set the pen, but save it's state first - self.SetPort() - save = Qd.GetPenState() - Qd.PenPat(Qd.qd.gray) - Qd.PenMode(srcXor) - # how far do we have to scroll? - distance = self.lists[1].rect[0] - self.lists[0].rect[0] - step = 30 - lasttime = time.clock() # for delay - # do it - for i in range(0, distance, step): - if i <> 0: - Qd.FrameRgn(mylastregion) # erase last region - Qd.OffsetRgn(mylastregion, step * leftright, 0) - # draw gray region - Qd.FrameRgn(myregion) - Qd.OffsetRgn(myregion, step * leftright, 0) - while time.clock() - lasttime < 0.05: - pass # delay - lasttime = time.clock() - # clean up after your dog - Qd.FrameRgn(mylastregion) - Qd.SetPenState(save) - - def reset(self): - for list in self.lists: - point = (0,0) - ok, point = list.list.LGetSelect(1, point) - if ok: - sel = list.keylist[point[1]] - list.setcontent(list.content, list.title) - if ok: - list.list.LSetSelect(1, (0, list.keylist.index(sel))) - list.list.LAutoScroll() - - def do_itemhit(self, item, event): - if item in self.listitems: - self.do_listhit(event, item) - elif item == MAIN_LEFT: - self.do_leftbutton() - elif item == MAIN_RIGHT: - self.do_rightbutton() - elif item == MAIN_CLOSE: - self.close() - elif item == MAIN_RESET: - self.reset() - -# helper function that returns a short string containing the type of an arbitrary object -# eg: cleantype("wat is dit nu weer?") -> '(string)' -def cleantype(obj): - # type() typically returns something like: <type 'string'> - items = string.split(str(type(obj)), "'") - if len(items) == 3: - return '(' + items[1] + ')' - else: - # just in case, I don't know. - return str(type(obj)) - -# helper for VarBrowser.scroll -def AddRect2Rgn(theRect, theRgn): - rRgn = Qd.NewRgn() - Qd.RectRgn(rRgn, theRect) - Qd.UnionRgn(rRgn, theRgn, theRgn) - - -if __name__ == "__main__": - main() |