summaryrefslogtreecommitdiffstats
path: root/Mac/Tools/twit/mactwit_browser.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Tools/twit/mactwit_browser.py')
-rw-r--r--Mac/Tools/twit/mactwit_browser.py429
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()