1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
# wdbframewin.py -- frame window for wdb.py
# XXX To do:
# - display function name in window title
# - execute arbitrary statements instead of just evaluating expressions
# - allow setting variables by editing their values
import stdwin
from stdwinevents import *
import basewin
import sys
WIDTH = 40
MINHEIGHT = 8
MAXHEIGHT = 16
class FrameWindow(basewin.BaseWindow):
def __init__(self, debugger, frame, dict, name):
self.debugger = debugger
self.frame = frame # Not used except for identity tests
self.dict = dict
self.name = name
nl = max(MINHEIGHT, len(self.dict) + 5)
nl = min(nl, MAXHEIGHT)
width = WIDTH*stdwin.textwidth('0')
height = nl*stdwin.lineheight()
stdwin.setdefwinsize(width, height)
basewin.BaseWindow.__init__(
self, '--Frame ' + name + '--')
# XXX Should use current function name
self.initeditor()
self.displaylist = ['>>>', '', '-'*WIDTH]
self.refreshframe()
def initeditor(self):
r = (stdwin.textwidth('>>> '), 0), (30000, stdwin.lineheight())
self.editor = self.win.textcreate(r)
def closeeditor(self):
self.editor.close()
def dispatch(self, event):
type, win, detail = event
if type == WE_NULL: return # Dummy tested by mainloop
if type in (WE_DRAW, WE_COMMAND) \
or not self.editor.event(event):
basewin.BaseWindow.dispatch(self, event)
def close(self):
del self.debugger.framewindows[self.name]
del self.debugger, self.dict
self.closeeditor()
basewin.BaseWindow.close(self)
def command(self, detail):
if detail == WC_RETURN:
self.re_eval()
else:
dummy = self.editor.event(WE_COMMAND, \
self.win, detail)
def mouse_down(self, detail):
(h, v), clicks, button, mask = detail
if clicks != 2:
return
i = v / stdwin.lineheight()
if 5 <= i < len(self.displaylist):
import string
name = string.splitfields(self.displaylist[i],' = ')[0]
if not self.dict.has_key(name):
stdwin.fleep()
return
value = self.dict[name]
if not hasattr(value, '__dict__'):
stdwin.fleep()
return
name = 'instance ' + `value`
if self.debugger.framewindows.has_key(name):
self.debugger.framewindows[name].popup()
else:
self.debugger.framewindows[name] = \
FrameWindow(self.debugger,
self.frame, value.__dict__,
name)
return
stdwin.fleep()
def re_eval(self):
import string, repr
expr = string.strip(self.editor.gettext())
if expr == '':
output = ''
else:
globals = self.frame.f_globals
globals['__privileged__'] = 1
locals = self.dict
try:
value = eval(expr, globals, locals)
output = repr.repr(value)
except:
if type(sys.exc_type) == type(''):
exc_type_name = sys.exc_type
else: exc_type_name = sys.exc_type.__name__
output = exc_type_name + ': ' + `sys.exc_value`
self.displaylist[1] = output
lh = stdwin.lineheight()
r = (-10, 0), (30000, 2*lh)
self.win.change(r)
self.editor.setfocus(0, len(expr))
def draw(self, detail):
(left, top), (right, bottom) = detail
dummy = self.editor.draw(detail)
d = self.win.begindrawing()
try:
lh = d.lineheight()
h, v = 0, 0
for line in self.displaylist:
if v+lh > top and v < bottom:
d.text((h, v), line)
v = v + lh
finally:
d.close()
def refreshframe(self):
import repr
del self.displaylist[3:]
self.re_eval()
names = self.dict.keys()
for key, label in ('__args__', 'Args: '), \
('__return__', 'Return: '):
if self.dict.has_key(key):
names.remove(key)
value = self.dict[key]
label = label + repr.repr(value)
self.displaylist.append(label)
names.sort()
for name in names:
value = self.dict[name]
line = name + ' = ' + repr.repr(value)
self.displaylist.append(line)
self.win.setdocsize(0, \
stdwin.lineheight() * len(self.displaylist))
self.refreshall() # XXX Be more subtle later
|