summaryrefslogtreecommitdiffstats
path: root/Mac/Unsupported
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>2000-08-20 20:21:38 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>2000-08-20 20:21:38 (GMT)
commit9ebf2d2ca4694ec38ae07fcb8e7b7a115f5bf977 (patch)
treec00da186177ef0b9b6e230ffbe0998ecba1e8d40 /Mac/Unsupported
parent51f357049b6a83167e46af5e07e8ce1ea1be7b2f (diff)
downloadcpython-9ebf2d2ca4694ec38ae07fcb8e7b7a115f5bf977.zip
cpython-9ebf2d2ca4694ec38ae07fcb8e7b7a115f5bf977.tar.gz
cpython-9ebf2d2ca4694ec38ae07fcb8e7b7a115f5bf977.tar.bz2
Moved to unsupported: it never lived up to its expectancies, and for the Mac all the functionality is available in the IDE.
Diffstat (limited to 'Mac/Unsupported')
-rw-r--r--Mac/Unsupported/twit/TwitCore.py549
-rw-r--r--Mac/Unsupported/twit/mac_widgets.py317
-rw-r--r--Mac/Unsupported/twit/mactwit_app.py267
-rw-r--r--Mac/Unsupported/twit/mactwit_browser.py429
-rw-r--r--Mac/Unsupported/twit/mactwit_edit.py24
-rw-r--r--Mac/Unsupported/twit/mactwit_mod.py114
-rw-r--r--Mac/Unsupported/twit/mactwit_stack.py159
-rw-r--r--Mac/Unsupported/twit/twit.py59
-rw-r--r--Mac/Unsupported/twit/twit.rsrcbin0 -> 46350 bytes
-rw-r--r--Mac/Unsupported/twit/twittest.py13
10 files changed, 1931 insertions, 0 deletions
diff --git a/Mac/Unsupported/twit/TwitCore.py b/Mac/Unsupported/twit/TwitCore.py
new file mode 100644
index 0000000..8cd8c0e
--- /dev/null
+++ b/Mac/Unsupported/twit/TwitCore.py
@@ -0,0 +1,549 @@
+# Window-interface-independent part of twit
+import sys
+import types
+import bdb
+import types
+import os
+
+SIMPLE_TYPES=(
+ types.NoneType,
+ types.IntType,
+ types.LongType,
+ types.FloatType,
+ types.ComplexType,
+ types.StringType
+)
+
+# XXXX Mac-specific
+ICON_NORMAL=500
+ICON_RETURN=503
+ICON_CALL=504
+ICON_ZERO=505
+ICON_DEAD=506
+
+class DebuggerStuff(bdb.Bdb):
+
+ def __init__(self, parent):
+ bdb.Bdb.__init__(self)
+ self.parent = parent
+ self.exception_info = (None, None)
+ self.reason = 'Not running'
+ self.icon = ICON_NORMAL
+ self.reset()
+
+ def reset(self):
+ bdb.Bdb.reset(self)
+ self.forget()
+
+ def forget(self):
+ self.lineno = None
+ self.stack = []
+ self.curindex = 0
+ self.curframe = None
+
+ def run(self, cmd, locals, globals):
+ self.reason = 'Running'
+ bdb.Bdb.run(self, cmd, locals, globals)
+ print 'RETURN from run'
+ self.reason = 'Not running'
+
+ def setup(self, f, t):
+ self.forget()
+ self.stack, self.curindex = self.get_stack(f, t)
+ self.curframe = self.stack[self.curindex][0]
+
+ def interaction(self, frame, traceback):
+ self.setup(frame, traceback)
+ self.parent.interact()
+ self.exception_info = (None, None)
+
+# def user_call(self, frame, argument_list):
+# self.reason = 'Calling'
+# self.icon = ICON_CALL
+# self.interaction(frame, None)
+
+ def user_line(self, frame):
+ self.reason = 'Stopped'
+ self.icon = ICON_NORMAL
+ self.interaction(frame, None)
+
+ def user_return(self, frame, return_value):
+ self.reason = 'Returning'
+ self.icon = ICON_RETURN
+ self.interaction(frame, None)
+
+ def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
+ self.reason = 'Exception occurred'
+ self.icon = ICON_DEAD
+ self.parent.setstate('tb')
+ self.exception_info = (exc_type, exc_value)
+ self.interaction(frame, exc_traceback)
+
+ def getexception(self):
+ tp, value = self.exception_info
+ if tp <> None and type(tp) <> type(''):
+ tp = tp.__name__
+ if value <> None and type(value) <> type(''):
+ value = `value`
+ return tp, value
+
+ def getstacktrace(self):
+ names, locations = [], []
+ for frame, lineno in self.stack:
+ name = frame.f_code.co_name
+ if not name:
+ name = "<lambda>"
+ elif name == '?':
+ name = "<not a function>"
+ else:
+ name = name + '()'
+ names.append(name)
+
+ if lineno == -1:
+ lineno = getframelineno(frame)
+
+ modname = getframemodname(frame)
+ if not modname: modname = "<unknown>"
+
+ locations.append("%s:%d" % (modname, lineno))
+ return names, locations
+
+ def getframe(self, number):
+ if number < 0 or number >= len(self.stack):
+ return None
+ return self.stack[number][0]
+
+ def getframevars(self, number, show_complex=1, show_system=1):
+ frame = self.getframe(number)
+ if not frame:
+ return [], []
+ return getvarsfromdict(frame.f_locals, show_complex, show_system)
+
+ def getframevar(self, number, var):
+ frame = self.getframe(number)
+ return frame.f_locals[var]
+
+ def getframefilepos(self, frameno):
+ if frameno == None or frameno < 0 or frameno >= len(self.stack):
+ return None, None, None
+ frame, line = self.stack[frameno]
+ if line == -1:
+ line = getframelineno(frame)
+ modname = getframemodname(frame)
+ filename = frame.f_code.co_filename
+ return filename, modname, line
+
+ def getprogramstate(self):
+ return self.reason
+
+class Application:
+ """Base code for the application"""
+
+ def mi_init(self, sessiontype, arg):
+ self.dbg = DebuggerStuff(self)
+ self.run_dialog = self.new_stack_browser(self)
+ self.run_dialog.open()
+ self.module_dialog = None
+ self.initial_cmd = None
+ self.cur_string_name = None
+ if sessiontype == 'tb':
+ while arg.tb_next <> None:
+ arg = arg.tb_next
+ self.dbg.setup(arg.tb_frame, arg)
+ self.run_dialog.setup()
+ elif sessiontype == 'run':
+ self.initial_cmd = arg
+
+ def breaks_changed(self, filename):
+ self.run_dialog.breaks_changed(filename)
+ if self.module_dialog:
+ self.module_dialog.breaks_changed(filename)
+
+ def to_debugger(self):
+ cmd = self.initial_cmd
+ self.initial_cmd = None
+ self.setstate('run')
+ self.switch_to_app()
+ apply(self.dbg.run, cmd)
+ self.setstate('none')
+ self.switch_to_dbg()
+ self.run_dialog.update_views()
+ if self.module_dialog:
+ self.module_dialog.update_views()
+
+ def interact(self):
+ # Interact with user. First, display correct info
+ self.switch_to_dbg()
+ self.run_dialog.update_views()
+ if self.module_dialog:
+ self.module_dialog.update_views()
+
+ # Next, go into mainloop
+ self.one_mainloop()
+
+ # Finally (before we start the debuggee again) show state
+ self.switch_to_app()
+ self.run_dialog.show_it_running()
+
+ def quit_bdb(self):
+ self.dbg.set_quit()
+
+ def run(self):
+ cmd = self.AskString('Statement to execute:')
+ self.runstring(cmd)
+
+ def runfile(self, path):
+ dir, file = os.path.split(path)
+ try:
+ os.chdir(dir)
+ except os.error, arg:
+ self.Message("%s: %s"%(dir, arg))
+ return
+ ns = {'__name__':'__main__', '__file__':path}
+ cmd = "execfile('%s')"%file
+ self.runstring(cmd, ns, ns)
+
+ def runstring(self, cmd, globals={}, locals={}):
+ self.cur_string_name = '<string: "%s">'%cmd
+ try:
+ cmd = compile(cmd, self.cur_string_name, 'exec')
+ except SyntaxError, arg:
+ self.Message('Syntax error: %s'%`arg`)
+ return
+ self.initial_cmd = (cmd, globals, locals)
+ self.exit_mainloop()
+
+ def cont(self):
+ self.dbg.set_continue()
+ self.exit_mainloop()
+
+ def step(self, frame):
+ self.dbg.set_next(frame)
+ self.exit_mainloop()
+
+ def step_in(self):
+ self.dbg.set_step()
+ self.exit_mainloop()
+
+ def step_out(self, frame):
+ self.dbg.set_return(frame)
+ self.exit_mainloop()
+
+ def kill(self):
+ self.dbg.set_quit()
+ self.exit_mainloop()
+
+ def quit(self):
+ self.do_quit()
+
+ def browse(self, module):
+ if not self.module_dialog:
+ self.module_dialog = self.new_module_browser(self)
+ self.module_dialog.open(module)
+ else:
+ self.module_dialog.focus(module)
+
+ def browse_var(self, var):
+ b = self.new_var_browser(self, var)
+
+class StackBrowser:
+ """Base code for stack browser"""
+ def mi_open(self):
+ """Setup initial data structures"""
+ self.cur_stackitem = None
+ self.cur_source = None
+ self.cur_modname = None
+ self.cur_line = None
+ self.show_complex = 1
+ self.show_system = 0
+ self.setup()
+
+ # create_items(self) should create self.modules, self.vars and self.source
+
+ def setup(self):
+ self.parent.SetWatch()
+ """Fill the various widgets with values"""
+ name, value = self.parent.dbg.getexception()
+ self.setexception(name, value)
+ self.setprogramstate(self.parent.dbg.getprogramstate())
+
+ names, locations = self.parent.dbg.getstacktrace()
+ self.stack_setcontent(names, locations)
+ self.cur_stackitem = len(names)-1
+ self.stack_select(self.cur_stackitem)
+ self.setup_frame()
+
+ def setup_frame(self):
+ """Setup frame-dependent widget data"""
+ self.parent.SetWatch()
+ self.cont_varnames, self.cont_varvalues = \
+ self.parent.dbg.getframevars(self.cur_stackitem,
+ self.show_complex, self.show_system)
+ self.setvars()
+ self.set_var_buttons()
+
+ msg = ""
+ if self.cur_stackitem == None:
+ self.cur_source = None
+ self.cur_modname = None
+ self.cur_line = None
+ msg = "No stackframe selected"
+ else:
+ self.cur_source, self.cur_modname, optnextline = \
+ self.parent.dbg.getframefilepos(self.cur_stackitem)
+ if optnextline >= 0:
+ self.cur_line = optnextline
+ if self.cur_source == '<string>':
+ self.cur_source = None
+ msg = "Executing from unknown <string>"
+ elif type(self.cur_source) == types.StringType and \
+ self.cur_source[:8] == '<string:':
+ msg = "Executing from "+self.cur_source
+ self.cur_source = None
+
+ self.setsource(msg)
+ if not self.cur_line:
+ self.source_setline(1, ICON_ZERO)
+ else:
+ self.source_setline(self.cur_line, self.parent.dbg.icon)
+ self.breaks_changed(self.cur_source)
+
+
+ self.parent.SetCursor()
+
+ # setsource(msg) should display cur_source+content, or msg if None
+
+ def show_it_running(self):
+ self.setprogramstate("Running")
+
+ def update_views(self):
+ self.setup()
+
+ def click_stack(self, number, *dummy):
+ if number == self.cur_stackitem: return
+ self.cur_stackitem = number
+ self.stack_select(self.cur_stackitem)
+ self.setup_frame()
+
+ def click_var(self, var, *dummy):
+ v = self.parent.dbg.getframevar(self.cur_stackitem, var)
+ self.parent.browse_var(v)
+
+ def click_source(self, lineno, inborder):
+ if not inborder:
+ self.source_select(lineno)
+ self.cur_line = lineno
+ if lineno == None or not self.cur_source or not inborder:
+ return
+ if self.parent.dbg.get_break(self.cur_source, lineno):
+ self.parent.dbg.clear_break(self.cur_source, lineno)
+ else:
+ self.parent.dbg.set_break(self.cur_source, lineno)
+ self.parent.breaks_changed(self.cur_source)
+
+ def breaks_changed(self, filename):
+ if filename == self.cur_source:
+ list = self.parent.dbg.get_file_breaks(filename)
+ self.source_setbreaks(list)
+
+ def click_quit(self):
+ self.parent.quit()
+
+ def click_run(self):
+ self.parent.run()
+
+ def click_continue(self):
+ self.parent.cont()
+
+ def click_step(self):
+ if self.cur_stackitem <> None:
+ frame = self.parent.dbg.getframe(self.cur_stackitem)
+ self.parent.step(frame)
+ else:
+ self.parent.step_in()
+
+ def click_step_in(self):
+ self.parent.step_in()
+
+ def click_step_out(self):
+ if self.cur_stackitem <> None:
+ frame = self.parent.dbg.getframe(self.cur_stackitem)
+ self.parent.step_out(frame)
+ else:
+ self.parent.step_in()
+
+ def click_kill(self):
+ self.parent.kill()
+
+ def click_browse(self):
+ self.parent.browse(self.cur_modname)
+
+ def click_edit(self):
+ lino = self.cur_line
+ if not lino:
+ lino = 1
+ if self.cur_source:
+ self.parent.edit(self.cur_source, lino)
+
+class ModuleBrowser:
+ """Base code for a module-browser"""
+
+ def mi_open(self, module):
+ """Setup initial data structures"""
+ self.cur_module = module
+ self.cur_source = None
+ self.cur_line = None
+ self.cont_modules = []
+ self.value_windows = []
+ self.setup()
+
+ # create_items(self) should create self.modules, self.vars and self.source
+
+ def setup(self):
+ """Fill the various widgets with values"""
+ self.parent.SetWatch()
+ modnames = getmodulenames()
+ if not self.cur_module in modnames:
+ self.cur_module = None
+ if modnames <> self.cont_modules:
+ self.cont_modules = modnames
+ self.setmodulenames()
+ if self.cur_module:
+ self.module_select(self.cont_modules.index(self.cur_module))
+ else:
+ self.module_select(None)
+ self.setup_module()
+
+ def setup_module(self):
+ """Setup module-dependent widget data"""
+ self.parent.SetWatch()
+ if not self.cur_module:
+ self.cont_varnames = []
+ self.cont_varvalues = []
+ else:
+ self.cont_varnames, self.cont_varvalues = getmodulevars(self.cur_module)
+ self.setvars()
+
+ msg = ""
+ if not self.cur_module:
+ self.cur_source = None
+ msg = "No module selected"
+ else:
+ m = sys.modules[self.cur_module]
+ try:
+ self.cur_source = m.__file__
+ except AttributeError:
+ self.cur_source = None
+ msg = "Not a python module"
+ self.cur_lineno = 0
+ self.setsource(msg)
+ self.source_select(self.cur_line)
+ self.breaks_changed(self.cur_source)
+
+ self.parent.SetCursor()
+
+ # setsource(msg) should display cur_source+content, or msg if None
+
+ def update_views(self):
+ self.setup_module()
+
+ def click_module(self, module, *dummy):
+ if not module or module == self.cur_module: return
+ self.focus(module)
+
+ def focus(self, module):
+ self.cur_module = module
+ self.setup()
+
+ def click_var(self, var, *dummy):
+ if not var: return
+ m = sys.modules[self.cur_module]
+ dict = m.__dict__
+ self.parent.browse_var(dict[var])
+
+ def click_source(self, lineno, inborder):
+ if not inborder:
+ self.source_select(lineno)
+ self.cur_lineno = lineno
+ if lineno == None or not self.cur_source or not inborder:
+ return
+ if self.parent.dbg.get_break(self.cur_source, lineno):
+ self.parent.dbg.clear_break(self.cur_source, lineno)
+ else:
+ self.parent.dbg.set_break(self.cur_source, lineno)
+ self.parent.breaks_changed(self.cur_source)
+
+ def breaks_changed(self, filename):
+ if filename == self.cur_source:
+ list = self.parent.dbg.get_file_breaks(filename)
+ self.source_setbreaks(list)
+
+ def click_edit(self):
+ lino = self.cur_lineno
+ if not lino:
+ lino = 1
+ if self.cur_source:
+ self.parent.edit(self.cur_source, lino)
+
+
+def getmodulenames():
+ """Return a list of all current modules, sorted"""
+ list = sys.modules.keys()[:]
+ list.sort()
+ return list
+
+def getmodulevars(name):
+ """For given module return lists with names and values"""
+ m = sys.modules[name]
+ try:
+ dict = m.__dict__
+ except AttributeError:
+ dict = {}
+ return getvarsfromdict(dict)
+
+def getvarsfromdict(dict, show_complex=1, show_system=1):
+ allnames = dict.keys()[:]
+ allnames.sort()
+ names = []
+ for n in allnames:
+ if not show_complex:
+ if not type(dict[n]) in SIMPLE_TYPES:
+ continue
+ if not show_system:
+ if n[:2] == '__' and n[-2:] == '__':
+ continue
+ names.append(n)
+ values = []
+ for n in names:
+ v = pretty(dict[n])
+ values.append(v)
+ return names, values
+
+def pretty(var):
+ t = type(var)
+ if t == types.FunctionType: return '<function>'
+ if t == types.ClassType: return '<class>'
+ return `var`
+
+def getframelineno(frame):
+ """Given a frame return the line number"""
+ return getcodelineno(frame.f_code)
+
+def getfunclineno(func):
+ """Given a function return the line number"""
+ return getcodelineno(func.func_code)
+
+def getcodelineno(cobj):
+ """Given a code object return the line number"""
+ code = cobj.co_code
+ lineno = -1
+ if ord(code[0]) == 127: # SET_LINENO instruction
+ lineno = ord(code[1]) | (ord(code[2]) << 8)
+ return lineno
+
+def getframemodname(frame):
+ """Given a frame return the module name"""
+ globals = frame.f_globals
+ if globals.has_key('__name__'):
+ return globals['__name__']
+ return None
diff --git a/Mac/Unsupported/twit/mac_widgets.py b/Mac/Unsupported/twit/mac_widgets.py
new file mode 100644
index 0000000..569214f
--- /dev/null
+++ b/Mac/Unsupported/twit/mac_widgets.py
@@ -0,0 +1,317 @@
+from FrameWork import *
+import Win
+import Qd
+import Controls
+import Ctl
+import TE
+import List
+import os
+import string
+import macfs
+
+SCROLLBAR=16
+MARGIN=2
+ICONSIZE=16
+TEXTWIDTH=4096 # More-or-less random value
+
+TEXTFONT=4
+TEXTSIZE=9
+
+# Resource numbers
+PIC_CURRENT=500
+PIC_BREAK=501
+
+picture_cache={}
+
+class MT_TextWidget:
+ def __init__(self, wid, r):
+ self.wid = wid
+ self.rect = r
+ left, top, right, bottom = r
+ self.terect = left+MARGIN+ICONSIZE, top+MARGIN, \
+ right-(MARGIN+SCROLLBAR), bottom-(MARGIN+SCROLLBAR)
+ dr = self.terect[0], self.terect[1], TEXTWIDTH, self.terect[3]
+ Qd.SetPort(wid)
+ Qd.TextFont(TEXTFONT)
+ Qd.TextSize(TEXTSIZE)
+ self.ted = TE.TENew(dr, self.terect)
+ self.ted.TEAutoView(1)
+ self.activate(1)
+
+ rect = right-SCROLLBAR, top, right, bottom-SCROLLBAR+1
+ self.bary = Ctl.NewControl(self.wid, rect, "", 1, 0, 0, 0, 16, 0)
+ rect = left, bottom-SCROLLBAR, right-SCROLLBAR+1, bottom
+ self.barx = Ctl.NewControl(self.wid, rect, "", 1, 0, 0, 0, 16, 0)
+
+ self.have_data = 0
+ self.line_index = []
+
+ def close(self):
+ del self.barx
+ del self.bary
+ del self.ted
+
+ def scrollbars(self):
+ pass
+
+ def setcontent(self, file):
+ self.line_index = []
+ if file == None:
+ data = ''
+ self.have_data = 0
+ else:
+ try:
+ fp = open(file, 'rb') # NOTE the binary
+ data = fp.read()
+ self.have_data = 1
+ except IOError, arg:
+ data = 'Cannot open file:\r'+`arg`
+ self.have_data = 0
+ if len(data) > 32767:
+ self.have_data = 0
+ data = 'File too big'
+ self.ted.TESetText(data)
+ if self.have_data:
+ cur = 0
+ while 1:
+ self.line_index.append(cur)
+ try:
+ cur = string.index(data, '\r', cur+1)
+ except ValueError:
+ break
+ self.line_index.append(len(data))
+ Win.InvalRect(self.rect)
+ self.ted.TESetSelect(0,0)
+ self.ted.TECalText()
+ self.ted.TESelView()
+ self.setscrollbars()
+
+ def setscrollbars(self):
+ docleft, doctop, docright, docbot = self.ted.destRect
+ winleft, wintop, winright, winbot = self.ted.viewRect
+ docbot = self.ted.nLines*self.ted.lineHeight + doctop
+ self.setbar(self.barx, docleft, docright, winleft, winright)
+ self.setbar(self.bary, doctop, docbot, wintop, winbot)
+
+ def setbar(self, bar, minmin, maxmax, curmin, curmax):
+ if maxmax-minmin > 32767 or (curmin <= minmin and curmax >= maxmax):
+ bar.SetControlMinimum(0)
+ bar.SetControlMaximum(0)
+ bar.SetControlValue(0)
+ return
+ bar.SetControlMinimum(minmin)
+ bar.SetControlMaximum(maxmax-(curmax-curmin))
+ bar.SetControlValue(curmin)
+
+ def update(self, rgn):
+ Qd.EraseRect(self.terect)
+ Qd.FrameRect(self.rect)
+ self.ted.TEUpdate(self.terect)
+
+ def activate(self, onoff):
+ if onoff:
+ self.ted.TEActivate()
+ else:
+ self.ted.TEDeactivate()
+
+ def select(self, line):
+ if line == None or line <= 0 or not self.have_data:
+ self.ted.TESetSelect(0,0)
+ else:
+ line = line - 1
+ if line > len(self.line_index)-1: line = len(self.line_index)-1
+ if line == 1:
+ self.ted.TESetSelect(0, self.line_index[1])
+ else:
+ self.ted.TESetSelect(self.line_index[line]+1, self.line_index[line+1])
+ self.setscrollbars()
+
+ def click(self, where, modifiers):
+ # First check scrollbars
+ ctltype, control = Ctl.FindControl(where, self.wid)
+ if ctltype and control:
+ partcode = control.TrackControl(where)
+ if partcode:
+ self.controlhit(control, partcode)
+ return None, 0
+ off = self.ted.TEGetOffset(where)
+ inborder = where[0] < self.terect[0]
+ l, t, r, b = self.terect
+ if l <= where[0] <= r and t <= where[1] <= b or inborder:
+ return self.offsettoline(off), inborder
+ return None, 0 # In the grow box or something.
+
+ def offsettoline(self, offset):
+ for i in range(len(self.line_index)):
+ if offset < self.line_index[i]:
+ return i # Not i-1: 1-based line numbers in files
+ return None
+
+ def controlhit(self, control, partcode):
+ if partcode <> Controls.inThumb:
+ if control == self.barx:
+ if partcode == Controls.inUpButton:
+ delta = -10
+ if partcode == Controls.inDownButton:
+ delta = 10
+ if partcode == Controls.inPageUp:
+ delta = 10-(self.terect[2]-self.terect[0])
+ if partcode == Controls.inPageDown:
+ delta = (self.terect[2]-self.terect[0])-10
+ old = control.GetControlValue()
+ control.SetControlValue(old+delta)
+ if control == self.bary:
+ if partcode == Controls.inUpButton:
+ delta = -self.ted.lineHeight
+ if partcode == Controls.inDownButton:
+ delta = self.ted.lineHeight
+ if partcode == Controls.inPageUp:
+ delta = self.ted.lineHeight-(self.terect[3]-self.terect[1])
+ if partcode == Controls.inPageDown:
+ delta = (self.terect[3]-self.terect[1])-self.ted.lineHeight
+ old = control.GetControlValue()
+ control.SetControlValue(old+delta)
+ newx = self.barx.GetControlValue()
+ newy = self.bary.GetControlValue()
+ oldx = self.ted.viewRect[0]
+ oldy = self.ted.viewRect[1]
+ self.ted.TEPinScroll(oldx-newx, oldy-newy)
+ self.setscrollbars() # XXXX Bibbert, maar hoe anders?
+
+class MT_IconTextWidget(MT_TextWidget):
+ def __init__(self, wid, r):
+ MT_TextWidget.__init__(self, wid, r)
+ self.breakpointlist = []
+ self.curline = None
+ self.iconrect = (self.rect[0]+1, self.rect[1]+1,
+ self.terect[0]-1, self.rect[3]-SCROLLBAR)
+ self.curlinerange = (self.terect[1]+self.ted.lineHeight,
+ self.terect[3]-2*self.ted.lineHeight)
+ self.piccurrent = PIC_CURRENT
+
+ def setbreaks(self, list):
+ self.breakpointlist = list[:]
+ Qd.SetPort(self.wid)
+ Win.InvalRect(self.iconrect)
+
+ def setcurline(self, line, pic=PIC_CURRENT):
+ self.curline = line
+ self.piccurrent = pic
+ Qd.SetPort(self.wid)
+ self.showline(line)
+
+ def showline(self, line):
+ if line <= 0: line = 1
+ if line >= len(self.line_index): line = len(self.line_index)-1
+ if line < 0: return
+ off = self.line_index[line]
+ x, y = self.ted.TEGetPoint(off)
+ if self.curlinerange[0] <= y <= self.curlinerange[1]:
+ return # It is in view
+ middle = (self.curlinerange[0]+self.curlinerange[1])/2
+ self.ted.TEPinScroll(0, middle-y) # Of andersom?
+ self.setscrollbars()
+
+ def setscrollbars(self):
+ MT_TextWidget.setscrollbars(self)
+ Win.InvalRect(self.iconrect)
+
+ def update(self, rgn):
+ MT_TextWidget.update(self, rgn)
+ self.drawallicons()
+
+ def drawallicons(self):
+ Qd.EraseRect(self.iconrect)
+ Qd.MoveTo(self.iconrect[2], self.iconrect[1])
+ Qd.LineTo(self.iconrect[2], self.iconrect[3])
+ topoffset = self.ted.TEGetOffset((self.terect[0], self.terect[1]))
+ botoffset = self.ted.TEGetOffset((self.terect[0], self.terect[3]))
+ topline = self.offsettoline(topoffset)
+ botline = self.offsettoline(botoffset)
+ if topline == None: topline = 1 # ???
+ if botline == None: botline = len(self.line_index)
+ for i in self.breakpointlist:
+ if topline <= i <= botline:
+ self.draw1icon(i, PIC_BREAK)
+ if self.curline <> None and topline <= self.curline <= botline:
+ self.draw1icon(self.curline, self.piccurrent)
+
+ def draw1icon(self, line, which):
+ offset = self.line_index[line]
+ botx, boty = self.ted.TEGetPoint(offset)
+ rect = self.rect[0]+2, boty-self.ted.lineHeight, \
+ self.rect[0]+ICONSIZE-2, boty
+ if not picture_cache.has_key(which):
+ picture_cache[which] = Qd.GetPicture(which)
+ self.drawicon(rect, picture_cache[which])
+
+ def drawicon(self, rect, which):
+ Qd.DrawPicture(which, rect)
+
+class MT_IndexList:
+ def __init__(self, wid, rect, width):
+ # wid is the window (dialog) where our list is going to be in
+ # rect is it's item rectangle (as in dialog item)
+ self.rect = rect
+ rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
+ self.list = List.LNew(rect2, (0, 0, width, 0), (0,0), 0, wid,
+ 0, 1, 0, 1)
+ self.wid = wid
+ self.width = width
+
+ def setcontent(self, *content):
+ self.list.LDelRow(0, 1)
+ self.list.LSetDrawingMode(0)
+ self.list.LAddRow(len(content[0]), 0)
+ for x in range(len(content)):
+ column = content[x]
+ for y in range(len(column)):
+ self.list.LSetCell(column[y], (x, y))
+ self.list.LSetDrawingMode(1)
+ Win.InvalRect(self.rect)
+
+ def deselectall(self):
+ while 1:
+ ok, pt = self.list.LGetSelect(1, (0,0))
+ if not ok: return
+ self.list.LSetSelect(0, pt)
+
+ def select(self, num):
+ self.deselectall()
+ if num < 0:
+ return
+ for i in range(self.width):
+ self.list.LSetSelect(1, (i, num))
+
+ def click(self, where, modifiers):
+ is_double = self.list.LClick(where, modifiers)
+ ok, (x, y) = self.list.LGetSelect(1, (0, 0))
+ if ok:
+ return y, is_double
+ else:
+ return None, is_double
+
+ # draw a frame around the list, List Manager doesn't do that
+ def drawframe(self):
+ Qd.SetPort(self.wid)
+ Qd.FrameRect(self.rect)
+
+ def update(self, rgn):
+ self.drawframe()
+ self.list.LUpdate(rgn)
+
+ def activate(self, onoff):
+ self.list.LActivate(onoff)
+
+class MT_AnyList(MT_IndexList):
+
+ def click(self, where, modifiers):
+ is_double = self.list.LClick(where, modifiers)
+ ok, (x, y) = self.list.LGetSelect(1, (0, 0))
+ if ok:
+ self.select(y)
+ field0 = self.list.LGetCell(1000,(0,y))
+ else:
+ field0 = None
+ return field0, is_double
+
diff --git a/Mac/Unsupported/twit/mactwit_app.py b/Mac/Unsupported/twit/mactwit_app.py
new file mode 100644
index 0000000..8c568df
--- /dev/null
+++ b/Mac/Unsupported/twit/mactwit_app.py
@@ -0,0 +1,267 @@
+import FrameWork
+import MiniAEFrame
+import EasyDialogs
+import AE
+import AppleEvents
+import Res
+import sys
+import Qd
+import Evt
+import Events
+import Dlg
+import Win
+import Menu
+import TwitCore
+import mactwit_mod
+import mactwit_stack
+import mactwit_browser
+import mactwit_edit
+import macfs
+import string
+
+# Resource-id (for checking existence)
+ID_MODULES=500
+
+ID_ABOUT=502
+
+_arrow = Qd.qd.arrow
+_watch = Qd.GetCursor(4).data
+
+class Twit(FrameWork.Application, TwitCore.Application, MiniAEFrame.AEServer):
+ """The twit main class - mac-dependent part"""
+
+ def __init__(self, sessiontype, arg=None):
+ # First init menus, etc.
+ self.app_menu_bar = Menu.GetMenuBar()
+ FrameWork.Application.__init__(self)
+ MiniAEFrame.AEServer.__init__(self)
+ AE.AESetInteractionAllowed(AppleEvents.kAEInteractWithAll)
+ self.installaehandler('aevt', 'odoc', self.ae_open_doc)
+ self.installaehandler('aevt', 'quit', self.do_quit)
+ self.installaehandler('pyth', 'EXEC', self.do_bbpyexec) # BBpy execute event
+
+ self.dbg_menu_bar = Menu.GetMenuBar()
+ self.setstate(sessiontype)
+ self._quitting = 0
+ self.real_quit = 0
+ self.window_aware = 1
+
+ # Next create our dialogs
+ self.mi_init(sessiontype, arg)
+ while 1:
+ if self.real_quit:
+ break
+ if self.initial_cmd:
+ self.to_debugger() # Will get to mainloop via debugger
+ else:
+ self.one_mainloop() # Else do it ourselves.
+
+ def switch_to_app(self):
+ if not self.window_aware:
+ return
+ self.dbg_menu_bar = Menu.GetMenuBar()
+ Menu.SetMenuBar(self.app_menu_bar)
+ Menu.DrawMenuBar()
+
+ def switch_to_dbg(self):
+ if not self.window_aware:
+ return
+ self.app_menu_bar = Menu.GetMenuBar()
+ Menu.SetMenuBar(self.dbg_menu_bar)
+ Menu.DrawMenuBar()
+ self.run_dialog.force_redraw()
+ if self.module_dialog:
+ self.module_dialog.force_redraw()
+
+ def makeusermenus(self):
+ self.filemenu = m = FrameWork.Menu(self.menubar, "Debug")
+ self._openitem = FrameWork.MenuItem(m, "Run File...", "O", self.do_open)
+ self._runitem = FrameWork.MenuItem(m, "Run String...", "R", self.do_run)
+ FrameWork.Separator(m)
+ self._awareitem = FrameWork.MenuItem(m, "Window-aware", "", self.do_aware)
+ self._awareitem.check(1)
+ FrameWork.Separator(m)
+ self._quititem = FrameWork.MenuItem(m, "Quit", "Q", self.do_quit)
+
+ self.controlmenu = m = FrameWork.Menu(self.menubar, "Control")
+ self._stepitem = FrameWork.MenuItem(m, "Step Next", "N", self.do_step)
+ self._stepinitem = FrameWork.MenuItem(m, "Step In", "S", self.do_stepin)
+ self._stepoutitem = FrameWork.MenuItem(m, "Step Out", "U", self.do_stepout)
+ self._continueitem = FrameWork.MenuItem(m, "Continue", "G", self.do_continue)
+ FrameWork.Separator(m)
+ self._killitem = FrameWork.MenuItem(m, "Kill", "K", self.do_kill)
+
+ def setstate(self, state):
+ self.state = state
+ if state == 'run':
+ self._stepitem.enable(1)
+ self._stepoutitem.enable(1)
+ self._stepinitem.enable(1)
+ self._continueitem.enable(1)
+ self._killitem.enable(1)
+ else:
+ self._stepitem.enable(0)
+ self._stepoutitem.enable(0)
+ self._stepinitem.enable(0)
+ self._continueitem.enable(0)
+ self._killitem.enable(0)
+
+ def asknewsession(self):
+ if self.state == 'none':
+ return 1
+ if EasyDialogs.AskYesNoCancel("Abort current debug session?") == 1:
+ self.quit_bdb()
+ return 1
+ return 0
+
+ def do_about(self, id, item, window, event):
+ import time
+ d = Dlg.GetNewDialog(ID_ABOUT, -1)
+ if not d:
+ return
+ w = d.GetDialogWindow()
+ port = w.GetWindowPort()
+ l, t, r, b = port.portRect
+ sl, st, sr, sb = Qd.qd.screenBits.bounds
+ x = ((sr-sl) - (r-l)) / 2
+ y = ((sb-st-16) - (b-t)) / 5
+ w.MoveWindow(x, y, 0)
+ w.ShowWindow()
+ d.DrawDialog()
+
+ tp, h, rect = d.GetDialogItem(2)
+ x0, y0, x1, y1 = rect
+ ybot = y0 + 32
+
+ rgn = Qd.NewRgn()
+ Qd.SetPort(d)
+ ok, evt = self.getevent(Events.mDownMask|Events.keyDownMask, 1)
+ if ok: return
+ (what, message, when, where, modifiers) = event
+ delta_t = 128
+ nexttime = when+delta_t
+ while ybot < y1:
+ # Do the animation, if it is time
+ if when > nexttime:
+ Qd.ScrollRect((x0, y0, x1, ybot), 0, 1, rgn)
+ y0 = y0 + 1
+ ybot = ybot + 1
+ # And update next time
+ delta_t = int(delta_t*0.6)-1
+ if delta_t < 0:
+ delta_t = 0
+ nexttime = when + delta_t
+ # Check for an event.
+ ok, evt = self.getevent(Events.mDownMask|Events.keyDownMask, 0)
+ if ok: return
+ (what, message, when, where, modifiers) = evt
+ while 1:
+ ok, evt = self.getevent(Events.mDownMask|Events.keyDownMask, -1)
+ if ok: return
+
+ def do_open(self, *args):
+ if not self.asknewsession():
+ return
+ fss, ok = macfs.StandardGetFile('TEXT')
+ if not ok: return
+ self.runfile(fss.as_pathname())
+
+ def ae_open_doc(self, object=None, **args):
+ if not object: return
+ if self.state <> 'none':
+ if AE.AEInteractWithUser(AppleEvents.kAEDefaultTimeout) == 0:
+ if not self.asknewsession():
+ return
+ if type(object) == type([]):
+ object = object[0]
+ fss, changed = object.Resolve()
+ self.runfile(fss.as_pathname())
+
+ def do_bbpyexec(self, object=None, NAME=None, **args):
+ if type(object) <> type(''):
+ if AE.AEInteractWithUser(AppleEvents.kAEDefaultTimeout) == 0:
+ EasyDialogs.Message('EXEC AppleEvent arg should be a string')
+ return
+ if self.state <> 'none':
+ if AE.AEInteractWithUser(AppleEvents.kAEDefaultTimeout) == 0:
+ if not self.asknewsession():
+ return
+ stuff = string.splitfields(object, '\r')
+ stuff = string.joinfields(stuff, '\n')
+ self.runstring(stuff)
+
+ def do_run(self, *args):
+ if not self.asknewsession():
+ return
+ self.run()
+
+ def do_aware(self, *args):
+ self.window_aware = not self.window_aware
+ self._awareitem.check(self.window_aware)
+
+ def do_quit(self, *args):
+ self._quit() # Signal FrameWork.Application to stop
+ self.real_quit = 1
+ self.quit_bdb() # Tell debugger to quit.
+
+ def do_step(self, *args):
+ self.run_dialog.click_step()
+
+ def do_stepin(self, *args):
+ self.run_dialog.click_step_in()
+
+ def do_stepout(self, *args):
+ self.run_dialog.click_step_out()
+
+ def do_continue(self, *args):
+ self.run_dialog.click_continue()
+
+ def do_kill(self, *args):
+ self.run_dialog.click_kill()
+
+ def exit_mainloop(self):
+ self._quit() # Signal FrameWork.Application to stop
+ self.real_quit = 0
+
+ def one_mainloop(self):
+ self.quitting = 0
+ self.mainloop()
+
+ def SetCursor(self):
+ Qd.SetCursor(_arrow)
+
+ def SetWatch(self):
+ Qd.SetCursor(_watch)
+
+ def AskString(self, *args):
+ return apply(EasyDialogs.AskString, args)
+
+ def Message(self, *args):
+ return apply(EasyDialogs.Message, args)
+
+ def new_module_browser(self, parent):
+ return mactwit_mod.ModuleBrowser(parent)
+
+ def new_stack_browser(self, parent):
+ return mactwit_stack.StackBrowser(parent)
+
+ def new_var_browser(self, parent, var):
+ return mactwit_browser.VarBrowser(parent).open(var)
+
+ def edit(self, file, line):
+ return mactwit_edit.edit(file, line)
+
+
+def Initialize():
+ try:
+ # if this doesn't raise an error, we are an applet containing the
+ # necessary resources or we have been initialized already
+ # so we don't have to bother opening the resource file
+ dummy = Res.GetResource('DLOG', ID_MODULES)
+ except Res.Error:
+ try:
+ Res.FSpOpenResFile("Twit.rsrc", 1)
+ except Res.Error, arg:
+ EasyDialogs.Message("Cannot open Twit.rsrc: "+arg[1])
+ sys.exit(1)
+
diff --git a/Mac/Unsupported/twit/mactwit_browser.py b/Mac/Unsupported/twit/mactwit_browser.py
new file mode 100644
index 0000000..070de43
--- /dev/null
+++ b/Mac/Unsupported/twit/mactwit_browser.py
@@ -0,0 +1,429 @@
+"""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()
diff --git a/Mac/Unsupported/twit/mactwit_edit.py b/Mac/Unsupported/twit/mactwit_edit.py
new file mode 100644
index 0000000..ace253d
--- /dev/null
+++ b/Mac/Unsupported/twit/mactwit_edit.py
@@ -0,0 +1,24 @@
+"""Edit a file using the MetroWerks editor. Modify to suit your needs"""
+
+import MacOS
+import aetools
+import Metrowerks_Shell_Suite
+import Required_Suite
+
+_talker = None
+
+class MWShell(aetools.TalkTo,
+ Metrowerks_Shell_Suite.Metrowerks_Shell_Suite,
+ Required_Suite.Required_Suite):
+ pass
+
+def edit(file, line):
+ global _talker
+ if _talker == None:
+ _talker = MWShell('CWIE', start=1)
+ try:
+ _talker.open(file)
+ _talker.Goto_Line(line)
+ except "(MacOS.Error, aetools.Error)":
+ pass
+
diff --git a/Mac/Unsupported/twit/mactwit_mod.py b/Mac/Unsupported/twit/mactwit_mod.py
new file mode 100644
index 0000000..8c54480
--- /dev/null
+++ b/Mac/Unsupported/twit/mactwit_mod.py
@@ -0,0 +1,114 @@
+# A stab at a python debugger
+import Res
+import Qd
+import Dlg
+import Win
+import FrameWork
+import EasyDialogs
+import sys
+import TwitCore
+from mac_widgets import MT_AnyList, MT_IconTextWidget
+
+# Our dialogs
+ID_MODULES=500
+I_MODULES_TITLE=1
+I_MODULES=2
+I_VARS_TITLE=3
+I_VARS=4
+I_SOURCE_TITLE=5
+I_SOURCE=6
+I_RULER=7
+I_EDIT=8
+
+class ModuleBrowser(FrameWork.DialogWindow, TwitCore.ModuleBrowser):
+ """The module-browser dialog - mac-dependent part"""
+ def open(self, module):
+ FrameWork.DialogWindow.open(self, ID_MODULES)
+ self.SetPort()
+ Qd.TextFont(3)
+ Qd.TextSize(9)
+
+ tp, h, rect = self.wid.GetDialogItem(I_MODULES)
+ self.modules = MT_AnyList(self.wid, rect, 1)
+ tp, h, rect = self.wid.GetDialogItem(I_VARS)
+ self.vars = MT_AnyList(self.wid, rect, 2)
+ tp, h, rect = self.wid.GetDialogItem(I_SOURCE)
+ self.source = MT_IconTextWidget(self.wid, rect)
+
+ self.mi_open(module)
+
+ def setsource(self, msg):
+ tp, h, rect = self.wid.GetDialogItem(I_SOURCE_TITLE)
+ if self.cur_source:
+ Dlg.SetDialogItemText(h, self.cur_source)
+ else:
+ Dlg.SetDialogItemText(h, msg)
+ self.source.setcontent(self.cur_source)
+
+ def source_setbreaks(self, list):
+ self.source.setbreaks(list)
+
+ def source_setline(self, lineno, icon):
+ self.source.setcurline(lineno, icon)
+
+ def source_select(self, lineno):
+ self.source.select(lineno)
+
+ def setmodulenames(self):
+ self.modules.setcontent(self.cont_modules)
+
+ def module_select(self, number):
+ self.modules.select(number)
+
+ def setvars(self):
+ self.vars.setcontent(self.cont_varnames, self.cont_varvalues)
+
+ def do_itemhit(self, item, event):
+ (what, message, when, where, modifiers) = event
+ Qd.SetPort(self.wid)
+ where = Qd.GlobalToLocal(where)
+
+ if item == I_MODULES:
+ new_module, double = self.modules.click(where, 0)
+ self.click_module(new_module)
+ elif item == I_VARS:
+ new_var, double = self.vars.click(where, 0)
+ if double:
+ self.click_var(new_var)
+ elif item == I_SOURCE:
+ lineno, inborder = self.source.click(where, 0)
+ if lineno <> None and lineno >= 0:
+ self.click_source(lineno, inborder)
+ elif item == I_EDIT:
+ self.click_edit()
+
+ def do_rawupdate(self, window, event):
+ Qd.SetPort(self.wid)
+ rgn = self.wid.GetWindowPort().visRgn
+ tp, h, rect = self.wid.GetDialogItem(I_RULER)
+ Qd.MoveTo(rect[0], rect[1])
+ Qd.LineTo(rect[2], rect[1])
+ self.modules.update(rgn)
+ self.vars.update(rgn)
+ self.source.update(rgn)
+
+ def force_redraw(self):
+ Qd.SetPort(self.wid)
+ Win.InvalRgn(self.wid.GetWindowPort().visRgn)
+
+ def do_activate(self, activate, event):
+ self.modules.activate(activate)
+ self.vars.activate(activate)
+ self.source.activate(activate)
+
+ def close(self):
+ self.parent.module_dialog = None
+ self.source.close()
+ del self.modules
+ del self.vars
+ del self.source
+ self.do_postclose()
+
+if __name__ == '__main__':
+ main()
+
diff --git a/Mac/Unsupported/twit/mactwit_stack.py b/Mac/Unsupported/twit/mactwit_stack.py
new file mode 100644
index 0000000..e38fec3
--- /dev/null
+++ b/Mac/Unsupported/twit/mactwit_stack.py
@@ -0,0 +1,159 @@
+# A stab at a python debugger
+import Res
+import Qd
+import Dlg
+import Win
+import FrameWork
+import EasyDialogs
+import sys
+import TwitCore
+from mac_widgets import MT_AnyList, MT_IndexList, MT_IconTextWidget
+
+# Our dialogs
+ID_STACK=501
+I_STACK_TITLE=1
+I_STACK=2
+I_VARS_TITLE=3
+I_VARS=4
+I_SOURCE_TITLE=5
+I_SOURCE=6
+I_EXC_TITLE=7
+I_EXC=8
+I_EXCVALUE_TITLE=9
+I_EXCVALUE=10
+I_BROWSE=11
+I_RULER1=12
+I_RULER2=13
+I_STATE_TITLE=14
+I_STATE=15
+I_SHOW_COMPLEX=16
+I_SHOW_SYSTEM=17
+I_EDIT=18
+
+class StackBrowser(FrameWork.DialogWindow, TwitCore.StackBrowser):
+ """The stack-browser dialog - mac-dependent part"""
+ def open(self):
+ FrameWork.DialogWindow.open(self, ID_STACK)
+ self.SetPort()
+ Qd.TextFont(3)
+ Qd.TextSize(9)
+
+ tp, h, rect = self.wid.GetDialogItem(I_STACK)
+ self.stack = MT_IndexList(self.wid, rect, 2)
+ tp, h, rect = self.wid.GetDialogItem(I_VARS)
+ self.vars = MT_AnyList(self.wid, rect, 2)
+ tp, h, rect = self.wid.GetDialogItem(I_SOURCE)
+ self.source = MT_IconTextWidget(self.wid, rect)
+
+ self.mi_open()
+
+ def setsource(self, msg):
+ tp, h, rect = self.wid.GetDialogItem(I_SOURCE_TITLE)
+ if self.cur_source:
+ Dlg.SetDialogItemText(h, self.cur_source)
+ else:
+ Dlg.SetDialogItemText(h, msg)
+ self.source.setcontent(self.cur_source)
+
+ def source_setbreaks(self, list):
+ self.source.setbreaks(list)
+
+ def source_setline(self, lineno, icon):
+ self.source.setcurline(lineno, icon)
+
+ def source_select(self, lineno):
+ self.source.select(lineno)
+
+ def stack_setcontent(self, names, locations):
+ self.stack.setcontent(names, locations)
+
+ def stack_select(self, number):
+ self.stack.select(number)
+
+ def setvars(self):
+ self.vars.setcontent(self.cont_varnames, self.cont_varvalues)
+
+ def setexception(self, name, value):
+ if name == None:
+ self.wid.HideDialogItem(I_EXC)
+ self.wid.HideDialogItem(I_EXC_TITLE)
+ value = None
+ else:
+ self.wid.ShowDialogItem(I_EXC)
+ self.wid.ShowDialogItem(I_EXC_TITLE)
+ tp, h, rect = self.wid.GetDialogItem(I_EXC)
+ Dlg.SetDialogItemText(h, name)
+ if value == None:
+ self.wid.HideDialogItem(I_EXCVALUE)
+ self.wid.HideDialogItem(I_EXCVALUE_TITLE)
+ else:
+ self.wid.ShowDialogItem(I_EXCVALUE)
+ self.wid.ShowDialogItem(I_EXCVALUE_TITLE)
+ tp, h, rect = self.wid.GetDialogItem(I_EXCVALUE)
+ Dlg.SetDialogItemText(h, value)
+
+ def setprogramstate(self, msg):
+ tp, h, rect = self.wid.GetDialogItem(I_STATE)
+ Dlg.SetDialogItemText(h, msg)
+
+ def do_itemhit(self, item, event):
+ (what, message, when, where, modifiers) = event
+ Qd.SetPort(self.wid)
+ where = Qd.GlobalToLocal(where)
+
+ if item == I_STACK:
+ new_stackitem, double = self.stack.click(where, 0)
+ self.click_stack(new_stackitem)
+ elif item == I_VARS:
+ new_var, double = self.vars.click(where, 0)
+ if double:
+ self.click_var(new_var)
+ elif item == I_SOURCE:
+ lineno, inborder = self.source.click(where, 0)
+ if lineno <> None and lineno >= 0:
+ self.click_source(lineno, inborder)
+ elif item == I_BROWSE:
+ self.click_browse()
+ elif item == I_SHOW_COMPLEX:
+ self.show_complex = not self.show_complex
+ self.setup_frame()
+ elif item == I_SHOW_SYSTEM:
+ self.show_system = not self.show_system
+ self.setup_frame()
+ elif item == I_EDIT:
+ self.click_edit()
+
+ def set_var_buttons(self):
+ tp, h, rect = self.wid.GetDialogItem(I_SHOW_COMPLEX)
+ h.as_Control().SetControlValue(self.show_complex)
+ tp, h, rect = self.wid.GetDialogItem(I_SHOW_SYSTEM)
+ h.as_Control().SetControlValue(self.show_system)
+
+ def do_rawupdate(self, window, event):
+ Qd.SetPort(self.wid)
+ rgn = self.wid.GetWindowPort().visRgn
+ tp, h, rect = self.wid.GetDialogItem(I_RULER1)
+ Qd.MoveTo(rect[0], rect[1])
+ Qd.LineTo(rect[2], rect[1])
+ tp, h, rect = self.wid.GetDialogItem(I_RULER2)
+ Qd.MoveTo(rect[0], rect[1])
+ Qd.LineTo(rect[2], rect[1])
+ self.stack.update(rgn)
+ self.vars.update(rgn)
+ self.source.update(rgn)
+
+ def force_redraw(self):
+ Qd.SetPort(self.wid)
+ Win.InvalRgn(self.wid.GetWindowPort().visRgn)
+
+ def do_activate(self, activate, event):
+ self.stack.activate(activate)
+ self.vars.activate(activate)
+ self.source.activate(activate)
+
+ def close(self):
+ self.source.close()
+ del self.stack
+ del self.vars
+ del self.source
+ self.do_postclose()
diff --git a/Mac/Unsupported/twit/twit.py b/Mac/Unsupported/twit/twit.py
new file mode 100644
index 0000000..2cc3f41
--- /dev/null
+++ b/Mac/Unsupported/twit/twit.py
@@ -0,0 +1,59 @@
+"""twit - The Window-Independent Tracer.
+
+Interface:
+twit.main() Enter debugger in inactive interactive state
+twit.run(stmt, globals, locals) Enter debugger and start running stmt
+twit.post_mortem(traceback) Enter debugger in post-mortem mode on traceback
+twit.pm() Enter debugger in pm-mode on sys.last_traceback
+
+main program: nothing but a bit of glue to put it all together.
+
+Jack Jansen, CWI, August 1996."""
+
+import os
+import sys
+
+# Add our directory to path, if needed
+dirname = os.path.split(__file__)[0]
+if not dirname in sys.path:
+ sys.path.append(dirname)
+
+if os.name == 'mac':
+ import MacOS
+ MacOS.splash(502) # Try to show the splash screen
+ import mactwit_app; twit_app = mactwit_app
+else:
+ try:
+ import _tkinter
+ have_tk = 1
+ except ImportError:
+ have_tk = 0
+ if have_tk:
+ import tktwit_app; twit_app = tktwit_app
+ else:
+ print 'Please implementent machine-dependent code and try again:-)'
+ sys.exit(1)
+
+import sys
+
+def main():
+ twit_app.Initialize()
+ if os.name == 'mac':
+ MacOS.splash()
+ twit_app.Twit('none', None)
+
+def run(statement, globals=None, locals=None):
+ twit_app.Initialize()
+ twit_app.Twit('run', (statement, globals, locals))
+
+def post_mortem(t):
+ Initialize()
+ twit_app.Twit('pm', t)
+
+def pm():
+ post_mortem(sys.last_traceback)
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/Mac/Unsupported/twit/twit.rsrc b/Mac/Unsupported/twit/twit.rsrc
new file mode 100644
index 0000000..a659719
--- /dev/null
+++ b/Mac/Unsupported/twit/twit.rsrc
Binary files differ
diff --git a/Mac/Unsupported/twit/twittest.py b/Mac/Unsupported/twit/twittest.py
new file mode 100644
index 0000000..10d3693
--- /dev/null
+++ b/Mac/Unsupported/twit/twittest.py
@@ -0,0 +1,13 @@
+# Test program
+
+def foo(arg1, arg2):
+ bar(arg1+arg2)
+ bar(arg1-arg2)
+ foo(arg1+1, arg2-1)
+
+def bar(arg):
+ rv = 10/arg
+ print rv
+
+foo(0,10)
+