summaryrefslogtreecommitdiff
path: root/gi/overrides
diff options
context:
space:
mode:
Diffstat (limited to 'gi/overrides')
-rw-r--r--gi/overrides/GIMarshallingTests.py2
-rw-r--r--gi/overrides/Gdk.py2
-rw-r--r--gi/overrides/Gtk.py548
-rw-r--r--gi/overrides/Makefile.in3
-rw-r--r--gi/overrides/__init__.py43
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_
+