# 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) self = basewin.BaseWindow.init(self, '--Frame ' + name + '--') # XXX Should use current function name self.initeditor() self.displaylist = ['>>>', '', '-'*WIDTH] self.refreshframe() return self 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().init(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: output = sys.exc_type + ': ' + `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