summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2000-12-06 06:55:16 +0000
committerJames Henstridge <jamesh@src.gnome.org>2000-12-06 06:55:16 +0000
commit8fd02269f1de89f4e72e316890bbbbc32b81f254 (patch)
tree5b41c5b784185af08d9824d24bb2c931d50a06c1
parente49f0432406a2ea6325caca7b847298c6fa8189b (diff)
downloadpygtk-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--ChangeLog32
-rw-r--r--codegen/argtypes.py1
-rw-r--r--codegen/codegen.py4
-rw-r--r--examples/testgtk/demos/treemodel.py105
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/__init__.py7
-rw-r--r--gtk/gtk-extrafuncs.defs20
-rw-r--r--gtk/gtk.override1
-rw-r--r--gtk/pygtktreemodel.c98
9 files changed, 239 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index b445f953..f2b0660a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;