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