diff options
author | James Henstridge <james@daa.com.au> | 2000-12-06 06:55:16 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 2000-12-06 06:55:16 +0000 |
commit | 8fd02269f1de89f4e72e316890bbbbc32b81f254 (patch) | |
tree | 5b41c5b784185af08d9824d24bb2c931d50a06c1 | |
parent | e49f0432406a2ea6325caca7b847298c6fa8189b (diff) | |
download | pygtk-8fd02269f1de89f4e72e316890bbbbc32b81f254.tar.gz |
fix PyObject_CallMethod calls to add parentheses around argument type
2000-12-06 James Henstridge <james@daa.com.au>
* gtk/pygtktreemodel.c: fix PyObject_CallMethod calls to add
parentheses around argument type list.
(pygtk_tree_model_get_flags): decref py_ret -- not Py_None
(pygtk_tree_model_get_n_columns): same here.
(pygtk_tree_model_get_column_type): same here.
(*): conditionally print out debugging messages.
* examples/testgtk/demos/treemodel.py: simple test of
PyGtkTreeModel.
* gtk/pygtktreemodel.c: set iter->tree_node to NULL when returning
FALSE, as GTK sometimes ignores the return value :(
* codegen/codegen.py (interfacetypetmpl): don't set the interface
type as having an instance dictionary.
(write_interface): actually use interfacetypetmpl when writing out
the interface type def.
* codegen/argtypes.py (_conv_special_cases): add a special case
for the underscore version of PyGtkTreeModel.
* gtk/gtk.override: include pygtktreemodel.h
* gtk/__init__.py: don't error out if we can't import ltihooks.
* gtk/gtk-extrafuncs.defs: include defs for PyGtkTreeModel type.
* gtk/Makefile.am (_gtkmodule_la_SOURCES): compile PyGtkTreeModel
into pygtk.
* gtk/pygtktreemodel.c: fix errors.
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | codegen/argtypes.py | 1 | ||||
-rw-r--r-- | codegen/codegen.py | 4 | ||||
-rw-r--r-- | examples/testgtk/demos/treemodel.py | 105 | ||||
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/__init__.py | 7 | ||||
-rw-r--r-- | gtk/gtk-extrafuncs.defs | 20 | ||||
-rw-r--r-- | gtk/gtk.override | 1 | ||||
-rw-r--r-- | gtk/pygtktreemodel.c | 98 |
9 files changed, 239 insertions, 31 deletions
@@ -1,5 +1,37 @@ 2000-12-06 James Henstridge <james@daa.com.au> + * gtk/pygtktreemodel.c: fix PyObject_CallMethod calls to add + parentheses around argument type list. + (pygtk_tree_model_get_flags): decref py_ret -- not Py_None + (pygtk_tree_model_get_n_columns): same here. + (pygtk_tree_model_get_column_type): same here. + (*): conditionally print out debugging messages. + + * examples/testgtk/demos/treemodel.py: simple test of + PyGtkTreeModel. + + * gtk/pygtktreemodel.c: set iter->tree_node to NULL when returning + FALSE, as GTK sometimes ignores the return value :( + + * codegen/codegen.py (interfacetypetmpl): don't set the interface + type as having an instance dictionary. + (write_interface): actually use interfacetypetmpl when writing out + the interface type def. + + * codegen/argtypes.py (_conv_special_cases): add a special case + for the underscore version of PyGtkTreeModel. + + * gtk/gtk.override: include pygtktreemodel.h + + * gtk/__init__.py: don't error out if we can't import ltihooks. + + * gtk/gtk-extrafuncs.defs: include defs for PyGtkTreeModel type. + + * gtk/Makefile.am (_gtkmodule_la_SOURCES): compile PyGtkTreeModel + into pygtk. + + * gtk/pygtktreemodel.c: fix errors. + * gtk/pygtktreemodel.[ch]: check in initial leaky implementation of the GtkTreeModel for use from python. Can't test it right now because gtk head is broken. diff --git a/codegen/argtypes.py b/codegen/argtypes.py index d1b247c0..125f1f40 100644 --- a/codegen/argtypes.py +++ b/codegen/argtypes.py @@ -14,6 +14,7 @@ _conv_special_cases = { 'GnomeRootWin': '_GNOME_ROOTWIN', 'GnomeAppBar': '_GNOME_APPBAR', 'GnomeDEntryEdit': '_GNOME_DENTRY_EDIT', + 'PyGtkTreeModel': '_PYGTK_TREE_MODEL' } def _to_upper_str(str): diff --git a/codegen/codegen.py b/codegen/codegen.py index 7e15fafb..4e64d8d1 100644 --- a/codegen/codegen.py +++ b/codegen/codegen.py @@ -130,7 +130,7 @@ interfacetypetmpl = 'PyExtensionClass Py%(class)s_Type = {\n' + \ ' 0L, 0L,\n' + \ ' NULL, /* Documentation string */\n' + \ ' %(methods)s,\n' + \ - ' EXTENSIONCLASS_BASICNEW_FLAG,\n' + \ + ' 0,\n' + \ '};\n\n' def fixname(name): @@ -411,7 +411,7 @@ def write_interface(parser, interface, overrides, fp=sys.stdout): # write the type template dict = { 'class': interface.c_name, 'getattr': '0' } dict['methods'] = 'METHOD_CHAIN(_Py' + dict['class'] + '_methods)' - fp.write(typetmpl % dict) + fp.write(interfacetypetmpl % dict) def write_functions(parser, overrides, prefix, fp=sys.stdout): fp.write('\n/* ----------- functions ----------- */\n\n') diff --git a/examples/testgtk/demos/treemodel.py b/examples/testgtk/demos/treemodel.py new file mode 100644 index 00000000..70b28d52 --- /dev/null +++ b/examples/testgtk/demos/treemodel.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +'''Tree Model Test + +This test is designed to demonstrate creating a new type of tree model +in python for use with the new tree widget in gtk 2.0.''' +description = 'Tree Model' + +import gtk + +# to create a new GtkTreeModel from python, you must derive from +# PyGtkTreeModel. +class MyTreeModel(gtk.PyGtkTreeModel): + '''This class represents the model of a tree. The iterators used + to represent positions are converted to python objects when passed + to the on_* methods. This means you can use any python object to + represent a node in the tree. The None object represents a NULL + iterator. + + In this tree, we use simple tuples to represent nodes, which also + happen to be the tree paths for those nodes. This model is a tree + of depth 3 with 5 nodes at each level of the tree. The values in + the tree are just the string representations of the nodes.''' + + TREE_DEPTH = 4 + TREE_SIBLINGS = 5 + def __init__(self): + '''constructor for the model. Make sure you call + PyGtkTreeModel.__init__''' + gtk.PyGtkTreeModel.__init__(self) + + # the implementations for GtkTreeModel methods are prefixed with on_ + def on_get_flags(self): + '''returns the GtkTreeModelFlags for this particular type of model''' + return 0 + def on_get_n_columns(self): + '''returns the number of columns in the model''' + return 1 + def on_get_column_type(self, index): + '''returns the type of a column in the model''' + STRING_TYPE = 14 # XXXX have to fix this up at some point + return STRING_TYPE + def on_get_path(self, node): + '''returns the tree path (a tuple of indices at the various + levels) for a particular node.''' + return obj + def on_get_value(self, node, column): + '''returns the value stored in a particular column for the node''' + assert column == 0 + return `node` + def on_iter_next(self, node): + '''returns the next node at this level of the tree''' + if node[-1] == self.TREE_SIBLINGS - 1: # last node at level + return None + return node[:-1] + (node[-1]+1,) + def on_iter_children(self, node): + '''returns the first child of this node''' + if node == None: # top of tree + return (0,) + if len(node) >= self.TREE_DEPTH: # no more levels + return None + return node + (0,) + def on_iter_has_child(self, node): + '''returns true if this node has children''' + return len(node) < self.TREE_DEPTH + def on_iter_n_children(self, node): + '''returns the number of children of this node''' + if len(node) < self.TREE_DEPTH: + return self.TREE_SIBLINGS + else: + return 0 + def on_iter_nth_child(self, node, n): + '''returns the nth child of this node''' + if node == None: + return (n,) + if len(node) < self.TREE_DEPTH and n < self.TREE_SIBLINGS: + return node + (n,) + else: + return None + def on_iter_parent(self, node): + '''returns the parent of this node''' + if len(node) == 0: + return None + else: + return node[:-1] + +def main(): + window = gtk.GtkWindow() + if __name__ == '__main__': + window.connect('destroy', lambda win: gtk.main_quit()) + window.set_title('Menus') + + model = MyTreeModel() + tree_view = gtk.GtkTreeView(model) + cell = gtk.GtkCellRendererText() + # the text in the column comes from column 0 + column = gtk.GtkTreeViewColumn("tuples", cell, text=0) + tree_view.append_column(column) + + window.add(tree_view) + window.show_all() + + if __name__ == '__main__': gtk.main() + +if __name__ == '__main__': main() + diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 52a9a27b..b94c5dcd 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -26,6 +26,8 @@ _gtkmodule_la_SOURCES = \ gtkmodule.c \ gtkobject-support.c \ gtk-types.c \ + pygtktreemodel.h \ + pygtktreemodel.c \ gtk.c #imlibmodule_la_LDFLAGS = -module -avoid-version diff --git a/gtk/__init__.py b/gtk/__init__.py index 339fea7c..146db8b6 100644 --- a/gtk/__init__.py +++ b/gtk/__init__.py @@ -1,8 +1,11 @@ # -*- Mode: Python; py-indent-offset: 4 -*- # this can go when things are a little further along -import ltihooks -del ltihooks +try: + import ltihooks + del ltihooks +except ImportError: + pass # hack so that ltihooks is used when importing ExtensionClass ... import ExtensionClass diff --git a/gtk/gtk-extrafuncs.defs b/gtk/gtk-extrafuncs.defs index 35367d2d..52c6dcee 100644 --- a/gtk/gtk-extrafuncs.defs +++ b/gtk/gtk-extrafuncs.defs @@ -25,3 +25,23 @@ (c-name gtk_widget_get_allocation) (return-type GtkAllocation) ) + +;; PyGtkTreeModel + +(object TreeModel + (in-module PyGtk) + (parent Object (G)) + (c-name PyGtkTreeModel) + (implements GtkTreeModel) +) + +(function pygtk_tree_model_get_type + (c-name pygtk_tree_model_get_type) + (return-type GtkType) +) + +(function pygtk_tree_model_new + (c-name pygtk_tree_model_new) + (is-constructor-of PyGtkTreeModel) + (return-type PyGtkTreeModel*) +) diff --git a/gtk/gtk.override b/gtk/gtk.override index f232cd70..3f44ce66 100644 --- a/gtk/gtk.override +++ b/gtk/gtk.override @@ -6,6 +6,7 @@ headers #include <gtk/gtk.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include "pygtk-private.h" +#include "pygtktreemodel.h" /* small fix */ #undef gdk_window_get_type diff --git a/gtk/pygtktreemodel.c b/gtk/pygtktreemodel.c index 02de0c40..2bc5e309 100644 --- a/gtk/pygtktreemodel.c +++ b/gtk/pygtktreemodel.c @@ -6,6 +6,10 @@ #include "pygtktreemodel.h" #include <Python.h> #include "pygobject.h" +#include "pygtk-private.h" + +/* define this to print out debug messages */ +#undef DEBUG_TREE_MODEL static void pygtk_tree_model_class_init(PyGtkTreeModelClass *klass); static void pygtk_tree_model_init(PyGtkTreeModel *self); @@ -155,7 +159,7 @@ pygtk_tree_model_new(void) /* format of GtkTreeIter's for PyGtkTreeModel: - * tree_node1 == python object + * tree_node == python object * tree_node2 == floating reference? * * I haven't worked out how everything should work. For now I will @@ -169,15 +173,18 @@ pygtk_tree_model_get_flags(GtkTreeModel *tree_model) { PyObject *self, *py_ret; - g_return_val_if_fail(PYGTK_IS_TREE_MODEL(tree_model)); + g_return_val_if_fail(PYGTK_IS_TREE_MODEL(tree_model), 0); /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("get_flags()"); +#endif py_ret = PyObject_CallMethod(self, METHOD_PREFIX "get_flags", ""); if (py_ret) { - guint ret = PyInt_FromLong(py_ret); + guint ret = PyInt_AsLong(py_ret); - Py_DECREF(Py_None); + Py_DECREF(py_ret); return ret; } else { PyErr_Print(); @@ -196,11 +203,14 @@ pygtk_tree_model_get_n_columns(GtkTreeModel *tree_model) /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("get_n_columns()"); +#endif py_ret = PyObject_CallMethod(self, METHOD_PREFIX "get_n_columns", ""); if (py_ret) { - gint ret = PyInt_FromLong(py_ret); + gint ret = PyInt_AsLong(py_ret); - Py_DECREF(Py_None); + Py_DECREF(py_ret); return ret; } else { PyErr_Print(); @@ -219,12 +229,15 @@ pygtk_tree_model_get_column_type(GtkTreeModel *tree_model, gint index) /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("get_column_type(%d)", index); +#endif py_ret = PyObject_CallMethod(self, METHOD_PREFIX "get_column_type", - "i", index); + "(i)", index); if (py_ret) { - GType ret = PyInt_FromLong(py_ret); + GType ret = PyInt_AsLong(py_ret); - Py_DECREF(Py_None); + Py_DECREF(py_ret); return ret; } else { PyErr_Print(); @@ -244,12 +257,15 @@ pygtk_tree_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter) /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); - py_ret = PyObject_CallMethod(self, METHOD_PREFIX "get_column_type", - "O", (PyObject *)iter->tree_node1); +#ifdef DEBUG_TREE_MODEL + g_message("get_tree_path(%p)", iter); +#endif + py_ret = PyObject_CallMethod(self, METHOD_PREFIX "get_tree_path", + "(O)", (PyObject *)iter->tree_node); if (py_ret) { GtkTreePath *path = pygtk_tree_path_from_pyobject(py_ret); - Py_DECREF(Py_None); + Py_DECREF(py_ret); return path; } else { PyErr_Print(); @@ -267,15 +283,17 @@ pygtk_tree_model_get_value(GtkTreeModel*tree_model, GtkTreeIter *iter, g_return_if_fail(tree_model != NULL); g_return_if_fail(PYGTK_IS_TREE_MODEL(tree_model)); g_return_if_fail(iter != NULL); - /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("get_value(%p, %d)", iter, column); +#endif /* init value to column type */ g_value_init(value, pygtk_tree_model_get_column_type(tree_model, column)); py_value = PyObject_CallMethod(self, METHOD_PREFIX "get_value", - "Oi", (PyObject *)iter->tree_node1, column); + "(Oi)", (PyObject *)iter->tree_node,column); if (py_value) { pyg_value_from_pyobject(value, py_value); @@ -297,18 +315,23 @@ pygtk_tree_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter) /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("iter_next(%p)", iter); +#endif py_ret = PyObject_CallMethod(self, METHOD_PREFIX "iter_next", - "O", (PyObject *)iter->tree_node1); + "(O)", (PyObject *)iter->tree_node); if (py_ret) { if (py_ret != Py_None) { /* XXXX handle reference counting here */ - iter->tree_node1 = py_ret; + iter->tree_node = py_ret; return TRUE; } else { + iter->tree_node = NULL; Py_DECREF(py_ret); return FALSE; } } else { + iter->tree_node = NULL; PyErr_Print(); PyErr_Clear(); return FALSE; @@ -327,19 +350,24 @@ pygtk_tree_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); - if (parent) py_parent = (PyObject *)parent->tree_node1; +#ifdef DEBUG_TREE_MODEL + g_message("iter_children(%p, %p)", iter, parent); +#endif + if (parent) py_parent = (PyObject *)parent->tree_node; py_ret = PyObject_CallMethod(self, METHOD_PREFIX "iter_children", - "O", py_parent); + "(O)", py_parent); if (py_ret) { if (py_ret != Py_None) { /* XXXX handle reference counting here */ - iter->tree_node1 = py_ret; + iter->tree_node = py_ret; return TRUE; } else { + iter->tree_node = NULL; Py_DECREF(py_ret); return FALSE; } } else { + iter->tree_node = NULL; PyErr_Print(); PyErr_Clear(); return FALSE; @@ -357,8 +385,11 @@ pygtk_tree_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter) /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("iter_has_child(%p)", iter); +#endif py_ret = PyObject_CallMethod(self, METHOD_PREFIX "iter_has_child", - "O", (PyObject *)iter->tree_node1); + "(O)", (PyObject *)iter->tree_node); if (py_ret) { gboolean ret = PyObject_IsTrue(py_ret); @@ -382,8 +413,11 @@ pygtk_tree_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter) /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); +#ifdef DEBUG_TREE_MODEL + g_message("iter_n_children(%p)", iter); +#endif py_ret = PyObject_CallMethod(self, METHOD_PREFIX "iter_n_children", - "O", (PyObject *)iter->tree_node1); + "(O)", (PyObject *)iter->tree_node); if (py_ret) { gint ret = PyInt_AsLong(py_ret); @@ -408,19 +442,24 @@ pygtk_tree_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); - if (parent) py_parent = (PyObject *)parent->tree_node1; +#ifdef DEBUG_TREE_MODEL + g_message("iter_nth_child(%p, %p, %d)", iter, parent, n); +#endif + if (parent) py_parent = (PyObject *)parent->tree_node; py_ret = PyObject_CallMethod(self, METHOD_PREFIX "iter_nth_child", - "Oi", py_parent, n); + "(Oi)", py_parent, n); if (py_ret) { if (py_ret != Py_None) { /* XXXX handle reference counting here */ - iter->tree_node1 = py_ret; + iter->tree_node = py_ret; return TRUE; } else { + iter->tree_node = NULL; Py_DECREF(py_ret); return FALSE; } } else { + iter->tree_node = NULL; PyErr_Print(); PyErr_Clear(); return FALSE; @@ -439,19 +478,24 @@ pygtk_tree_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, /* this call finds the wrapper for this GObject */ self = pygobject_new((GObject *)tree_model); - if (child) py_child = (PyObject *)child->tree_node1; +#ifdef DEBUG_TREE_MODEL + g_message("iter_parent(%p, %p)", iter, child); +#endif + if (child) py_child = (PyObject *)child->tree_node; py_ret = PyObject_CallMethod(self, METHOD_PREFIX "iter_parent", - "O", py_child); + "(O)", py_child); if (py_ret) { if (py_ret != Py_None) { /* XXXX handle reference counting here */ - iter->tree_node1 = py_ret; + iter->tree_node = py_ret; return TRUE; } else { + iter->tree_node = NULL; Py_DECREF(py_ret); return FALSE; } } else { + iter->tree_node = NULL; PyErr_Print(); PyErr_Clear(); return FALSE; |