Imported Upstream version 3.21.91
[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         elif isinstance(key, tuple):
1083             return [self[k] for k in key]
1084         else:
1085             raise TypeError("indices must be integers, slice or tuple, not %s"
1086                             % type(key).__name__)
1087
1088     def __setitem__(self, key, value):
1089         if isinstance(key, int):
1090             if key >= self.model.get_n_columns():
1091                 raise IndexError("column index is out of bounds: %d" % key)
1092             elif key < 0:
1093                 key = self._convert_negative_index(key)
1094             self.model.set_value(self.iter, key, value)
1095         elif isinstance(key, slice):
1096             start, stop, step = key.indices(self.model.get_n_columns())
1097             indexList = range(start, stop, step)
1098             if len(indexList) != len(value):
1099                 raise ValueError(
1100                     "attempt to assign sequence of size %d to slice of size %d"
1101                     % (len(value), len(indexList)))
1102
1103             for i, v in enumerate(indexList):
1104                 self.model.set_value(self.iter, v, value[i])
1105         elif isinstance(key, tuple):
1106             if len(key) != len(value):
1107                 raise ValueError(
1108                     "attempt to assign sequence of size %d to sequence of size %d"
1109                     % (len(value), len(key)))
1110             for k, v in zip(key, value):
1111                 self[k] = v
1112         else:
1113             raise TypeError("indices must be an integer, slice or tuple, not %s"
1114                             % type(key).__name__)
1115
1116     def _convert_negative_index(self, index):
1117         new_index = self.model.get_n_columns() + index
1118         if new_index < 0:
1119             raise IndexError("column index is out of bounds: %d" % index)
1120         return new_index
1121
1122     def iterchildren(self):
1123         child_iter = self.model.iter_children(self.iter)
1124         return TreeModelRowIter(self.model, child_iter)
1125
1126 __all__.append('TreeModelRow')
1127
1128
1129 class TreeModelRowIter(object):
1130
1131     def __init__(self, model, aiter):
1132         self.model = model
1133         self.iter = aiter
1134
1135     def __next__(self):
1136         if not self.iter:
1137             raise StopIteration
1138         row = TreeModelRow(self.model, self.iter)
1139         self.iter = self.model.iter_next(self.iter)
1140         return row
1141
1142     # alias for Python 2.x object protocol
1143     next = __next__
1144
1145     def __iter__(self):
1146         return self
1147
1148 __all__.append('TreeModelRowIter')
1149
1150
1151 class TreePath(Gtk.TreePath):
1152
1153     def __new__(cls, path=0):
1154         if isinstance(path, int):
1155             path = str(path)
1156         elif not isinstance(path, _basestring):
1157             path = ":".join(str(val) for val in path)
1158
1159         if len(path) == 0:
1160             raise TypeError("could not parse subscript '%s' as a tree path" % path)
1161         try:
1162             return TreePath.new_from_string(path)
1163         except TypeError:
1164             raise TypeError("could not parse subscript '%s' as a tree path" % path)
1165
1166     def __init__(self, *args, **kwargs):
1167         super(TreePath, self).__init__()
1168
1169     def __str__(self):
1170         return self.to_string()
1171
1172     def __lt__(self, other):
1173         return other is not None and self.compare(other) < 0
1174
1175     def __le__(self, other):
1176         return other is not None and self.compare(other) <= 0
1177
1178     def __eq__(self, other):
1179         return other is not None and self.compare(other) == 0
1180
1181     def __ne__(self, other):
1182         return other is None or self.compare(other) != 0
1183
1184     def __gt__(self, other):
1185         return other is None or self.compare(other) > 0
1186
1187     def __ge__(self, other):
1188         return other is None or self.compare(other) >= 0
1189
1190     def __iter__(self):
1191         return iter(self.get_indices())
1192
1193     def __len__(self):
1194         return self.get_depth()
1195
1196     def __getitem__(self, index):
1197         return self.get_indices()[index]
1198
1199 TreePath = override(TreePath)
1200 __all__.append('TreePath')
1201
1202
1203 class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable):
1204     def __init__(self, *column_types):
1205         Gtk.TreeStore.__init__(self)
1206         self.set_column_types(column_types)
1207
1208     def _do_insert(self, parent, position, row):
1209         if row is not None:
1210             row, columns = self._convert_row(row)
1211             treeiter = self.insert_with_values(parent, position, columns, row)
1212         else:
1213             treeiter = Gtk.TreeStore.insert(self, parent, position)
1214
1215         return treeiter
1216
1217     def append(self, parent, row=None):
1218         return self._do_insert(parent, -1, row)
1219
1220     def prepend(self, parent, row=None):
1221         return self._do_insert(parent, 0, row)
1222
1223     def insert(self, parent, position, row=None):
1224         return self._do_insert(parent, position, row)
1225
1226     # FIXME: sends two signals; check if this can use an atomic
1227     # insert_with_valuesv()
1228
1229     def insert_before(self, parent, sibling, row=None):
1230         treeiter = Gtk.TreeStore.insert_before(self, parent, sibling)
1231
1232         if row is not None:
1233             self.set_row(treeiter, row)
1234
1235         return treeiter
1236
1237     # FIXME: sends two signals; check if this can use an atomic
1238     # insert_with_valuesv()
1239
1240     def insert_after(self, parent, sibling, row=None):
1241         treeiter = Gtk.TreeStore.insert_after(self, parent, sibling)
1242
1243         if row is not None:
1244             self.set_row(treeiter, row)
1245
1246         return treeiter
1247
1248     def set_value(self, treeiter, column, value):
1249         value = self._convert_value(column, value)
1250         Gtk.TreeStore.set_value(self, treeiter, column, value)
1251
1252     def set(self, treeiter, *args):
1253
1254         def _set_lists(columns, values):
1255             if len(columns) != len(values):
1256                 raise TypeError('The number of columns do not match the number of values')
1257             for col_num, val in zip(columns, values):
1258                 if not isinstance(col_num, int):
1259                     raise TypeError('TypeError: Expected integer argument for column.')
1260                 self.set_value(treeiter, col_num, val)
1261
1262         if args:
1263             if isinstance(args[0], int):
1264                 columns = args[::2]
1265                 values = args[1::2]
1266                 _set_lists(columns, values)
1267             elif isinstance(args[0], (tuple, list)):
1268                 if len(args) != 2:
1269                     raise TypeError('Too many arguments')
1270                 _set_lists(args[0], args[1])
1271             elif isinstance(args[0], dict):
1272                 columns = args[0].keys()
1273                 values = args[0].values()
1274                 _set_lists(columns, values)
1275             else:
1276                 raise TypeError('Argument list must be in the form of (column, value, ...), ((columns,...), (values, ...)) or {column: value}.  No -1 termination is needed.')
1277
1278 TreeStore = override(TreeStore)
1279 __all__.append('TreeStore')
1280
1281
1282 class TreeView(Gtk.TreeView, Container):
1283     __init__ = deprecated_init(Gtk.TreeView.__init__,
1284                                arg_names=('model',),
1285                                category=PyGTKDeprecationWarning)
1286
1287     get_path_at_pos = strip_boolean_result(Gtk.TreeView.get_path_at_pos)
1288     get_visible_range = strip_boolean_result(Gtk.TreeView.get_visible_range)
1289     get_dest_row_at_pos = strip_boolean_result(Gtk.TreeView.get_dest_row_at_pos)
1290
1291     def enable_model_drag_source(self, start_button_mask, targets, actions):
1292         target_entries = _construct_target_list(targets)
1293         super(TreeView, self).enable_model_drag_source(start_button_mask,
1294                                                        target_entries,
1295                                                        actions)
1296
1297     def enable_model_drag_dest(self, targets, actions):
1298         target_entries = _construct_target_list(targets)
1299         super(TreeView, self).enable_model_drag_dest(target_entries,
1300                                                      actions)
1301
1302     def scroll_to_cell(self, path, column=None, use_align=False, row_align=0.0, col_align=0.0):
1303         if not isinstance(path, Gtk.TreePath):
1304             path = TreePath(path)
1305         super(TreeView, self).scroll_to_cell(path, column, use_align, row_align, col_align)
1306
1307     def set_cursor(self, path, column=None, start_editing=False):
1308         if not isinstance(path, Gtk.TreePath):
1309             path = TreePath(path)
1310         super(TreeView, self).set_cursor(path, column, start_editing)
1311
1312     def get_cell_area(self, path, column=None):
1313         if not isinstance(path, Gtk.TreePath):
1314             path = TreePath(path)
1315         return super(TreeView, self).get_cell_area(path, column)
1316
1317     def insert_column_with_attributes(self, position, title, cell, **kwargs):
1318         column = TreeViewColumn()
1319         column.set_title(title)
1320         column.pack_start(cell, False)
1321         self.insert_column(column, position)
1322         column.set_attributes(cell, **kwargs)
1323
1324 TreeView = override(TreeView)
1325 __all__.append('TreeView')
1326
1327
1328 class TreeViewColumn(Gtk.TreeViewColumn):
1329     def __init__(self, title='',
1330                  cell_renderer=None,
1331                  **attributes):
1332         Gtk.TreeViewColumn.__init__(self, title=title)
1333         if cell_renderer:
1334             self.pack_start(cell_renderer, True)
1335
1336         for (name, value) in attributes.items():
1337             self.add_attribute(cell_renderer, name, value)
1338
1339     cell_get_position = strip_boolean_result(Gtk.TreeViewColumn.cell_get_position)
1340
1341     def set_cell_data_func(self, cell_renderer, func, func_data=None):
1342         super(TreeViewColumn, self).set_cell_data_func(cell_renderer, func, func_data)
1343
1344     def set_attributes(self, cell_renderer, **attributes):
1345         Gtk.CellLayout.clear_attributes(self, cell_renderer)
1346
1347         for (name, value) in attributes.items():
1348             Gtk.CellLayout.add_attribute(self, cell_renderer, name, value)
1349
1350
1351 TreeViewColumn = override(TreeViewColumn)
1352 __all__.append('TreeViewColumn')
1353
1354
1355 class TreeSelection(Gtk.TreeSelection):
1356
1357     def select_path(self, path):
1358         if not isinstance(path, Gtk.TreePath):
1359             path = TreePath(path)
1360         super(TreeSelection, self).select_path(path)
1361
1362     def get_selected(self):
1363         success, model, aiter = super(TreeSelection, self).get_selected()
1364         if success:
1365             return (model, aiter)
1366         else:
1367             return (model, None)
1368
1369     # for compatibility with PyGtk
1370
1371     def get_selected_rows(self):
1372         rows, model = super(TreeSelection, self).get_selected_rows()
1373         return (model, rows)
1374
1375
1376 TreeSelection = override(TreeSelection)
1377 __all__.append('TreeSelection')
1378
1379
1380 class Button(Gtk.Button, Container):
1381     _init = deprecated_init(Gtk.Button.__init__,
1382                             arg_names=('label', 'stock', 'use_stock', 'use_underline'),
1383                             ignore=('stock',),
1384                             category=PyGTKDeprecationWarning,
1385                             stacklevel=3)
1386
1387     def __init__(self, *args, **kwargs):
1388         # Doubly deprecated initializer, the stock keyword is non-standard.
1389         # Simply give a warning that stock items are deprecated even though
1390         # we want to deprecate the non-standard keyword as well here from
1391         # the overrides.
1392         if 'stock' in kwargs and kwargs['stock']:
1393             warnings.warn('Stock items are deprecated. '
1394                           'Please use: Gtk.Button.new_with_mnemonic(label)',
1395                           PyGTKDeprecationWarning, stacklevel=2)
1396             new_kwargs = kwargs.copy()
1397             new_kwargs['label'] = new_kwargs['stock']
1398             new_kwargs['use_stock'] = True
1399             new_kwargs['use_underline'] = True
1400             del new_kwargs['stock']
1401             Gtk.Button.__init__(self, **new_kwargs)
1402         else:
1403             self._init(*args, **kwargs)
1404
1405 Button = override(Button)
1406 __all__.append('Button')
1407
1408
1409 class LinkButton(Gtk.LinkButton):
1410     __init__ = deprecated_init(Gtk.LinkButton.__init__,
1411                                arg_names=('uri', 'label'),
1412                                category=PyGTKDeprecationWarning)
1413
1414 LinkButton = override(LinkButton)
1415 __all__.append('LinkButton')
1416
1417
1418 class Label(Gtk.Label):
1419     __init__ = deprecated_init(Gtk.Label.__init__,
1420                                arg_names=('label',),
1421                                category=PyGTKDeprecationWarning)
1422
1423 Label = override(Label)
1424 __all__.append('Label')
1425
1426
1427 class Adjustment(Gtk.Adjustment):
1428     _init = deprecated_init(Gtk.Adjustment.__init__,
1429                             arg_names=('value', 'lower', 'upper',
1430                                        'step_increment', 'page_increment', 'page_size'),
1431                             deprecated_aliases={'page_increment': 'page_incr',
1432                                                 'step_increment': 'step_incr'},
1433                             category=PyGTKDeprecationWarning,
1434                             stacklevel=3)
1435
1436     def __init__(self, *args, **kwargs):
1437         self._init(*args, **kwargs)
1438
1439         # The value property is set between lower and (upper - page_size).
1440         # Just in case lower, upper or page_size was still 0 when value
1441         # was set, we set it again here.
1442         if 'value' in kwargs:
1443             self.set_value(kwargs['value'])
1444
1445 Adjustment = override(Adjustment)
1446 __all__.append('Adjustment')
1447
1448
1449 class Table(Gtk.Table, Container):
1450     __init__ = deprecated_init(Gtk.Table.__init__,
1451                                arg_names=('n_rows', 'n_columns', 'homogeneous'),
1452                                deprecated_aliases={'n_rows': 'rows', 'n_columns': 'columns'},
1453                                category=PyGTKDeprecationWarning)
1454
1455     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):
1456         Gtk.Table.attach(self, child, left_attach, right_attach, top_attach, bottom_attach, xoptions, yoptions, xpadding, ypadding)
1457
1458 Table = override(Table)
1459 __all__.append('Table')
1460
1461
1462 class ScrolledWindow(Gtk.ScrolledWindow):
1463     __init__ = deprecated_init(Gtk.ScrolledWindow.__init__,
1464                                arg_names=('hadjustment', 'vadjustment'),
1465                                category=PyGTKDeprecationWarning)
1466
1467 ScrolledWindow = override(ScrolledWindow)
1468 __all__.append('ScrolledWindow')
1469
1470
1471 class HScrollbar(Gtk.HScrollbar):
1472     __init__ = deprecated_init(Gtk.HScrollbar.__init__,
1473                                arg_names=('adjustment',),
1474                                category=PyGTKDeprecationWarning)
1475
1476 HScrollbar = override(HScrollbar)
1477 __all__.append('HScrollbar')
1478
1479
1480 class VScrollbar(Gtk.VScrollbar):
1481     __init__ = deprecated_init(Gtk.VScrollbar.__init__,
1482                                arg_names=('adjustment',),
1483                                category=PyGTKDeprecationWarning)
1484
1485 VScrollbar = override(VScrollbar)
1486 __all__.append('VScrollbar')
1487
1488
1489 class Paned(Gtk.Paned):
1490     def pack1(self, child, resize=False, shrink=True):
1491         super(Paned, self).pack1(child, resize, shrink)
1492
1493     def pack2(self, child, resize=True, shrink=True):
1494         super(Paned, self).pack2(child, resize, shrink)
1495
1496 Paned = override(Paned)
1497 __all__.append('Paned')
1498
1499
1500 class Arrow(Gtk.Arrow):
1501     __init__ = deprecated_init(Gtk.Arrow.__init__,
1502                                arg_names=('arrow_type', 'shadow_type'),
1503                                category=PyGTKDeprecationWarning)
1504
1505 Arrow = override(Arrow)
1506 __all__.append('Arrow')
1507
1508
1509 class IconSet(Gtk.IconSet):
1510     def __new__(cls, pixbuf=None):
1511         if pixbuf is not None:
1512             warnings.warn('Gtk.IconSet(pixbuf) has been deprecated. Please use: '
1513                           'Gtk.IconSet.new_from_pixbuf(pixbuf)',
1514                           PyGTKDeprecationWarning, stacklevel=2)
1515             iconset = Gtk.IconSet.new_from_pixbuf(pixbuf)
1516         else:
1517             iconset = Gtk.IconSet.__new__(cls)
1518         return iconset
1519
1520     def __init__(self, *args, **kwargs):
1521         return super(IconSet, self).__init__()
1522
1523 IconSet = override(IconSet)
1524 __all__.append('IconSet')
1525
1526
1527 class Viewport(Gtk.Viewport):
1528     __init__ = deprecated_init(Gtk.Viewport.__init__,
1529                                arg_names=('hadjustment', 'vadjustment'),
1530                                category=PyGTKDeprecationWarning)
1531
1532 Viewport = override(Viewport)
1533 __all__.append('Viewport')
1534
1535
1536 class TreeModelFilter(Gtk.TreeModelFilter):
1537     def set_visible_func(self, func, data=None):
1538         super(TreeModelFilter, self).set_visible_func(func, data)
1539
1540     def set_value(self, iter, column, value):
1541         # Delegate to child model
1542         iter = self.convert_iter_to_child_iter(iter)
1543         self.get_model().set_value(iter, column, value)
1544
1545 TreeModelFilter = override(TreeModelFilter)
1546 __all__.append('TreeModelFilter')
1547
1548 if Gtk._version != '2.0':
1549     class Menu(Gtk.Menu):
1550         def popup(self, parent_menu_shell, parent_menu_item, func, data, button, activate_time):
1551             self.popup_for_device(None, parent_menu_shell, parent_menu_item, func, data, button, activate_time)
1552     Menu = override(Menu)
1553     __all__.append('Menu')
1554
1555 _Gtk_main_quit = Gtk.main_quit
1556
1557
1558 @override(Gtk.main_quit)
1559 def main_quit(*args):
1560     _Gtk_main_quit()
1561
1562 stock_lookup = strip_boolean_result(Gtk.stock_lookup)
1563 __all__.append('stock_lookup')
1564
1565 initialized, argv = Gtk.init_check(sys.argv)
1566 sys.argv = list(argv)