2c81d3fe46943fa5288d42bc8f89455825b982bb
[platform/upstream/python-gobject.git] / gi / pygtkcompat.py
1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
3 #
4 # Copyright (C) 2011-2012 Johan Dahlin <johan@gnome.org>
5 #
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.
10 #
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.
15 #
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
19 # USA
20
21 """
22 PyGTK compatibility layer.
23
24 This modules goes a little bit longer to maintain PyGTK compatibility than
25 the normal overrides system.
26
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.
29
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.
32
33 """
34
35 import sys
36 import warnings
37
38 try:
39     # Python 3
40     from collections import UserList
41     from imp import reload
42     UserList  # pyflakes
43 except ImportError:
44     # Python 2 ships that in a different module
45     from UserList import UserList
46     UserList  # pyflakes
47
48 import gi
49 from gi.repository import GObject
50
51
52 def _install_enums(module, dest=None, strip=''):
53     if dest is None:
54         dest = module
55     modname = dest.__name__.rsplit('.', 1)[1].upper()
56     for attr in dir(module):
57         try:
58             obj = getattr(module, attr, None)
59         except:
60             continue
61         try:
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)
69         except TypeError:
70             continue
71         try:
72             if issubclass(obj, GObject.GFlags):
73                 for value, flag in obj.__flags_values__.items():
74                     name = flag.value_names[-1].replace(modname + '_', '')
75                     setattr(dest, name, flag)
76         except TypeError:
77             continue
78
79
80 def enable():
81     # gobject
82     from gi.repository import GLib
83     sys.modules['glib'] = GLib
84
85     # gobject
86     from gi.repository import GObject
87     sys.modules['gobject'] = GObject
88     from gi._gobject import propertyhelper
89     sys.modules['gobject.propertyhelper'] = propertyhelper
90
91     # gio
92     from gi.repository import Gio
93     sys.modules['gio'] = Gio
94
95 _unset = object()
96
97
98 def enable_gtk(version='2.0'):
99     # set the default encoding like PyGTK
100     reload(sys)
101     if sys.version_info < (3, 0):
102         sys.setdefaultencoding('utf-8')
103
104     # atk
105     gi.require_version('Atk', '1.0')
106     from gi.repository import Atk
107     sys.modules['atk'] = Atk
108     _install_enums(Atk)
109
110     # pango
111     gi.require_version('Pango', '1.0')
112     from gi.repository import Pango
113     sys.modules['pango'] = Pango
114     _install_enums(Pango)
115
116     # pangocairo
117     gi.require_version('PangoCairo', '1.0')
118     from gi.repository import PangoCairo
119     sys.modules['pangocairo'] = PangoCairo
120
121     # gdk
122     gi.require_version('Gdk', version)
123     gi.require_version('GdkPixbuf', '2.0')
124     from gi.repository import Gdk
125     from gi.repository import GdkPixbuf
126     sys.modules['gtk.gdk'] = Gdk
127     _install_enums(Gdk)
128     _install_enums(GdkPixbuf, dest=Gdk)
129     Gdk._2BUTTON_PRESS = 5
130     Gdk.BUTTON_PRESS = 4
131
132     Gdk.screen_get_default = Gdk.Screen.get_default
133     Gdk.Pixbuf = GdkPixbuf.Pixbuf
134     Gdk.PixbufLoader = GdkPixbuf.PixbufLoader.new_with_type
135     Gdk.pixbuf_new_from_data = GdkPixbuf.Pixbuf.new_from_data
136     Gdk.pixbuf_new_from_file = GdkPixbuf.Pixbuf.new_from_file
137     Gdk.pixbuf_new_from_file_at_scale = GdkPixbuf.Pixbuf.new_from_file_at_scale
138     Gdk.pixbuf_new_from_file_at_size = GdkPixbuf.Pixbuf.new_from_file_at_size
139     Gdk.pixbuf_new_from_inline = GdkPixbuf.Pixbuf.new_from_inline
140     Gdk.pixbuf_new_from_stream = GdkPixbuf.Pixbuf.new_from_stream
141     Gdk.pixbuf_new_from_stream_at_scale = GdkPixbuf.Pixbuf.new_from_stream_at_scale
142     Gdk.pixbuf_new_from_xpm_data = GdkPixbuf.Pixbuf.new_from_xpm_data
143     Gdk.pixbuf_get_file_info = GdkPixbuf.Pixbuf.get_file_info
144
145     orig_get_formats = GdkPixbuf.Pixbuf.get_formats
146
147     def get_formats():
148         formats = orig_get_formats()
149         result = []
150
151         def make_dict(format_):
152             result = {}
153             result['description'] = format_.get_description()
154             result['name'] = format_.get_name()
155             result['mime_types'] = format_.get_mime_types()
156             result['extensions'] = format_.get_extensions()
157             return result
158
159         for format_ in formats:
160             result.append(make_dict(format_))
161         return result
162
163     Gdk.pixbuf_get_formats = get_formats
164
165     orig_get_frame_extents = Gdk.Window.get_frame_extents
166
167     def get_frame_extents(window):
168         try:
169             try:
170                 rect = Gdk.Rectangle(0, 0, 0, 0)
171             except TypeError:
172                 rect = Gdk.Rectangle()
173             orig_get_frame_extents(window, rect)
174         except TypeError:
175             rect = orig_get_frame_extents(window)
176         return rect
177     Gdk.Window.get_frame_extents = get_frame_extents
178
179     orig_get_origin = Gdk.Window.get_origin
180
181     def get_origin(self):
182         return orig_get_origin(self)[1:]
183     Gdk.Window.get_origin = get_origin
184
185     Gdk.screen_width = Gdk.Screen.width
186     Gdk.screen_height = Gdk.Screen.height
187
188     # gtk
189     gi.require_version('Gtk', version)
190     from gi.repository import Gtk
191     sys.modules['gtk'] = Gtk
192     Gtk.gdk = Gdk
193
194     Gtk.pygtk_version = (2, 99, 0)
195
196     Gtk.gtk_version = (Gtk.MAJOR_VERSION,
197                        Gtk.MINOR_VERSION,
198                        Gtk.MICRO_VERSION)
199     _install_enums(Gtk)
200
201     # Action
202
203     def set_tool_item_type(menuaction, gtype):
204         warnings.warn('set_tool_item_type() is not supported',
205                       DeprecationWarning, stacklevel=2)
206     Gtk.Action.set_tool_item_type = classmethod(set_tool_item_type)
207
208     # Alignment
209
210     orig_Alignment = Gtk.Alignment
211
212     class Alignment(orig_Alignment):
213         def __init__(self, xalign=0.0, yalign=0.0, xscale=0.0, yscale=0.0):
214             orig_Alignment.__init__(self)
215             self.props.xalign = xalign
216             self.props.yalign = yalign
217             self.props.xscale = xscale
218             self.props.yscale = yscale
219
220     Gtk.Alignment = Alignment
221
222     # Box
223
224     orig_pack_end = Gtk.Box.pack_end
225
226     def pack_end(self, child, expand=True, fill=True, padding=0):
227         orig_pack_end(self, child, expand, fill, padding)
228     Gtk.Box.pack_end = pack_end
229
230     orig_pack_start = Gtk.Box.pack_start
231
232     def pack_start(self, child, expand=True, fill=True, padding=0):
233         orig_pack_start(self, child, expand, fill, padding)
234     Gtk.Box.pack_start = pack_start
235
236     # TreeViewColumn
237
238     orig_tree_view_column_pack_end = Gtk.TreeViewColumn.pack_end
239
240     def tree_view_column_pack_end(self, cell, expand=True):
241         orig_tree_view_column_pack_end(self, cell, expand)
242     Gtk.TreeViewColumn.pack_end = tree_view_column_pack_end
243
244     orig_tree_view_column_pack_start = Gtk.TreeViewColumn.pack_start
245
246     def tree_view_column_pack_start(self, cell, expand=True):
247         orig_tree_view_column_pack_start(self, cell, expand)
248     Gtk.TreeViewColumn.pack_start = tree_view_column_pack_start
249
250     # CellLayout
251
252     orig_cell_pack_end = Gtk.CellLayout.pack_end
253
254     def cell_pack_end(self, cell, expand=True):
255         orig_cell_pack_end(self, cell, expand)
256     Gtk.CellLayout.pack_end = cell_pack_end
257
258     orig_cell_pack_start = Gtk.CellLayout.pack_start
259
260     def cell_pack_start(self, cell, expand=True):
261         orig_cell_pack_start(self, cell, expand)
262     Gtk.CellLayout.pack_start = cell_pack_start
263
264     orig_set_cell_data_func = Gtk.CellLayout.set_cell_data_func
265
266     def set_cell_data_func(self, cell, func, user_data=_unset):
267         def callback(*args):
268             if args[-1] == _unset:
269                 args = args[:-1]
270             return func(*args)
271         orig_set_cell_data_func(self, cell, callback, user_data)
272     Gtk.CellLayout.set_cell_data_func = set_cell_data_func
273
274     # CellRenderer
275
276     class GenericCellRenderer(Gtk.CellRenderer):
277         pass
278     Gtk.GenericCellRenderer = GenericCellRenderer
279
280     # ComboBox
281
282     orig_combo_row_separator_func = Gtk.ComboBox.set_row_separator_func
283
284     def combo_row_separator_func(self, func, user_data=_unset):
285         def callback(*args):
286             if args[-1] == _unset:
287                 args = args[:-1]
288             return func(*args)
289         orig_combo_row_separator_func(self, callback, user_data)
290     Gtk.ComboBox.set_row_separator_func = combo_row_separator_func
291
292     # ComboBoxEntry
293
294     class ComboBoxEntry(Gtk.ComboBox):
295         def __init__(self, **kwds):
296             Gtk.ComboBox.__init__(self, has_entry=True, **kwds)
297
298         def set_text_column(self, text_column):
299             self.set_entry_text_column(text_column)
300
301         def get_text_column(self):
302             return self.get_entry_text_column()
303     Gtk.ComboBoxEntry = ComboBoxEntry
304
305     def combo_box_entry_new():
306         return Gtk.ComboBoxEntry()
307     Gtk.combo_box_entry_new = combo_box_entry_new
308
309     def combo_box_entry_new_with_model(model):
310         return Gtk.ComboBoxEntry(model=model)
311     Gtk.combo_box_entry_new_with_model = combo_box_entry_new_with_model
312
313     # Container
314
315     def install_child_property(container, flag, pspec):
316         warnings.warn('install_child_property() is not supported',
317                       DeprecationWarning, stacklevel=2)
318     Gtk.Container.install_child_property = classmethod(install_child_property)
319
320     def new_text():
321         combo = Gtk.ComboBox()
322         model = Gtk.ListStore(str)
323         combo.set_model(model)
324         combo.set_entry_text_column(0)
325         return combo
326     Gtk.combo_box_new_text = new_text
327
328     def append_text(self, text):
329         model = self.get_model()
330         model.append([text])
331     Gtk.ComboBox.append_text = append_text
332     Gtk.expander_new_with_mnemonic = Gtk.Expander.new_with_mnemonic
333     Gtk.icon_theme_get_default = Gtk.IconTheme.get_default
334     Gtk.image_new_from_pixbuf = Gtk.Image.new_from_pixbuf
335     Gtk.image_new_from_stock = Gtk.Image.new_from_stock
336     Gtk.image_new_from_animation = Gtk.Image.new_from_animation
337     Gtk.image_new_from_icon_set = Gtk.Image.new_from_icon_set
338     Gtk.image_new_from_file = Gtk.Image.new_from_file
339     Gtk.settings_get_default = Gtk.Settings.get_default
340     Gtk.window_set_default_icon = Gtk.Window.set_default_icon
341     Gtk.clipboard_get = Gtk.Clipboard.get
342
343     #AccelGroup
344     Gtk.AccelGroup.connect_group = Gtk.AccelGroup.connect
345
346     #StatusIcon
347     Gtk.status_icon_position_menu = Gtk.StatusIcon.position_menu
348     Gtk.StatusIcon.set_tooltip = Gtk.StatusIcon.set_tooltip_text
349
350     # Scale
351
352     orig_HScale = Gtk.HScale
353     orig_VScale = Gtk.VScale
354
355     class HScale(orig_HScale):
356         def __init__(self, adjustment=None):
357             orig_HScale.__init__(self, adjustment=adjustment)
358     Gtk.HScale = HScale
359
360     class VScale(orig_VScale):
361         def __init__(self, adjustment=None):
362             orig_VScale.__init__(self, adjustment=adjustment)
363     Gtk.VScale = VScale
364
365     Gtk.stock_add = lambda items: None
366
367     # Widget
368
369     Gtk.widget_get_default_direction = Gtk.Widget.get_default_direction
370     orig_size_request = Gtk.Widget.size_request
371
372     def size_request(widget):
373         class SizeRequest(UserList):
374             def __init__(self, req):
375                 self.height = req.height
376                 self.width = req.width
377                 UserList.__init__(self, [self.width, self.height])
378         return SizeRequest(orig_size_request(widget))
379     Gtk.Widget.size_request = size_request
380     Gtk.Widget.hide_all = Gtk.Widget.hide
381
382     class BaseGetter(object):
383         def __init__(self, context):
384             self.context = context
385
386         def __getitem__(self, state):
387             color = self.context.get_background_color(state)
388             return Gdk.Color(red=int(color.red * 65535),
389                              green=int(color.green * 65535),
390                              blue=int(color.blue * 65535))
391
392     class Styles(object):
393         def __init__(self, widget):
394             context = widget.get_style_context()
395             self.base = BaseGetter(context)
396             self.black = Gdk.Color(red=0, green=0, blue=0)
397
398     class StyleDescriptor(object):
399         def __get__(self, instance, class_):
400             return Styles(instance)
401     Gtk.Widget.style = StyleDescriptor()
402
403     # gtk.unixprint
404
405     class UnixPrint(object):
406         pass
407     unixprint = UnixPrint()
408     sys.modules['gtkunixprint'] = unixprint
409
410     # gtk.keysyms
411
412     class Keysyms(object):
413         pass
414     keysyms = Keysyms()
415     sys.modules['gtk.keysyms'] = keysyms
416     Gtk.keysyms = keysyms
417     for name in dir(Gdk):
418         if name.startswith('KEY_'):
419             target = name[4:]
420             if target[0] in '0123456789':
421                 target = '_' + target
422             value = getattr(Gdk, name)
423             setattr(keysyms, target, value)
424
425
426 def enable_vte():
427     gi.require_version('Vte', '0.0')
428     from gi.repository import Vte
429     sys.modules['vte'] = Vte
430
431
432 def enable_poppler():
433     gi.require_version('Poppler', '0.18')
434     from gi.repository import Poppler
435     sys.modules['poppler'] = Poppler
436     Poppler.pypoppler_version = (1, 0, 0)
437
438
439 def enable_webkit(version='1.0'):
440     gi.require_version('WebKit', version)
441     from gi.repository import WebKit
442     sys.modules['webkit'] = WebKit
443     WebKit.WebView.get_web_inspector = WebKit.WebView.get_inspector
444
445
446 def enable_gudev():
447     gi.require_version('GUdev', '1.0')
448     from gi.repository import GUdev
449     sys.modules['gudev'] = GUdev
450
451
452 def enable_gst():
453     gi.require_version('Gst', '0.10')
454     from gi.repository import Gst
455     sys.modules['gst'] = Gst
456     _install_enums(Gst)
457     Gst.registry_get_default = Gst.Registry.get_default
458     Gst.element_register = Gst.Element.register
459     Gst.element_factory_make = Gst.ElementFactory.make
460     Gst.caps_new_any = Gst.Caps.new_any
461     Gst.get_pygst_version = lambda: (0, 10, 19)
462     Gst.get_gst_version = lambda: (0, 10, 40)
463
464     from gi.repository import GstInterfaces
465     sys.modules['gst.interfaces'] = GstInterfaces
466     _install_enums(GstInterfaces)
467
468     from gi.repository import GstAudio
469     sys.modules['gst.audio'] = GstAudio
470     _install_enums(GstAudio)
471
472     from gi.repository import GstVideo
473     sys.modules['gst.video'] = GstVideo
474     _install_enums(GstVideo)
475
476     from gi.repository import GstBase
477     sys.modules['gst.base'] = GstBase
478     _install_enums(GstBase)
479
480     Gst.BaseTransform = GstBase.BaseTransform
481     Gst.BaseSink = GstBase.BaseSink
482
483     from gi.repository import GstController
484     sys.modules['gst.controller'] = GstController
485     _install_enums(GstController, dest=Gst)
486
487     from gi.repository import GstPbutils
488     sys.modules['gst.pbutils'] = GstPbutils
489     _install_enums(GstPbutils)
490
491
492 def enable_goocanvas():
493     gi.require_version('GooCanvas', '2.0')
494     from gi.repository import GooCanvas
495     sys.modules['goocanvas'] = GooCanvas
496     _install_enums(GooCanvas, strip='GOO_CANVAS_')
497     GooCanvas.ItemSimple = GooCanvas.CanvasItemSimple
498     GooCanvas.Item = GooCanvas.CanvasItem
499     GooCanvas.Image = GooCanvas.CanvasImage
500     GooCanvas.Group = GooCanvas.CanvasGroup
501     GooCanvas.Rect = GooCanvas.CanvasRect