Port pgconsole to Python3 + GTK3.
authorRadek Brich <radek.brich@devl.cz>
Sun, 10 Mar 2013 16:14:53 +0100
changeset 76 3a41b351b122
parent 75 39f777341db4
child 77 2cfef775f518
Port pgconsole to Python3 + GTK3.
README
pgconsole/app.py
pgconsole/database.py
pgconsole/dataview.py
pgconsole/editor.py
pgconsole/panedext.py
pgconsole/settings.py
--- a/README	Thu Mar 07 18:26:52 2013 +0100
+++ b/README	Sun Mar 10 16:14:53 2013 +0100
@@ -2,6 +2,22 @@
 pgtoolkit
 =========
 
+Requirements
+------------
+
+ * Python 3.2+
+ * Psycopg2
+
+Optional:
+ * MyManager:
+   * MySQLdb 1.2.3
+   * see extras for Python3 patch
+ * pgconsole:
+   * GTK3 + Python bindings + Cairo + GtkSource
+   * packages in Debian: python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-gtksource-3.0
+ * browser:
+   * tuikit (http://hg.devl.cz/tuikit)
+
 General Python Modules
 ----------------------
 
--- a/pgconsole/app.py	Thu Mar 07 18:26:52 2013 +0100
+++ b/pgconsole/app.py	Sun Mar 10 16:14:53 2013 +0100
@@ -1,11 +1,15 @@
-import time
-import gobject, gtk, pango, cairo
-import gtksourceview2 as gtksourceview
+from gi.repository import GObject
+from gi.repository import Gtk, Gdk
+from gi.repository import GdkPixbuf
+from gi.repository import cairo, Pango
+from gi.repository import GtkSource
 
 import psycopg2
 import psycopg2.extensions
 import psycopg2.extras
 
+import time
+
 from pgconsole.config import cfg
 from pgconsole.editor import Editor
 from pgconsole.dataview import DataView
@@ -19,7 +23,7 @@
         self.db = Database()
         self.conn = None
 
-        win = gtk.Window(gtk.WINDOW_TOPLEVEL)
+        win = Gtk.Window()
         self.win = win
         win.set_title('PostgreSQL Console')
         win.set_size_request(300, 200)  # minimal size
@@ -30,18 +34,18 @@
         win.connect('configure-event', self.on_configure)
 
         # toolbar
-        toolbar = gtk.Toolbar()
-        toolbar.set_style(gtk.TOOLBAR_ICONS)
-        toolbar.set_property("icon-size", gtk.ICON_SIZE_SMALL_TOOLBAR)
+        toolbar = Gtk.Toolbar()
+        toolbar.set_style(Gtk.ToolbarStyle.ICONS)
+        toolbar.set_property("icon-size", Gtk.IconSize.SMALL_TOOLBAR)
 
-        tb = gtk.ToolButton(gtk.STOCK_PREFERENCES)
+        tb = Gtk.ToolButton(Gtk.STOCK_PREFERENCES)
         tb.set_label('Settings')
         tb.set_tooltip_text('Settings')
         tb.connect('clicked', self.settings)
         self.tb_settings = tb
         toolbar.add(tb)
 
-        self.cb_server = gtk.combo_box_entry_new_text()
+        self.cb_server = Gtk.ComboBoxText.new_with_entry()
         self.cb_server.set_tooltip_text('Server')
         self.cb_server.get_child().set_property("editable", False)
         self.cb_server.set_property("add_tearoffs", True)
@@ -49,52 +53,52 @@
         self.cb_server.set_property("can-focus", True)
         self.cb_server.connect('changed', self.on_server_changed)
         self.cb_server.connect("key_press_event", self.toolbar_server_keypress)
-        ti = gtk.ToolItem()
+        ti = Gtk.ToolItem()
         ti.add(self.cb_server)
         toolbar.add(ti)
 
-        self.cb_dbname = gtk.combo_box_entry_new_text()
+        self.cb_dbname = Gtk.ComboBoxText.new_with_entry()
         self.cb_dbname.set_tooltip_text('Database')
         self.cb_dbname.get_child().set_property("editable", False)
         self.cb_dbname.set_property("add_tearoffs", True)
         #self.cb_dbname.set_property("focus-on-click", False)
         self.cb_dbname.set_property("can-focus", True)
-        ti = gtk.ToolItem()
+        ti = Gtk.ToolItem()
         ti.add(self.cb_dbname)
         toolbar.add(ti)
 
-        tb = gtk.ToolButton(gtk.STOCK_CONNECT)
+        tb = Gtk.ToolButton(Gtk.STOCK_CONNECT)
         tb.set_label('Connect')
         tb.set_tooltip_text('Connect')
         tb.connect('clicked', self.connect)
         toolbar.add(tb)
         self.tb_connect = tb
 
-        sep = gtk.SeparatorToolItem()
+        sep = Gtk.SeparatorToolItem()
         toolbar.add(sep)
 
-        tb = gtk.ToolButton(gtk.STOCK_EXECUTE)
+        tb = Gtk.ToolButton(Gtk.STOCK_EXECUTE)
         tb.set_label('Execute')
         tb.set_tooltip_text('Execute')
         tb.connect('clicked', self.execute)
         toolbar.add(tb)
         tb.set_sensitive(False)
         self.tb_execute = tb
-        tb = gtk.ToolButton(gtk.STOCK_NEW)
+        tb = Gtk.ToolButton(Gtk.STOCK_NEW)
         tb.set_label('Begin transaction')
         tb.set_tooltip_text('Begin transaction')
         tb.connect('clicked', self.begin)
         tb.set_sensitive(False)
         toolbar.add(tb)
         self.tb_begin = tb
-        tb = gtk.ToolButton(gtk.STOCK_APPLY)
+        tb = Gtk.ToolButton(Gtk.STOCK_APPLY)
         tb.set_label('Commit')
         tb.set_tooltip_text('Commit')
         tb.connect('clicked', self.commit)
         tb.set_sensitive(False)
         self.tb_commit = tb
         toolbar.add(tb)
-        tb = gtk.ToolButton(gtk.STOCK_CANCEL)
+        tb = Gtk.ToolButton(Gtk.STOCK_CANCEL)
         tb.set_label('Rollback')
         tb.set_tooltip_text('Rollback')
         tb.connect('clicked', self.rollback)
@@ -102,7 +106,7 @@
         self.tb_rollback = tb
         toolbar.add(tb)
 
-        sep = gtk.SeparatorToolItem()
+        sep = Gtk.SeparatorToolItem()
         toolbar.add(sep)
 
         # editor
@@ -112,19 +116,19 @@
         self.dataview = DataView()
 
 
-        vbox = gtk.VBox(False, 2)
+        vbox = Gtk.VBox(False, 2)
 
-        sep = gtk.SeparatorToolItem()
+        sep = Gtk.SeparatorToolItem()
         sep.set_expand(True)
         sep.set_draw(False)
         toolbar.add(sep)
 
-        self.throbber_anim = gtk.gdk.PixbufAnimation('data/Throbber.gif')
-        self.throbber = gtk.Image()
-        tb = gtk.ToolItem()
+        self.throbber_anim = GdkPixbuf.PixbufAnimation.new_from_file('data/Throbber.gif')
+        self.throbber = Gtk.Image()
+        tb = Gtk.ToolItem()
         tb.add(self.throbber)
         toolbar.add(tb)
-        sep = gtk.SeparatorToolItem()
+        sep = Gtk.SeparatorToolItem()
         sep.set_draw(False)
         toolbar.add(sep)
 
@@ -151,20 +155,20 @@
         self.hpaned = hpaned
 
         # log
-        self.logbuf = gtk.TextBuffer()
-        view = gtk.TextView(self.logbuf)
+        self.logbuf = Gtk.TextBuffer()
+        view = Gtk.TextView.new_with_buffer(self.logbuf)
         view.set_editable(False)
-        font_desc = pango.FontDescription('monospace')
+        font_desc = Pango.FontDescription('monospace')
         if font_desc:
             view.modify_font(font_desc)
 
-        sw = gtk.ScrolledWindow()
-        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        sw = Gtk.ScrolledWindow()
+        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+        sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
         sw.add(view)
         hpaned.add2(sw)
 
-        vbox.pack_start(vpaned, padding=0)
+        vbox.pack_start(vpaned, expand=True, fill=True, padding=0)
 
         win.add(vbox)
 
@@ -178,13 +182,13 @@
 
 
     def main(self):
-        gtk.main()
+        Gtk.main()
 
 
     def destroy(self, widget, data=None):
         self.save_win_state()
         cfg.save()
-        gtk.main_quit()
+        Gtk.main_quit()
 
 
     def on_configure(self, w, ev):
@@ -251,7 +255,7 @@
             self.conn = None
             self.cb_server.set_sensitive(True)
             self.cb_dbname.set_sensitive(True)
-            self.tb_connect.set_stock_id(gtk.STOCK_CONNECT)
+            self.tb_connect.set_stock_id(Gtk.STOCK_CONNECT)
             self.tb_connect.set_label('Connect')
             self.tb_connect.set_tooltip_text('Connect')
             self.tb_execute.set_sensitive(False)
@@ -266,7 +270,7 @@
                 return
             self.cb_server.set_sensitive(False)
             self.cb_dbname.set_sensitive(False)
-            self.tb_connect.set_stock_id(gtk.STOCK_DISCONNECT)
+            self.tb_connect.set_stock_id(Gtk.STOCK_DISCONNECT)
             self.tb_connect.set_label('Disconnect')
             self.tb_connect.set_tooltip_text('Disconnect')
             self.tb_execute.set_sensitive(True)
@@ -341,9 +345,9 @@
         if state == psycopg2.extensions.POLL_OK:
             self.execute_finish()
         elif state == psycopg2.extensions.POLL_WRITE:
-            gobject.io_add_watch(self.conn.fileno(), gobject.IO_OUT, self.execute_poll)
+            GObject.io_add_watch(self.conn.fileno(), GObject.IO_OUT, self.execute_poll)
         elif state == psycopg2.extensions.POLL_READ:
-            gobject.io_add_watch(self.conn.fileno(), gobject.IO_IN, self.execute_poll)
+            GObject.io_add_watch(self.conn.fileno(), GObject.IO_IN, self.execute_poll)
         else:
             self.logbuf.insert(self.logbuf.get_end_iter(), "poll() returned %s" % state)
             return
@@ -388,7 +392,7 @@
 
 
     def keypress(self, w, event):
-        keyname = gtk.gdk.keyval_name(event.keyval)
+        keyname = Gdk.keyval_name(event.keyval)
         if keyname == 'F1':
             self.simulate_click(self.tb_settings)
             return True
@@ -418,7 +422,7 @@
 
 
     def toolbar_server_keypress(self, w, event):
-        keyname = gtk.gdk.keyval_name(event.keyval)
+        keyname = Gdk.keyval_name(event.keyval)
         if keyname == 'Tab':
             self.populate_db_list()
             self.cb_dbname.grab_focus()
@@ -446,7 +450,7 @@
         self.db.put_conn(conninfo, conn)
 
         for i in range(self.cb_dbname.get_model().iter_n_children(None)):
-            self.cb_dbname.remove_text(0)
+            self.cb_dbname.remove(0)
 
         for row in rows:
             self.cb_dbname.append_text(row[0])
@@ -457,7 +461,7 @@
     def reload_server_list(self, sel=None):
         # clean
         for i in range(self.cb_server.get_model().iter_n_children(None)):
-            self.cb_server.remove_text(0)
+            self.cb_server.remove(0)
         self.cb_server.get_child().set_text('')
 
         try:
--- a/pgconsole/database.py	Thu Mar 07 18:26:52 2013 +0100
+++ b/pgconsole/database.py	Sun Mar 10 16:14:53 2013 +0100
@@ -37,7 +37,7 @@
         try:
             conn = psycopg2.connect(conninfo, async=1)
             psycopg2.extras.wait_select(conn)
-        except psycopg2.DatabaseError, e:
+        except psycopg2.DatabaseError as e:
             raise DatabaseError(str(e))
         return conn
 
@@ -71,12 +71,12 @@
             curs.execute(q, args)
             psycopg2.extras.wait_select(curs.connection)
 #            conn.commit()
-        except psycopg2.OperationalError, e:
+        except psycopg2.OperationalError as e:
             # disconnected?
 #            conn.rollback()
             conn.close()
             raise BadConnectionError(str(e))
-        except psycopg2.DatabaseError, e:
+        except psycopg2.DatabaseError as e:
 #            conn.rollback()
             raise DatabaseError(str(e), curs.query)
         return curs
--- a/pgconsole/dataview.py	Thu Mar 07 18:26:52 2013 +0100
+++ b/pgconsole/dataview.py	Sun Mar 10 16:14:53 2013 +0100
@@ -1,33 +1,36 @@
-import gtk, gobject, pango
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import Pango
+
 from cgi import escape
 
 
-class DataView(gtk.ScrolledWindow):
+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)
+        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)
+        liststore = Gtk.ListStore(*x)
 
         for c in self.treeview.get_columns():
             self.treeview.remove_column(c)
 
-        tvcolumn = gtk.TreeViewColumn()
+        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_property('sizing', Gtk.TREE_VIEW_COLUMN_FIXED)
         tvcolumn.set_attributes(cell, text=0)
         tvcolumn.set_min_width(2)
         self.treeview.append_column(tvcolumn)
@@ -40,10 +43,10 @@
             if typename:
                 title += '\n<span size="small">%s</span>' % typename
 
-            tvcolumn = gtk.TreeViewColumn()
+            tvcolumn = Gtk.TreeViewColumn()
             cell = DataViewCellRenderer()
 
-            lab = gtk.Label()
+            lab = Gtk.Label()
             lab.set_use_underline(False)
             lab.set_markup(title)
             lab.show()
@@ -63,21 +66,21 @@
 
 
 
-class DataViewCellRenderer(gtk.GenericCellRenderer):
+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)}
+        '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)
+        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
+            raise AttributeError('Unknown property: %s' % pspec.name)
         self._props[pspec.name] = value
 
 
@@ -88,7 +91,7 @@
     def on_get_size(self, widget, cell_area):
         if cell_area == None:
             pangoctx = widget.get_pango_context()
-            layout = pango.Layout(pangoctx)
+            layout = Pango.Layout(pangoctx)
             layout.set_width(-1)
             layout.set_text(self.get_property('text') or 'NULL')
             w,h = layout.get_pixel_size()
@@ -120,7 +123,7 @@
         ctx.stroke()
 
         pangoctx = widget.get_pango_context()
-        layout = pango.Layout(pangoctx)
+        layout = Pango.Layout(pangoctx)
         text = self.get_property('text')
         head = self.get_property('head')
 
@@ -132,7 +135,7 @@
             else:
                 layout.set_text(text)
 
-        widget.style.paint_layout(window, gtk.STATE_NORMAL, True,
+        widget.style.paint_layout(window, Gtk.STATE_NORMAL, True,
                                 cell_area, widget, '',
                                 cell_area.x, cell_area.y,
                                 layout)
--- a/pgconsole/editor.py	Thu Mar 07 18:26:52 2013 +0100
+++ b/pgconsole/editor.py	Sun Mar 10 16:14:53 2013 +0100
@@ -1,88 +1,90 @@
-import gtk, pango
-import gtksourceview2 as gtksourceview
+from gi.repository import Gtk
+from gi.repository import Pango
+from gi.repository import GtkSource
+
 from lxml import etree
 
-from panedext import HPanedExt
-from config import cfg
+from pgconsole.panedext import HPanedExt
+from pgconsole.config import cfg
 
 
 class Editor(HPanedExt):
     def __init__(self):
         super(Editor, self).__init__()
 
-        self.view = gtksourceview.View()
+        self.view = GtkSource.View()
         self.view.connect('toggle-overwrite', self.on_toggle_overwrite)
 
-        vbox = gtk.VBox()
+        vbox = Gtk.VBox()
         self.vbox1 = vbox
         self.add1(vbox)
 
-        sw = gtk.ScrolledWindow()
-        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        sw.set_shadow_type(gtk.SHADOW_IN)
-        vbox.pack_start(sw)
-        tree = gtk.TreeView()
+        sw = Gtk.ScrolledWindow()
+        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
+        sw.set_shadow_type(Gtk.ShadowType.IN)
+        vbox.pack_start(sw, expand=True, fill=True, padding=0)
+        tree = Gtk.TreeView()
         tree.set_headers_visible(False)
-        tree.get_selection().set_mode(gtk.SELECTION_BROWSE)
+        tree.get_selection().set_mode(Gtk.SelectionMode.BROWSE)
         sw.add(tree)
 
-        model = gtk.ListStore(str, str, object, bool)  # title, filename, buffer, modified
+        model = Gtk.ListStore(str, str, object, bool)  # title, filename, buffer, modified
         tree.set_model(model)
-        cell = gtk.CellRendererPixbuf()
-        cell.set_property('stock-id', gtk.STOCK_SAVE)
-        column = gtk.TreeViewColumn("File", cell, visible=3)
+        cell = Gtk.CellRendererPixbuf()
+        cell.set_property('stock-id', Gtk.STOCK_SAVE)
+        column = Gtk.TreeViewColumn("File", cell, visible=3)
         tree.append_column(column)
-        column = gtk.TreeViewColumn("File", gtk.CellRendererText(), text=0)
+        column = Gtk.TreeViewColumn("File", Gtk.CellRendererText(), text=0)
         tree.append_column(column)
         tree.get_selection().connect('changed', self.item_change)
         tree.set_property('can-focus', False)
         self.filelist = tree
 
 
-        hbox = gtk.HBox()
+        hbox = Gtk.HBox()
 
-        img = gtk.Image()
-        img.set_from_stock(gtk.STOCK_NEW, gtk.ICON_SIZE_SMALL_TOOLBAR)
-        btn = gtk.Button()
-        btn.set_relief(gtk.RELIEF_NONE)
+        img = Gtk.Image()
+        img.set_from_stock(Gtk.STOCK_NEW, Gtk.IconSize.SMALL_TOOLBAR)
+        btn = Gtk.Button()
+        btn.set_relief(Gtk.ReliefStyle.NONE)
         btn.set_focus_on_click(False)
         btn.set_image(img)
         btn.connect('clicked', self.item_new)
-        hbox.pack_start(btn, expand=False)
+        hbox.pack_start(btn, expand=False, fill=True, padding=0)
 
-        img = gtk.Image()
-        img.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_SMALL_TOOLBAR)
-        btn = gtk.Button()
-        btn.set_relief(gtk.RELIEF_NONE)
+        img = Gtk.Image()
+        img.set_from_stock(Gtk.STOCK_OPEN, Gtk.IconSize.SMALL_TOOLBAR)
+        btn = Gtk.Button()
+        btn.set_relief(Gtk.ReliefStyle.NONE)
         btn.set_focus_on_click(False)
         btn.set_image(img)
         btn.connect('clicked', self.item_open)
-        hbox.pack_start(btn, expand=False)
+        hbox.pack_start(btn, expand=False, fill=True, padding=0)
 
-        img = gtk.Image()
-        img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
-        btn = gtk.Button()
-        btn.set_relief(gtk.RELIEF_NONE)
+        img = Gtk.Image()
+        img.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.SMALL_TOOLBAR)
+        btn = Gtk.Button()
+        btn.set_relief(Gtk.ReliefStyle.NONE)
         btn.set_focus_on_click(False)
         btn.set_image(img)
         btn.connect('clicked', self.item_close)
-        hbox.pack_start(btn, expand=False)
-        hbox.connect('size-request', self.leftbuttons_size_request)
+        hbox.pack_start(btn, expand=False, fill=True, padding=0)
+        hbox.connect('size-allocate', self.leftbuttons_size_request)
 
-        vbox.pack_start(hbox, expand=False)
+        vbox.pack_start(hbox, expand=False, fill=True, padding=0)
 
-        vbox = gtk.VBox()
+        vbox = Gtk.VBox()
         vbox.set_property("width-request", 200)
         self.add2(vbox)
         self.child_set_property(vbox, 'shrink', False)
 
 
         # scroll
-        sw = gtk.ScrolledWindow()
-        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        sw = Gtk.ScrolledWindow()
+        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+        sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
         sw.add(self.view)
-        vbox.pack_start(sw)
+        vbox.pack_start(sw, expand=True, fill=True, padding=0)
 
 
         self.view.set_show_line_numbers(True)
@@ -92,76 +94,76 @@
         self.view.set_auto_indent(True)
 
         # font
-        font_desc = pango.FontDescription('monospace')
+        font_desc = Pango.FontDescription('monospace')
         if font_desc:
             self.view.modify_font(font_desc)
 
         # status bar
-        hbox = gtk.HBox()
+        hbox = Gtk.HBox()
 
         self.st_file, fr1 = self.construct_status('SQL snippet')
-        self.st_file.set_ellipsize(pango.ELLIPSIZE_START)
+        self.st_file.set_ellipsize(Pango.EllipsizeMode.START)
         self.st_insovr, fr2 = self.construct_status('INS')
         self.st_linecol, fr3 = self.construct_status('Line: 0 Col: 0')
 
 
-        img = gtk.Image()
-        img.set_from_stock(gtk.STOCK_SAVE, gtk.ICON_SIZE_SMALL_TOOLBAR)
+        img = Gtk.Image()
+        img.set_from_stock(Gtk.STOCK_SAVE, Gtk.IconSize.SMALL_TOOLBAR)
         #save = img
-        save = gtk.Button()
-        save.set_relief(gtk.RELIEF_NONE)
+        save = Gtk.Button()
+        save.set_relief(Gtk.ReliefStyle.NONE)
         save.set_focus_on_click(False)
         save.set_image(img)
         save.connect('clicked', self.item_save)
-        hbox.pack_start(save, expand=False)
+        hbox.pack_start(save, expand=False, fill=True, padding=0)
 
-        hbox.pack_start(fr1, expand=True)
-        hbox.pack_start(fr2, expand=False)
-        hbox.pack_start(fr3, expand=False)
+        hbox.pack_start(fr1, expand=True, fill=True, padding=0)
+        hbox.pack_start(fr2, expand=False, fill=True, padding=0)
+        hbox.pack_start(fr3, expand=False, fill=True, padding=0)
 
-        #sep = gtk.HSeparator()
+        #sep = Gtk.HSeparator()
         #vbox.pack_start(sep, expand=False, fill=False, padding=0)
 
-        #align = gtk.Alignment()
+        #align = Gtk.Alignment()
         #align.set_property("bottom-padding", 3)
         #align.set_property("xscale", 1.0)
         #align.add(hbox)
 
-        #frame = gtk.Frame()
+        #frame = Gtk.Frame()
         #frame.add(hbox)
-        #frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
-        vbox.pack_start(hbox, expand=False, padding=0)
+        #frame.set_shadow_type(Gtk.SHADOW_ETCHED_IN)
+        vbox.pack_start(hbox, expand=False, fill=True, padding=0)
 
         self.load_nodes()
         self.build_context_menu()
 
 
     def build_context_menu(self):
-        menu = gtk.Menu()
-        item = gtk.ImageMenuItem(gtk.STOCK_SAVE, "Save")
+        menu = Gtk.Menu()
+        item = Gtk.ImageMenuItem(use_stock=True, label=Gtk.STOCK_SAVE)
         item.connect("activate", self.item_save)
         item.show()
         menu.append(item)
 
-        item = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS, "Save as")
+        item = Gtk.ImageMenuItem(use_stock=True, label=Gtk.STOCK_SAVE_AS)
         item.connect("activate", self.item_save_as)
         item.show()
         menu.append(item)
 
-        item = gtk.ImageMenuItem(gtk.STOCK_CLOSE, "Close")
+        item = Gtk.ImageMenuItem(use_stock=True, label=Gtk.STOCK_CLOSE)
         item.connect("activate", self.item_close)
         item.show()
         menu.append(item)
 
-        item = gtk.SeparatorMenuItem()
+        item = Gtk.SeparatorMenuItem()
         item.show()
         menu.append(item)
 
-        item = gtk.ImageMenuItem(gtk.STOCK_GO_UP, "Move up")
+        item = Gtk.ImageMenuItem(use_stock=True, label=Gtk.STOCK_GO_UP)
         item.show()
         menu.append(item)
 
-        item = gtk.ImageMenuItem(gtk.STOCK_GO_DOWN, "Move down")
+        item = Gtk.ImageMenuItem(use_stock=True, label=Gtk.STOCK_GO_DOWN)
         item.show()
         menu.append(item)
 
@@ -179,24 +181,24 @@
                 path, col, cellx, celly = pathinfo
                 self.filelist.grab_focus()
                 self.filelist.set_cursor(path, col, 0)
-                self.filelist_menu.popup(None, None, None, event.button, event.time)
+                self.filelist_menu.popup(None, None, None, None, event.button, event.time)
             return True
 
 
 
     def make_buffer(self):
-        buffer = gtksourceview.Buffer()
+        buffer = GtkSource.Buffer()
         buffer.connect('mark-set', self.buffer_mark_set)
         buffer.connect('changed', self.buffer_changed)
 
         # style
-        mgr = gtksourceview.style_scheme_manager_get_default()
+        mgr = GtkSource.StyleSchemeManager.get_default()
         style_scheme = mgr.get_scheme('kate')
         if style_scheme:
             buffer.set_style_scheme(style_scheme)
 
         # syntax
-        lngman = gtksourceview.language_manager_get_default()
+        lngman = GtkSource.LanguageManager.get_default()
         langsql = lngman.get_language('sql')
         buffer.set_language(langsql)
         buffer.set_highlight_syntax(True)
@@ -216,7 +218,10 @@
                 buffer.set_text(node.text)
             if type == 'file':
                 filename = node.text
-                content = open(filename).read()
+                try:
+                    content = open(filename).read()
+                except IOError:
+                    content = ''
                 buffer.set_text(content)
             iter = model.append([name, filename, buffer, False])
             if sel == name:
@@ -240,12 +245,12 @@
 
 
     def construct_status(self, text):
-        st = gtk.Label(text)
+        st = Gtk.Label(text)
         st.set_property("single-line-mode", True)
         st.set_property("xpad", 3)
         st.set_alignment(0.0, 0.5)
-        fr = gtk.Frame()
-        fr.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
+        fr = Gtk.Frame()
+        fr.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
         fr.add(st)
         return st, fr
 
@@ -319,23 +324,23 @@
 
 
     def item_open(self, w):
-        dialog = gtk.FileChooserDialog(title='Open file', action=gtk.FILE_CHOOSER_ACTION_OPEN,
-            buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
-        dialog.set_default_response(gtk.RESPONSE_OK)
+        dialog = Gtk.FileChooserDialog(title='Open file', action=Gtk.FileChooserAction.OPEN,
+            buttons=(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
+        dialog.set_default_response(Gtk.ResponseType.OK)
         dialog.set_select_multiple(True)
 
-        filter = gtk.FileFilter()
+        filter = Gtk.FileFilter()
         filter.set_name("SQL files")
         filter.add_pattern("*.sql")
         dialog.add_filter(filter)
 
-        filter = gtk.FileFilter()
+        filter = Gtk.FileFilter()
         filter.set_name("All files")
         filter.add_pattern("*")
         dialog.add_filter(filter)
 
         response = dialog.run()
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             filenames = dialog.get_filenames()
             for fname in filenames:
                 self.open_file(fname)
@@ -393,24 +398,24 @@
 
         path, file = filename.rsplit('/',1)
 
-        dialog = gtk.FileChooserDialog(title='Save as', action=gtk.FILE_CHOOSER_ACTION_SAVE,
-            buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
-        dialog.set_default_response(gtk.RESPONSE_OK)
+        dialog = Gtk.FileChooserDialog(title='Save as', action=Gtk.FileChooserAction.SAVE,
+            buttons=(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_SAVE,Gtk.ResponseType.OK))
+        dialog.set_default_response(Gtk.ResponseType.OK)
         dialog.set_current_folder(path)
         dialog.set_current_name(file)
 
-        filter = gtk.FileFilter()
+        filter = Gtk.FileFilter()
         filter.set_name("SQL files")
         filter.add_pattern("*.sql")
         dialog.add_filter(filter)
 
-        filter = gtk.FileFilter()
+        filter = Gtk.FileFilter()
         filter.set_name("All files")
         filter.add_pattern("*")
         dialog.add_filter(filter)
 
         response = dialog.run()
-        if response == gtk.RESPONSE_OK:
+        if response == Gtk.ResponseType.OK:
             filename = dialog.get_filename()
             data = buffer.get_text(*buffer.get_bounds())
             open(filename, 'w').write(data)
@@ -430,8 +435,8 @@
             return
         iter = model.get_iter(sel[0])
         newiter = model.iter_next(iter)
-        if newiter is None and sel[0][0] > 0:
-            newiter = model.get_iter((sel[0][0]-1,))
+        if newiter is None and sel[0].get_indices()[0] > 0:
+            newiter = model.get_iter((sel[0].get_indices()[0]-1,))
 
         title, buffer = model.get(iter, 0, 2)
         #buffer.destroy()
@@ -450,6 +455,6 @@
 
 
     def leftbuttons_size_request(self, w, request):
-        self.set_snap1(request[0])
+        self.set_snap1(request.width)
         return True
 
--- a/pgconsole/panedext.py	Thu Mar 07 18:26:52 2013 +0100
+++ b/pgconsole/panedext.py	Sun Mar 10 16:14:53 2013 +0100
@@ -1,8 +1,8 @@
-import gtk
+from gi.repository import Gtk
 
 
-class PanedExt(gtk.Paned):
-    """Extended gtk.Paned (abstract)
+class PanedExt(Gtk.Paned):
+    """Extended Gtk.Paned (abstract)
 
     set_snap1(int), set_snap2(int)
         set minimum size of child widget
@@ -23,7 +23,7 @@
 
 
     def on_position_change(self, w, scrolltype):
-        if self.allocation[0] == -1:
+        if self.get_allocation().width == -1:
             return False
 
         pos = self.get_position()
@@ -48,14 +48,14 @@
         return False
 
 
-class HPanedExt(gtk.HPaned, PanedExt):
+class HPanedExt(Gtk.HPaned, PanedExt):
     def __init__(self):
-        gtk.HPaned.__init__(self)
+        Gtk.HPaned.__init__(self)
         PanedExt.__init__(self)
 
 
-class VPanedExt(gtk.VPaned, PanedExt):
+class VPanedExt(Gtk.VPaned, PanedExt):
     def __init__(self):
-        gtk.VPaned.__init__(self)
+        Gtk.VPaned.__init__(self)
         PanedExt.__init__(self)
 
--- a/pgconsole/settings.py	Thu Mar 07 18:26:52 2013 +0100
+++ b/pgconsole/settings.py	Sun Mar 10 16:14:53 2013 +0100
@@ -1,44 +1,45 @@
-import gtk
+from gi.repository import Gtk
+from gi.repository import Gdk
 
-from config import cfg
+from pgconsole.config import cfg
 
 
-class Settings(gtk.Window):
+class Settings(Gtk.Window):
     def __init__(self, parent):
-        super(Settings, self).__init__(gtk.WINDOW_TOPLEVEL)
+        super(Settings, self).__init__()
 
         self._parent = parent
 
         self.set_title('Settings')
         self.set_modal(True)
         self.set_transient_for(parent.win)
-        self.set_position(gtk.WIN_POS_CENTER)
+        self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
         #self.set_border_width(10)
         self.connect("key_press_event", self.on_keypress)
         self.connect("destroy", self.on_destroy)
 
-        self.tabs = gtk.Notebook()
+        self.tabs = Gtk.Notebook()
         self.add(self.tabs)
 
         ### Servers
-        vbox = gtk.VBox(spacing=10)
+        vbox = Gtk.VBox(spacing=10)
         vbox.set_border_width(10)
-        self.tabs.append_page(vbox, gtk.Label('Servers'))
+        self.tabs.append_page(vbox, Gtk.Label('Servers'))
 
-        hbox = gtk.HBox(spacing=10)
-        vbox.pack_start(hbox)
-        sw = gtk.ScrolledWindow()
-        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        sw.set_shadow_type(gtk.SHADOW_IN)
-        hbox.pack_start(sw)
-        tree = gtk.TreeView()
+        hbox = Gtk.HBox(spacing=10)
+        vbox.pack_start(hbox, expand=True, fill=True, padding=0)
+        sw = Gtk.ScrolledWindow()
+        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
+        sw.set_shadow_type(Gtk.ShadowType.IN)
+        hbox.pack_start(sw, expand=True, fill=True, padding=0)
+        tree = Gtk.TreeView()
         tree.set_headers_visible(False)
         sw.add(tree)
-        tree.get_selection().set_mode(gtk.SELECTION_BROWSE)
+        tree.get_selection().set_mode(Gtk.SelectionMode.BROWSE)
 
-        model = gtk.ListStore(str, object)
+        model = Gtk.ListStore(str, object)
         tree.set_model(model)
-        column = gtk.TreeViewColumn("Server", gtk.CellRendererText(), text=0)
+        column = Gtk.TreeViewColumn("Server", Gtk.CellRendererText(), text=0)
         tree.append_column(column)
         tree.get_selection().connect('changed', self.item_change)
         tree.set_size_request(100, -1)
@@ -55,69 +56,69 @@
 
         self.itemtree = tree
 
-        vbox = gtk.VBox(spacing=10)
-        hbox.pack_start(vbox)
+        vbox = Gtk.VBox(spacing=10)
+        hbox.pack_start(vbox, expand=True, fill=True, padding=0)
 
-        table = gtk.Table(5, 2)
+        table = Gtk.Table(5, 2)
         table.set_row_spacings(4)
         table.set_col_spacings(10)
-        vbox.pack_start(table)
+        vbox.pack_start(table, expand=True, fill=True, padding=0)
 
-        label = gtk.Label("Name:")
+        label = Gtk.Label("Name:")
         label.set_alignment(0.0, 0.5)
         table.attach(label, 0, 1, 0, 1)
-        entry = gtk.Entry()
+        entry = Gtk.Entry()
         table.attach(entry, 1, 2, 0, 1)
         self.entry_name = entry
 
-        label = gtk.Label("Host:")
+        label = Gtk.Label("Host:")
         label.set_alignment(0.0, 0.5)
         table.attach(label, 0, 1, 1, 2)
-        entry = gtk.Entry()
+        entry = Gtk.Entry()
         entry.set_text('127.0.0.1')
         table.attach(entry, 1, 2, 1, 2)
         self.entry_host = entry
 
-        label = gtk.Label("Port:")
+        label = Gtk.Label("Port:")
         label.set_alignment(0.0, 0.5)
         table.attach(label, 0, 1, 2, 3)
-        entry = gtk.Entry()
+        entry = Gtk.Entry()
         entry.set_text('5432')
         table.attach(entry, 1, 2, 2, 3)
         self.entry_port = entry
 
-        label = gtk.Label("User:")
+        label = Gtk.Label("User:")
         label.set_alignment(0.0, 0.5)
         table.attach(label, 0, 1, 3, 4)
-        entry = gtk.Entry()
+        entry = Gtk.Entry()
         entry.set_text('postgres')
         table.attach(entry, 1, 2, 3, 4)
         self.entry_user = entry
 
-        label = gtk.Label("Password:")
+        label = Gtk.Label("Password:")
         label.set_alignment(0.0, 0.5)
         table.attach(label, 0, 1, 4, 5)
-        entry = gtk.Entry()
+        entry = Gtk.Entry()
         table.attach(entry, 1, 2, 4, 5)
         self.entry_password = entry
 
-        hbox = gtk.HBox()
-        vbox.pack_start(hbox)
+        hbox = Gtk.HBox()
+        vbox.pack_start(hbox, expand=True, fill=True, padding=0)
 
-        btn = gtk.Button('Add')
+        btn = Gtk.Button('Add')
         btn.connect('clicked', self.item_add)
-        hbox.pack_start(btn)
-        btn = gtk.Button('Save')
+        hbox.pack_start(btn, expand=True, fill=True, padding=0)
+        btn = Gtk.Button('Save')
         btn.connect('clicked', self.item_save)
-        hbox.pack_start(btn)
-        btn = gtk.Button('Remove')
+        hbox.pack_start(btn, expand=True, fill=True, padding=0)
+        btn = Gtk.Button('Remove')
         btn.connect('clicked', self.item_remove)
-        hbox.pack_start(btn)
+        hbox.pack_start(btn, expand=True, fill=True, padding=0)
 
         ### Editor
-        vbox = gtk.VBox(spacing=10)
+        vbox = Gtk.VBox(spacing=10)
         vbox.set_border_width(10)
-        self.tabs.append_page(vbox, gtk.Label('Editor'))
+        self.tabs.append_page(vbox, Gtk.Label('Editor'))
 
         self.show_all()
         self.itemtree.grab_focus()
@@ -180,7 +181,7 @@
 
 
     def on_keypress(self, w, event):
-        keyname = gtk.gdk.keyval_name(event.keyval)
+        keyname = Gdk.keyval_name(event.keyval)
 
         if keyname == 'Escape':
             self.destroy()
@@ -191,7 +192,7 @@
     def on_destroy(self, w):
         model, sel = self.itemtree.get_selection().get_selected_rows()
         if sel:
-            sel = sel[0][0]
+            sel = sel[0].get_indices()[0]
         else:
             sel = None
         self._parent.reload_server_list(sel)