00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 from base import Base
00029 import gobject
00030 import gtk
00031 import gtk.gdk
00032 import os
00033 from pixman import PixMan
00034 import zero
00035
00036
00037 class Code(Base):
00038 """
00039 Base class for source code and assembly views
00040 """
00041 def __init__(self, w):
00042 Base.__init__(self)
00043 self.__fname = None
00044 self.__pixman = PixMan(w)
00045 self.__currentLine = 0
00046
00047 self.__breakpoints = { }
00048 self.__model = gtk.ListStore(
00049 gobject.TYPE_OBJECT,
00050 gobject.TYPE_STRING,
00051 gobject.TYPE_STRING,
00052 gobject.TYPE_STRING,
00053 )
00054 self.__init_pixbufs(w)
00055 self.__scrolled = gtk.ScrolledWindow()
00056 self.__scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00057 self.__w = gtk.TreeView(self.__model)
00058 self.__thread = None
00059 self.__addr = 0
00060 self.__scrolled.add(self.__w)
00061 tree = self.__w
00062 tree.connect("button_press_event", self.__on_button_press)
00063 tree.set_headers_visible(False)
00064 tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
00065
00066 renderer = gtk.CellRendererPixbuf()
00067 tree.append_column(gtk.TreeViewColumn("", renderer, pixbuf=0))
00068 renderer = gtk.CellRendererText()
00069 tree.append_column(gtk.TreeViewColumn("", renderer, text=1))
00070 tree.append_column(gtk.TreeViewColumn("", renderer, text=2))
00071 tree.append_column(gtk.TreeViewColumn("", renderer, text=3))
00072
00073 def __init_pixbufs(self, w):
00074 self.__arrow = self.__pixman.get_pixbuf("arrow")
00075 self.__stop = self.__pixman.get_pixbuf("brkpnt")
00076
00077 def widget(self):
00078 return self.__scrolled
00079
00080 def filename(self):
00081 return self.__fname
00082
00083 def set_current_line(self, addr, line):
00084 iter = self.__model.iter_nth_child(None, self.__currentLine)
00085 try:
00086 b = self.__breakpoints[self.__addr]
00087 self.__model.set_value(iter, 0, self.__stop)
00088 except KeyError:
00089 self.__model.set_value(iter, 0, None)
00090 self.__currentLine = line
00091
00092
00093 def read(self, thread, addr, sym):
00094 if thread.process():
00095 breakpoints = thread.process().breakpoints()
00096 else:
00097 breakpoints = thread.breakpoints()
00098
00099 self.read_file(thread, addr, sym, breakpoints)
00100
00101 def show(self, thread, addr, sym):
00102 assert sym
00103 if sym:
00104 if self.__fname != sym.filename():
00105 self.read(thread, addr, sym)
00106 self.__fname = sym.filename()
00107 self.set_current_line(addr, sym.line() - 1)
00108
00109 iter = self.mark_current_line()
00110 if thread.program_count() == addr:
00111 pixbuf = self.__arrow
00112 try:
00113 b = self.__breakpoints[addr]
00114 pixbuf = self.__pixman.compose(self.__stop, pixbuf)
00115 except KeyError:
00116 pass
00117 self.__model.set_value(iter, 0, pixbuf)
00118 self.__thread = thread
00119 self.__addr = addr
00120 self.__sym = sym
00121
00122
00123 def mark_current_line(self):
00124 line = self.__currentLine
00125 iter = self.__model.iter_nth_child(None, line)
00126 tree = self.__w
00127 path = self.__model.get_path(iter)
00128 try:
00129
00130 tree.set_cursor_on_cell(path)
00131 except:
00132 tree.set_cursor(path, None, False)
00133 return iter
00134
00135 def clear(self):
00136 self.__model.clear()
00137
00138 def get_token(self, iter):
00139 "Get the token under cursor in the code view"
00140 return ""
00141
00142 def __on_button_press(self, w, event):
00143 if event.button == 3:
00144 self.__popup_menu(event)
00145
00146 def __popup_menu(self, event):
00147 x = int(event.x)
00148 y = int(event.y)
00149 path = self.__w.get_path_at_pos(x, y)[0]
00150 if path:
00151 iter = self.__model.get_iter(path)
00152 if iter:
00153
00154
00155 addresses = self.get_addresses(iter)
00156
00157 token = self.get_token(iter)
00158 menu = self.__make_contextual_menu(addresses, token)
00159 if menu:
00160 menu.popup(None,
00161 None,
00162 None,
00163 event.button,
00164 event.get_time())
00165
00166 def __make_contextual_menu(self, addrs, token):
00167 menu = gtk.Menu()
00168 if self.__thread:
00169 self.__add_breakpoint_menu_items(menu, self.__thread, addrs)
00170 menu.show_all()
00171 return menu
00172
00173 def __add_breakpoint_menu_items(self, menu, thread, addresses):
00174 breakpoints_to_enable = []
00175 breakpoints_to_disable = []
00176 breakpoints_to_remove = []
00177 breakpoints_to_set = []
00178
00179 for a in addresses:
00180 allBreakpoints = thread.process().breakpoints(a)
00181 for b in allBreakpoints:
00182 breakpoints_to_remove.append(b)
00183 if b.is_enabled():
00184 breakpoints_to_disable.append(b)
00185 else:
00186 breakpoints_to_enable.append(b)
00187 if len(allBreakpoints) == 0:
00188 breakpoints_to_set.append(a)
00189 if len(breakpoints_to_set):
00190 self.__add_set_breakpoint_item(menu,
00191 "Set Breakpoint",
00192 thread.process(),
00193 breakpoints_to_set)
00194 self.__add_set_breakpoint_item(menu,
00195 "Set Thread Breakpoint",
00196 thread,
00197 breakpoints_to_set)
00198
00199 if len(breakpoints_to_remove):
00200 self.__add_remove_breakpoint_item(menu, breakpoints_to_remove)
00201
00202
00203
00204
00205 def __add_set_breakpoint_item(self, menu, label, thread, breakpoints):
00206 item = gtk.ImageMenuItem("gtk-dialog-error")
00207 item.get_child().set_label(label)
00208 menu.append(item)
00209 if len(breakpoints) > 1:
00210 subMenu = gtk.Menu()
00211 item.set_submenu(subMenu)
00212 for a in breakpoints:
00213 print "__add_set_breakpoint_item",hex(a)
00214 subItem = gtk.MenuItem(hex(a))
00215 subMenu.append(subItem)
00216 subItem.connect("activate", self.__set_breakpoint, thread, a)
00217 elif len(breakpoints):
00218 a = breakpoints[0]
00219 item.connect("activate", self.__set_breakpoint, thread, a)
00220
00221
00222 def __add_remove_breakpoint_item(self, menu, breakpoints):
00223 assert len(breakpoints)
00224 item = gtk.ImageMenuItem("todo")
00225 item.get_child().set_label("Remove Breakpoint")
00226 menu.append(item)
00227 if len(breakpoints) == 1:
00228 b = breakpoints[0]
00229 item.connect("activate", self.__remove_breakpoint, b)
00230 else:
00231 subMenu = gtk.Menu()
00232 item.set_submenu(subMenu)
00233 for b in breakpoints:
00234 subItem = gtk.MenuItem(hex(b.addr()))
00235 subMenu.append(subItem)
00236 subItem.connect("activate", self.__remove_breakpoint, b)
00237
00238
00239 def __set_icon_at_line(self, lineNum, pixbuf):
00240 assert lineNum
00241 iter = self.__model.iter_nth_child(None, lineNum - 1)
00242 self.__model.set_value(iter, 0, pixbuf)
00243
00244
00245 def set_icon_at_symbol(self, sym, pixbuf):
00246 self.__set_icon_at_line(self.symbol_line(sym), pixbuf)
00247
00248
00249 def __set_breakpoint(self, item, thread, addr):
00250 thread.set_breakpoint(addr)
00251 self.__breakpoints[addr] = thread.breakpoints(addr)[0]
00252 sym = thread.symbols().lookup(addr)
00253 if sym:
00254 if sym.filename() == self.filename():
00255 self.set_icon_at_symbol(sym, self.__stop)
00256
00257
00258 def __remove_breakpoint(self, item, brkpnt):
00259 a = brkpnt.addr()
00260 sym = brkpnt.symbol()
00261 brkpnt.remove()
00262 if not len(self.__thread.process().breakpoints(a)):
00263 del self.__breakpoints[a]
00264 if a == self.__thread.program_count():
00265 self.set_icon_at_symbol(sym, self.__arrow)
00266 else:
00267 self.set_icon_at_symbol(sym, None)
00268
00269
00270 def symbol_line(self, sym):
00271 return sym.line()