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