pgconsole/dataview.py
changeset 10 f3a1b9792cc9
child 76 3a41b351b122
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pgconsole/dataview.py	Tue Aug 16 23:53:54 2011 +0200
@@ -0,0 +1,139 @@
+import gtk, gobject, pango
+from cgi import escape
+
+
+class DataView(gtk.ScrolledWindow):
+    def __init__(self):
+        super(DataView, self).__init__()
+
+        sw = self
+        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        self.treeview = gtk.TreeView(gtk.ListStore(str))
+        self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+        self.treeview.set_property("rubber-banding", True)
+        sw.add(self.treeview)
+
+
+    def load_data(self, names, rows):
+        x = [str] * (len(names) + 1)
+        liststore = gtk.ListStore(*x)
+
+        for c in self.treeview.get_columns():
+            self.treeview.remove_column(c)
+
+        tvcolumn = gtk.TreeViewColumn()
+        cell = DataViewCellRenderer()
+        cell.set_property('head', True)
+        tvcolumn.pack_start(cell, True)
+        tvcolumn.set_property('resizable', True)
+        #tvcolumn.set_property('sizing', gtk.TREE_VIEW_COLUMN_FIXED)
+        tvcolumn.set_attributes(cell, text=0)
+        tvcolumn.set_min_width(2)
+        self.treeview.append_column(tvcolumn)
+
+        i = 0
+        for c in names:
+            i += 1
+            typename = c[1]
+            title = '<b>%s</b>' % escape(c[0])
+            if typename:
+                title += '\n<span size="small">%s</span>' % typename
+
+            tvcolumn = gtk.TreeViewColumn()
+            cell = DataViewCellRenderer()
+
+            lab = gtk.Label()
+            lab.set_use_underline(False)
+            lab.set_markup(title)
+            lab.show()
+            tvcolumn.set_widget(lab)
+            tvcolumn.set_property('resizable', True)
+            tvcolumn.pack_start(cell, True)
+            tvcolumn.set_attributes(cell, text=i)
+
+            self.treeview.append_column(tvcolumn)
+
+        self.treeview.set_model(liststore)
+
+        i = 0
+        for row in rows:
+            i += 1
+            liststore.append([i]+list(row))
+
+
+
+class DataViewCellRenderer(gtk.GenericCellRenderer):
+    __gtype_name__ = 'DataViewCellRenderer'
+    __gproperties__ = {
+        'text': (gobject.TYPE_STRING, None, None, '', gobject.PARAM_READWRITE),
+        'head': (gobject.TYPE_BOOLEAN, None, None, False, gobject.PARAM_READWRITE)}
+
+
+    def __init__(self):
+        gtk.GenericCellRenderer.__init__(self)
+        self._props = {'text' : '', 'head' : False}
+
+
+    def do_set_property(self, pspec, value):
+        if not pspec.name in self._props:
+            raise AttributeError, 'Unknown property: %s' % pspec.name
+        self._props[pspec.name] = value
+
+
+    def do_get_property(self, pspec):
+        return self._props[pspec.name]
+
+
+    def on_get_size(self, widget, cell_area):
+        if cell_area == None:
+            pangoctx = widget.get_pango_context()
+            layout = pango.Layout(pangoctx)
+            layout.set_width(-1)
+            layout.set_text(self.get_property('text') or 'NULL')
+            w,h = layout.get_pixel_size()
+            return (0, 0, w+5, 20)
+        x = cell_area.x
+        y = cell_area.x
+        w = cell_area.width
+        h = cell_area.height
+
+        return (x,y,w,h)
+
+
+    def on_render(self, window, widget, background_area, cell_area, expose_area, flags):
+        x = background_area.x
+        y = background_area.y
+        w = background_area.width
+        h = background_area.height
+
+        ctx = window.cairo_create()
+        ctx.set_line_width(0.4)
+        ctx.set_source_rgb(0, 0, 0)
+        ctx.move_to(x+w-1.5, y-0.5)
+        ctx.line_to(x+w-1.5, y+h-0.5)
+        ctx.line_to(x-0.5, y+h-0.5)
+        ctx.stroke()
+        ctx.set_source_rgb(1, 1, 1)
+        ctx.move_to(x+w-0.5, y-0.5)
+        ctx.line_to(x+w-0.5, y+h-0.5)
+        ctx.stroke()
+
+        pangoctx = widget.get_pango_context()
+        layout = pango.Layout(pangoctx)
+        text = self.get_property('text')
+        head = self.get_property('head')
+
+        if head:
+            layout.set_markup('<b>%s</b>' % text)
+        else:
+            if text is None:
+                layout.set_markup('<span foreground="gray">NULL</span>')
+            else:
+                layout.set_text(text)
+
+        widget.style.paint_layout(window, gtk.STATE_NORMAL, True,
+                                cell_area, widget, '',
+                                cell_area.x, cell_area.y,
+                                layout)
+