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