Clarify portability and main program.
[python/dscho.git] / Mac / Contrib / PyIDE-src / IDELib / Widgets / Wtraceback.py
blob5804cd7711666202b0baf2c4cf5af034342b9017
1 import traceback
2 import sys
3 import W
4 import os
5 import types
7 class TraceList(W.List):
9 LDEF_ID = 468
11 def createlist(self):
12 import List
13 self._calcbounds()
14 self.SetPort()
15 rect = self._bounds
16 rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
17 self._list = List.LNew(rect, (0, 0, 1, 0), (0, 28), self.LDEF_ID, self._parentwindow.wid,
18 0, 1, 0, 1)
19 self.set(self.items)
22 class TraceBack:
24 def __init__(self, title = "Traceback"):
25 app = W.getapplication() # checks if W is properly initialized
26 self.title = title
27 self.w = None
28 self.closed = 1
29 self.start = 0
30 self.lastwindowtitle = ""
31 self.bounds = (360, 298)
33 def traceback(self, start = 0, lastwindowtitle = ""):
34 try:
35 self.lastwindowtitle = lastwindowtitle
36 self.start = start
37 self.type, self.value, self.tb = sys.exc_type, sys.exc_value, sys.exc_traceback
38 if self.type is not SyntaxError:
39 self.show()
40 if type(self.type) == types.ClassType:
41 errortext = self.type.__name__
42 else:
43 errortext = str(self.type)
44 value = str(self.value)
45 if self.value and value:
46 errortext = errortext + ": " + value
47 self.w.text.set(errortext)
48 self.buildtblist()
49 self.w.list.set(self.textlist)
50 self.w.list.setselection([len(self.textlist) - 1])
51 self.w.wid.SelectWindow()
52 self.closed = 0
53 else:
54 self.syntaxerror()
55 except:
56 traceback.print_exc()
58 def syntaxerror(self):
59 try:
60 value, (filename, lineno, charno, line) = self.value
61 except:
62 filename = ""
63 lineno = None
64 value = self.value
65 if not filename and self.lastwindowtitle:
66 filename = self.lastwindowtitle
67 elif not filename:
68 filename = "<unknown>"
69 if filename and os.path.exists(filename):
70 filename = os.path.split(filename)[1]
71 if lineno:
72 charno = charno - 1
73 text = value + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "€" + line[charno:-1]
74 else:
75 text = value + '\rFile: "' + str(filename) + '"'
76 self.syntaxdialog = W.ModalDialog((360, 120), "Syntax Error")
77 self.syntaxdialog.text = W.TextBox((10, 10, -10, -40), text)
78 self.syntaxdialog.cancel = W.Button((-190, -32, 80, 16), "Cancel", self.syntaxclose)
79 self.syntaxdialog.edit = W.Button((-100, -32, 80, 16), "Edit", self.syntaxedit)
80 self.syntaxdialog.setdefaultbutton(self.syntaxdialog.edit)
81 self.syntaxdialog.bind("cmd.", self.syntaxdialog.cancel.push)
82 self.syntaxdialog.open()
84 def syntaxclose(self):
85 self.syntaxdialog.close()
86 del self.syntaxdialog
88 def syntaxedit(self):
89 try:
90 value, (filename, lineno, charno, line) = self.value
91 except:
92 filename = ""
93 lineno = None
94 if not filename and self.lastwindowtitle:
95 filename = self.lastwindowtitle
96 elif not filename:
97 filename = "<unknown>"
98 self.syntaxclose()
99 if lineno:
100 W.getapplication().openscript(filename, lineno, charno - 1)
101 else:
102 W.getapplication().openscript(filename)
104 def show(self):
105 if self.closed:
106 self.setupwidgets()
107 self.w.open()
108 else:
109 self.w.wid.ShowWindow()
110 self.w.wid.SelectWindow()
112 def close(self):
113 self.bounds = self.w.getbounds()
114 self.closed = 1
115 self.type, self.value, self.tb = None, None, None
116 self.tblist = None
118 def activate(self, onoff):
119 if onoff:
120 if self.closed:
121 self.traceback()
122 self.closed = 0
123 self.checkbuttons()
125 def setupwidgets(self):
126 self.w = W.Window(self.bounds, self.title, minsize = (316, 168))
127 self.w.text = W.TextBox((10, 10, -10, 30))
128 self.w.tbtitle = W.TextBox((10, 40, -10, 10), "Traceback (innermost last):")
129 self.w.list = TraceList((10, 60, -10, -40), callback = self.listhit)
131 self.w.editbutton = W.Button((10, -30, 60, 16), "Edit", self.edit)
132 self.w.editbutton.enable(0)
134 self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse localsŠ", self.browselocals)
135 self.w.browselocalsbutton.enable(0)
137 self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortemŠ", self.postmortem)
139 self.w.setdefaultbutton(self.w.editbutton)
140 self.w.bind("cmdb", self.w.browselocalsbutton.push)
141 self.w.bind("<close>", self.close)
142 self.w.bind("<activate>", self.activate)
144 def buildtblist(self):
145 tb = self.tb
146 for i in range(self.start):
147 if tb.tb_next is None:
148 break
149 tb = tb.tb_next
150 self.tblist = traceback.extract_tb(tb)
151 self.textlist = []
152 for filename, lineno, func, line in self.tblist:
153 tbline = ""
154 if os.path.exists(filename):
155 filename = os.path.split(filename)[1]
156 tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + func
157 else:
158 tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + func
159 if line:
160 tbline = tbline + '\r ' + line
161 self.textlist.append(tbline[:255])
163 def edit(self):
164 sel = self.w.list.getselection()
165 for i in sel:
166 filename, lineno, func, line = self.tblist[i]
167 W.getapplication().openscript(filename, lineno)
169 def browselocals(self):
170 sel = self.w.list.getselection()
171 for i in sel:
172 tb = self.tb
173 for j in range(i + self.start):
174 tb = tb.tb_next
175 self.browse(tb.tb_frame.f_locals)
177 def browse(self, object):
178 import PyBrowser
179 PyBrowser.Browser(object)
181 def postmortem(self):
182 import PyDebugger
183 PyDebugger.postmortem(self.type, self.value, self.tb)
185 def listhit(self, isdbl):
186 if isdbl:
187 self.w.editbutton.push()
188 else:
189 self.checkbuttons()
191 def checkbuttons(self):
192 havefile = len(self.w.list.getselection()) > 0
193 self.w.editbutton.enable(havefile)
194 self.w.browselocalsbutton.enable(havefile)
195 self.w.setdefaultbutton(havefile and self.w.editbutton or self.w.postmortembutton)