Browse code

Port to GTK3.

Timo Vanwynsberghe authored on 03/04/2013 20:57:08 • Jose Fonseca committed on 14/07/2015 21:19:23
Showing 2 changed files

... ...
@@ -17,8 +17,7 @@
17 17
 #
18 18
 
19 19
 
20
-import gtk
21
-import gtk.gdk
20
+from gi.repository import Gtk
22 21
 
23 22
 import xdot
24 23
 
... ...
@@ -27,12 +26,12 @@ class MyDotWindow(xdot.DotWindow):
27 26
 
28 27
     def __init__(self):
29 28
         xdot.DotWindow.__init__(self)
30
-        self.widget.connect('clicked', self.on_url_clicked)
29
+        self.dotwidget.connect('clicked', self.on_url_clicked)
31 30
 
32 31
     def on_url_clicked(self, widget, url, event):
33
-        dialog = gtk.MessageDialog(
32
+        dialog = Gtk.MessageDialog(
34 33
                 parent = self, 
35
-                buttons = gtk.BUTTONS_OK,
34
+                buttons = Gtk.ButtonsType.OK,
36 35
                 message_format="%s clicked" % url)
37 36
         dialog.connect('response', lambda dialog, response: dialog.destroy())
38 37
         dialog.run()
... ...
@@ -51,8 +50,8 @@ digraph G {
51 50
 def main():
52 51
     window = MyDotWindow()
53 52
     window.set_dotcode(dotcode)
54
-    window.connect('destroy', gtk.main_quit)
55
-    gtk.main()
53
+    window.connect('delete-event', Gtk.main_quit)
54
+    Gtk.main()
56 55
 
57 56
 
58 57
 if __name__ == '__main__':
... ...
@@ -30,13 +30,14 @@ import time
30 30
 import re
31 31
 import optparse
32 32
 
33
-import gobject
34
-import gtk
35
-import gtk.gdk
36
-import gtk.keysyms
33
+from gi.repository import GLib
34
+from gi.repository import GObject
35
+from gi.repository import Gtk
36
+from gi.repository import Gdk
37
+from gi.repository import GdkPixbuf
38
+from gi.repository import Pango
39
+from gi.repository import PangoCairo
37 40
 import cairo
38
-import pango
39
-import pangocairo
40 41
 
41 42
 
42 43
 # See http://www.graphviz.org/pub/scm/graphviz-cairo/plugin/cairo/gvrender_cairo.c
... ...
@@ -119,27 +120,27 @@ class TextShape(Shape):
119 120
         try:
120 121
             layout = self.layout
121 122
         except AttributeError:
122
-            layout = cr.create_layout()
123
+            context = Gdk.pango_context_get()
124
+            layout = Pango.Layout(context)
123 125
 
124 126
             # set font options
125 127
             # see http://lists.freedesktop.org/archives/cairo/2007-February/009688.html
126
-            context = layout.get_context()
127 128
             fo = cairo.FontOptions()
128 129
             fo.set_antialias(cairo.ANTIALIAS_DEFAULT)
129 130
             fo.set_hint_style(cairo.HINT_STYLE_NONE)
130 131
             fo.set_hint_metrics(cairo.HINT_METRICS_OFF)
131 132
             try:
132
-                pangocairo.context_set_font_options(context, fo)
133
+                PangoCairo.context_set_font_options(context, fo)
133 134
             except TypeError:
134 135
                 # XXX: Some broken pangocairo bindings show the error
135 136
                 # 'TypeError: font_options must be a cairo.FontOptions or None'
136 137
                 pass
137 138
 
138 139
             # set font
139
-            font = pango.FontDescription()
140
+            font = Pango.FontDescription()
140 141
 
141 142
             # https://developer.gnome.org/pango/stable/PangoMarkupFormat.html
142
-            markup = gobject.markup_escape_text(self.t)
143
+            markup = GObject.markup_escape_text(self.t)
143 144
             if self.pen.bold:
144 145
                 markup = '<b>' + markup + '</b>'
145 146
             if self.pen.italic:
... ...
@@ -153,26 +154,27 @@ class TextShape(Shape):
153 154
             if self.pen.subscript:
154 155
                 markup = '<sub><small>' + markup + '</small></sub>'
155 156
 
156
-            attrs, text, accel_char = pango.parse_markup(markup, u'\x00')
157
+            success, attrs, text, accel_char = Pango.parse_markup(markup, -1, u'\x00')
158
+            assert success
157 159
             layout.set_attributes(attrs)
158 160
 
159 161
             font.set_family(self.pen.fontname)
160
-            font.set_absolute_size(self.pen.fontsize*pango.SCALE)
162
+            font.set_absolute_size(self.pen.fontsize*Pango.SCALE)
161 163
             layout.set_font_description(font)
162 164
 
163 165
             # set text
164
-            layout.set_text(text)
166
+            layout.set_text(text, len(text))
165 167
 
166 168
             # cache it
167 169
             self.layout = layout
168 170
         else:
169
-            cr.update_layout(layout)
171
+            PangoCairo.update_layout(cr, layout)
170 172
 
171 173
         descent = 2 # XXX get descender from font metrics
172 174
 
173 175
         width, height = layout.get_size()
174
-        width = float(width)/pango.SCALE
175
-        height = float(height)/pango.SCALE
176
+        width = float(width)/Pango.SCALE
177
+        height = float(height)/Pango.SCALE
176 178
 
177 179
         # we know the width that dot thinks this text should have
178 180
         # we do not necessarily have a font with the same metrics
... ...
@@ -201,7 +203,7 @@ class TextShape(Shape):
201 203
         cr.save()
202 204
         cr.scale(f, f)
203 205
         cr.set_source_rgba(*self.select_pen(highlight).color)
204
-        cr.show_layout(layout)
206
+        PangoCairo.show_layout(cr, layout)
205 207
         cr.restore()
206 208
 
207 209
         if 0: # DEBUG
... ...
@@ -233,15 +235,14 @@ class ImageShape(Shape):
233 235
         self.path = path
234 236
 
235 237
     def draw(self, cr, highlight=False):
236
-        cr2 = gtk.gdk.CairoContext(cr)
237
-        pixbuf = gtk.gdk.pixbuf_new_from_file(self.path)
238
+        pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.path)
238 239
         sx = float(self.w)/float(pixbuf.get_width())
239 240
         sy = float(self.h)/float(pixbuf.get_height())
240 241
         cr.save()
241 242
         cr.translate(self.x0, self.y0 - self.h)
242 243
         cr.scale(sx, sy)
243
-        cr2.set_source_pixbuf(pixbuf, 0, 0)
244
-        cr2.paint()
244
+        Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0)
245
+        cr.paint()
245 246
         cr.restore()
246 247
 
247 248
 
... ...
@@ -622,7 +623,7 @@ class XDotAttrParser:
622 623
 
623 624
     def lookup_color(self, c):
624 625
         try:
625
-            color = gtk.gdk.color_parse(c)
626
+            color = Gdk.color_parse(c)
626 627
         except ValueError:
627 628
             pass
628 629
         else:
... ...
@@ -1304,12 +1305,12 @@ class Animation(object):
1304 1305
         self.timeout_id = None
1305 1306
 
1306 1307
     def start(self):
1307
-        self.timeout_id = gobject.timeout_add(int(self.step * 1000), self.tick)
1308
+        self.timeout_id = GLib.timeout_add(int(self.step * 1000), self.tick)
1308 1309
 
1309 1310
     def stop(self):
1310 1311
         self.dot_widget.animation = NoAnimation(self.dot_widget)
1311 1312
         if self.timeout_id is not None:
1312
-            gobject.source_remove(self.timeout_id)
1313
+            GLib.source_remove(self.timeout_id)
1313 1314
             self.timeout_id = None
1314 1315
 
1315 1316
     def tick(self):
... ...
@@ -1397,7 +1398,7 @@ class DragAction(object):
1397 1398
 
1398 1399
     def on_motion_notify(self, event):
1399 1400
         if event.is_hint:
1400
-            x, y, state = event.window.get_pointer()
1401
+            window, x, y, state = event.window.get_device_position(event.device)
1401 1402
         else:
1402 1403
             x, y, state = event.x, event.y, event.state
1403 1404
         deltax = self.prevmousex - x
... ...
@@ -1431,7 +1432,7 @@ class NullAction(DragAction):
1431 1432
 
1432 1433
     def on_motion_notify(self, event):
1433 1434
         if event.is_hint:
1434
-            x, y, state = event.window.get_pointer()
1435
+            window, x, y, state = event.window.get_device_position(event.device)
1435 1436
         else:
1436 1437
             x, y, state = event.x, event.y, event.state
1437 1438
         dot_widget = self.dot_widget
... ...
@@ -1439,17 +1440,17 @@ class NullAction(DragAction):
1439 1440
         if item is None:
1440 1441
             item = dot_widget.get_jump(x, y)
1441 1442
         if item is not None:
1442
-            dot_widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
1443
+            dot_widget.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))
1443 1444
             dot_widget.set_highlight(item.highlight)
1444 1445
         else:
1445
-            dot_widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
1446
+            dot_widget.get_window().set_cursor(None)
1446 1447
             dot_widget.set_highlight(None)
1447 1448
 
1448 1449
 
1449 1450
 class PanAction(DragAction):
1450 1451
 
1451 1452
     def start(self):
1452
-        self.dot_widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
1453
+        self.dot_widget.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.FLEUR))
1453 1454
 
1454 1455
     def drag(self, deltax, deltay):
1455 1456
         self.dot_widget.x += deltax / self.dot_widget.zoom_ratio
... ...
@@ -1457,7 +1458,7 @@ class PanAction(DragAction):
1457 1458
         self.dot_widget.queue_draw()
1458 1459
 
1459 1460
     def stop(self):
1460
-        self.dot_widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
1461
+        self.dot_widget.get_window().set_cursor(None)
1461 1462
 
1462 1463
     abort = stop
1463 1464
 
... ...
@@ -1504,28 +1505,32 @@ class ZoomAreaAction(DragAction):
1504 1505
         self.dot_widget.queue_draw()
1505 1506
 
1506 1507
 
1507
-class DotWidget(gtk.DrawingArea):
1508
-    """PyGTK widget that draws dot graphs."""
1508
+class DotWidget(Gtk.DrawingArea):
1509
+    """GTK widget that draws dot graphs."""
1509 1510
 
1511
+    #TODO GTK3: Second argument has to be of type Gdk.EventButton instead of object.
1510 1512
     __gsignals__ = {
1511
-        'expose-event': 'override',
1512
-        'clicked' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, gtk.gdk.Event))
1513
+        'clicked' : (GObject.SIGNAL_RUN_LAST, None, (str, object))
1513 1514
     }
1514 1515
 
1515 1516
     filter = 'dot'
1516 1517
 
1517 1518
     def __init__(self):
1518
-        gtk.DrawingArea.__init__(self)
1519
+        Gtk.DrawingArea.__init__(self)
1519 1520
 
1520 1521
         self.graph = Graph()
1521 1522
         self.openfilename = None
1522 1523
 
1523
-        self.set_flags(gtk.CAN_FOCUS)
1524
+        self.set_can_focus(True)
1524 1525
 
1525
-        self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
1526
+        self.connect("draw", self.on_draw)
1527
+        self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
1526 1528
         self.connect("button-press-event", self.on_area_button_press)
1527 1529
         self.connect("button-release-event", self.on_area_button_release)
1528
-        self.add_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
1530
+        self.add_events(Gdk.EventMask.POINTER_MOTION_MASK | 
1531
+                        Gdk.EventMask.POINTER_MOTION_HINT_MASK | 
1532
+                        Gdk.EventMask.BUTTON_RELEASE_MASK | 
1533
+                        Gdk.EventMask.SCROLL_MASK)
1529 1534
         self.connect("motion-notify-event", self.on_area_motion_notify)
1530 1535
         self.connect("scroll-event", self.on_area_scroll_event)
1531 1536
         self.connect("size-allocate", self.on_area_size_allocate)
... ...
@@ -1533,7 +1538,7 @@ class DotWidget(gtk.DrawingArea):
1533 1538
         self.connect('key-press-event', self.on_key_press_event)
1534 1539
         self.last_mtime = None
1535 1540
 
1536
-        gobject.timeout_add(1000, self.update)
1541
+        GLib.timeout_add(1000, self.update)
1537 1542
 
1538 1543
         self.x, self.y = 0.0, 0.0
1539 1544
         self.zoom_ratio = 1.0
... ...
@@ -1567,9 +1572,9 @@ class DotWidget(gtk.DrawingArea):
1567 1572
         if error:
1568 1573
             sys.stderr.write(error + '\n')
1569 1574
         if p.returncode != 0:
1570
-            dialog = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
1575
+            dialog = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
1571 1576
                                        message_format=error,
1572
-                                       buttons=gtk.BUTTONS_OK)
1577
+                                       buttons=Gtk.ButtonsType.OK)
1573 1578
             dialog.set_title('Dot Viewer')
1574 1579
             dialog.run()
1575 1580
             dialog.destroy()
... ...
@@ -1586,9 +1591,9 @@ class DotWidget(gtk.DrawingArea):
1586 1591
         try:
1587 1592
             self.set_xdotcode(xdotcode)
1588 1593
         except ParseError as ex:
1589
-            dialog = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
1594
+            dialog = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
1590 1595
                                        message_format=str(ex),
1591
-                                       buttons=gtk.BUTTONS_OK)
1596
+                                       buttons=Gtk.ButtonsType.OK)
1592 1597
             dialog.set_title('Dot Viewer')
1593 1598
             dialog.run()
1594 1599
             dialog.destroy()
... ...
@@ -1623,16 +1628,7 @@ class DotWidget(gtk.DrawingArea):
1623 1628
                 self.reload()
1624 1629
         return True
1625 1630
 
1626
-    def do_expose_event(self, event):
1627
-        cr = self.window.cairo_create()
1628
-
1629
-        # set a clip region for the expose event
1630
-        cr.rectangle(
1631
-            event.area.x, event.area.y,
1632
-            event.area.width, event.area.height
1633
-        )
1634
-        cr.clip()
1635
-
1631
+    def on_draw(self, widget, cr):
1636 1632
         cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
1637 1633
         cr.paint()
1638 1634
 
... ...
@@ -1728,59 +1724,59 @@ class DotWidget(gtk.DrawingArea):
1728 1724
     POS_INCREMENT = 100
1729 1725
 
1730 1726
     def on_key_press_event(self, widget, event):
1731
-        if event.keyval == gtk.keysyms.Left:
1727
+        if event.keyval == Gdk.KEY_Left:
1732 1728
             self.x -= self.POS_INCREMENT/self.zoom_ratio
1733 1729
             self.queue_draw()
1734 1730
             return True
1735
-        if event.keyval == gtk.keysyms.Right:
1731
+        if event.keyval == Gdk.KEY_Right:
1736 1732
             self.x += self.POS_INCREMENT/self.zoom_ratio
1737 1733
             self.queue_draw()
1738 1734
             return True
1739
-        if event.keyval == gtk.keysyms.Up:
1735
+        if event.keyval == Gdk.KEY_Up:
1740 1736
             self.y -= self.POS_INCREMENT/self.zoom_ratio
1741 1737
             self.queue_draw()
1742 1738
             return True
1743
-        if event.keyval == gtk.keysyms.Down:
1739
+        if event.keyval == Gdk.KEY_Down:
1744 1740
             self.y += self.POS_INCREMENT/self.zoom_ratio
1745 1741
             self.queue_draw()
1746 1742
             return True
1747
-        if event.keyval in (gtk.keysyms.Page_Up,
1748
-                            gtk.keysyms.plus,
1749
-                            gtk.keysyms.equal,
1750
-                            gtk.keysyms.KP_Add):
1743
+        if event.keyval in (Gdk.KEY_Page_Up,
1744
+                            Gdk.KEY_plus,
1745
+                            Gdk.KEY_equal,
1746
+                            Gdk.KEY_KP_Add):
1751 1747
             self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT)
1752 1748
             self.queue_draw()
1753 1749
             return True
1754
-        if event.keyval in (gtk.keysyms.Page_Down,
1755
-                            gtk.keysyms.minus,
1756
-                            gtk.keysyms.KP_Subtract):
1750
+        if event.keyval in (Gdk.KEY_Page_Down,
1751
+                            Gdk.KEY_minus,
1752
+                            Gdk.KEY_KP_Subtract):
1757 1753
             self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT)
1758 1754
             self.queue_draw()
1759 1755
             return True
1760
-        if event.keyval == gtk.keysyms.Escape:
1756
+        if event.keyval == Gdk.KEY_Escape:
1761 1757
             self.drag_action.abort()
1762 1758
             self.drag_action = NullAction(self)
1763 1759
             return True
1764
-        if event.keyval == gtk.keysyms.r:
1760
+        if event.keyval == Gdk.KEY_r:
1765 1761
             self.reload()
1766 1762
             return True
1767
-        if event.keyval == gtk.keysyms.f:
1763
+        if event.keyval == Gdk.KEY_f:
1768 1764
             win = widget.get_toplevel()
1769 1765
             find_toolitem = win.uimanager.get_widget('/ToolBar/Find')
1770 1766
             textentry = find_toolitem.get_children()
1771 1767
             win.set_focus(textentry[0])
1772 1768
             return True
1773
-        if event.keyval == gtk.keysyms.q:
1774
-            gtk.main_quit()
1769
+        if event.keyval == Gdk.KEY_q:
1770
+            Gtk.main_quit()
1775 1771
             return True
1776
-        if event.keyval == gtk.keysyms.p:
1772
+        if event.keyval == Gdk.KEY_p:
1777 1773
             self.on_print()
1778 1774
             return True
1779 1775
         return False
1780 1776
 
1781 1777
     print_settings = None
1782 1778
     def on_print(self, action=None):
1783
-        print_op = gtk.PrintOperation()
1779
+        print_op = Gtk.PrintOperation()
1784 1780
 
1785 1781
         if self.print_settings != None:
1786 1782
             print_op.set_print_settings(self.print_settings)
... ...
@@ -1788,10 +1784,9 @@ class DotWidget(gtk.DrawingArea):
1788 1784
         print_op.connect("begin_print", self.begin_print)
1789 1785
         print_op.connect("draw_page", self.draw_page)
1790 1786
 
1791
-        res = print_op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG, self.parent.parent)
1792
-
1793
-        if res == gtk.PRINT_OPERATION_RESULT_APPLY:
1794
-            print_settings = print_op.get_print_settings()
1787
+        res = print_op.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.get_toplevel())
1788
+        if res == Gtk.PrintOperationResult.APPLY:
1789
+            self.print_settings = print_op.get_print_settings()
1795 1790
 
1796 1791
     def begin_print(self, operation, context):
1797 1792
         operation.set_n_pages(1)
... ...
@@ -1810,9 +1805,10 @@ class DotWidget(gtk.DrawingArea):
1810 1805
     def get_drag_action(self, event):
1811 1806
         state = event.state
1812 1807
         if event.button in (1, 2): # left or middle button
1813
-            if state & gtk.gdk.CONTROL_MASK:
1808
+            modifiers = Gtk.accelerator_get_default_mod_mask()
1809
+            if state & modifiers == Gdk.ModifierType.CONTROL_MASK:
1814 1810
                 return ZoomAction
1815
-            elif state & gtk.gdk.SHIFT_MASK:
1811
+            elif state & modifiers == Gdk.ModifierType.SHIFT_MASK:
1816 1812
                 return ZoomAreaAction
1817 1813
             else:
1818 1814
                 return PanAction
... ...
@@ -1830,7 +1826,7 @@ class DotWidget(gtk.DrawingArea):
1830 1826
         return False
1831 1827
 
1832 1828
     def is_click(self, event, click_fuzz=4, click_timeout=1.0):
1833
-        assert event.type == gtk.gdk.BUTTON_RELEASE
1829
+        assert event.type == Gdk.EventType.BUTTON_RELEASE
1834 1830
         if self.presstime is None:
1835 1831
             # got a button release without seeing the press?
1836 1832
             return False
... ...
@@ -1872,11 +1868,11 @@ class DotWidget(gtk.DrawingArea):
1872 1868
         return False
1873 1869
 
1874 1870
     def on_area_scroll_event(self, area, event):
1875
-        if event.direction == gtk.gdk.SCROLL_UP:
1871
+        if event.direction == Gdk.ScrollDirection.UP:
1876 1872
             self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT,
1877 1873
                             pos=(event.x, event.y))
1878 1874
             return True
1879
-        if event.direction == gtk.gdk.SCROLL_DOWN:
1875
+        if event.direction == Gdk.ScrollDirection.DOWN:
1880 1876
             self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT,
1881 1877
                             pos=(event.x, event.y))
1882 1878
             return True
... ...
@@ -1917,15 +1913,14 @@ class DotWidget(gtk.DrawingArea):
1917 1913
         return self.graph.get_jump(x, y)
1918 1914
 
1919 1915
 
1920
-class FindMenuToolAction(gtk.Action):
1916
+class FindMenuToolAction(Gtk.Action):
1921 1917
     __gtype_name__ = "FindMenuToolAction"
1922 1918
 
1923
-    def __init__(self, *args, **kw):
1924
-        gtk.Action.__init__(self, *args, **kw)
1925
-        self.set_tool_item_type(gtk.ToolItem)
1919
+    def do_create_tool_item(self):
1920
+        return Gtk.ToolItem()
1926 1921
 
1927 1922
 
1928
-class DotWindow(gtk.Window):
1923
+class DotWindow(Gtk.Window):
1929 1924
 
1930 1925
     ui = '''
1931 1926
     <ui>
... ...
@@ -1947,7 +1942,7 @@ class DotWindow(gtk.Window):
1947 1942
     base_title = 'Dot Viewer'
1948 1943
 
1949 1944
     def __init__(self, widget=None):
1950
-        gtk.Window.__init__(self)
1945
+        Gtk.Window.__init__(self)
1951 1946
 
1952 1947
         self.graph = Graph()
1953 1948
 
... ...
@@ -1955,31 +1950,31 @@ class DotWindow(gtk.Window):
1955 1950
 
1956 1951
         window.set_title(self.base_title)
1957 1952
         window.set_default_size(512, 512)
1958
-        vbox = gtk.VBox()
1953
+        vbox = Gtk.VBox()
1959 1954
         window.add(vbox)
1960 1955
 
1961
-        self.widget = widget or DotWidget()
1956
+        self.dotwidget = widget or DotWidget()
1962 1957
 
1963 1958
         # Create a UIManager instance
1964
-        uimanager = self.uimanager = gtk.UIManager()
1959
+        uimanager = self.uimanager = Gtk.UIManager()
1965 1960
 
1966 1961
         # Add the accelerator group to the toplevel window
1967 1962
         accelgroup = uimanager.get_accel_group()
1968 1963
         window.add_accel_group(accelgroup)
1969 1964
 
1970 1965
         # Create an ActionGroup
1971
-        actiongroup = gtk.ActionGroup('Actions')
1966
+        actiongroup = Gtk.ActionGroup('Actions')
1972 1967
         self.actiongroup = actiongroup
1973 1968
 
1974 1969
         # Create actions
1975 1970
         actiongroup.add_actions((
1976
-            ('Open', gtk.STOCK_OPEN, None, None, None, self.on_open),
1977
-            ('Reload', gtk.STOCK_REFRESH, None, None, None, self.on_reload),
1978
-            ('Print', gtk.STOCK_PRINT, None, None, "Prints the currently visible part of the graph", self.widget.on_print),
1979
-            ('ZoomIn', gtk.STOCK_ZOOM_IN, None, None, None, self.widget.on_zoom_in),
1980
-            ('ZoomOut', gtk.STOCK_ZOOM_OUT, None, None, None, self.widget.on_zoom_out),
1981
-            ('ZoomFit', gtk.STOCK_ZOOM_FIT, None, None, None, self.widget.on_zoom_fit),
1982
-            ('Zoom100', gtk.STOCK_ZOOM_100, None, None, None, self.widget.on_zoom_100),
1971
+            ('Open', Gtk.STOCK_OPEN, None, None, None, self.on_open),
1972
+            ('Reload', Gtk.STOCK_REFRESH, None, None, None, self.on_reload),
1973
+            ('Print', Gtk.STOCK_PRINT, None, None, "Prints the currently visible part of the graph", self.dotwidget.on_print),
1974
+            ('ZoomIn', Gtk.STOCK_ZOOM_IN, None, None, None, self.dotwidget.on_zoom_in),
1975
+            ('ZoomOut', Gtk.STOCK_ZOOM_OUT, None, None, None, self.dotwidget.on_zoom_out),
1976
+            ('ZoomFit', Gtk.STOCK_ZOOM_FIT, None, None, None, self.dotwidget.on_zoom_fit),
1977
+            ('Zoom100', Gtk.STOCK_ZOOM_100, None, None, None, self.dotwidget.on_zoom_100),
1983 1978
         ))
1984 1979
 
1985 1980
         find_action = FindMenuToolAction("Find", None,
... ...
@@ -1994,18 +1989,18 @@ class DotWindow(gtk.Window):
1994 1989
 
1995 1990
         # Create a Toolbar
1996 1991
         toolbar = uimanager.get_widget('/ToolBar')
1997
-        vbox.pack_start(toolbar, False)
1992
+        vbox.pack_start(toolbar, False, False, 0)
1998 1993
 
1999
-        vbox.pack_start(self.widget)
1994
+        vbox.pack_start(self.dotwidget, True, True, 0)
2000 1995
 
2001 1996
         self.last_open_dir = "."
2002 1997
 
2003
-        self.set_focus(self.widget)
1998
+        self.set_focus(self.dotwidget)
2004 1999
 
2005 2000
         # Add Find text search
2006 2001
         find_toolitem = uimanager.get_widget('/ToolBar/Find')
2007
-        self.textentry = gtk.Entry(max=20)
2008
-        self.textentry.set_icon_from_stock(0, gtk.STOCK_FIND)
2002
+        self.textentry = Gtk.Entry(max_length=20)
2003
+        self.textentry.set_icon_from_stock(0, Gtk.STOCK_FIND)
2009 2004
         find_toolitem.add(self.textentry)
2010 2005
 
2011 2006
         self.textentry.set_activates_default(True)
... ...
@@ -2016,7 +2011,7 @@ class DotWindow(gtk.Window):
2016 2011
 
2017 2012
     def find_text(self, entry_text):
2018 2013
         found_items = []
2019
-        dot_widget = self.widget
2014
+        dot_widget = self.dotwidget
2020 2015
         regexp = re.compile(entry_text)
2021 2016
         for node in dot_widget.graph.nodes:
2022 2017
             if node.search_text(regexp):
... ...
@@ -2025,7 +2020,7 @@ class DotWindow(gtk.Window):
2025 2020
 
2026 2021
     def textentry_changed(self, widget, entry):
2027 2022
         entry_text = entry.get_text()
2028
-        dot_widget = self.widget        
2023
+        dot_widget = self.dotwidget        
2029 2024
         if not entry_text:
2030 2025
             dot_widget.set_highlight(None)
2031 2026
             return
... ...
@@ -2035,7 +2030,7 @@ class DotWindow(gtk.Window):
2035 2030
 
2036 2031
     def textentry_activate(self, widget, entry):
2037 2032
         entry_text = entry.get_text()
2038
-        dot_widget = self.widget        
2033
+        dot_widget = self.dotwidget        
2039 2034
         if not entry_text:
2040 2035
             dot_widget.set_highlight(None)
2041 2036
             return;
... ...
@@ -2046,17 +2041,17 @@ class DotWindow(gtk.Window):
2046 2041
             dot_widget.animate_to(found_items[0].x, found_items[0].y)
2047 2042
 
2048 2043
     def set_filter(self, filter):
2049
-        self.widget.set_filter(filter)
2044
+        self.dotwidget.set_filter(filter)
2050 2045
 
2051 2046
     def set_dotcode(self, dotcode, filename=None):
2052
-        if self.widget.set_dotcode(dotcode, filename):
2047
+        if self.dotwidget.set_dotcode(dotcode, filename):
2053 2048
             self.update_title(filename)
2054
-            self.widget.zoom_to_fit()
2049
+            self.dotwidget.zoom_to_fit()
2055 2050
 
2056 2051
     def set_xdotcode(self, xdotcode, filename=None):
2057
-        if self.widget.set_xdotcode(xdotcode):
2052
+        if self.dotwidget.set_xdotcode(xdotcode):
2058 2053
             self.update_title(filename)
2059
-            self.widget.zoom_to_fit()
2054
+            self.dotwidget.zoom_to_fit()
2060 2055
         
2061 2056
     def update_title(self, filename=None):
2062 2057
         if filename is None:
... ...
@@ -2070,31 +2065,31 @@ class DotWindow(gtk.Window):
2070 2065
             self.set_dotcode(fp.read(), filename)
2071 2066
             fp.close()
2072 2067
         except IOError as ex:
2073
-            dlg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
2068
+            dlg = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
2074 2069
                                     message_format=str(ex),
2075
-                                    buttons=gtk.BUTTONS_OK)
2070
+                                    buttons=Gtk.ButtonsType.OK)
2076 2071
             dlg.set_title(self.base_title)
2077 2072
             dlg.run()
2078 2073
             dlg.destroy()
2079 2074
 
2080 2075
     def on_open(self, action):
2081
-        chooser = gtk.FileChooserDialog(title="Open dot File",
2082
-                                        action=gtk.FILE_CHOOSER_ACTION_OPEN,
2083
-                                        buttons=(gtk.STOCK_CANCEL,
2084
-                                                 gtk.RESPONSE_CANCEL,
2085
-                                                 gtk.STOCK_OPEN,
2086
-                                                 gtk.RESPONSE_OK))
2087
-        chooser.set_default_response(gtk.RESPONSE_OK)
2076
+        chooser = Gtk.FileChooserDialog(title="Open dot File",
2077
+                                        action=Gtk.FileChooserAction.OPEN,
2078
+                                        buttons=(Gtk.STOCK_CANCEL,
2079
+                                                 Gtk.ResponseType.CANCEL,
2080
+                                                 Gtk.STOCK_OPEN,
2081
+                                                 Gtk.ResponseType.OK))
2082
+        chooser.set_default_response(Gtk.ResponseType.OK)
2088 2083
         chooser.set_current_folder(self.last_open_dir)
2089
-        filter = gtk.FileFilter()
2084
+        filter = Gtk.FileFilter()
2090 2085
         filter.set_name("Graphviz dot files")
2091 2086
         filter.add_pattern("*.dot")
2092 2087
         chooser.add_filter(filter)
2093
-        filter = gtk.FileFilter()
2088
+        filter = Gtk.FileFilter()
2094 2089
         filter.set_name("All files")
2095 2090
         filter.add_pattern("*")
2096 2091
         chooser.add_filter(filter)
2097
-        if chooser.run() == gtk.RESPONSE_OK:
2092
+        if chooser.run() == Gtk.ResponseType.OK:
2098 2093
             filename = chooser.get_filename()
2099 2094
             self.last_open_dir = chooser.get_current_folder()
2100 2095
             chooser.destroy()
... ...
@@ -2103,7 +2098,7 @@ class DotWindow(gtk.Window):
2103 2098
             chooser.destroy()
2104 2099
 
2105 2100
     def on_reload(self, action):
2106
-        self.widget.reload()
2101
+        self.dotwidget.reload()
2107 2102
 
2108 2103
 
2109 2104
 class OptionParser(optparse.OptionParser):
... ...
@@ -2147,14 +2142,14 @@ Shortcuts:
2147 2142
         parser.error('incorrect number of arguments')
2148 2143
 
2149 2144
     win = DotWindow()
2150
-    win.connect('destroy', gtk.main_quit)
2145
+    win.connect('delete-event', Gtk.main_quit)
2151 2146
     win.set_filter(options.filter)
2152 2147
     if len(args) >= 1:
2153 2148
         if args[0] == '-':
2154 2149
             win.set_dotcode(sys.stdin.read())
2155 2150
         else:
2156 2151
             win.open_file(args[0])
2157
-    gtk.main()
2152
+    Gtk.main()
2158 2153
 
2159 2154
 
2160 2155
 # Apache-Style Software License for ColorBrewer software and ColorBrewer Color