pgconsole/dataview.py
author Radek Brich <radek.brich@devl.cz>
Sat, 13 Apr 2013 15:22:05 +0200
changeset 83 515fadd3d286
parent 76 3a41b351b122
permissions -rw-r--r--
Add dependency on pycolib. Move common modules to pycolib. Add example table schema for meta DB.

from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Pango

from cgi import escape


class DataView(Gtk.ScrolledWindow):
    def __init__(self):
        super(DataView, self).__init__()

        sw = self
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
        self.treeview = Gtk.TreeView(Gtk.ListStore(str))
        self.treeview.get_selection().set_mode(Gtk.SelectionMode.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.CellRenderer):
    __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.CellRenderer.__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)