pgconsole/dataview.py
changeset 10 f3a1b9792cc9
child 76 3a41b351b122
equal deleted inserted replaced
9:2fcc8ef0b97d 10:f3a1b9792cc9
       
     1 import gtk, gobject, pango
       
     2 from cgi import escape
       
     3 
       
     4 
       
     5 class DataView(gtk.ScrolledWindow):
       
     6     def __init__(self):
       
     7         super(DataView, self).__init__()
       
     8 
       
     9         sw = self
       
    10         sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
       
    11         sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
       
    12         self.treeview = gtk.TreeView(gtk.ListStore(str))
       
    13         self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
       
    14         self.treeview.set_property("rubber-banding", True)
       
    15         sw.add(self.treeview)
       
    16 
       
    17 
       
    18     def load_data(self, names, rows):
       
    19         x = [str] * (len(names) + 1)
       
    20         liststore = gtk.ListStore(*x)
       
    21 
       
    22         for c in self.treeview.get_columns():
       
    23             self.treeview.remove_column(c)
       
    24 
       
    25         tvcolumn = gtk.TreeViewColumn()
       
    26         cell = DataViewCellRenderer()
       
    27         cell.set_property('head', True)
       
    28         tvcolumn.pack_start(cell, True)
       
    29         tvcolumn.set_property('resizable', True)
       
    30         #tvcolumn.set_property('sizing', gtk.TREE_VIEW_COLUMN_FIXED)
       
    31         tvcolumn.set_attributes(cell, text=0)
       
    32         tvcolumn.set_min_width(2)
       
    33         self.treeview.append_column(tvcolumn)
       
    34 
       
    35         i = 0
       
    36         for c in names:
       
    37             i += 1
       
    38             typename = c[1]
       
    39             title = '<b>%s</b>' % escape(c[0])
       
    40             if typename:
       
    41                 title += '\n<span size="small">%s</span>' % typename
       
    42 
       
    43             tvcolumn = gtk.TreeViewColumn()
       
    44             cell = DataViewCellRenderer()
       
    45 
       
    46             lab = gtk.Label()
       
    47             lab.set_use_underline(False)
       
    48             lab.set_markup(title)
       
    49             lab.show()
       
    50             tvcolumn.set_widget(lab)
       
    51             tvcolumn.set_property('resizable', True)
       
    52             tvcolumn.pack_start(cell, True)
       
    53             tvcolumn.set_attributes(cell, text=i)
       
    54 
       
    55             self.treeview.append_column(tvcolumn)
       
    56 
       
    57         self.treeview.set_model(liststore)
       
    58 
       
    59         i = 0
       
    60         for row in rows:
       
    61             i += 1
       
    62             liststore.append([i]+list(row))
       
    63 
       
    64 
       
    65 
       
    66 class DataViewCellRenderer(gtk.GenericCellRenderer):
       
    67     __gtype_name__ = 'DataViewCellRenderer'
       
    68     __gproperties__ = {
       
    69         'text': (gobject.TYPE_STRING, None, None, '', gobject.PARAM_READWRITE),
       
    70         'head': (gobject.TYPE_BOOLEAN, None, None, False, gobject.PARAM_READWRITE)}
       
    71 
       
    72 
       
    73     def __init__(self):
       
    74         gtk.GenericCellRenderer.__init__(self)
       
    75         self._props = {'text' : '', 'head' : False}
       
    76 
       
    77 
       
    78     def do_set_property(self, pspec, value):
       
    79         if not pspec.name in self._props:
       
    80             raise AttributeError, 'Unknown property: %s' % pspec.name
       
    81         self._props[pspec.name] = value
       
    82 
       
    83 
       
    84     def do_get_property(self, pspec):
       
    85         return self._props[pspec.name]
       
    86 
       
    87 
       
    88     def on_get_size(self, widget, cell_area):
       
    89         if cell_area == None:
       
    90             pangoctx = widget.get_pango_context()
       
    91             layout = pango.Layout(pangoctx)
       
    92             layout.set_width(-1)
       
    93             layout.set_text(self.get_property('text') or 'NULL')
       
    94             w,h = layout.get_pixel_size()
       
    95             return (0, 0, w+5, 20)
       
    96         x = cell_area.x
       
    97         y = cell_area.x
       
    98         w = cell_area.width
       
    99         h = cell_area.height
       
   100 
       
   101         return (x,y,w,h)
       
   102 
       
   103 
       
   104     def on_render(self, window, widget, background_area, cell_area, expose_area, flags):
       
   105         x = background_area.x
       
   106         y = background_area.y
       
   107         w = background_area.width
       
   108         h = background_area.height
       
   109 
       
   110         ctx = window.cairo_create()
       
   111         ctx.set_line_width(0.4)
       
   112         ctx.set_source_rgb(0, 0, 0)
       
   113         ctx.move_to(x+w-1.5, y-0.5)
       
   114         ctx.line_to(x+w-1.5, y+h-0.5)
       
   115         ctx.line_to(x-0.5, y+h-0.5)
       
   116         ctx.stroke()
       
   117         ctx.set_source_rgb(1, 1, 1)
       
   118         ctx.move_to(x+w-0.5, y-0.5)
       
   119         ctx.line_to(x+w-0.5, y+h-0.5)
       
   120         ctx.stroke()
       
   121 
       
   122         pangoctx = widget.get_pango_context()
       
   123         layout = pango.Layout(pangoctx)
       
   124         text = self.get_property('text')
       
   125         head = self.get_property('head')
       
   126 
       
   127         if head:
       
   128             layout.set_markup('<b>%s</b>' % text)
       
   129         else:
       
   130             if text is None:
       
   131                 layout.set_markup('<span foreground="gray">NULL</span>')
       
   132             else:
       
   133                 layout.set_text(text)
       
   134 
       
   135         widget.style.paint_layout(window, gtk.STATE_NORMAL, True,
       
   136                                 cell_area, widget, '',
       
   137                                 cell_area.x, cell_area.y,
       
   138                                 layout)
       
   139