pgconsole/dataview.py
author Radek Brich <radek.brich@devl.cz>
Sun, 10 Mar 2013 16:14:53 +0100
changeset 76 3a41b351b122
parent 10 f3a1b9792cc9
permissions -rw-r--r--
Port pgconsole to Python3 + GTK3.

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)