1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
4 # Copyright (C) 2011-2012 Johan Dahlin <johan@gnome.org>
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 PyGTK compatibility layer.
24 This modules goes a little bit longer to maintain PyGTK compatibility than
25 the normal overrides system.
27 It is recommended to not depend on this layer, but only use it as an
28 intermediate step when porting your application to PyGI.
30 Compatibility might never be 100%, but the aim is to make it possible to run
31 a well behaved PyGTK application mostly unmodified on top of PyGI.
40 from collections import UserList
41 from imp import reload
44 # Python 2 ships that in a different module
45 from UserList import UserList
49 from gi.repository import GObject
52 def _install_enums(module, dest=None, strip=''):
55 modname = dest.__name__.rsplit('.', 1)[1].upper()
56 for attr in dir(module):
58 obj = getattr(module, attr, None)
62 if issubclass(obj, GObject.GEnum):
63 for value, enum in obj.__enum_values__.items():
64 name = enum.value_name
65 name = name.replace(modname + '_', '')
66 if strip and name.startswith(strip):
67 name = name[len(strip):]
68 setattr(dest, name, enum)
72 if issubclass(obj, GObject.GFlags):
73 for value, flag in obj.__flags_values__.items():
75 name = flag.value_names[-1].replace(modname + '_', '')
77 # FIXME: this happens for some large flags which do not
78 # fit into a long on 32 bit systems
80 setattr(dest, name, flag)
87 from gi.repository import GLib
88 sys.modules['glib'] = GLib
91 from gi.repository import GObject
92 sys.modules['gobject'] = GObject
93 from gi._gobject import propertyhelper
94 sys.modules['gobject.propertyhelper'] = propertyhelper
97 from gi.repository import Gio
98 sys.modules['gio'] = Gio
103 def enable_gtk(version='2.0'):
104 # set the default encoding like PyGTK
106 if sys.version_info < (3, 0):
107 sys.setdefaultencoding('utf-8')
110 gi.require_version('Atk', '1.0')
111 from gi.repository import Atk
112 sys.modules['atk'] = Atk
116 gi.require_version('Pango', '1.0')
117 from gi.repository import Pango
118 sys.modules['pango'] = Pango
119 _install_enums(Pango)
122 gi.require_version('PangoCairo', '1.0')
123 from gi.repository import PangoCairo
124 sys.modules['pangocairo'] = PangoCairo
127 gi.require_version('Gdk', version)
128 gi.require_version('GdkPixbuf', '2.0')
129 from gi.repository import Gdk
130 from gi.repository import GdkPixbuf
131 sys.modules['gtk.gdk'] = Gdk
133 _install_enums(GdkPixbuf, dest=Gdk)
134 Gdk._2BUTTON_PRESS = 5
137 Gdk.screen_get_default = Gdk.Screen.get_default
138 Gdk.Pixbuf = GdkPixbuf.Pixbuf
139 Gdk.PixbufLoader = GdkPixbuf.PixbufLoader.new_with_type
140 Gdk.pixbuf_new_from_data = GdkPixbuf.Pixbuf.new_from_data
141 Gdk.pixbuf_new_from_file = GdkPixbuf.Pixbuf.new_from_file
142 Gdk.pixbuf_new_from_file_at_scale = GdkPixbuf.Pixbuf.new_from_file_at_scale
143 Gdk.pixbuf_new_from_file_at_size = GdkPixbuf.Pixbuf.new_from_file_at_size
144 Gdk.pixbuf_new_from_inline = GdkPixbuf.Pixbuf.new_from_inline
145 Gdk.pixbuf_new_from_stream = GdkPixbuf.Pixbuf.new_from_stream
146 Gdk.pixbuf_new_from_stream_at_scale = GdkPixbuf.Pixbuf.new_from_stream_at_scale
147 Gdk.pixbuf_new_from_xpm_data = GdkPixbuf.Pixbuf.new_from_xpm_data
148 Gdk.pixbuf_get_file_info = GdkPixbuf.Pixbuf.get_file_info
150 orig_get_formats = GdkPixbuf.Pixbuf.get_formats
153 formats = orig_get_formats()
156 def make_dict(format_):
158 result['description'] = format_.get_description()
159 result['name'] = format_.get_name()
160 result['mime_types'] = format_.get_mime_types()
161 result['extensions'] = format_.get_extensions()
164 for format_ in formats:
165 result.append(make_dict(format_))
168 Gdk.pixbuf_get_formats = get_formats
170 orig_get_frame_extents = Gdk.Window.get_frame_extents
172 def get_frame_extents(window):
175 rect = Gdk.Rectangle(0, 0, 0, 0)
177 rect = Gdk.Rectangle()
178 orig_get_frame_extents(window, rect)
180 rect = orig_get_frame_extents(window)
182 Gdk.Window.get_frame_extents = get_frame_extents
184 orig_get_origin = Gdk.Window.get_origin
186 def get_origin(self):
187 return orig_get_origin(self)[1:]
188 Gdk.Window.get_origin = get_origin
190 Gdk.screen_width = Gdk.Screen.width
191 Gdk.screen_height = Gdk.Screen.height
194 gi.require_version('Gtk', version)
195 from gi.repository import Gtk
196 sys.modules['gtk'] = Gtk
199 Gtk.pygtk_version = (2, 99, 0)
201 Gtk.gtk_version = (Gtk.MAJOR_VERSION,
208 def set_tool_item_type(menuaction, gtype):
209 warnings.warn('set_tool_item_type() is not supported',
210 gi.PyGIDeprecationWarning, stacklevel=2)
211 Gtk.Action.set_tool_item_type = classmethod(set_tool_item_type)
215 orig_Alignment = Gtk.Alignment
217 class Alignment(orig_Alignment):
218 def __init__(self, xalign=0.0, yalign=0.0, xscale=0.0, yscale=0.0):
219 orig_Alignment.__init__(self)
220 self.props.xalign = xalign
221 self.props.yalign = yalign
222 self.props.xscale = xscale
223 self.props.yscale = yscale
225 Gtk.Alignment = Alignment
229 orig_pack_end = Gtk.Box.pack_end
231 def pack_end(self, child, expand=True, fill=True, padding=0):
232 orig_pack_end(self, child, expand, fill, padding)
233 Gtk.Box.pack_end = pack_end
235 orig_pack_start = Gtk.Box.pack_start
237 def pack_start(self, child, expand=True, fill=True, padding=0):
238 orig_pack_start(self, child, expand, fill, padding)
239 Gtk.Box.pack_start = pack_start
243 orig_tree_view_column_pack_end = Gtk.TreeViewColumn.pack_end
245 def tree_view_column_pack_end(self, cell, expand=True):
246 orig_tree_view_column_pack_end(self, cell, expand)
247 Gtk.TreeViewColumn.pack_end = tree_view_column_pack_end
249 orig_tree_view_column_pack_start = Gtk.TreeViewColumn.pack_start
251 def tree_view_column_pack_start(self, cell, expand=True):
252 orig_tree_view_column_pack_start(self, cell, expand)
253 Gtk.TreeViewColumn.pack_start = tree_view_column_pack_start
257 orig_cell_pack_end = Gtk.CellLayout.pack_end
259 def cell_pack_end(self, cell, expand=True):
260 orig_cell_pack_end(self, cell, expand)
261 Gtk.CellLayout.pack_end = cell_pack_end
263 orig_cell_pack_start = Gtk.CellLayout.pack_start
265 def cell_pack_start(self, cell, expand=True):
266 orig_cell_pack_start(self, cell, expand)
267 Gtk.CellLayout.pack_start = cell_pack_start
269 orig_set_cell_data_func = Gtk.CellLayout.set_cell_data_func
271 def set_cell_data_func(self, cell, func, user_data=_unset):
273 if args[-1] == _unset:
276 orig_set_cell_data_func(self, cell, callback, user_data)
277 Gtk.CellLayout.set_cell_data_func = set_cell_data_func
281 class GenericCellRenderer(Gtk.CellRenderer):
283 Gtk.GenericCellRenderer = GenericCellRenderer
287 orig_combo_row_separator_func = Gtk.ComboBox.set_row_separator_func
289 def combo_row_separator_func(self, func, user_data=_unset):
291 if args[-1] == _unset:
294 orig_combo_row_separator_func(self, callback, user_data)
295 Gtk.ComboBox.set_row_separator_func = combo_row_separator_func
299 class ComboBoxEntry(Gtk.ComboBox):
300 def __init__(self, **kwds):
301 Gtk.ComboBox.__init__(self, has_entry=True, **kwds)
303 def set_text_column(self, text_column):
304 self.set_entry_text_column(text_column)
306 def get_text_column(self):
307 return self.get_entry_text_column()
308 Gtk.ComboBoxEntry = ComboBoxEntry
310 def combo_box_entry_new():
311 return Gtk.ComboBoxEntry()
312 Gtk.combo_box_entry_new = combo_box_entry_new
314 def combo_box_entry_new_with_model(model):
315 return Gtk.ComboBoxEntry(model=model)
316 Gtk.combo_box_entry_new_with_model = combo_box_entry_new_with_model
320 def install_child_property(container, flag, pspec):
321 warnings.warn('install_child_property() is not supported',
322 gi.PyGIDeprecationWarning, stacklevel=2)
323 Gtk.Container.install_child_property = classmethod(install_child_property)
326 combo = Gtk.ComboBox()
327 model = Gtk.ListStore(str)
328 combo.set_model(model)
329 combo.set_entry_text_column(0)
331 Gtk.combo_box_new_text = new_text
333 def append_text(self, text):
334 model = self.get_model()
336 Gtk.ComboBox.append_text = append_text
337 Gtk.expander_new_with_mnemonic = Gtk.Expander.new_with_mnemonic
338 Gtk.icon_theme_get_default = Gtk.IconTheme.get_default
339 Gtk.image_new_from_pixbuf = Gtk.Image.new_from_pixbuf
340 Gtk.image_new_from_stock = Gtk.Image.new_from_stock
341 Gtk.image_new_from_animation = Gtk.Image.new_from_animation
342 Gtk.image_new_from_icon_set = Gtk.Image.new_from_icon_set
343 Gtk.image_new_from_file = Gtk.Image.new_from_file
344 Gtk.settings_get_default = Gtk.Settings.get_default
345 Gtk.window_set_default_icon = Gtk.Window.set_default_icon
346 Gtk.clipboard_get = Gtk.Clipboard.get
349 Gtk.AccelGroup.connect_group = Gtk.AccelGroup.connect
352 Gtk.status_icon_position_menu = Gtk.StatusIcon.position_menu
353 Gtk.StatusIcon.set_tooltip = Gtk.StatusIcon.set_tooltip_text
357 orig_HScale = Gtk.HScale
358 orig_VScale = Gtk.VScale
360 class HScale(orig_HScale):
361 def __init__(self, adjustment=None):
362 orig_HScale.__init__(self, adjustment=adjustment)
365 class VScale(orig_VScale):
366 def __init__(self, adjustment=None):
367 orig_VScale.__init__(self, adjustment=adjustment)
370 Gtk.stock_add = lambda items: None
374 Gtk.widget_get_default_direction = Gtk.Widget.get_default_direction
375 orig_size_request = Gtk.Widget.size_request
377 def size_request(widget):
378 class SizeRequest(UserList):
379 def __init__(self, req):
380 self.height = req.height
381 self.width = req.width
382 UserList.__init__(self, [self.width, self.height])
383 return SizeRequest(orig_size_request(widget))
384 Gtk.Widget.size_request = size_request
385 Gtk.Widget.hide_all = Gtk.Widget.hide
387 class BaseGetter(object):
388 def __init__(self, context):
389 self.context = context
391 def __getitem__(self, state):
392 color = self.context.get_background_color(state)
393 return Gdk.Color(red=int(color.red * 65535),
394 green=int(color.green * 65535),
395 blue=int(color.blue * 65535))
397 class Styles(object):
398 def __init__(self, widget):
399 context = widget.get_style_context()
400 self.base = BaseGetter(context)
401 self.black = Gdk.Color(red=0, green=0, blue=0)
403 class StyleDescriptor(object):
404 def __get__(self, instance, class_):
405 return Styles(instance)
406 Gtk.Widget.style = StyleDescriptor()
410 class UnixPrint(object):
412 unixprint = UnixPrint()
413 sys.modules['gtkunixprint'] = unixprint
417 class Keysyms(object):
420 sys.modules['gtk.keysyms'] = keysyms
421 Gtk.keysyms = keysyms
422 for name in dir(Gdk):
423 if name.startswith('KEY_'):
425 if target[0] in '0123456789':
426 target = '_' + target
427 value = getattr(Gdk, name)
428 setattr(keysyms, target, value)
432 gi.require_version('Vte', '0.0')
433 from gi.repository import Vte
434 sys.modules['vte'] = Vte
437 def enable_poppler():
438 gi.require_version('Poppler', '0.18')
439 from gi.repository import Poppler
440 sys.modules['poppler'] = Poppler
441 Poppler.pypoppler_version = (1, 0, 0)
444 def enable_webkit(version='1.0'):
445 gi.require_version('WebKit', version)
446 from gi.repository import WebKit
447 sys.modules['webkit'] = WebKit
448 WebKit.WebView.get_web_inspector = WebKit.WebView.get_inspector
452 gi.require_version('GUdev', '1.0')
453 from gi.repository import GUdev
454 sys.modules['gudev'] = GUdev
458 gi.require_version('Gst', '0.10')
459 from gi.repository import Gst
460 sys.modules['gst'] = Gst
462 Gst.registry_get_default = Gst.Registry.get_default
463 Gst.element_register = Gst.Element.register
464 Gst.element_factory_make = Gst.ElementFactory.make
465 Gst.caps_new_any = Gst.Caps.new_any
466 Gst.get_pygst_version = lambda: (0, 10, 19)
467 Gst.get_gst_version = lambda: (0, 10, 40)
469 from gi.repository import GstInterfaces
470 sys.modules['gst.interfaces'] = GstInterfaces
471 _install_enums(GstInterfaces)
473 from gi.repository import GstAudio
474 sys.modules['gst.audio'] = GstAudio
475 _install_enums(GstAudio)
477 from gi.repository import GstVideo
478 sys.modules['gst.video'] = GstVideo
479 _install_enums(GstVideo)
481 from gi.repository import GstBase
482 sys.modules['gst.base'] = GstBase
483 _install_enums(GstBase)
485 Gst.BaseTransform = GstBase.BaseTransform
486 Gst.BaseSink = GstBase.BaseSink
488 from gi.repository import GstController
489 sys.modules['gst.controller'] = GstController
490 _install_enums(GstController, dest=Gst)
492 from gi.repository import GstPbutils
493 sys.modules['gst.pbutils'] = GstPbutils
494 _install_enums(GstPbutils)
497 def enable_goocanvas():
498 gi.require_version('GooCanvas', '2.0')
499 from gi.repository import GooCanvas
500 sys.modules['goocanvas'] = GooCanvas
501 _install_enums(GooCanvas, strip='GOO_CANVAS_')
502 GooCanvas.ItemSimple = GooCanvas.CanvasItemSimple
503 GooCanvas.Item = GooCanvas.CanvasItem
504 GooCanvas.Image = GooCanvas.CanvasImage
505 GooCanvas.Group = GooCanvas.CanvasGroup
506 GooCanvas.Rect = GooCanvas.CanvasRect