Added controller class:
[pygdb.git] / BreakpointsFrame.py
1 #!/usr/bin/python
2 #shuber, 2008-06-04
3
4 __author__ = "shuber"
5
6
7 import gobject
8 import gtk
9 import re
10 import string
11 import vte
12
13 import DbgTerminal
14 import StatusFrame
15
16
17 class BreakpointsFrame (StatusFrame.StatusFrame):
18
19
20 def __init__(self, debugger):
21
22 StatusFrame.StatusFrame.__init__(self, debugger)
23 self.set_label("Breakpoints")
24
25 debugger.gotActiveCallback += [self.updateValues]
26
27 vbox = gtk.VBox(False, 5)
28 self.add(vbox)
29
30 hbox = gtk.HBox()
31 vbox.pack_start(hbox, False, False)
32 self.bpEntry = gtk.Entry()
33 hbox.add(self.bpEntry)
34
35
36 hbox = gtk.HBox()
37 vbox.pack_start(hbox, False, False)
38 self.addBtn = gtk.Button(stock=gtk.STOCK_ADD)
39 self.delBtn = gtk.Button(stock=gtk.STOCK_REMOVE)
40 self.updBtn = gtk.Button("Update")
41 hbox.add(self.addBtn)
42 hbox.add(self.delBtn)
43 hbox.add(self.updBtn)
44
45 sw = gtk.ScrolledWindow()
46 sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
47 sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
48 vbox.add(sw)
49
50 self.model = self.__createModel()
51 self.tv = gtk.TreeView(self.model)
52 self.tv.set_rules_hint(True)
53 self.tv.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
54 self.tv.get_selection().connect("changed", self.selChanged)
55
56 self.__addColumns(self.tv)
57 sw.add(self.tv)
58
59 self.addBtn.connect("clicked", self.addBtnClicked)
60 self.delBtn.connect("clicked", self.delBtnClicked)
61 self.updBtn.connect("clicked", self.updBtnClicked)
62
63
64
65 def __createModel(self):
66 #Breakpoint number, position and a boolean flag indicating
67 #whether BP has been set at debugger yet
68 model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
69
70 return model
71
72
73 def __addColumns(self, tv):
74
75 model = tv.get_model()
76
77 renderer = gtk.CellRendererText()
78 renderer.set_data("column", 0)
79 col = gtk.TreeViewColumn("No", renderer, text=0)
80 col.set_resizable(True)
81 tv.append_column(col)
82
83
84 renderer = gtk.CellRendererText()
85 renderer.set_data("column", 1)
86 col = gtk.TreeViewColumn("Specification", renderer, text=1)
87 col.set_resizable(True)
88 tv.append_column(col)
89
90
91 def selChanged(self, sel):
92 model, paths = sel.get_selected_rows()
93
94 if len(paths) > 0:
95 path = paths[0]
96 iter = model.get_iter(path)
97 bpspec, = model.get(iter, 1)
98 self.bpEntry.set_text(bpspec)
99
100
101
102 def addBreakpoint(self, file, lineno, cond=None):
103
104 no = self.debugger.setBreakpoint(file, lineno, cond)
105 if no!=None:
106 self.addBreakpointToList(no, file, lineno, cond)
107 else:
108 dialog = gtk.MessageDialog(None, \
109 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, \
110 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
111 "Invalid specification!")
112 dialog.run()
113 dialog.destroy()
114
115 return no
116
117
118 def delBreakpoints(self, file, lineno):
119
120 def addIters(model, path, iter, iters):
121 expr = model.get_value(iter,1)
122 expr = string.split(expr, " if ")[0].strip()
123 if expr == "%s:%d"%(file,lineno):
124 iters += [iter]
125
126 iters = []
127 self.model.foreach(addIters, iters)
128
129 #Need reversed here since rows are moved
130 #when removing rows
131 for i in reversed(iters):
132 self.model.remove(i)
133
134
135
136 def applyConfiguration(self, conf):
137 for b in conf.breakpoints:
138 self.addBreakpoint(b["file"], b["lineno"], b["cond"])
139 self.updateValues(None, None)
140
141 def fillConfiguration(self, conf):
142 iter = self.model.get_iter_first()
143 while iter != None:
144 spec, = self.model.get(iter, 1)
145
146 #Replacing file by absolute path
147 file = string.split(spec, ":")[0]
148 file = self.debugger.toAbsPath(file)
149 postfile = string.join( string.split(spec,":")[1:], ":")
150
151 conf.parseBreak(file + ":" + postfile )
152 iter = self.model.iter_next(iter)
153
154
155
156 def addBreakpointToList(self, no, file, lineno, cond=None):
157
158 if cond==None:
159 expr = "%s:%s" % (str(file), str(lineno))
160 else:
161 expr = "%s:%s if %s" % (str(file), str(lineno), str(cond))
162
163 iter = self.model.get_iter_first()
164 while iter != None:
165 newiter = self.model.iter_next(iter)
166 #Found a expression which is the same --> remove the breakpoint
167 if (expr,) == self.model.get(iter,1):
168 self.debugger.delBreakpoint(no)
169 return
170 iter = newiter
171
172 #Add the entry to the breakpoint list
173 iter = self.model.append()
174 self.model.set(iter, 0, no)
175 self.model.set(iter, 1, expr)
176
177
178 def addBtnClicked(self, btn):
179
180 if not self.debugger.isActive():
181 return
182
183
184 bpspec = self.bpEntry.get_text()
185 bpspec = bpspec.strip()
186 rx = re.compile("^[\w/\._\-]+:\d+(\s+if\s+\S+.*)?$")
187
188 #Check if format is correct
189 if not rx.search(bpspec):
190 dialog = gtk.MessageDialog(None, \
191 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, \
192 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
193 "Invalid format!")
194 dialog.run()
195 dialog.destroy()
196 return
197
198
199 ifsplit = string.split(bpspec, " if ")
200
201 if len(ifsplit)>1:
202 cond = ifsplit[1].strip()
203 else:
204 cond = None
205
206 pos = ifsplit[0].strip()
207 [file,lineno] = string.split(pos, ":")
208
209 self.addBreakpoint(file, lineno, cond)
210
211
212
213
214 def delBtnClicked(self, btn):
215
216 self.delBreakpoints("main.cpp", 26)
217 return
218
219 if not self.debugger.isActive():
220 return
221
222 selection = self.tv.get_selection()
223 model, paths = selection.get_selected_rows()
224
225 for path in reversed(paths):
226 iter = model.get_iter(path)
227 bpno, = self.model.get(iter, 0)
228 self.debugger.delBreakpoint(bpno)
229 model.remove(iter)
230
231
232 def updBtnClicked(self, btn):
233
234 if not self.debugger.isActive():
235 return
236
237 self.updateValues(None, None)
238
239
240 def updateValues(self, status, param):
241
242 bpnts = self.debugger.getBreakpoints()
243
244 #Remove them all
245 iter = self.model.get_iter_first()
246 while iter != None:
247 newiter = self.model.iter_next(iter)
248 self.model.remove(iter)
249 iter = newiter
250
251 for bp in bpnts:
252 [no, file, lineno, cond] = bp
253 self.addBreakpointToList(no, file, lineno, cond)
254
255
256