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