blah
authorJorge Gorbe <j.gorbe@stcsl.es>
Wed, 31 Oct 2012 14:15:20 +0000 (15:15 +0100)
committerJorge Gorbe <j.gorbe@stcsl.es>
Wed, 31 Oct 2012 14:15:20 +0000 (15:15 +0100)
samples/test3.cc
samples/test4.cc [new file with mode: 0644]
samples/view.py

index 17196d537babba939ac34d46d3764d8d23e30d78..14f1fd4fa41e56543829dd2df3c806e74882f8b3 100644 (file)
@@ -1,5 +1,12 @@
+struct a {
+    int b;
+    int c;
+    a(): b(10), c(20) {}
+};
+
 struct treenode {
     int value;
+    a nested;
     treenode *left;
     treenode *right;
     treenode(): value(-1), left(0), right(0) {}
diff --git a/samples/test4.cc b/samples/test4.cc
new file mode 100644 (file)
index 0000000..607a0e9
--- /dev/null
@@ -0,0 +1,12 @@
+#include <map>
+#include <string>
+
+int main()
+{
+    std::map<std::string, int> m;
+    m["trololo"]=1;
+    m["blah"]=2;
+    m["lolailo"]=3;
+    m["xyz"]=4;
+    m["meh"]=5;
+}
index f4ba35b1687b0914bf918b6b4bacb1b23c87f1d9..793b09366f17652aa9ccc140b95e3e8a7e47a739 100644 (file)
@@ -1,9 +1,14 @@
 import gdb
+import gdb.types
 import gtk
 import pango
 import pangocairo
 import math
 
+def type_has_fields(t):
+    basic_type = gdb.types.get_basic_type(t)
+    return basic_type.code == gdb.TYPE_CODE_STRUCT or basic_type.code == gdb.TYPE_CODE_UNION
+
 def segment_intersection(A, B, C, D):
     """Computes the intersection between the rect segment AB and the rect segment CD.
     All parameters are 2D points expressed as (x,y) tuples. Result is also a (x,y) tuple, or
@@ -87,23 +92,39 @@ class GraphViewerNode():
         self.name = name
         self.gdb_value = gdb_value
         self.connections = [] # outgoing pointers to other nodes, to draw arrows
-        self.fill_color = (0.8, 0.4, 0)
+        self.fill_color = (0.4, 0.4, 0.5)
 
 
 
 class GraphViewer(gtk.DrawingArea):
-    def __init__(self):
+    def __init__(self, value_viewer):
         super(gtk.DrawingArea, self).__init__()
         self.nodes = []
-        self.connect("expose_event", self.expose)
+        self.selected_node = None
+        self.value_viewer = value_viewer
+        self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+        self.connect("expose_event", self.on_expose)
+        self.connect("button_press_event", self.on_click)
 
-    def expose(self, widget, event):
+    def on_expose(self, widget, event):
         context = pangocairo.CairoContext(widget.window.cairo_create())
         context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
         context.clip()
         self.draw(context)
         return False
 
+    def on_click(self, widget, event):
+        self.selected_node = None
+        for node in self.nodes:
+            if event.x >= node.x and event.x < node.x + node.width and event.y >= node.y and event.y < node.y + node.height:
+                self.selected_node = node
+
+        if self.selected_node != None:
+             self.value_viewer.set_value(self.selected_node.gdb_value)
+
+        self.queue_draw()
+        return False
+
 
     def draw_node(self, context, node):
         # draw node name
@@ -115,17 +136,22 @@ class GraphViewer(gtk.DrawingArea):
         context.show_layout(name_layout)
 
         # draw node rect
+        context.save()
         context.rectangle(node.x, node.y, node.width, node.height)
         context.set_source_rgb(*node.fill_color)
         context.fill()
-        context.set_source_rgb(0,0,0)
-        context.set_line_width(1)
+        if node is self.selected_node:
+            context.set_source_rgb(1,0,0)
+            context.set_line_width(3)
         context.rectangle(node.x, node.y, node.width, node.height)
         context.stroke()
+        context.restore()
 
 
     def draw_connection(self, context, n1, n2):
         (p1, p2) = node_connection_points(n1, n2)
+        context.set_source_rgb(0,0,0)
+        context.set_line_width(1)
         context.move_to(*p1)
         context.line_to(*p2)
         context.stroke()
@@ -145,13 +171,55 @@ class GraphViewer(gtk.DrawingArea):
             for other in node.connections:
                 self.draw_connection(context, node, other)
         
+class GdbValueViewer(gtk.TreeView):
+    def __init__(self):
+        super(gtk.TreeView, self).__init__()
+        self.store = gtk.TreeStore(str, str)
+        self.set_model(self.store)
+        # column setup
+        # column 0
+        self.field_column = gtk.TreeViewColumn("Field")
+        self.field_cell = gtk.CellRendererText()
+        self.field_column.pack_start(self.field_cell)
+        self.append_column(self.field_column)
+        self.field_column.add_attribute(self.field_cell, 'text', 0)
+        # column 1
+        self.value_column = gtk.TreeViewColumn("Value")
+        self.value_cell = gtk.CellRendererText()
+        self.value_column.pack_start(self.value_cell)
+        self.append_column(self.value_column)
+        self.value_column.add_attribute(self.value_cell, 'text', 1)
+
+        # make column 0 searchable and sortable
+        self.set_search_column(0)
+        self.field_column.set_sort_column_id(0)
+
+    def visit_value(self, value, store_iter):
+        if type_has_fields(value.type):
+            for f in value.type.fields():
+                field_value = value[f.name]
+                if type_has_fields(field_value.type) > 0:
+                    child_iter = self.store.append(store_iter, (f.name, str(f.type)))
+                    self.visit_value(field_value, child_iter)
+                else:
+                    self.store.append(store_iter, (f.name, str(field_value)))
+        else:
+            self.store.append(None, ("<value>", str(value)))
+
+
+    def set_value(self, value):
+        self.store.clear()
+        self.visit_value(value, None)
+        # fill the TreeStore with value fields
+        self.queue_draw()
+
 
 class ViewerWindow(gtk.Window):
     def __init__(self):
         super(gtk.Window, self).__init__()
         self.entry = gtk.Entry()
-        self.viewer = GraphViewer()
-        self.properties = gtk.TreeView()
+        self.properties = GdbValueViewer()
+        self.viewer = GraphViewer(self.properties)
         self.vbox = gtk.VBox()
         self.paned = gtk.HPaned()
         labelhbox = gtk.HBox()
@@ -192,7 +260,7 @@ def visit_values(value, x, y, recursion_level):
         pointee_width, pointee_height, pointee_nodes = visit_values(pointee, children_x, children_y, recursion_level - 1)
         merge_dict(result, pointee_nodes)
         return NODE_SPACING+pointee_width, max(NODE_SPACING, pointee_height), result
-    elif len(value.type.fields()) > 0: 
+    elif type_has_fields(value.type):
         for f in value.type.fields():
             child = value[f.name]
             if child.type.code == gdb.TYPE_CODE_PTR:
@@ -258,7 +326,6 @@ class ViewerCommand(gdb.Command):
             window.viewer.queue_draw()
             gtk.main()
         except:
-            print "trololo"
             window.destroy()
             raise