05ef40393b9459ef4ba120c7ff93bf900a177f54
[platform/upstream/python-gobject.git] / gi / overrides / Gtk.py
1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
3 #
4 # Copyright (C) 2009 Johan Dahlin <johan@gnome.org>
5 #               2010 Simon van der Linden <svdlinden@src.gnome.org>
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
20 # USA
21
22 import collections
23 import sys
24 import warnings
25
26 from gi.repository import GObject
27 from ..overrides import override, strip_boolean_result, deprecated_init
28 from ..module import get_introspection_module
29 from gi import PyGIDeprecationWarning
30
31 if sys.version_info >= (3, 0):
32     _basestring = str
33     _callable = lambda c: hasattr(c, '__call__')
34 else:
35     _basestring = basestring
36     _callable = callable
37
38 Gtk = get_introspection_module('Gtk')
39
40 __all__ = []
41
42 if Gtk._version == '2.0':
43     warn_msg = "You have imported the Gtk 2.0 module.  Because Gtk 2.0 \
44 was not designed for use with introspection some of the \
45 interfaces and API will fail.  As such this is not supported \
46 by the pygobject development team and we encourage you to \
47 port your app to Gtk 3 or greater. PyGTK is the recomended \
48 python module to use with Gtk 2.0"
49
50     warnings.warn(warn_msg, RuntimeWarning)
51
52
53 class PyGTKDeprecationWarning(PyGIDeprecationWarning):
54     pass
55
56 __all__.append('PyGTKDeprecationWarning')
57
58
59 def _construct_target_list(targets):
60     """Create a list of TargetEntry items from a list of tuples in the form (target, flags, info)
61
62     The list can also contain existing TargetEntry items in which case the existing entry
63     is re-used in the return list.
64     """
65     target_entries = []
66     for entry in targets:
67         if not isinstance(entry, Gtk.TargetEntry):
68             entry = Gtk.TargetEntry.new(*entry)
69         target_entries.append(entry)
70     return target_entries
71
72 __all__.append('_construct_target_list')
73
74
75 def _extract_handler_and_args(obj_or_map, handler_name):
76     handler = None
77     if isinstance(obj_or_map, collections.Mapping):
78         handler = obj_or_map.get(handler_name, None)
79     else:
80         handler = getattr(obj_or_map, handler_name, None)
81
82     if handler is None:
83         raise AttributeError('Handler %s not found' % handler_name)
84
85     args = ()
86     if isinstance(handler, collections.Sequence):
87         if len(handler) == 0:
88             raise TypeError("Handler %s tuple can not be empty" % handler)
89         args = handler[1:]
90         handler = handler[0]
91
92     elif not _callable(handler):
93         raise TypeError('Handler %s is not a method, function or tuple' % handler)
94
95     return handler, args
96
97
98 # Exposed for unit-testing.
99 __all__.append('_extract_handler_and_args')
100
101
102 def _builder_connect_callback(builder, gobj, signal_name, handler_name, connect_obj, flags, obj_or_map):
103     handler, args = _extract_handler_and_args(obj_or_map, handler_name)
104
105     after = flags & GObject.ConnectFlags.AFTER
106     if connect_obj is not None:
107         if after:
108             gobj.connect_object_after(signal_name, handler, connect_obj, *args)
109         else:
110             gobj.connect_object(signal_name, handler, connect_obj, *args)
111     else:
112         if after:
113             gobj.connect_after(signal_name, handler, *args)
114         else:
115             gobj.connect(signal_name, handler, *args)
116
117
118 class Widget(Gtk.Widget):
119
120     translate_coordinates = strip_boolean_result(Gtk.Widget.translate_coordinates)
121
122     def drag_dest_set_target_list(self, target_list):
123         if (target_list is not None) and (not isinstance(target_list, Gtk.TargetList)):
124             target_list = Gtk.TargetList.new(_construct_target_list(target_list))
125         super(Widget, self).drag_dest_set_target_list(target_list)
126
127     def drag_source_set_target_list(self, target_list):
128         if (target_list is not None) and (not isinstance(target_list, Gtk.TargetList)):
129             target_list = Gtk.TargetList.new(_construct_target_list(target_list))
130         super(Widget, self).drag_source_set_target_list(target_list)
131
132     def style_get_property(self, property_name, value=None):
133         if value is None:
134             prop = self.find_style_property(property_name)
135             if prop is None:
136                 raise ValueError('Class "%s" does not contain style property "%s"' %
137                                  (self, property_name))
138             value = GObject.Value(prop.value_type)
139
140         Gtk.Widget.style_get_property(self, property_name, value)
141         return value.get_value()
142
143
144 Widget = override(Widget)
145 __all__.append('Widget')
146
147
148 class Container(Gtk.Container, Widget):
149
150     def __len__(self):
151         return len(self.get_children())
152
153     def __contains__(self, child):
154         return child in self.get_children()
155
156     def __iter__(self):
157         return iter(self.get_children())
158
159     def __bool__(self):
160         return True
161
162     # alias for Python 2.x object protocol
163     __nonzero__ = __bool__
164
165     get_focus_chain = strip_boolean_result(Gtk.Container.get_focus_chain)
166
167     def child_get_property(self, child, property_name, value=None):
168         if value is None:
169             prop = self.find_child_property(property_name)
170             if prop is None:
171                 raise ValueError('Class "%s" does not contain child property "%s"' %
172                                  (self, property_name))
173             value = GObject.Value(prop.value_type)
174
175         Gtk.Container.child_get_property(self, child, property_name, value)
176         return value.get_value()
177
178     def child_get(self, child, *prop_names):
179         """Returns a list of child property values for the given names."""
180         return [self.child_get_property(child, name) for name in prop_names]
181
182     def child_set(self, child, **kwargs):
183         """Set a child properties on the given child to key/value pairs."""
184         for name, value in kwargs.items():
185             name = name.replace('_', '-')
186             self.child_set_property(child, name, value)
187
188
189 Container = override(Container)
190 __all__.append('Container')
191
192
193 class Editable(Gtk.Editable):
194
195     def insert_text(self, text, position):
196         return super(Editable, self).insert_text(text, -1, position)
197
198     get_selection_bounds = strip_boolean_result(Gtk.Editable.get_selection_bounds, fail_ret=())
199
200
201 Editable = override(Editable)
202 __all__.append("Editable")
203
204
205 class Action(Gtk.Action):
206     __init__ = deprecated_init(Gtk.Action.__init__,
207                                arg_names=('name', 'label', 'tooltip', 'stock_id'),
208                                category=PyGTKDeprecationWarning)
209
210 Action = override(Action)
211 __all__.append("Action")
212
213
214 class RadioAction(Gtk.RadioAction):
215     __init__ = deprecated_init(Gtk.RadioAction.__init__,
216                                arg_names=('name', 'label', 'tooltip', 'stock_id', 'value'),
217                                category=PyGTKDeprecationWarning)
218
219 RadioAction = override(RadioAction)
220 __all__.append("RadioAction")
221
222
223 class ActionGroup(Gtk.ActionGroup):
224     __init__ = deprecated_init(Gtk.ActionGroup.__init__,
225                                arg_names=('name',),
226                                category=PyGTKDeprecationWarning)
227
228     def add_actions(self, entries, user_data=None):
229         """
230         The add_actions() method is a convenience method that creates a number
231         of gtk.Action  objects based on the information in the list of action
232         entry tuples contained in entries and adds them to the action group.
233         The entry tuples can vary in size from one to six items with the
234         following information:
235
236             * The name of the action. Must be specified.
237             * The stock id for the action. Optional with a default value of None
238               if a label is specified.
239             * The label for the action. This field should typically be marked
240               for translation, see the set_translation_domain() method. Optional
241               with a default value of None if a stock id is specified.
242             * The accelerator for the action, in the format understood by the
243               gtk.accelerator_parse() function. Optional with a default value of
244               None.
245             * The tooltip for the action. This field should typically be marked
246               for translation, see the set_translation_domain() method. Optional
247               with a default value of None.
248             * The callback function invoked when the action is activated.
249               Optional with a default value of None.
250
251         The "activate" signals of the actions are connected to the callbacks and
252         their accel paths are set to <Actions>/group-name/action-name.
253         """
254         try:
255             iter(entries)
256         except (TypeError):
257             raise TypeError('entries must be iterable')
258
259         def _process_action(name, stock_id=None, label=None, accelerator=None, tooltip=None, callback=None):
260             action = Action(name=name, label=label, tooltip=tooltip, stock_id=stock_id)
261             if callback is not None:
262                 if user_data is None:
263                     action.connect('activate', callback)
264                 else:
265                     action.connect('activate', callback, user_data)
266
267             self.add_action_with_accel(action, accelerator)
268
269         for e in entries:
270             # using inner function above since entries can leave out optional arguments
271             _process_action(*e)
272
273     def add_toggle_actions(self, entries, user_data=None):
274         """
275         The add_toggle_actions() method is a convenience method that creates a
276         number of gtk.ToggleAction objects based on the information in the list
277         of action entry tuples contained in entries and adds them to the action
278         group. The toggle action entry tuples can vary in size from one to seven
279         items with the following information:
280
281             * The name of the action. Must be specified.
282             * The stock id for the action. Optional with a default value of None
283               if a label is specified.
284             * The label for the action. This field should typically be marked
285               for translation, see the set_translation_domain() method. Optional
286               with a default value of None if a stock id is specified.
287             * The accelerator for the action, in the format understood by the
288               gtk.accelerator_parse() function. Optional with a default value of
289               None.
290             * The tooltip for the action. This field should typically be marked
291               for translation, see the set_translation_domain() method. Optional
292               with a default value of None.
293             * The callback function invoked when the action is activated.
294               Optional with a default value of None.
295             * A flag indicating whether the toggle action is active. Optional
296               with a default value of False.
297
298         The "activate" signals of the actions are connected to the callbacks and
299         their accel paths are set to <Actions>/group-name/action-name.
300         """
301
302         try:
303             iter(entries)
304         except (TypeError):
305             raise TypeError('entries must be iterable')
306
307         def _process_action(name, stock_id=None, label=None, accelerator=None, tooltip=None, callback=None, is_active=False):
308             action = Gtk.ToggleAction(name=name, label=label, tooltip=tooltip, stock_id=stock_id)
309             action.set_active(is_active)
310             if callback is not None:
311                 if user_data is None:
312                     action.connect('activate', callback)
313                 else:
314                     action.connect('activate', callback, user_data)
315
316             self.add_action_with_accel(action, accelerator)
317
318         for e in entries:
319             # using inner function above since entries can leave out optional arguments
320             _process_action(*e)
321
322     def add_radio_actions(self, entries, value=None, on_change=None, user_data=None):
323         """
324         The add_radio_actions() method is a convenience method that creates a
325         number of gtk.RadioAction objects based on the information in the list
326         of action entry tuples contained in entries and adds them to the action
327         group. The entry tuples can vary in size from one to six items with the
328         following information:
329
330             * The name of the action. Must be specified.
331             * The stock id for the action. Optional with a default value of None
332               if a label is specified.
333             * The label for the action. This field should typically be marked
334               for translation, see the set_translation_domain() method. Optional
335               with a default value of None if a stock id is specified.
336             * The accelerator for the action, in the format understood by the
337               gtk.accelerator_parse() function. Optional with a default value of
338               None.
339             * The tooltip for the action. This field should typically be marked
340               for translation, see the set_translation_domain() method. Optional
341               with a default value of None.
342             * The value to set on the radio action. Optional with a default
343               value of 0. Should be specified in applications.
344
345         The value parameter specifies the radio action that should be set
346         active. The "changed" signal of the first radio action is connected to
347         the on_change callback (if specified and not None) and the accel paths
348         of the actions are set to <Actions>/group-name/action-name.
349         """
350         try:
351             iter(entries)
352         except (TypeError):
353             raise TypeError('entries must be iterable')
354
355         first_action = None
356
357         def _process_action(group_source, name, stock_id=None, label=None, accelerator=None, tooltip=None, entry_value=0):
358             action = RadioAction(name=name, label=label, tooltip=tooltip, stock_id=stock_id, value=entry_value)
359
360             # FIXME: join_group is a patch to Gtk+ 3.0
361             #        otherwise we can't effectively add radio actions to a
362             #        group.  Should we depend on 3.0 and error out here
363             #        or should we offer the functionality via a compat
364             #        C module?
365             if hasattr(action, 'join_group'):
366                 action.join_group(group_source)
367
368             if value == entry_value:
369                 action.set_active(True)
370
371             self.add_action_with_accel(action, accelerator)
372             return action
373
374         for e in entries:
375             # using inner function above since entries can leave out optional arguments
376             action = _process_action(first_action, *e)
377             if first_action is None:
378                 first_action = action
379
380         if first_action is not None and on_change is not None:
381             if user_data is None:
382                 first_action.connect('changed', on_change)
383             else:
384                 first_action.connect('changed', on_change, user_data)
385
386 ActionGroup = override(ActionGroup)
387 __all__.append('ActionGroup')
388
389
390 class UIManager(Gtk.UIManager):
391     def add_ui_from_string(self, buffer):
392         if not isinstance(buffer, _basestring):
393             raise TypeError('buffer must be a string')
394
395         length = len(buffer.encode('UTF-8'))
396
397         return Gtk.UIManager.add_ui_from_string(self, buffer, length)
398
399     def insert_action_group(self, buffer, length=-1):
400         return Gtk.UIManager.insert_action_group(self, buffer, length)
401
402 UIManager = override(UIManager)
403 __all__.append('UIManager')
404
405
406 class ComboBox(Gtk.ComboBox, Container):
407     get_active_iter = strip_boolean_result(Gtk.ComboBox.get_active_iter)
408
409 ComboBox = override(ComboBox)
410 __all__.append('ComboBox')
411
412
413 class Box(Gtk.Box):
414     __init__ = deprecated_init(Gtk.Box.__init__,
415                                arg_names=('homogeneous', 'spacing'),
416                                category=PyGTKDeprecationWarning)
417
418 Box = override(Box)
419 __all__.append('Box')
420
421
422 class SizeGroup(Gtk.SizeGroup):
423     __init__ = deprecated_init(Gtk.SizeGroup.__init__,
424                                arg_names=('mode',),
425                                deprecated_defaults={'mode': Gtk.SizeGroupMode.VERTICAL},
426                                category=PyGTKDeprecationWarning)
427
428 SizeGroup = override(SizeGroup)
429 __all__.append('SizeGroup')
430
431
432 class MenuItem(Gtk.MenuItem):
433     __init__ = deprecated_init(Gtk.MenuItem.__init__,
434                                arg_names=('label',),
435                                category=PyGTKDeprecationWarning)
436
437 MenuItem = override(MenuItem)
438 __all__.append('MenuItem')
439
440
441 class Builder(Gtk.Builder):
442     def connect_signals(self, obj_or_map):
443         """Connect signals specified by this builder to a name, handler mapping.
444
445         Connect signal, name, and handler sets specified in the builder with
446         the given mapping "obj_or_map". The handler/value aspect of the mapping
447         can also contain a tuple in the form of (handler [,arg1 [,argN]])
448         allowing for extra arguments to be passed to the handler. For example:
449
450         .. code-block:: python
451
452             builder.connect_signals({'on_clicked': (on_clicked, arg1, arg2)})
453         """
454         self.connect_signals_full(_builder_connect_callback, obj_or_map)
455
456     def add_from_string(self, buffer):
457         if not isinstance(buffer, _basestring):
458             raise TypeError('buffer must be a string')
459
460         length = len(buffer)
461
462         return Gtk.Builder.add_from_string(self, buffer, length)
463
464     def add_objects_from_string(self, buffer, object_ids):
465         if not isinstance(buffer, _basestring):
466             raise TypeError('buffer must be a string')
467
468         length = len(buffer)
469
470         return Gtk.Builder.add_objects_from_string(self, buffer, length, object_ids)
471
472 Builder = override(Builder)
473 __all__.append('Builder')
474
475
476 # NOTE: This must come before any other Window/Dialog subclassing, to ensure
477 # that we have a correct inheritance hierarchy.
478
479
480 class Window(Gtk.Window):
481     __init__ = deprecated_init(Gtk.Window.__init__,
482                                arg_names=('type',),
483                                category=PyGTKDeprecationWarning)
484
485 Window = override(Window)
486 __all__.append('Window')
487
488
489 class Dialog(Gtk.Dialog, Container):
490     _old_arg_names = ('title', 'parent', 'flags', 'buttons', '_buttons_property')
491     _init = deprecated_init(Gtk.Dialog.__init__,
492                             arg_names=('title', 'transient_for', 'flags',
493                                        'add_buttons', 'buttons'),
494                             ignore=('flags', 'add_buttons'),
495                             deprecated_aliases={'transient_for': 'parent',
496                                                 'buttons': '_buttons_property'},
497                             category=PyGTKDeprecationWarning)
498
499     def __init__(self, *args, **kwargs):
500
501         new_kwargs = kwargs.copy()
502         old_kwargs = dict(zip(self._old_arg_names, args))
503         old_kwargs.update(kwargs)
504
505         # Increment the warning stacklevel for sub-classes which implement their own __init__.
506         stacklevel = 2
507         if self.__class__ != Dialog and self.__class__.__init__ != Dialog.__init__:
508             stacklevel += 1
509
510         # buttons was overloaded by PyGtk but is needed for Gtk.MessageDialog
511         # as a pass through, so type check the argument and give a deprecation
512         # when it is not of type Gtk.ButtonsType
513         add_buttons = old_kwargs.get('buttons', None)
514         if add_buttons is not None and not isinstance(add_buttons, Gtk.ButtonsType):
515             warnings.warn('The "buttons" argument must be a Gtk.ButtonsType enum value. '
516                           'Please use the "add_buttons" method for adding buttons. '
517                           'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations',
518                           PyGTKDeprecationWarning, stacklevel=stacklevel)
519             if 'buttons' in new_kwargs:
520                 del new_kwargs['buttons']
521         else:
522             add_buttons = None
523
524         flags = old_kwargs.get('flags', 0)
525         if flags:
526             warnings.warn('The "flags" argument for dialog construction is deprecated. '
527                           'Please use initializer keywords: modal=True and/or destroy_with_parent=True. '
528                           'See: https://wiki.gnome.org/PyGObject/InitializerDeprecations',
529                           PyGTKDeprecationWarning, stacklevel=stacklevel)
530
531             if flags & Gtk.DialogFlags.MODAL:
532                 new_kwargs['modal'] = True
533
534             if flags & Gtk.DialogFlags.DESTROY_WITH_PARENT:
535                 new_kwargs['destroy_with_parent'] = True
536
537         self._init(*args, **new_kwargs)
538
539         if add_buttons:
540             self.add_buttons(*add_buttons)
541
542     action_area = property(lambda dialog: dialog.get_action_area())
543     vbox = property(lambda dialog: dialog.get_content_area())
544
545     def add_buttons(self, *args):
546         """
547         The add_buttons() method adds several buttons to the Gtk.Dialog using
548         the button data passed as arguments to the method. This method is the
549         same as calling the Gtk.Dialog.add_button() repeatedly. The button data
550         pairs - button text (or stock ID) and a response ID integer are passed
551         individually. For example:
552
553         .. code-block:: python
554
555             dialog.add_buttons(Gtk.STOCK_OPEN, 42, "Close", Gtk.ResponseType.CLOSE)
556
557         will add "Open" and "Close" buttons to dialog.
558         """
559         def _button(b):
560             while b:
561                 t, r = b[0:2]
562                 b = b[2:]
563                 yield t, r
564
565         try:
566             for text, response in _button(args):
567                 self.add_button(text, response)
568         except (IndexError):
569             raise TypeError('Must pass an even number of arguments')
570
571 Dialog = override(Dialog)
572 __all__.append('Dialog')
573
574
575 class MessageDialog(Gtk.MessageDialog, Dialog):
576     __init__ = deprecated_init(Gtk.MessageDialog.__init__,
577                                arg_names=('parent', 'flags', 'message_type',
578                                           'buttons', 'message_format'),
579                                deprecated_aliases={'text': 'message_format',
580                                                    'message_type': 'type'},
581                                category=PyGTKDeprecationWarning)
582
583     def format_secondary_text(self, message_format):
584         self.set_property('secondary-use-markup', False)
585         self.set_property('secondary-text', message_format)
586
587     def format_secondary_markup(self, message_format):
588         self.set_property('secondary-use-markup', True)
589         self.set_property('secondary-text', message_format)
590
591 MessageDialog = override(MessageDialog)
592 __all__.append('MessageDialog')
593
594
595 class ColorSelectionDialog(Gtk.ColorSelectionDialog):
596     __init__ = deprecated_init(Gtk.ColorSelectionDialog.__init__,
597                                arg_names=('title',),
598                                category=PyGTKDeprecationWarning)
599
600 ColorSelectionDialog = override(ColorSelectionDialog)
601 __all__.append('ColorSelectionDialog')
602
603
604 class FileChooserDialog(Gtk.FileChooserDialog):
605     __init__ = deprecated_init(Gtk.FileChooserDialog.__init__,
606                                arg_names=('title', 'parent', 'action', 'buttons'),
607                                category=PyGTKDeprecationWarning)
608
609 FileChooserDialog = override(FileChooserDialog)
610 __all__.append('FileChooserDialog')
611
612
613 class FontSelectionDialog(Gtk.FontSelectionDialog):
614     __init__ = deprecated_init(Gtk.FontSelectionDialog.__init__,
615                                arg_names=('title',),
616                                category=PyGTKDeprecationWarning)
617
618 FontSelectionDialog = override(FontSelectionDialog)
619 __all__.append('FontSelectionDialog')
620
621
622 class RecentChooserDialog(Gtk.RecentChooserDialog):
623     # Note, the "manager" keyword must work across the entire 3.x series because
624     # "recent_manager" is not backwards compatible with PyGObject versions prior to 3.10.
625     __init__ = deprecated_init(Gtk.RecentChooserDialog.__init__,
626                                arg_names=('title', 'parent', 'recent_manager', 'buttons'),
627                                deprecated_aliases={'recent_manager': 'manager'},
628                                category=PyGTKDeprecationWarning)
629
630 RecentChooserDialog = override(RecentChooserDialog)
631 __all__.append('RecentChooserDialog')
632
633
634 class IconView(Gtk.IconView):
635     __init__ = deprecated_init(Gtk.IconView.__init__,
636                                arg_names=('model',),
637                                category=PyGTKDeprecationWarning)
638
639     get_item_at_pos = strip_boolean_result(Gtk.IconView.get_item_at_pos)
640     get_visible_range = strip_boolean_result(Gtk.IconView.get_visible_range)
641     get_dest_item_at_pos = strip_boolean_result(Gtk.IconView.get_dest_item_at_pos)
642
643 IconView = override(IconView)
644 __all__.append('IconView')
645
646
647 class ToolButton(Gtk.ToolButton):
648     __init__ = deprecated_init(Gtk.ToolButton.__init__,
649                                arg_names=('stock_id',),
650                                category=PyGTKDeprecationWarning)
651
652 ToolButton = override(ToolButton)
653 __all__.append('ToolButton')
654
655
656 class IMContext(Gtk.IMContext):
657     get_surrounding = strip_boolean_result(Gtk.IMContext.get_surrounding)
658
659 IMContext = override(IMContext)
660 __all__.append('IMContext')
661
662
663 class RecentInfo(Gtk.RecentInfo):
664     get_application_info = strip_boolean_result(Gtk.RecentInfo.get_application_info)
665
666 RecentInfo = override(RecentInfo)
667 __all__.append('RecentInfo')
668
669
670 class TextBuffer(Gtk.TextBuffer):
671     def _get_or_create_tag_table(self):
672         table = self.get_tag_table()
673         if table is None:
674             table = Gtk.TextTagTable()
675             self.set_tag_table(table)
676
677         return table
678
679     def create_tag(self, tag_name=None, **properties):
680         """Creates a tag and adds it to the tag table of the TextBuffer.
681
682         :param str tag_name:
683             Name of the new tag, or None
684         :param **properties:
685             Keyword list of properties and their values
686
687         This is equivalent to creating a Gtk.TextTag and then adding the
688         tag to the buffer's tag table. The returned tag is owned by
689         the buffer's tag table.
690
691         If ``tag_name`` is None, the tag is anonymous.
692
693         If ``tag_name`` is not None, a tag called ``tag_name`` must not already
694         exist in the tag table for this buffer.
695
696         Properties are passed as a keyword list of names and values (e.g.
697         foreground='DodgerBlue', weight=Pango.Weight.BOLD)
698
699         :returns:
700             A new tag.
701         """
702
703         tag = Gtk.TextTag(name=tag_name, **properties)
704         self._get_or_create_tag_table().add(tag)
705         return tag
706
707     def create_mark(self, mark_name, where, left_gravity=False):
708         return Gtk.TextBuffer.create_mark(self, mark_name, where, left_gravity)
709
710     def set_text(self, text, length=-1):
711         Gtk.TextBuffer.set_text(self, text, length)
712
713     def insert(self, iter, text, length=-1):
714         if not isinstance(text, _basestring):
715             raise TypeError('text must be a string, not %s' % type(text))
716
717         Gtk.TextBuffer.insert(self, iter, text, length)
718
719     def insert_with_tags(self, iter, text, *tags):
720         start_offset = iter.get_offset()
721         self.insert(iter, text)
722
723         if not tags:
724             return
725
726         start = self.get_iter_at_offset(start_offset)
727
728         for tag in tags:
729             self.apply_tag(tag, start, iter)
730
731     def insert_with_tags_by_name(self, iter, text, *tags):
732         if not tags:
733             return
734
735         tag_objs = []
736
737         for tag in tags:
738             tag_obj = self.get_tag_table().lookup(tag)
739             if not tag_obj:
740                 raise ValueError('unknown text tag: %s' % tag)
741             tag_objs.append(tag_obj)
742
743         self.insert_with_tags(iter, text, *tag_objs)
744
745     def insert_at_cursor(self, text, length=-1):
746         if not isinstance(text, _basestring):
747             raise TypeError('text must be a string, not %s' % type(text))
748
749         Gtk.TextBuffer.insert_at_cursor(self, text, length)
750
751     get_selection_bounds = strip_boolean_result(Gtk.TextBuffer.get_selection_bounds, fail_ret=())
752
753 TextBuffer = override(TextBuffer)
754 __all__.append('TextBuffer')
755
756
757 class TextIter(Gtk.TextIter):
758     forward_search = strip_boolean_result(Gtk.TextIter.forward_search)
759     backward_search = strip_boolean_result(Gtk.TextIter.backward_search)
760
761 TextIter = override(TextIter)
762 __all__.append('TextIter')
763
764
765 class TreeModel(Gtk.TreeModel):
766     def __len__(self):
767         return self.iter_n_children(None)
768
769     def __bool__(self):
770         return True
771
772     # alias for Python 2.x object protocol
773     __nonzero__ = __bool__
774
775     def _getiter(self, key):
776         if isinstance(key, Gtk.TreeIter):
777             return key
778         elif isinstance(key, int) and key < 0:
779             index = len(self) + key
780             if index < 0:
781                 raise IndexError("row index is out of bounds: %d" % key)
782             try:
783                 aiter = self.get_iter(index)
784             except ValueError:
785                 raise IndexError("could not find tree path '%s'" % key)
786             return aiter
787         else:
788             try:
789                 aiter = self.get_iter(key)
790             except ValueError:
791                 raise IndexError("could not find tree path '%s'" % key)
792             return aiter
793
794     def _coerce_path(self, path):
795         if isinstance(path, Gtk.TreePath):
796             return path
797         else:
798             return TreePath(path)
799
800     def __getitem__(self, key):
801         aiter = self._getiter(key)
802         return TreeModelRow(self, aiter)
803
804     def __setitem__(self, key, value):
805         row = self[key]
806         self.set_row(row.iter, value)
807
808     def __delitem__(self, key):
809         aiter = self._getiter(key)
810         self.remove(aiter)
811
812     def __iter__(self):
813         return TreeModelRowIter(self, self.get_iter_first())
814
815     get_iter_first = strip_boolean_result(Gtk.TreeModel.get_iter_first)
816     iter_children = strip_boolean_result(Gtk.TreeModel.iter_children)
817     iter_nth_child = strip_boolean_result(Gtk.TreeModel.iter_nth_child)
818     iter_parent = strip_boolean_result(Gtk.TreeModel.iter_parent)
819     get_iter_from_string = strip_boolean_result(Gtk.TreeModel.get_iter_from_string,
820                                                 ValueError, 'invalid tree path')
821
822     def get_iter(self, path):
823         path = self._coerce_path(path)
824         success, aiter = super(TreeModel, self).get_iter(path)
825         if not success:
826             raise ValueError("invalid tree path '%s'" % path)
827         return aiter
828
829     def iter_next(self, aiter):
830         next_iter = aiter.copy()
831         success = super(TreeModel, self).iter_next(next_iter)
832         if success:
833             return next_iter
834
835     def iter_previous(self, aiter):
836         prev_iter = aiter.copy()
837         success = super(TreeModel, self).iter_previous(prev_iter)
838         if success:
839             return prev_iter
840
841     def _convert_row(self, row):
842         # TODO: Accept a dictionary for row
843         # model.append(None,{COLUMN_ICON: icon, COLUMN_NAME: name})
844         if isinstance(row, str):
845             raise TypeError('Expected a list or tuple, but got str')
846
847         n_columns = self.get_n_columns()
848         if len(row) != n_columns:
849             raise ValueError('row sequence has the incorrect number of elements')
850
851         result = []
852         columns = []
853         for cur_col, value in enumerate(row):
854             # do not try to set None values, they are causing warnings
855             if value is None:
856                 continue
857             result.append(self._convert_value(cur_col, value))
858             columns.append(cur_col)
859         return (result, columns)
860
861     def set_row(self, treeiter, row):
862         converted_row, columns = self._convert_row(row)
863         for column in columns:
864             value = row[column]
865             if value is None:
866                 continue  # None means skip this row
867
868             self.set_value(treeiter, column, value)
869
870     def _convert_value(self, column, value):
871         '''Convert value to a GObject.Value of the expected type'''
872
873         if isinstance(value, GObject.Value):
874             return value
875         return GObject.Value(self.get_column_type(column), value)
876
877     def get(self, treeiter, *columns):
878         n_columns = self.get_n_columns()
879
880         values = []
881         for col in columns:
882             if not isinstance(col, int):
883                 raise TypeError("column numbers must be ints")
884
885             if col < 0 or col >= n_columns:
886                 raise ValueError("column number is out of range")
887
888             values.append(self.get_value(treeiter, col))
889
890         return tuple(values)
891
892     #
893     # Signals supporting python iterables as tree paths
894     #
895     def row_changed(self, path, iter):
896         return super(TreeModel, self).row_changed(self._coerce_path(path), iter)
897
898     def row_inserted(self, path, iter):
899         return super(TreeModel, self).row_inserted(self._coerce_path(path), iter)
900
901     def row_has_child_toggled(self, path, iter):
902         return super(TreeModel, self).row_has_child_toggled(self._coerce_path(path),
903                                                             iter)
904
905     def row_deleted(self, path):
906         return super(TreeModel, self).row_deleted(self._coerce_path(path))
907
908     def rows_reordered(self, path, iter, new_order):
909         return super(TreeModel, self).rows_reordered(self._coerce_path(path),
910                                                      iter, new_order)
911
912
913 TreeModel = override(TreeModel)
914 __all__.append('TreeModel')
915
916
917 class TreeSortable(Gtk.TreeSortable, ):
918
919     get_sort_column_id = strip_boolean_result(Gtk.TreeSortable.get_sort_column_id, fail_ret=(None, None))
920
921     def set_sort_func(self, sort_column_id, sort_func, user_data=None):
922         super(TreeSortable, self).set_sort_func(sort_column_id, sort_func, user_data)
923
924     def set_default_sort_func(self, sort_func, user_data=None):
925         super(TreeSortable, self).set_default_sort_func(sort_func, user_data)
926
927 TreeSortable = override(TreeSortable)
928 __all__.append('TreeSortable')
929
930
931 class TreeModelSort(Gtk.TreeModelSort):
932     __init__ = deprecated_init(Gtk.TreeModelSort.__init__,
933                                arg_names=('model',),
934                                category=PyGTKDeprecationWarning)
935
936 TreeModelSort = override(TreeModelSort)
937 __all__.append('TreeModelSort')
938
939
940 class ListStore(Gtk.ListStore, TreeModel, TreeSortable):
941     def __init__(self, *column_types):
942         Gtk.ListStore.__init__(self)
943         self.set_column_types(column_types)
944
945     def _do_insert(self, position, row):
946         if row is not None:
947             row, columns = self._convert_row(row)
948             treeiter = self.insert_with_valuesv(position, columns, row)
949         else:
950             treeiter = Gtk.ListStore.insert(self, position)
951
952         return treeiter
953
954     def append(self, row=None):
955         if row:
956             return self._do_insert(-1, row)
957         # gtk_list_store_insert() does not know about the "position == -1"
958         # case, so use append() here
959         else:
960             return Gtk.ListStore.append(self)
961
962     def prepend(self, row=None):
963         return self._do_insert(0, row)
964
965     def insert(self, position, row=None):
966         return self._do_insert(position, row)
967
968     # FIXME: sends two signals; check if this can use an atomic
969     # insert_with_valuesv()
970
971     def insert_before(self, sibling, row=None):
972         treeiter = Gtk.ListStore.insert_before(self, sibling)
973
974         if row is not None:
975             self.set_row(treeiter, row)
976
977         return treeiter
978
979     # FIXME: sends two signals; check if this can use an atomic
980     # insert_with_valuesv()
981
982     def insert_after(self, sibling, row=None):
983         treeiter = Gtk.ListStore.insert_after(self, sibling)
984
985         if row is not None:
986             self.set_row(treeiter, row)
987
988         return treeiter
989
990     def set_value(self, treeiter, column, value):
991         value = self._convert_value(column, value)
992         Gtk.ListStore.set_value(self, treeiter, column, value)
993
994     def set(self, treeiter, *args):
995
996         def _set_lists(columns, values):
997             if len(columns) != len(values):
998                 raise TypeError('The number of columns do not match the number of values')
999             for col_num, val in zip(columns, values):
1000                 if not isinstance(col_num, int):
1001                     raise TypeError('TypeError: Expected integer argument for column.')
1002                 self.set_value(treeiter, col_num, val)
1003
1004         if args:
1005             if isinstance(args[0], int):
1006                 columns = args[::2]
1007                 values = args[1::2]
1008                 _set_lists(columns, values)
1009             elif isinstance(args[0], (tuple, list)):
1010                 if len(args) != 2:
1011                     raise TypeError('Too many arguments')
1012                 _set_lists(args[0], args[1])
1013             elif isinstance(args[0], dict):
1014                 columns = args[0].keys()
1015                 values = args[0].values()
1016                 _set_lists(columns, values)
1017             else:
1018                 raise TypeError('Argument list must be in the form of (column, value, ...), ((columns,...), (values, ...)) or {column: value}.  No -1 termination is needed.')
1019
1020 ListStore = override(ListStore)
1021 __all__.append('ListStore')
1022
1023
1024 class TreeModelRow(object):
1025
1026     def __init__(self, model, iter_or_path):
1027         if not isinstance(model, Gtk.TreeModel):
1028             raise TypeError("expected Gtk.TreeModel, %s found" % type(model).__name__)
1029         self.model = model
1030         if isinstance(iter_or_path, Gtk.TreePath):
1031             self.iter = model.get_iter(iter_or_path)
1032         elif isinstance(iter_or_path, Gtk.TreeIter):
1033             self.iter = iter_or_path
1034         else:
1035             raise TypeError("expected Gtk.TreeIter or Gtk.TreePath, \
1036                 %s found" % type(iter_or_path).__name__)
1037
1038     @property
1039     def path(self):
1040         return self.model.get_path(self.iter)
1041
1042     @property
1043     def next(self):
1044         return self.get_next()
1045
1046     @property
1047     def previous(self):
1048         return self.get_previous()
1049
1050     @property
1051     def parent(self):
1052         return self.get_parent()
1053
1054     def get_next(self):
1055         next_iter = self.model.iter_next(self.iter)
1056         if next_iter:
1057             return TreeModelRow(self.model, next_iter)
1058
1059     def get_previous(self):
1060         prev_iter = self.model.iter_previous(self.iter)
1061         if prev_iter:
1062             return TreeModelRow(self.model, prev_iter)
1063
1064     def get_parent(self):
1065         parent_iter = self.model.iter_parent(self.iter)
1066         if parent_iter:
1067             return TreeModelRow(self.model, parent_iter)
1068
1069     def __getitem__(self, key):
1070         if isinstance(key, int):
1071             if key >= self.model.get_n_columns():
1072                 raise IndexError("column index is out of bounds: %d" % key)
1073             elif key < 0:
1074                 key = self._convert_negative_index(key)
1075             return self.model.get_value(self.iter, key)
1076         elif isinstance(key, slice):
1077             start, stop, step = key.indices(self.model.get_n_columns())
1078             alist = []
1079             for i in range(start, stop, step):
1080                 alist.append(self.model.get_value(self.iter, i))
1081             return alist
1082         else:
1083             raise TypeError("indices must be integers, not %s" % type(key).__name__)
1084
1085     def __setitem__(self, key, value):
1086         if isinstance(key, int):
1087             if key >= self.model.get_n_columns():
1088                 raise IndexError("column index is out of bounds: %d" % key)
1089             elif key < 0:
1090                 key = self._convert_negative_index(key)
1091             self.model.set_value(self.iter, key, value)
1092         elif isinstance(key, slice):
1093             start, stop, step = key.indices(self.model.get_n_columns())
1094             indexList = range(start, stop, step)
1095             if len(indexList) != len(value):
1096                 raise ValueError(
1097                     "attempt to assign sequence of size %d to slice of size %d"
1098                     % (len(value), len(indexList)))
1099
1100             for i, v in enumerate(indexList):
1101                 self.model.set_value(self.iter, v, value[i])
1102         else:
1103             raise TypeError("index must be an integer or slice, not %s" % type(key).__name__)
1104
1105     def _convert_negative_index(self, index):
1106         new_index = self.model.get_n_columns() + index
1107         if new_index < 0:
1108             raise IndexError("column index is out of bounds: %d" % index)
1109         return new_index
1110
1111     def iterchildren(self):
1112         child_iter = self.model.iter_children(self.iter)
1113         return TreeModelRowIter(self.model, child_iter)
1114
1115 __all__.append('TreeModelRow')
1116
1117
1118 class TreeModelRowIter(object):
1119
1120     def __init__(self, model, aiter):
1121         self.model = model
1122         self.iter = aiter
1123
1124     def __next__(self):
1125         if not self.iter:
1126             raise StopIteration
1127         row = TreeModelRow(self.model, self.iter)
1128         self.iter = self.model.iter_next(self.iter)
1129         return row
1130
1131     # alias for Python 2.x object protocol
1132     next = __next__
1133
1134     def __iter__(self):
1135         return self
1136
1137 __all__.append('TreeModelRowIter')
1138
1139
1140 class TreePath(Gtk.TreePath):
1141
1142     def __new__(cls, path=0):
1143         if isinstance(path, int):
1144             path = str(path)
1145         elif not isinstance(path, _basestring):
1146             path = ":".join(str(val) for val in path)
1147
1148         if len(path) == 0:
1149             raise TypeError("could not parse subscript '%s' as a tree path" % path)
1150         try:
1151             return TreePath.new_from_string(path)
1152         except TypeError:
1153             raise TypeError("could not parse subscript '%s' as a tree path" % path)
1154
1155     def __init__(self, *args, **kwargs):
1156         super(TreePath, self).__init__()
1157
1158     def __str__(self):
1159         return self.to_string()
1160
1161     def __lt__(self, other):
1162         return other is not None and self.compare(other) < 0
1163
1164     def __le__(self, other):
1165         return other is not None and self.compare(other) <= 0
1166
1167     def __eq__(self, other):
1168         return other is not None and self.compare(other) == 0
1169
1170     def __ne__(self, other):
1171         return other is None or self.compare(other) != 0
1172
1173     def __gt__(self, other):
1174         return other is None or self.compare(other) > 0
1175
1176     def __ge__(self, other):
1177         return other is None or self.compare(other) >= 0
1178
1179     def __iter__(self):
1180         return iter(self.get_indices())
1181
1182     def __len__(self):
1183         return self.get_depth()
1184
1185     def __getitem__(self, index):
1186         return self.get_indices()[index]
1187
1188 TreePath = override(TreePath)
1189 __all__.append('TreePath')
1190
1191
1192 class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
1193     def __init__(self, *column_types):
1194         Gtk.TreeStore.__init__(self)
1195         self.set_column_types(column_types)
1196
1197     def _do_insert(self, parent, position, row):
1198         if row is not None:
1199             row, columns = self._convert_row(row)
1200             treeiter = self.insert_with_values(parent, position, columns, row)
1201         else:
1202             treeiter = Gtk.TreeStore.insert(self, parent, position)
1203
1204         return treeiter
1205
1206     def append(self, parent, row=None):
1207         return self._do_insert(parent, -1, row)
1208
1209     def prepend(self, parent, row=None):
1210         return self._do_insert(parent, 0, row)
1211
1212     def insert(self, parent, position, row=None):
1213         return self._do_insert(parent, position, row)
1214
1215     # FIXME: sends two signals; check if this can use an atomic
1216     # insert_with_valuesv()
1217
1218     def insert_before(self, parent, sibling, row=None):
1219         treeiter = Gtk.TreeStore.insert_before(self, parent, sibling)
1220
1221         if row is not None:
1222             self.set_row(treeiter, row)
1223
1224         return treeiter
1225
1226     # FIXME: sends two signals; check if this can use an atomic
1227     # insert_with_valuesv()
1228
1229     def insert_after(self, parent, sibling, row=None):
1230         treeiter = Gtk.TreeStore.insert_after(self, parent, sibling)
1231
1232         if row is not None:
1233             self.set_row(treeiter, row)
1234
1235         return treeiter
1236
1237     def set_value(self, treeiter, column, value):
1238         value = self._convert_value(column, value)
1239         Gtk.TreeStore.set_value(self, treeiter, column, value)
1240
1241     def set(self, treeiter, *args):
1242
1243         def _set_lists(columns, values):
1244             if len(columns) != len(values):
1245                 raise TypeError('The number of columns do not match the number of values')
1246             for col_num, val in zip(columns, values):
1247                 if not isinstance(col_num, int):
1248                     raise TypeError('TypeError: Expected integer argument for column.')
1249                 self.set_value(treeiter, col_num, val)
1250
1251         if args:
1252             if isinstance(args[0], int):
1253                 columns = args[::2]
1254                 values = args[1::2]
1255                 _set_lists(columns, values)
1256             elif isinstance(args[0], (tuple, list)):
1257                 if len(args) != 2:
1258                     raise TypeError('Too many arguments')
1259                 _set_lists(args[0], args[1])
1260             elif isinstance(args[0], dict):
1261                 columns = args[0].keys()
1262                 values = args[0].values()
1263                 _set_lists(columns, values)
1264             else:
1265                 raise TypeError('Argument list must be in the form of (column, value, ...), ((columns,...), (values, ...)) or {column: value}.  No -1 termination is needed.')
1266
1267 TreeStore = override(TreeStore)
1268 __all__.append('TreeStore')
1269
1270
1271 class TreeView(Gtk.TreeView, Container):
1272     __init__ = deprecated_init(Gtk.TreeView.__init__,
1273                                arg_names=('model',),
1274                                category=PyGTKDeprecationWarning)
1275
1276     get_path_at_pos = strip_boolean_result(Gtk.TreeView.get_path_at_pos)
1277     get_visible_range = strip_boolean_result(Gtk.TreeView.get_visible_range)
1278     get_dest_row_at_pos = strip_boolean_result(Gtk.TreeView.get_dest_row_at_pos)
1279
1280     def enable_model_drag_source(self, start_button_mask, targets, actions):
1281         target_entries = _construct_target_list(targets)
1282         super(TreeView, self).enable_model_drag_source(start_button_mask,
1283                                                        target_entries,
1284                                                        actions)
1285
1286     def enable_model_drag_dest(self, targets, actions):
1287         target_entries = _construct_target_list(targets)
1288         super(TreeView, self).enable_model_drag_dest(target_entries,
1289                                                      actions)
1290
1291     def scroll_to_cell(self, path, column=None, use_align=False, row_align=0.0, col_align=0.0):
1292         if not isinstance(path, Gtk.TreePath):
1293             path = TreePath(path)
1294         super(TreeView, self).scroll_to_cell(path, column, use_align, row_align, col_align)
1295
1296     def set_cursor(self, path, column=None, start_editing=False):
1297         if not isinstance(path, Gtk.TreePath):
1298             path = TreePath(path)
1299         super(TreeView, self).set_cursor(path, column, start_editing)
1300
1301     def get_cell_area(self, path, column=None):
1302         if not isinstance(path, Gtk.TreePath):
1303             path = TreePath(path)
1304         return super(TreeView, self).get_cell_area(path, column)
1305
1306     def insert_column_with_attributes(self, position, title, cell, **kwargs):
1307         column = TreeViewColumn()
1308         column.set_title(title)
1309         column.pack_start(cell, False)
1310         self.insert_column(column, position)
1311         column.set_attributes(cell, **kwargs)
1312
1313 TreeView = override(TreeView)
1314 __all__.append('TreeView')
1315
1316
1317 class TreeViewColumn(Gtk.TreeViewColumn):
1318     def __init__(self, title='',
1319                  cell_renderer=None,
1320                  **attributes):
1321         Gtk.TreeViewColumn.__init__(self, title=title)
1322         if cell_renderer:
1323             self.pack_start(cell_renderer, True)
1324
1325         for (name, value) in attributes.items():
1326             self.add_attribute(cell_renderer, name, value)
1327
1328     cell_get_position = strip_boolean_result(Gtk.TreeViewColumn.cell_get_position)
1329
1330     def set_cell_data_func(self, cell_renderer, func, func_data=None):
1331         super(TreeViewColumn, self).set_cell_data_func(cell_renderer, func, func_data)
1332
1333     def set_attributes(self, cell_renderer, **attributes):
1334         Gtk.CellLayout.clear_attributes(self, cell_renderer)
1335
1336         for (name, value) in attributes.items():
1337             Gtk.CellLayout.add_attribute(self, cell_renderer, name, value)
1338
1339
1340 TreeViewColumn = override(TreeViewColumn)
1341 __all__.append('TreeViewColumn')
1342
1343
1344 class TreeSelection(Gtk.TreeSelection):
1345
1346     def select_path(self, path):
1347         if not isinstance(path, Gtk.TreePath):
1348             path = TreePath(path)
1349         super(TreeSelection, self).select_path(path)
1350
1351     def get_selected(self):
1352         success, model, aiter = super(TreeSelection, self).get_selected()
1353         if success:
1354             return (model, aiter)
1355         else:
1356             return (model, None)
1357
1358     # for compatibility with PyGtk
1359
1360     def get_selected_rows(self):
1361         rows, model = super(TreeSelection, self).get_selected_rows()
1362         return (model, rows)
1363
1364
1365 TreeSelection = override(TreeSelection)
1366 __all__.append('TreeSelection')
1367
1368
1369 class Button(Gtk.Button, Container):
1370     _init = deprecated_init(Gtk.Button.__init__,
1371                             arg_names=('label', 'stock', 'use_stock', 'use_underline'),
1372                             ignore=('stock',),
1373                             category=PyGTKDeprecationWarning,
1374                             stacklevel=3)
1375
1376     def __init__(self, *args, **kwargs):
1377         # Doubly deprecated initializer, the stock keyword is non-standard.
1378         # Simply give a warning that stock items are deprecated even though
1379         # we want to deprecate the non-standard keyword as well here from
1380         # the overrides.
1381         if 'stock' in kwargs and kwargs['stock']:
1382             warnings.warn('Stock items are deprecated. '
1383                           'Please use: Gtk.Button.new_with_mnemonic(label)',
1384                           PyGTKDeprecationWarning, stacklevel=2)
1385             new_kwargs = kwargs.copy()
1386             new_kwargs['label'] = new_kwargs['stock']
1387             new_kwargs['use_stock'] = True
1388             new_kwargs['use_underline'] = True
1389             del new_kwargs['stock']
1390             Gtk.Button.__init__(self, **new_kwargs)
1391         else:
1392             self._init(*args, **kwargs)
1393
1394 Button = override(Button)
1395 __all__.append('Button')
1396
1397
1398 class LinkButton(Gtk.LinkButton):
1399     __init__ = deprecated_init(Gtk.LinkButton.__init__,
1400                                arg_names=('uri', 'label'),
1401                                category=PyGTKDeprecationWarning)
1402
1403 LinkButton = override(LinkButton)
1404 __all__.append('LinkButton')
1405
1406
1407 class Label(Gtk.Label):
1408     __init__ = deprecated_init(Gtk.Label.__init__,
1409                                arg_names=('label',),
1410                                category=PyGTKDeprecationWarning)
1411
1412 Label = override(Label)
1413 __all__.append('Label')
1414
1415
1416 class Adjustment(Gtk.Adjustment):
1417     _init = deprecated_init(Gtk.Adjustment.__init__,
1418                             arg_names=('value', 'lower', 'upper',
1419                                        'step_increment', 'page_increment', 'page_size'),
1420                             deprecated_aliases={'page_increment': 'page_incr',
1421                                                 'step_increment': 'step_incr'},
1422                             category=PyGTKDeprecationWarning,
1423                             stacklevel=3)
1424
1425     def __init__(self, *args, **kwargs):
1426         self._init(*args, **kwargs)
1427
1428         # The value property is set between lower and (upper - page_size).
1429         # Just in case lower, upper or page_size was still 0 when value
1430         # was set, we set it again here.
1431         if 'value' in kwargs:
1432             self.set_value(kwargs['value'])
1433
1434 Adjustment = override(Adjustment)
1435 __all__.append('Adjustment')
1436
1437
1438 class Table(Gtk.Table, Container):
1439     __init__ = deprecated_init(Gtk.Table.__init__,
1440                                arg_names=('n_rows', 'n_columns', 'homogeneous'),
1441                                deprecated_aliases={'n_rows': 'rows', 'n_columns': 'columns'},
1442                                category=PyGTKDeprecationWarning)
1443
1444     def attach(self, child, left_attach, right_attach, top_attach, bottom_attach, xoptions=Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, xpadding=0, ypadding=0):
1445         Gtk.Table.attach(self, child, left_attach, right_attach, top_attach, bottom_attach, xoptions, yoptions, xpadding, ypadding)
1446
1447 Table = override(Table)
1448 __all__.append('Table')
1449
1450
1451 class ScrolledWindow(Gtk.ScrolledWindow):
1452     __init__ = deprecated_init(Gtk.ScrolledWindow.__init__,
1453                                arg_names=('hadjustment', 'vadjustment'),
1454                                category=PyGTKDeprecationWarning)
1455
1456 ScrolledWindow = override(ScrolledWindow)
1457 __all__.append('ScrolledWindow')
1458
1459
1460 class HScrollbar(Gtk.HScrollbar):
1461     __init__ = deprecated_init(Gtk.HScrollbar.__init__,
1462                                arg_names=('adjustment',),
1463                                category=PyGTKDeprecationWarning)
1464
1465 HScrollbar = override(HScrollbar)
1466 __all__.append('HScrollbar')
1467
1468
1469 class VScrollbar(Gtk.VScrollbar):
1470     __init__ = deprecated_init(Gtk.VScrollbar.__init__,
1471                                arg_names=('adjustment',),
1472                                category=PyGTKDeprecationWarning)
1473
1474 VScrollbar = override(VScrollbar)
1475 __all__.append('VScrollbar')
1476
1477
1478 class Paned(Gtk.Paned):
1479     def pack1(self, child, resize=False, shrink=True):
1480         super(Paned, self).pack1(child, resize, shrink)
1481
1482     def pack2(self, child, resize=True, shrink=True):
1483         super(Paned, self).pack2(child, resize, shrink)
1484
1485 Paned = override(Paned)
1486 __all__.append('Paned')
1487
1488
1489 class Arrow(Gtk.Arrow):
1490     __init__ = deprecated_init(Gtk.Arrow.__init__,
1491                                arg_names=('arrow_type', 'shadow_type'),
1492                                category=PyGTKDeprecationWarning)
1493
1494 Arrow = override(Arrow)
1495 __all__.append('Arrow')
1496
1497
1498 class IconSet(Gtk.IconSet):
1499     def __new__(cls, pixbuf=None):
1500         if pixbuf is not None:
1501             warnings.warn('Gtk.IconSet(pixbuf) has been deprecated. Please use: '
1502                           'Gtk.IconSet.new_from_pixbuf(pixbuf)',
1503                           PyGTKDeprecationWarning, stacklevel=2)
1504             iconset = Gtk.IconSet.new_from_pixbuf(pixbuf)
1505         else:
1506             iconset = Gtk.IconSet.__new__(cls)
1507         return iconset
1508
1509     def __init__(self, *args, **kwargs):
1510         return super(IconSet, self).__init__()
1511
1512 IconSet = override(IconSet)
1513 __all__.append('IconSet')
1514
1515
1516 class Viewport(Gtk.Viewport):
1517     __init__ = deprecated_init(Gtk.Viewport.__init__,
1518                                arg_names=('hadjustment', 'vadjustment'),
1519                                category=PyGTKDeprecationWarning)
1520
1521 Viewport = override(Viewport)
1522 __all__.append('Viewport')
1523
1524
1525 class TreeModelFilter(Gtk.TreeModelFilter):
1526     def set_visible_func(self, func, data=None):
1527         super(TreeModelFilter, self).set_visible_func(func, data)
1528
1529     def set_value(self, iter, column, value):
1530         # Delegate to child model
1531         iter = self.convert_iter_to_child_iter(iter)
1532         self.get_model().set_value(iter, column, value)
1533
1534 TreeModelFilter = override(TreeModelFilter)
1535 __all__.append('TreeModelFilter')
1536
1537 if Gtk._version != '2.0':
1538     class Menu(Gtk.Menu):
1539         def popup(self, parent_menu_shell, parent_menu_item, func, data, button, activate_time):
1540             self.popup_for_device(None, parent_menu_shell, parent_menu_item, func, data, button, activate_time)
1541     Menu = override(Menu)
1542     __all__.append('Menu')
1543
1544 _Gtk_main_quit = Gtk.main_quit
1545
1546
1547 @override(Gtk.main_quit)
1548 def main_quit(*args):
1549     _Gtk_main_quit()
1550
1551 stock_lookup = strip_boolean_result(Gtk.stock_lookup)
1552 __all__.append('stock_lookup')
1553
1554 initialized, argv = Gtk.init_check(sys.argv)
1555 sys.argv = list(argv)