Refactor ToolBase to allow tool composition. Add TableSync tool (composited). Move more tools under pgtool.
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)