diff options
Diffstat (limited to 'gi/overrides')
-rw-r--r-- | gi/overrides/GIMarshallingTests.py | 2 | ||||
-rw-r--r-- | gi/overrides/Gdk.py | 2 | ||||
-rw-r--r-- | gi/overrides/Gtk.py | 548 | ||||
-rw-r--r-- | gi/overrides/Makefile.in | 3 | ||||
-rw-r--r-- | gi/overrides/__init__.py | 43 |
5 files changed, 569 insertions, 29 deletions
diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py index ee01495..25a882f 100644 --- a/gi/overrides/GIMarshallingTests.py +++ b/gi/overrides/GIMarshallingTests.py @@ -18,7 +18,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 # USA -from ..types import override +from ..overrides import override from ..importer import modules GIMarshallingTests = modules['GIMarshallingTests'].introspection_module diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py index 23a9d8e..08141d7 100644 --- a/gi/overrides/Gdk.py +++ b/gi/overrides/Gdk.py @@ -19,7 +19,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 # USA -from ..types import override +from ..overrides import override from ..importer import modules Gdk = modules['Gdk'].introspection_module diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py index 1f6901c..a2f38ac 100644 --- a/gi/overrides/Gtk.py +++ b/gi/overrides/Gtk.py @@ -23,7 +23,7 @@ import sys import gobject from gi.repository import Gdk from gi.repository import GObject -from ..types import override +from ..overrides import override from ..importer import modules if sys.version_info >= (3, 0): @@ -36,6 +36,44 @@ else: Gtk = modules['Gtk'].introspection_module __all__ = [] +class Widget(Gtk.Widget): + + def translate_coordinates(self, dest_widget, src_x, src_y): + success, dest_x, dest_y = super(Widget, self).translate_coordinates( + dest_widget, src_x, src_y) + if success: + return (dest_x, dest_y,) + +Widget = override(Widget) +__all__.append('Widget') + +class Container(Gtk.Container, Widget): + + def get_focus_chain(self): + success, widgets = super(Container, self).get_focus_chain() + if success: + return widgets + +Container = override(Container) +__all__.append('Container') + +class Editable(Gtk.Editable): + + def insert_text(self, text, position): + pos = super(Editable, self).insert_text(text, -1, position) + + return pos + + def get_selection_bounds(self): + success, start_pos, end_pos = super(Editable, self).get_selection_bounds() + if success: + return (start_pos, end_pos,) + else: + return tuple() + +Editable = override(Editable) +__all__.append("Editable") + class ActionGroup(Gtk.ActionGroup): def add_actions(self, entries, user_data=None): """ @@ -202,6 +240,16 @@ class UIManager(Gtk.UIManager): UIManager = override(UIManager) __all__.append('UIManager') +class ComboBox(Gtk.ComboBox, Container): + + def get_active_iter(self): + success, aiter = super(ComboBox, self).get_active_iter() + if success: + return aiter + +ComboBox = override(ComboBox) +__all__.append('ComboBox') + class Builder(Gtk.Builder): def connect_signals(self, obj_or_map): @@ -252,10 +300,24 @@ class Builder(Gtk.Builder): Builder = override(Builder) __all__.append('Builder') -class Dialog(Gtk.Dialog): - def __init__(self, title=None, parent=None, flags=0, buttons=None): - Gtk.Dialog.__init__(self) +class Dialog(Gtk.Dialog, Container): + + def __init__(self, + title=None, + parent=None, + flags=0, + buttons=None, + _buttons_property=None, + **kwds): + + # buttons is overloaded by PyGtk so we have to do the same here + # this breaks some subclasses of Dialog so add a _buttons_property + # keyword to work around this + if _buttons_property is not None: + kwds['buttons'] = _buttons_property + + Gtk.Dialog.__init__(self, **kwds) if title: self.set_title(title) if parent: @@ -272,7 +334,7 @@ class Dialog(Gtk.Dialog): except AttributeError: pass - if buttons: + if buttons is not None: self.add_buttons(*buttons) def add_buttons(self, *args): @@ -287,15 +349,14 @@ class Dialog(Gtk.Dialog): will add "Open" and "Close" buttons to dialog. """ - - def buttons(b): + def _button(b): while b: t, r = b[0:2] b = b[2:] yield t, r try: - for text, response in buttons(args): + for text, response in _button(args): self.add_button(text, response) except (IndexError): raise TypeError('Must pass an even number of arguments') @@ -303,6 +364,124 @@ class Dialog(Gtk.Dialog): Dialog = override(Dialog) __all__.append('Dialog') +class MessageDialog(Gtk.MessageDialog, Dialog): + def __init__(self, + parent=None, + flags=0, + type=Gtk.MessageType.INFO, + buttons=Gtk.ButtonsType.NONE, + message_format=None, + **kwds): + + if message_format != None: + kwds['text'] = message_format + Gtk.MessageDialog.__init__(self, + _buttons_property=buttons, + **kwds) + Dialog.__init__(self, parent=parent, flags=flags) + +MessageDialog = override(MessageDialog) +__all__.append('MessageDialog') + +class AboutDialog(Gtk.AboutDialog, Dialog): + def __init__(self, **kwds): + Gtk.AboutDialog.__init__(self, **kwds) + Dialog.__init__(self) + +AboutDialog = override(AboutDialog) +__all__.append('AboutDialog') + +class ColorSelectionDialog(Gtk.ColorSelectionDialog, Dialog): + def __init__(self, title=None, **kwds): + Gtk.ColorSelectionDialog.__init__(self, **kwds) + Dialog.__init__(self, title=title) + +ColorSelectionDialog = override(ColorSelectionDialog) +__all__.append('ColorSelectionDialog') + +class FileChooserDialog(Gtk.FileChooserDialog, Dialog): + def __init__(self, + title=None, + parent=None, + action=Gtk.FileChooserAction.OPEN, + buttons=None, + **kwds): + Gtk.FileChooserDialog.__init__(self, + action=action, + **kwds) + Dialog.__init__(self, + title=title, + parent=parent, + buttons=buttons) + +FileChooserDialog = override(FileChooserDialog) +__all__.append('FileChooserDialog') + +class FontSelectionDialog(Gtk.FontSelectionDialog, Dialog): + def __init__(self, title=None, **kwds): + Gtk.FontSelectionDialog.__init__(self, **kwds) + Dialog.__init__(self, title=title) + +FontSelectionDialog = override(FontSelectionDialog) +__all__.append('FontSelectionDialog') + +class RecentChooserDialog(Gtk.RecentChooserDialog, Dialog): + def __init__(self, + title=None, + parent=None, + manager=None, + buttons=None, + **kwds): + + Gtk.RecentChooserDialog.__init__(self, recent_manager=manager, **kwds) + Dialog.__init__(self, + title=title, + parent=parent, + buttons=buttons) + +RecentChooserDialog = override(RecentChooserDialog) +__all__.append('RecentChooserDialog') + +class IconView(Gtk.IconView): + + def get_item_at_pos(self, x, y): + success, path, cell = super(IconView, self).get_item_at_pos(x, y) + if success: + return (path, cell,) + + def get_visible_range(self): + success, start_path, end_path = super(IconView, self).get_visible_range() + if success: + return (start_path, end_path,) + + def get_dest_item_at_pos(self, drag_x, drag_y): + success, path, pos = super(IconView, self).get_dest_item_at_pos(drag_x, drag_y) + if success: + return path, pos + +IconView = override(IconView) +__all__.append('IconView') + +class IMContext(Gtk.IMContext): + + def get_surrounding(self): + success, text, cursor_index = super(IMContext, self).get_surrounding() + if success: + return (text, cursor_index,) + +IMContext = override(IMContext) +__all__.append('IMContext') + +class RecentInfo(Gtk.RecentInfo): + + def get_application_info(self, app_name): + success, app_exec, count, time = super(RecentInfo, self).get_application_info(app_name) + if success: + return (app_exec, count, time,) + +RecentInfo = override(RecentInfo) +__all__.append('RecentInfo') + class TextBuffer(Gtk.TextBuffer): def _get_or_create_tag_table(self): table = self.get_tag_table() @@ -351,23 +530,121 @@ class TextBuffer(Gtk.TextBuffer): length = len(text) Gtk.TextBuffer.insert_at_cursor(self, text, length) + def get_selection_bounds(self): + success, start, end = super(TextBuffer, self).get_selection_bounds(string, + flags, limit) + return (start, end) + TextBuffer = override(TextBuffer) __all__.append('TextBuffer') +class TextIter(Gtk.TextIter): + + def forward_search(self, string, flags, limit): + success, match_start, match_end = super(TextIter, self).forward_search(string, + flags, limit) + return (match_start, match_end,) + + def backward_search(self, string, flags, limit): + success, match_start, match_end = super(TextIter, self).backward_search(string, + flags, limit) + return (match_start, match_end,) + +TextIter = override(TextIter) +__all__.append('TextIter') + class TreeModel(Gtk.TreeModel): def __len__(self): return self.iter_n_children(None) -TreeModel = override(TreeModel) -__all__.append('TreeModel') + def __bool__(self): + return True + + # alias for Python 2.x object protocol + __nonzero__ = __bool__ + + def __getitem__(self, key): + if isinstance(key, Gtk.TreeIter): + return TreeModelRow(self, key) + elif isinstance(key, int) and key < 0: + index = len(self) + key + if index < 0: + raise IndexError("row index is out of bounds: %d" % key) + try: + aiter = self.get_iter(index) + except ValueError: + raise IndexError("could not find tree path '%s'" % key) + return TreeModelRow(self, aiter) + else: + try: + aiter = self.get_iter(key) + except ValueError: + raise IndexError("could not find tree path '%s'" % key) + return TreeModelRow(self, aiter) -class ListStore(Gtk.ListStore, TreeModel): - def __init__(self, *column_types): - Gtk.ListStore.__init__(self) - self.set_column_types(column_types) + def __iter__(self): + return TreeModelRowIter(self, self.get_iter_first()) - def append(self, row): - treeiter = Gtk.ListStore.append(self) + def get_iter(self, path): + if isinstance(path, Gtk.TreePath): + pass + elif isinstance(path, (int, str,)): + path = self._tree_path_from_string(str(path)) + elif isinstance(path, tuple): + path_str = ":".join(str(val) for val in path) + path = self._tree_path_from_string(path_str) + else: + raise TypeError("tree path must be one of Gtk.TreeIter, Gtk.TreePath, \ + int, str or tuple, not %s" % type(path).__name__) + + success, aiter = super(TreeModel, self).get_iter(path) + if not success: + raise ValueError("invalid tree path '%s'" % path) + return aiter + + def _tree_path_from_string(self, path): + if len(path) == 0: + raise TypeError("could not parse subscript '%s' as a tree path" % path) + try: + return TreePath.new_from_string(path) + except TypeError: + raise TypeError("could not parse subscript '%s' as a tree path" % path) + + def get_iter_first(self): + success, aiter = super(TreeModel, self).get_iter_first() + if success: + return aiter + + def get_iter_from_string(self, path_string): + success, aiter = super(TreeModel, self).get_iter_from_string(path_string) + if not success: + raise ValueError("invalid tree path '%s'" % path_string) + return aiter + + def iter_next(self, aiter): + next_iter = aiter.copy() + success = super(TreeModel, self).iter_next(next_iter) + if success: + return next_iter + + def iter_children(self, aiter): + success, child_iter = super(TreeModel, self).iter_children(aiter) + if success: + return child_iter + + def iter_nth_child(self, parent, n): + success, child_iter = super(TreeModel, self).iter_nth_child(parent, n) + if success: + return child_iter + + def iter_parent(self, aiter): + success, parent_iter = super(TreeModel, self).iter_parent(aiter) + if success: + return parent_iter + + def set_row(self, treeiter, row): + # TODO: Accept a dictionary for row + # model.append(None,{COLUMN_ICON: icon, COLUMN_NAME: name}) n_columns = self.get_n_columns(); if len(row) != n_columns: @@ -377,34 +654,236 @@ class ListStore(Gtk.ListStore, TreeModel): if row[i] is not None: self.set_value(treeiter, i, row[i]) +TreeModel = override(TreeModel) +__all__.append('TreeModel') + +class TreeSortable(Gtk.TreeSortable, ): + + def get_sort_column_id(self): + success, sort_column_id, order = super(TreeSortable, self).get_sort_column_id() + if success: + return (sort_column_id, order,) + else: + return (None, None,) + +TreeSortable = override(TreeSortable) +__all__.append('TreeSortable') + +class ListStore(Gtk.ListStore, TreeModel, TreeSortable): + def __init__(self, *column_types): + Gtk.ListStore.__init__(self) + self.set_column_types(column_types) + + def append(self, row=None): + treeiter = Gtk.ListStore.append(self) + + if row is not None: + self.set_row(treeiter, row) + + return treeiter + + def insert(self, position, row=None): + treeiter = Gtk.ListStore.insert(self, position) + + if row is not None: + self.set_row(treeiter, row) + + return treeiter + + def insert_before(self, sibling, row=None): + treeiter = Gtk.ListStore.insert_before(self, sibling) + + if row is not None: + self.set_row(treeiter, row) + return treeiter + + def insert_after(self, sibling, row=None): + treeiter = Gtk.ListStore.insert_after(self, sibling) + + if row is not None: + self.set_row(treeiter, row) + + return treeiter + + ListStore = override(ListStore) __all__.append('ListStore') -class TreeStore(Gtk.TreeStore, TreeModel): +class TreeModelRow(object): + + def __init__(self, model, iter_or_path): + if not isinstance(model, Gtk.TreeModel): + raise TypeError("expected Gtk.TreeModel, %s found" % type(model).__name__) + self.model = model + if isinstance(iter_or_path, Gtk.TreePath): + self.iter = model.get_iter(iter_or_path) + elif isinstance(iter_or_path, Gtk.TreeIter): + self.iter = iter_or_path + else: + raise TypeError("expected Gtk.TreeIter or Gtk.TreePath, \ + %s found" % type(iter_or_path).__name__) + + @property + def path(self): + return self.model.get_path(self.iter) + + @property + def next(self): + return self.get_next() + + @property + def parent(self): + return self.get_parent() + + def get_next(self): + next_iter = self.model.iter_next(self.iter) + if next_iter: + return TreeModelRow(self.model, next_iter) + + def get_parent(self): + parent_iter = self.model.iter_parent(self.iter) + if parent_iter: + return TreeModelRow(self.model, parent_iter) + + def __getitem__(self, key): + if isinstance(key, int): + if key >= self.model.get_n_columns(): + raise IndexError("column index is out of bounds: %d" % key) + elif key < 0: + key = self._convert_negative_index(key) + return self.model.get_value(self.iter, key) + else: + raise TypeError("indices must be integers, not %s" % type(key).__name__) + + def __setitem__(self, key, value): + if isinstance(key, int): + if key >= self.model.get_n_columns(): + raise IndexError("column index is out of bounds: %d" % key) + elif key < 0: + key = self._convert_negative_index(key) + return self.model.set_value(self.iter, key, value) + else: + raise TypeError("indices must be integers, not %s" % type(key).__name__) + + def _convert_negative_index(self, index): + new_index = self.model.get_n_columns() + index + if new_index < 0: + raise IndexError("column index is out of bounds: %d" % index) + return new_index + + def iterchildren(self): + child_iter = self.model.iter_children(self.iter) + return TreeModelRowIter(self.model, child_iter) + +__all__.append('TreeModelRow') + +class TreeModelRowIter(object): + + def __init__(self, model, aiter): + self.model = model + self.iter = aiter + + def __next__(self): + if not self.iter: + raise StopIteration + row = TreeModelRow(self.model, self.iter) + self.iter = self.model.iter_next(self.iter) + return row + + # alias for Python 2.x object protocol + next = __next__ + + def __iter__(self): + return self + +__all__.append('TreeModelRowIter') + +class TreePath(Gtk.TreePath): + + def __str__(self): + return self.to_string() + + def __lt__(self, other): + return self.compare(other) < 0 + + def __le__(self, other): + return self.compare(other) <= 0 + + def __eq__(self, other): + return self.compare(other) == 0 + + def __ne__(self, other): + return self.compare(other) != 0 + + def __gt__(self, other): + return self.compare(other) > 0 + + def __ge__(self, other): + return self.compare(other) >= 0 + +TreePath = override(TreePath) +__all__.append('TreePath') + +class TreeStore(Gtk.TreeStore, TreeModel, TreeSortable): def __init__(self, *column_types): Gtk.TreeStore.__init__(self) self.set_column_types(column_types) - def append(self, parent, row): - + def append(self, parent, row=None): treeiter = Gtk.TreeStore.append(self, parent) - n_columns = self.get_n_columns(); - if len(row) != n_columns: - raise ValueError('row sequence has the incorrect number of elements') + if row is not None: + self.set_row(treeiter, row) - for i in range(n_columns): - if row[i] is not None: - self.set_value(treeiter, i, row[i]) + return treeiter + + def insert(self, parent, position, row=None): + treeiter = Gtk.TreeStore.insert(self, parent, position) + + if row is not None: + self.set_row(treeiter, row) return treeiter + def insert_before(self, parent, sibling, row=None): + treeiter = Gtk.TreeStore.insert_before(self, parent, sibling) + + if row is not None: + self.set_row(treeiter, row) + + return treeiter + + + def insert_after(self, parent, sibling, row=None): + treeiter = Gtk.TreeStore.insert_after(self, parent, sibling) + + if row is not None: + self.set_row(treeiter, row) + + return treeiter + + TreeStore = override(TreeStore) __all__.append('TreeStore') +class TreeView(Gtk.TreeView, Container): + + def get_path_at_pos(self, x, y): + success, path, column, cell_x, cell_y = super(TreeView, self).get_path_at_pos(x, y) + if success: + return (path, column, cell_x, cell_y,) + + def get_dest_row_at_pos(self, drag_x, drag_y): + success, path, pos = super(TreeView, self).get_dest_row_at_pos(drag_x, drag_y) + if success: + return (path, pos,) + +TreeView = override(TreeView) +__all__.append('TreeView') + class TreeViewColumn(Gtk.TreeViewColumn): def __init__(self, title='', cell_renderer=None, @@ -416,10 +895,27 @@ class TreeViewColumn(Gtk.TreeViewColumn): for (name, value) in attributes.items(): self.add_attribute(cell_renderer, name, value) + def cell_get_position(self, cell_renderer): + success, start_pos, width = super(TreeViewColumn, self).cell_get_position(cell_renderer) + if success: + return (start_pos, width,) + TreeViewColumn = override(TreeViewColumn) __all__.append('TreeViewColumn') -class Button(Gtk.Button): +class TreeSelection(Gtk.TreeSelection): + + def get_selected(self): + success, model, aiter = super(TreeSelection, self).get_selected() + if success: + return (model, aiter) + else: + return (model, None) + +TreeSelection = override(TreeSelection) +__all__.append('TreeSelection') + +class Button(Gtk.Button, Container): def __init__(self, label=None, stock=None, use_underline=False): if stock: label = stock diff --git a/gi/overrides/Makefile.in b/gi/overrides/Makefile.in index 630735c..d0a78be 100644 --- a/gi/overrides/Makefile.in +++ b/gi/overrides/Makefile.in @@ -157,6 +157,8 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM = @PLATFORM@ PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ PYCAIRO_LIBS = @PYCAIRO_LIBS@ @@ -214,7 +216,6 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ diff --git a/gi/overrides/__init__.py b/gi/overrides/__init__.py index e69de29..d4cd80b 100644 --- a/gi/overrides/__init__.py +++ b/gi/overrides/__init__.py @@ -0,0 +1,43 @@ +import gobject + +registry = None +class _Registry(dict): + def __setitem__(self, key, value): + '''We do checks here to make sure only submodules of the override + module are added. Key and value should be the same object and come + from the gi.override module. + + We add the override to the dict as "override_module.name". For instance + if we were overriding Gtk.Button you would retrive it as such: + registry['Gtk.Button'] + ''' + if not key == value: + raise KeyError('You have tried to modify the registry. This should only be done by the override decorator') + + info = getattr(value, '__info__') + if info == None: + raise KeyError('Can not override a type %s, which is not in a gobject introspection typelib' % value.__name__) + + if not value.__module__.startswith('gi.overrides'): + raise KeyError('You have tried to modify the registry outside of the overrides module. This is not allowed') + + g_type = info.get_g_type() + assert g_type != gobject.TYPE_NONE + if g_type != gobject.TYPE_INVALID: + g_type.pytype = value + + # strip gi.overrides from module name + module = value.__module__[13:] + key = "%s.%s" % (module, value.__name__) + super(_Registry, self).__setitem__(key, value) + + def register(self, override_class): + self[override_class] = override_class + +registry = _Registry() + +def override(type_): + '''Decorator for registering an override''' + registry.register(type_) + return type_ + |