Imported Upstream version 3.7.3
[platform/upstream/python-gobject.git] / pygtkcompat / 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                     try:
75                         name = flag.value_names[-1].replace(modname + '_', '')
76                     except IndexError:
77                         # FIXME: this happens for some large flags which do not
78                         # fit into a long on 32 bit systems
79                         continue
80                     setattr(dest, name, flag)
81         except TypeError:
82             continue
83
84
85 def enable():
86     # gobject
87     from gi.repository import GLib
88     sys.modules['glib'] = GLib
89
90     # gobject
91     from gi.repository import GObject
92     sys.modules['gobject'] = GObject
93     from gi._gobject import propertyhelper
94     sys.modules['gobject.propertyhelper'] = propertyhelper
95
96     # gio
97     from gi.repository import Gio
98     sys.modules['gio'] = Gio
99
100 _unset = object()
101
102
103 def enable_gtk(version='2.0'):
104     # set the default encoding like PyGTK
105     reload(sys)
106     if sys.version_info < (3, 0):
107         sys.setdefaultencoding('utf-8')
108
109     # atk
110     gi.require_version('Atk', '1.0')
111     from gi.repository import Atk
112     sys.modules['atk'] = Atk
113     _install_enums(Atk)
114
115     # pango
116     gi.require_version('Pango', '1.0')
117     from gi.repository import Pango
118     sys.modules['pango'] = Pango
119     _install_enums(Pango)
120
121     # pangocairo
122     gi.require_version('PangoCairo', '1.0')
123     from gi.repository import PangoCairo
124     sys.modules['pangocairo'] = PangoCairo
125
126     # gdk
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
132     _install_enums(Gdk)
133     _install_enums(GdkPixbuf, dest=Gdk)
134     Gdk._2BUTTON_PRESS = 5
135     Gdk.BUTTON_PRESS = 4
136
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
149
150     orig_get_formats = GdkPixbuf.Pixbuf.get_formats
151
152     def get_formats():
153         formats = orig_get_formats()
154         result = []
155
156         def make_dict(format_):
157             result = {}
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()
162             return result
163
164         for format_ in formats:
165             result.append(make_dict(format_))
166         return result
167
168     Gdk.pixbuf_get_formats = get_formats
169
170     orig_get_frame_extents = Gdk.Window.get_frame_extents
171
172     def get_frame_extents(window):
173         try:
174             try:
175                 rect = Gdk.Rectangle(0, 0, 0, 0)
176             except TypeError:
177                 rect = Gdk.Rectangle()
178             orig_get_frame_extents(window, rect)
179         except TypeError:
180             rect = orig_get_frame_extents(window)
181         return rect
182     Gdk.Window.get_frame_extents = get_frame_extents
183
184     orig_get_origin = Gdk.Window.get_origin
185
186     def get_origin(self):
187         return orig_get_origin(self)[1:]
188     Gdk.Window.get_origin = get_origin
189
190     Gdk.screen_width = Gdk.Screen.width
191     Gdk.screen_height = Gdk.Screen.height
192
193     # gtk
194     gi.require_version('Gtk', version)
195     from gi.repository import Gtk
196     sys.modules['gtk'] = Gtk
197     Gtk.gdk = Gdk
198
199     Gtk.pygtk_version = (2, 99, 0)
200
201     Gtk.gtk_version = (Gtk.MAJOR_VERSION,
202                        Gtk.MINOR_VERSION,
203                        Gtk.MICRO_VERSION)
204     _install_enums(Gtk)
205
206     # Action
207
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)
212
213     # Alignment
214
215     orig_Alignment = Gtk.Alignment
216
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
224
225     Gtk.Alignment = Alignment
226
227     # Box
228
229     orig_pack_end = Gtk.Box.pack_end
230
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
234
235     orig_pack_start = Gtk.Box.pack_start
236
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
240
241     # TreeViewColumn
242
243     orig_tree_view_column_pack_end = Gtk.TreeViewColumn.pack_end
244
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
248
249     orig_tree_view_column_pack_start = Gtk.TreeViewColumn.pack_start
250
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
254
255     # CellLayout
256
257     orig_cell_pack_end = Gtk.CellLayout.pack_end
258
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
262
263     orig_cell_pack_start = Gtk.CellLayout.pack_start
264
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
268
269     orig_set_cell_data_func = Gtk.CellLayout.set_cell_data_func
270
271     def set_cell_data_func(self, cell, func, user_data=_unset):
272         def callback(*args):
273             if args[-1] == _unset:
274                 args = args[:-1]
275             return func(*args)
276         orig_set_cell_data_func(self, cell, callback, user_data)
277     Gtk.CellLayout.set_cell_data_func = set_cell_data_func
278
279     # CellRenderer
280
281     class GenericCellRenderer(Gtk.CellRenderer):
282         pass
283     Gtk.GenericCellRenderer = GenericCellRenderer
284
285     # ComboBox
286
287     orig_combo_row_separator_func = Gtk.ComboBox.set_row_separator_func
288
289     def combo_row_separator_func(self, func, user_data=_unset):
290         def callback(*args):
291             if args[-1] == _unset:
292                 args = args[:-1]
293             return func(*args)
294         orig_combo_row_separator_func(self, callback, user_data)
295     Gtk.ComboBox.set_row_separator_func = combo_row_separator_func
296
297     # ComboBoxEntry
298
299     class ComboBoxEntry(Gtk.ComboBox):
300         def __init__(self, **kwds):
301             Gtk.ComboBox.__init__(self, has_entry=True, **kwds)
302
303         def set_text_column(self, text_column):
304             self.set_entry_text_column(text_column)
305
306         def get_text_column(self):
307             return self.get_entry_text_column()
308     Gtk.ComboBoxEntry = ComboBoxEntry
309
310     def combo_box_entry_new():
311         return Gtk.ComboBoxEntry()
312     Gtk.combo_box_entry_new = combo_box_entry_new
313
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
317
318     # Container
319
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)
324
325     def new_text():
326         combo = Gtk.ComboBox()
327         model = Gtk.ListStore(str)
328         combo.set_model(model)
329         combo.set_entry_text_column(0)
330         return combo
331     Gtk.combo_box_new_text = new_text
332
333     def append_text(self, text):
334         model = self.get_model()
335         model.append([text])
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
347
348     #AccelGroup
349     Gtk.AccelGroup.connect_group = Gtk.AccelGroup.connect
350
351     #StatusIcon
352     Gtk.status_icon_position_menu = Gtk.StatusIcon.position_menu
353     Gtk.StatusIcon.set_tooltip = Gtk.StatusIcon.set_tooltip_text
354
355     # Scale
356
357     orig_HScale = Gtk.HScale
358     orig_VScale = Gtk.VScale
359
360     class HScale(orig_HScale):
361         def __init__(self, adjustment=None):
362             orig_HScale.__init__(self, adjustment=adjustment)
363     Gtk.HScale = HScale
364
365     class VScale(orig_VScale):
366         def __init__(self, adjustment=None):
367             orig_VScale.__init__(self, adjustment=adjustment)
368     Gtk.VScale = VScale
369
370     Gtk.stock_add = lambda items: None
371
372     # Widget
373
374     Gtk.widget_get_default_direction = Gtk.Widget.get_default_direction
375     orig_size_request = Gtk.Widget.size_request
376
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
386
387     class BaseGetter(object):
388         def __init__(self, context):
389             self.context = context
390
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))
396
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)
402
403     class StyleDescriptor(object):
404         def __get__(self, instance, class_):
405             return Styles(instance)
406     Gtk.Widget.style = StyleDescriptor()
407
408     # gtk.unixprint
409
410     class UnixPrint(object):
411         pass
412     unixprint = UnixPrint()
413     sys.modules['gtkunixprint'] = unixprint
414
415     # gtk.keysyms
416
417     class Keysyms(object):
418         pass
419     keysyms = Keysyms()
420     sys.modules['gtk.keysyms'] = keysyms
421     Gtk.keysyms = keysyms
422     for name in dir(Gdk):
423         if name.startswith('KEY_'):
424             target = name[4:]
425             if target[0] in '0123456789':
426                 target = '_' + target
427             value = getattr(Gdk, name)
428             setattr(keysyms, target, value)
429
430
431 def enable_vte():
432     gi.require_version('Vte', '0.0')
433     from gi.repository import Vte
434     sys.modules['vte'] = Vte
435
436
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)
442
443
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
449
450
451 def enable_gudev():
452     gi.require_version('GUdev', '1.0')
453     from gi.repository import GUdev
454     sys.modules['gudev'] = GUdev
455
456
457 def enable_gst():
458     gi.require_version('Gst', '0.10')
459     from gi.repository import Gst
460     sys.modules['gst'] = Gst
461     _install_enums(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)
468
469     from gi.repository import GstInterfaces
470     sys.modules['gst.interfaces'] = GstInterfaces
471     _install_enums(GstInterfaces)
472
473     from gi.repository import GstAudio
474     sys.modules['gst.audio'] = GstAudio
475     _install_enums(GstAudio)
476
477     from gi.repository import GstVideo
478     sys.modules['gst.video'] = GstVideo
479     _install_enums(GstVideo)
480
481     from gi.repository import GstBase
482     sys.modules['gst.base'] = GstBase
483     _install_enums(GstBase)
484
485     Gst.BaseTransform = GstBase.BaseTransform
486     Gst.BaseSink = GstBase.BaseSink
487
488     from gi.repository import GstController
489     sys.modules['gst.controller'] = GstController
490     _install_enums(GstController, dest=Gst)
491
492     from gi.repository import GstPbutils
493     sys.modules['gst.pbutils'] = GstPbutils
494     _install_enums(GstPbutils)
495
496
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