1/* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygtk- Python bindings for the GTK toolkit.
3 * Copyright (C) 1998-2003  James Henstridge
4 *
5 *   gtktreeview.override: overrides for the gtk.TreeView object.
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 Street, Fifth Floor, Boston, MA 02110-1301
20 * USA
21 */
22%%
23headers
24#include "pygtktreemodel.h"
25#include "pygtkcellrenderer.h"
26
27static void
28pygtk_cell_data_func_marshal (GtkCellLayout *cell_layout,
29                              GtkCellRenderer   *cell,
30                              GtkTreeModel      *tree_model,
31                              GtkTreeIter       *iter,
32			      gpointer           data);
33
34%%
35init
36    PyGtkListStore_Type.tp_as_number  = PyGtkTreeModel_Type.tp_as_number;
37    PyGtkListStore_Type.tp_as_mapping = PyGtkTreeModel_Type.tp_as_mapping;
38    PyGtkListStore_Type.tp_iter       = PyGtkTreeModel_Type.tp_iter;
39    PyGtkTreeStore_Type.tp_as_number  = PyGtkTreeModel_Type.tp_as_number;
40    PyGtkTreeStore_Type.tp_as_mapping = PyGtkTreeModel_Type.tp_as_mapping;
41    PyGtkTreeStore_Type.tp_iter       = PyGtkTreeModel_Type.tp_iter;
42    PyPyGtkGenericTreeModel_Type.tp_as_number  = PyGtkTreeModel_Type.tp_as_number;
43    PyPyGtkGenericTreeModel_Type.tp_as_mapping = PyGtkTreeModel_Type.tp_as_mapping;
44    PyPyGtkGenericTreeModel_Type.tp_iter       = PyGtkTreeModel_Type.tp_iter;
45    PyGtkTreeModelSort_Type.tp_as_number  = PyGtkTreeModel_Type.tp_as_number;
46    PyGtkTreeModelSort_Type.tp_as_mapping = PyGtkTreeModel_Type.tp_as_mapping;
47    PyGtkTreeModelSort_Type.tp_iter       = PyGtkTreeModel_Type.tp_iter;
48    PyGtkTreeModelFilter_Type.tp_as_number  = PyGtkTreeModel_Type.tp_as_number;
49    PyGtkTreeModelFilter_Type.tp_as_mapping = PyGtkTreeModel_Type.tp_as_mapping;
50    PyGtkTreeModelFilter_Type.tp_iter       = PyGtkTreeModel_Type.tp_iter;
51%%
52ignore-glob
53  gtk_tree_path_*
54%%
55ignore
56  gtk_tree_view_new
57  gtk_tree_model_get_valist
58  gtk_tree_row_reference_new_proxy
59  gtk_tree_row_reference_inserted
60  gtk_tree_row_reference_deleted
61  gtk_tree_row_reference_reordered
62  gtk_tree_view_column_set_cell_data_func
63  gtk_tree_view_column_pack_start
64  gtk_tree_view_column_pack_end
65  gtk_tree_view_column_clear
66  gtk_tree_view_column_set_attributes
67  gtk_tree_view_get_row_separator_func
68  gtk_tree_view_get_search_equal_func
69  gtk_tree_view_get_search_position_func
70  gtk_list_store_insert_with_values
71  gtk_list_store_insert_with_valuesv
72  gtk_tree_store_insert_with_values
73  gtk_tree_store_insert_with_valuesv
74%%
75new-constructor GTK_TYPE_TREE_VIEW_COLUMN
76%%
77override gtk_tree_view_column_new kwargs
78static int
79_wrap_gtk_tree_view_column_new(PyGObject *self, PyObject*args, PyObject*kwargs)
80{
81    PyObject *py_cell = NULL, *key, *item;
82    GtkTreeViewColumn *tvc;
83    gchar *title = NULL;
84    GtkCellRenderer *cell = NULL;
85    Py_ssize_t i = 0;
86
87    if (!PyArg_ParseTuple(args, "|zO:GtkTreeViewColumn.__init__", &title,
88                          &py_cell))
89        return -1;
90    if (py_cell != NULL) {
91        if (pygobject_check(py_cell, &PyGtkCellRenderer_Type))
92            cell = GTK_CELL_RENDERER(pygobject_get(py_cell));
93        else if (py_cell != Py_None) {
94            PyErr_SetString(PyExc_TypeError,
95                            "cell must be a GtkCellRenderer or None");
96            return -1;
97        }
98    }
99
100    pygobject_construct(self, "title", title, NULL);
101    tvc = GTK_TREE_VIEW_COLUMN(self->obj);
102
103    if (cell)
104        gtk_tree_view_column_pack_start(tvc, cell, TRUE);
105
106    if (kwargs) {
107        while (PyDict_Next(kwargs, &i, &key, &item)) {
108            gchar *attr = PyString_AsString(key);
109
110            if (!PyInt_Check(item)) {
111                gchar err[128];
112                g_snprintf(err, sizeof(err),
113                           "%s must be an integer column number", attr);
114                PyErr_SetString(PyExc_TypeError, err);
115                g_object_unref(tvc);
116                self->obj = NULL;
117                return -1;
118            }
119
120            if (PyBool_Check(item)) {
121                g_warning("column number is a boolean, but will be interpreted "
122                          "as an integer; this is likely not what you intended");
123            }
124
125            gtk_tree_view_column_add_attribute(tvc, cell, attr,
126                                               PyInt_AsLong(item));
127        }
128    }
129    return 0;
130}
131%%
132override gtk_tree_view_column_cell_get_size kwargs
133static PyObject *
134_wrap_gtk_tree_view_column_cell_get_size(PyGObject *self, PyObject *args, PyObject *kwargs)
135{
136    static char *kwlist[] = { "cell_area", NULL };
137    PyObject *py_cell_area = Py_None;
138    GdkRectangle cell_area = { 0, 0, 0, 0};
139    gint x_offset = 0, y_offset = 0, width, height;
140
141    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
142				     "|O:GtkTreeViewColumn.cell_get_size",
143				     kwlist, &py_cell_area))
144        return NULL;
145
146    if (py_cell_area != Py_None) {
147        if (!pygdk_rectangle_from_pyobject(py_cell_area, &cell_area))
148            return NULL;
149    }
150
151    gtk_tree_view_column_cell_get_size(GTK_TREE_VIEW_COLUMN(self->obj),
152                                       (py_cell_area == Py_None) ? NULL : &cell_area,
153                                       &x_offset, &y_offset, &width, &height);
154
155    return Py_BuildValue("(Niiii)",
156                         pyg_boxed_new(GDK_TYPE_RECTANGLE,
157                                       &cell_area, TRUE, TRUE),
158                         x_offset, y_offset, width, height);
159}
160%%
161override gtk_tree_view_column_get_cell_renderers noargs
162static PyObject *
163_wrap_gtk_tree_view_column_get_cell_renderers(PyGObject *self)
164{
165    GList *list, *tmp;
166    PyObject *ret;
167
168    list = gtk_tree_view_column_get_cell_renderers(
169                        GTK_TREE_VIEW_COLUMN(self->obj));
170
171    ret = PyList_New(0);
172    for (tmp = list; tmp != NULL; tmp = tmp->next) {
173        GtkWidget *renderer = tmp->data;
174        PyObject *item = pygobject_new((GObject *)renderer);
175
176        PyList_Append(ret, item);
177        Py_DECREF(item);
178    }
179    g_list_free(list);
180    return ret;
181}
182%%
183override gtk_cell_layout_set_cell_data_func kwargs
184static void
185pygtk_cell_data_func_marshal (GtkCellLayout *cell_layout,
186                              GtkCellRenderer *cell,
187                              GtkTreeModel *tree_model,
188                              GtkTreeIter *iter, gpointer data)
189{
190    PyGILState_STATE state;
191    PyGtkCustomNotify *cunote = data;
192    PyObject *retobj;
193    PyObject *pycelllayout, *pycell, *pytreemodel, *pyiter;
194
195    g_assert (cunote->func);
196
197    state = pyg_gil_state_ensure();
198
199    pycelllayout = pygobject_new((GObject *)cell_layout);
200    pycell = pygobject_new((GObject *)cell);
201    pytreemodel = pygobject_new((GObject *)tree_model);
202    pyiter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter,
203                           FALSE, FALSE);
204    if (cunote->data)
205        retobj = PyEval_CallFunction(cunote->func, "(NNNNO)",
206                                     pycelllayout, pycell,
207                                     pytreemodel, pyiter, cunote->data);
208    else
209        retobj = PyEval_CallFunction(cunote->func, "(NNNN)",
210                                     pycelllayout, pycell,
211                                     pytreemodel, pyiter);
212
213    if (retobj == NULL) {
214        PyErr_Print();
215    } else
216        Py_DECREF(retobj);
217
218    pyg_gil_state_release(state);
219}
220
221static PyObject *
222_wrap_gtk_cell_layout_set_cell_data_func (PyGObject *self, PyObject *args,
223                                               PyObject *kwargs)
224{
225    PyObject *pycell, *pyfunc, *pyarg = NULL;
226    GtkCellRenderer *cell;
227    PyGtkCustomNotify *cunote;
228
229    if (!PyArg_ParseTuple(args, "OO|O:GtkCellLayout.set_cell_data_func",
230                          &pycell, &pyfunc, &pyarg))
231        return NULL;
232
233    if (pygobject_check(pycell, &PyGtkCellRenderer_Type))
234        cell = GTK_CELL_RENDERER(pygobject_get(pycell));
235    else {
236        PyErr_SetString(PyExc_TypeError,
237                        "first argument must be a GtkCellRenderer");
238        return NULL;
239    }
240
241    if (pyfunc == Py_None) {
242	gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(self->obj), cell,
243                                           NULL, NULL, NULL);
244    } else {
245	cunote = g_new0(PyGtkCustomNotify, 1);
246	cunote->func = pyfunc;
247	cunote->data = pyarg;
248	Py_INCREF(cunote->func);
249	Py_XINCREF(cunote->data);
250
251	gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(self->obj), cell,
252                                           pygtk_cell_data_func_marshal,
253                                           cunote,
254                                           pygtk_custom_destroy_notify);
255    }
256
257    Py_INCREF(Py_None);
258    return Py_None;
259}
260%%
261override gtk_tree_view_insert_column_with_data_func kwargs
262static PyObject *
263_wrap_gtk_tree_view_insert_column_with_data_func (PyGObject *self,
264                                                  PyObject *args,
265                                                  PyObject *kwargs)
266{
267    int position;
268    gchar *title;
269    PyObject *pycell,*pyfunc, *pyarg = NULL;
270    GtkCellRenderer *cell;
271    PyGtkCustomNotify *cunote;
272    gint retval;
273
274    if (!PyArg_ParseTuple(args,
275                          "isOO|O:GtkTreeView.insert_column_with_data_func",
276                          &position, &title, &pycell, &pyfunc, &pyarg))
277        return NULL;
278
279    if (pygobject_check(pycell, &PyGtkCellRenderer_Type))
280        cell = GTK_CELL_RENDERER(pygobject_get(pycell));
281    else {
282        PyErr_SetString(PyExc_TypeError,
283                        "first argument must be a GtkCellRenderer");
284        return NULL;
285    }
286
287    cunote = g_new0(PyGtkCustomNotify, 1);
288    cunote->func = pyfunc;
289    cunote->data = pyarg;
290    Py_INCREF(cunote->func);
291    Py_XINCREF(cunote->data);
292
293    retval = gtk_tree_view_insert_column_with_data_func (
294        GTK_TREE_VIEW (self->obj),
295        position,
296        title,
297        cell,
298        (GtkTreeCellDataFunc)pygtk_cell_data_func_marshal,
299        cunote,
300        pygtk_custom_destroy_notify);
301    return PyInt_FromLong(retval);
302}
303%%
304override gtk_tree_view_get_path_at_pos kwargs
305static PyObject *
306_wrap_gtk_tree_view_get_path_at_pos(PyGObject *self, PyObject *args,
307                                    PyObject *kwargs)
308{
309    static char *kwlist[] = { "x", "y", NULL };
310    gint x, y;
311    GtkTreePath *path;
312    GtkTreeViewColumn *column;
313    gint cell_x, cell_y;
314
315    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
316                                     "ii:GtkTreeView.get_path_at_pos",
317                                     kwlist, &x, &y))
318        return NULL;
319    if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(self->obj), x, y,
320                                      &path, &column, &cell_x, &cell_y)) {
321        PyObject *ret = PyTuple_New(4);
322
323        if (path) {
324            PyTuple_SetItem(ret, 0, pygtk_tree_path_to_pyobject(path));
325            gtk_tree_path_free(path);
326        } else {
327            Py_INCREF(Py_None);
328            PyTuple_SetItem(ret, 0, Py_None);
329        }
330        PyTuple_SetItem(ret, 1, pygobject_new((GObject *)column));
331        PyTuple_SetItem(ret, 2, PyInt_FromLong(cell_x));
332        PyTuple_SetItem(ret, 3, PyInt_FromLong(cell_y));
333        return ret;
334    } else {
335        Py_INCREF(Py_None);
336        return Py_None;
337    }
338}
339%%
340override gtk_tree_view_insert_column_with_attributes kwargs
341static PyObject *
342_wrap_gtk_tree_view_insert_column_with_attributes(PyGObject *self, PyObject *args,
343                                                  PyObject *kwargs)
344{
345    gint position, columns, real_position;
346    GtkTreeViewColumn *column;
347    GtkCellRenderer *cell;
348    PyObject *py_cell, *key, *item;
349    const char *title;
350    Py_ssize_t i = 0;
351
352    if (!PyArg_ParseTuple(args,
353                          "isO!:GtkTreeView.insert_column_with_attributes",
354                          &position, &title, &PyGtkCellRenderer_Type, &py_cell))
355        return NULL;
356
357    cell = GTK_CELL_RENDERER(pygobject_get(py_cell));
358
359    columns =
360        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(self->obj),
361                                                     position, title, cell,
362                                                     NULL);
363    if (position == -1) {
364        real_position = columns - 1;
365    } else {
366        real_position = position;
367    }
368
369    column = gtk_tree_view_get_column (GTK_TREE_VIEW(self->obj),
370                                       real_position);
371
372    if (kwargs) {
373        while (PyDict_Next(kwargs, &i, &key, &item)) {
374            gchar *attr = PyString_AsString(key);
375
376            if (!PyInt_Check(item)) {
377                gchar err[128];
378                g_snprintf(err, sizeof(err),
379                           "%s must be an integer column number", attr);
380                PyErr_SetString(PyExc_TypeError, err);
381                return NULL;
382            }
383            gtk_tree_view_column_add_attribute(column, cell, attr,
384                                               PyInt_AsLong(item));
385        }
386    }
387    return pygobject_new ((GObject *) column);
388}
389%%
390override gtk_tree_view_get_visible_rect noargs
391static PyObject *
392_wrap_gtk_tree_view_get_visible_rect(PyGObject *self)
393{
394    GdkRectangle visible_rect;
395
396    gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(self->obj), &visible_rect);
397
398    return pyg_boxed_new(GDK_TYPE_RECTANGLE, &visible_rect, TRUE, TRUE);
399}
400%%
401override gtk_tree_view_get_cell_area kwargs
402static PyObject *
403_wrap_gtk_tree_view_get_cell_area(PyGObject *self, PyObject *args, PyObject *kwargs)
404{
405    static char *kwlist[] = { "path", "column", NULL };
406    PyObject *py_path;
407    PyGObject *column;
408    GdkRectangle rect;
409    GtkTreePath *path;
410
411    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO!:GtkTreeView.get_cell_area", kwlist, &py_path, &PyGtkTreeViewColumn_Type, &column))
412        return NULL;
413    path = pygtk_tree_path_from_pyobject(py_path);
414    if (!path) {
415        PyErr_SetString(PyExc_TypeError, "could not convert path to a GtkTreePath");
416        return NULL;
417    }
418    gtk_tree_view_get_cell_area(GTK_TREE_VIEW(self->obj), path, GTK_TREE_VIEW_COLUMN(column->obj), &rect);
419    if (path)
420        gtk_tree_path_free(path);
421    return pyg_boxed_new(GDK_TYPE_RECTANGLE, &rect, TRUE, TRUE);
422}
423%%
424override gtk_tree_view_get_background_area kwargs
425static PyObject *
426_wrap_gtk_tree_view_get_background_area(PyGObject *self, PyObject *args, PyObject *kwargs)
427{
428    static char *kwlist[] = { "path", "column", NULL };
429    PyObject *py_path;
430    PyGObject *column;
431    GdkRectangle rect;
432    GtkTreePath *path;
433
434    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO!:GtkTreeView.get_background_area", kwlist, &py_path, &PyGtkTreeViewColumn_Type, &column))
435        return NULL;
436    path = pygtk_tree_path_from_pyobject(py_path);
437    if (!path) {
438        PyErr_SetString(PyExc_TypeError, "could not convert path to a GtkTreePath");
439        return NULL;
440    }
441    gtk_tree_view_get_background_area(GTK_TREE_VIEW(self->obj), path, GTK_TREE_VIEW_COLUMN(column->obj), &rect);
442    if (path)
443        gtk_tree_path_free(path);
444    return pyg_boxed_new(GDK_TYPE_RECTANGLE, &rect, TRUE, TRUE);
445}
446%%
447override gtk_tree_view_widget_to_tree_coords args
448static PyObject *
449_wrap_gtk_tree_view_widget_to_tree_coords(PyGObject *self, PyObject *args)
450{
451    gint wx, wy, tx, ty;
452
453    if (!PyArg_ParseTuple(args, "ii:GtkTreeView.widget_to_tree_coords",
454                          &wx, &wy)) {
455        return NULL;
456    }
457
458    gtk_tree_view_widget_to_tree_coords(GTK_TREE_VIEW(self->obj), wx, wy, &tx, &ty);
459
460    return Py_BuildValue("(ii)", tx, ty);
461}
462%%
463override gtk_tree_view_tree_to_widget_coords args
464static PyObject *
465_wrap_gtk_tree_view_tree_to_widget_coords(PyGObject *self, PyObject *args)
466{
467    gint tx, ty, wx, wy;
468
469    if (!PyArg_ParseTuple(args, "ii:GtkTreeView.tree_to_widget_coords",
470                          &tx, &ty)) {
471        return NULL;
472    }
473
474    gtk_tree_view_tree_to_widget_coords(GTK_TREE_VIEW(self->obj), tx, ty, &wx, &wy);
475
476    return Py_BuildValue("(ii)", wx, wy);
477}
478%%
479override gtk_tree_view_get_cursor noargs
480static PyObject *
481_wrap_gtk_tree_view_get_cursor(PyGObject *self)
482{
483    PyObject *py_path;
484    PyObject *py_column;
485    GtkTreePath *path;
486    GtkTreeViewColumn *column;
487
488    gtk_tree_view_get_cursor(GTK_TREE_VIEW(self->obj),
489                             &path, &column);
490
491    if (path != NULL) {
492        py_path = pygtk_tree_path_to_pyobject(path);
493    } else {
494        Py_INCREF(Py_None);
495        py_path = Py_None;
496    }
497
498    if (column != NULL) {
499        py_column = pygobject_new((GObject*)column);
500    } else {
501        Py_INCREF(Py_None);
502        py_column = Py_None;
503    }
504
505    return Py_BuildValue("(NN)", py_path, py_column);
506}
507%%
508override gtk_tree_view_get_columns noargs
509static PyObject *
510_wrap_gtk_tree_view_get_columns(PyGObject *self)
511{
512    GList *list, *tmp;
513    PyObject *py_list;
514
515    list = gtk_tree_view_get_columns(GTK_TREE_VIEW(self->obj));
516
517    if ((py_list = PyList_New(0)) == NULL) {
518        g_list_free(list);
519        return NULL;
520    }
521    for (tmp = list; tmp != NULL; tmp = tmp->next) {
522        PyObject *gtk_obj = pygobject_new(G_OBJECT(tmp->data));
523
524        if (gtk_obj == NULL) {
525            g_list_free(list);
526            Py_DECREF(py_list);
527            return NULL;
528        }
529        PyList_Append(py_list, gtk_obj);
530        Py_DECREF(gtk_obj);
531    }
532    g_list_free(list);
533    return py_list;
534}
535%%
536override gtk_tree_selection_get_selected noargs
537static PyObject *
538_wrap_gtk_tree_selection_get_selected(PyGObject *self)
539{
540    GtkTreeModel *model;
541    GtkTreeIter iter;
542    GtkSelectionMode mode;
543
544    mode = gtk_tree_selection_get_mode(GTK_TREE_SELECTION(self->obj));
545    if (mode == GTK_SELECTION_MULTIPLE) {
546        PyErr_SetString(PyExc_TypeError,
547                        "GtkTreeSelection.get_selected can not be used when"
548                        " selection mode is gtk.SELECTION_MULTIPLE");
549        return NULL;
550    }
551
552    if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(self->obj),
553                                        &model, &iter)) {
554        return Py_BuildValue("(NN)",
555                             pygobject_new((GObject *)model),
556                             pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter,
557                                           TRUE, TRUE));
558    } else {
559	return Py_BuildValue ("(NO)",
560                              pygobject_new((GObject *)model),
561                              Py_None);
562    }
563}
564%%
565override gtk_tree_selection_get_selected_rows noargs
566static PyObject *
567_wrap_gtk_tree_selection_get_selected_rows(PyGObject *self)
568{
569    GtkTreeModel *model = NULL;
570    GList *selected, *tmp;
571    PyObject *py_selected;
572
573    selected = gtk_tree_selection_get_selected_rows
574	(GTK_TREE_SELECTION(self->obj), &model);
575    py_selected = PyList_New(0);
576    for (tmp = selected; tmp != NULL; tmp = tmp->next) {
577	GtkTreePath *path = tmp->data;
578	PyObject *item = pygtk_tree_path_to_pyobject(path);
579
580	PyList_Append(py_selected, item);
581	Py_DECREF(item);
582	gtk_tree_path_free(path);
583    }
584    g_list_free(selected);
585    return Py_BuildValue("(NN)", pygobject_new((GObject *)model), py_selected);
586}
587%%
588override gtk_tree_selection_selected_foreach
589
590static void
591pygtk_tree_selection_foreach_marshal(GtkTreeModel *model,
592                                     GtkTreePath *path,
593                                     GtkTreeIter *iter,
594                                     gpointer data)
595{
596    PyGILState_STATE state;
597    PyGtkCustomNotify *cunote = data;
598    PyObject *py_model, *py_path, *py_iter, *retobj;
599
600    g_assert(cunote->func);
601
602    state = pyg_gil_state_ensure();
603
604    py_model = pygobject_new((GObject *)model);
605    py_path = pygtk_tree_path_to_pyobject(path);
606    py_iter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter, FALSE, FALSE);
607    if (cunote->data)
608        retobj = PyEval_CallFunction(cunote->func, "(NNOO)",
609                                     py_model, py_path, py_iter,
610                                     cunote->data);
611    else
612        retobj = PyEval_CallFunction(cunote->func, "(NNO)",
613                                     py_model, py_path, py_iter);
614
615    if (retobj == NULL) {
616        PyErr_Print();
617    }
618    pygtk_boxed_unref_shared(py_iter);
619    Py_XDECREF(retobj);
620
621    pyg_gil_state_release(state);
622}
623static PyObject *
624_wrap_gtk_tree_selection_selected_foreach(PyGObject *self, PyObject *args)
625{
626    PyObject *pyfunc, *pyarg = NULL;
627    PyGtkCustomNotify cunote;
628
629    if(!PyArg_ParseTuple(args, "O|O:GtkTreeSelection.selected_foreach",
630                         &pyfunc, &pyarg))
631        return NULL;
632
633    cunote.func = pyfunc;
634    cunote.data = pyarg;
635    gtk_tree_selection_selected_foreach(GTK_TREE_SELECTION(self->obj),
636                                        pygtk_tree_selection_foreach_marshal,
637                                        &cunote);
638
639    Py_INCREF(Py_None);
640    return Py_None;
641}
642%%
643override gtk_tree_selection_set_select_function kwargs
644static gboolean
645pygtk_tree_selection_marshal(GtkTreeSelection *selection,
646                             GtkTreeModel *model,
647                             GtkTreePath *path,
648                             gboolean path_currently_selected,
649                             gpointer data)
650{
651    PyGILState_STATE state;
652    gboolean retval = FALSE;
653    PyGtkCustomNotify *cunote = data;
654    PyObject *pypath, *retobj;
655
656    g_assert(cunote->func);
657
658    state = pyg_gil_state_ensure();
659
660    pypath = pygtk_tree_path_to_pyobject(path);
661    if (cunote->data)
662        retobj = PyEval_CallFunction(cunote->func, "(NO)", pypath,
663                                     cunote->data);
664    else
665        retobj = PyEval_CallFunction(cunote->func, "(N)", pypath);
666
667    if (retobj == NULL) {
668        PyErr_Print();
669    }
670
671    Py_DECREF(pypath);
672    if (retobj) {
673        if(retobj == Py_None);
674        else if(PyInt_Check(retobj))
675            retval = PyInt_AsLong(retobj) && TRUE;
676        else if(PyLong_Check(retobj))
677            retval = PyLong_AsLongLong(retobj) && TRUE;
678        else if(PyString_Check(retobj))
679            retval = PyString_GET_SIZE(retobj) && TRUE;
680
681        Py_DECREF(retobj);
682    }
683
684
685    pyg_gil_state_release(state);
686
687    return retval;
688}
689static gboolean
690pygtk_tree_selection_marshal_full(GtkTreeSelection *selection,
691                                  GtkTreeModel *model,
692                                  GtkTreePath *path,
693                                  gboolean path_currently_selected,
694                                  gpointer data)
695{
696    PyGILState_STATE state;
697    gboolean retval = FALSE;
698    PyGtkCustomNotify *cunote = data;
699    PyObject *pyselection, *pymodel, *pypath, *retobj;
700
701    g_assert(cunote->func);
702
703    state = pyg_gil_state_ensure();
704
705    pyselection = pygobject_new((GObject*)selection);
706    pymodel = pygobject_new((GObject*)model);
707    pypath = pygtk_tree_path_to_pyobject(path);
708    if (cunote->data)
709        retobj = PyEval_CallFunction(cunote->func, "(NNNNO)", pyselection,
710                                     pymodel, pypath,
711                                     PyBool_FromLong(path_currently_selected),
712                                     cunote->data);
713    else
714        retobj = PyEval_CallFunction(cunote->func, "(NNNN)", pyselection,
715                                     pymodel, pypath,
716                                     PyBool_FromLong(path_currently_selected));
717
718    if (retobj == NULL) {
719        PyErr_Print();
720    }
721
722    Py_DECREF(pypath);
723    if (retobj) {
724        if(retobj == Py_None);
725        else if(PyInt_Check(retobj))
726            retval = PyInt_AsLong(retobj) && TRUE;
727        else if(PyLong_Check(retobj))
728            retval = PyLong_AsLongLong(retobj) && TRUE;
729        else if(PyString_Check(retobj))
730            retval = PyString_GET_SIZE(retobj) && TRUE;
731
732        Py_DECREF(retobj);
733    }
734
735
736    pyg_gil_state_release(state);
737
738    return retval;
739}
740static PyObject *
741_wrap_gtk_tree_selection_set_select_function(PyGObject *self, PyObject *args,
742                                             PyObject *kwargs)
743{
744    static char *kwlist[] = { "func", "data", "full", NULL };
745    PyObject *pyfunc, *pyarg = NULL, *pyfull = Py_False;
746    PyGtkCustomNotify *cunote;
747
748    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO:GtkTreeSelection.set_select_function",
749                                     kwlist, &pyfunc, &pyarg, &pyfull))
750        return NULL;
751
752    if (!PyCallable_Check(pyfunc)) {
753        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
754        return NULL;
755    }
756    cunote = g_new0(PyGtkCustomNotify, 1);
757    cunote->func = pyfunc;
758    cunote->data = pyarg;
759    Py_INCREF(cunote->func);
760    Py_XINCREF(cunote->data);
761    if (PyObject_IsTrue(pyfull))
762        gtk_tree_selection_set_select_function(GTK_TREE_SELECTION(self->obj),
763                                               pygtk_tree_selection_marshal_full,
764                                               cunote,
765                                               pygtk_custom_destroy_notify);
766    else
767        gtk_tree_selection_set_select_function(GTK_TREE_SELECTION(self->obj),
768                                               pygtk_tree_selection_marshal,
769                                               cunote,
770                                               pygtk_custom_destroy_notify);
771    Py_INCREF(Py_None);
772    return Py_None;
773}
774%%
775override gtk_tree_get_row_drag_data noargs
776static PyObject *
777_wrap_gtk_tree_get_row_drag_data(PyObject *self)
778{
779    GtkTreeModel *tree_model;
780    GtkTreePath *path;
781
782    if (gtk_tree_get_row_drag_data(pyg_boxed_get(self, GtkSelectionData),
783                                   &tree_model, &path)) {
784        PyObject *ret = Py_BuildValue("(NN)",
785                                      pygobject_new((GObject *)tree_model),
786                                      pygtk_tree_path_to_pyobject(path));
787
788        gtk_tree_path_free(path);
789        return ret;
790    }
791    Py_INCREF(Py_None);
792    return Py_None;
793}
794%%
795override gtk_tree_model_get_iter kwargs
796static PyObject *
797_wrap_gtk_tree_model_get_iter(PyGObject *self, PyObject *args,PyObject *kwargs)
798{
799    static char *kwlist[] = { "path", NULL };
800    PyObject *py_path;
801    GtkTreeIter iter;
802    GtkTreePath *path;
803
804    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GtkTreeModel.get_iter",
805                                     kwlist, &py_path))
806        return NULL;
807
808    path = pygtk_tree_path_from_pyobject(py_path);
809    if (!path) {
810        PyErr_SetString(PyExc_TypeError, "GtkTreeModel.get_iter requires a tree path as its argument");
811        return NULL;
812    }
813    if (gtk_tree_model_get_iter(GTK_TREE_MODEL(self->obj), &iter, path)) {
814        gtk_tree_path_free(path);
815        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
816    } else {
817        gtk_tree_path_free(path);
818        PyErr_SetString(PyExc_ValueError, "invalid tree path");
819        return NULL;
820    }
821}
822%%
823override gtk_tree_model_get_iter_from_string kwargs
824static PyObject *
825_wrap_gtk_tree_model_get_iter_from_string(PyGObject *self, PyObject *args,
826                                          PyObject *kwargs)
827{
828    static char *kwlist[] = { "path_string", NULL };
829    const gchar *path_string;
830    GtkTreeIter iter;
831
832    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
833                                     "s:GtkTreeModel.get_iter_from_string",
834                                     kwlist, &path_string))
835        return NULL;
836
837    if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(self->obj), &iter,
838                                            path_string)) {
839        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
840    } else {
841        PyErr_SetString(PyExc_ValueError, "invalid tree path");
842        return NULL;
843    }
844}
845%%
846override gtk_tree_model_get_value kwargs
847static PyObject *
848_wrap_gtk_tree_model_get_value(PyGObject *self, PyObject*args, PyObject*kwargs)
849{
850    static char *kwlist[] = { "iter", "column", NULL };
851    PyObject *iter, *ret;
852    gint column;
853    GValue value = { 0, };
854
855    if (!PyArg_ParseTupleAndKeywords(args,kwargs, "Oi:GtkTreeModel.get_value",
856                                     kwlist, &iter, &column))
857        return NULL;
858    if (column < 0 ||
859        column >= gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj))) {
860        PyErr_SetString(PyExc_ValueError, "column number is out of range");
861        return NULL;
862    }
863    if (!pyg_boxed_check(iter, GTK_TYPE_TREE_ITER)) {
864        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTreeIter");
865        return NULL;
866    }
867    gtk_tree_model_get_value(GTK_TREE_MODEL(self->obj),
868                             pyg_boxed_get(iter, GtkTreeIter), column, &value);
869    ret = pyg_value_as_pyobject(&value, TRUE);
870    g_value_unset(&value);
871    return ret;
872}
873%%
874override gtk_tree_model_rows_reordered kwargs
875static PyObject *
876_wrap_gtk_tree_model_rows_reordered(PyGObject *self, PyObject *args,
877                                          PyObject *kwargs)
878{
879    static char *kwlist[] = { "path", "iter", "new_order", NULL };
880    PyObject *py_path, *py_iter, *py_new_order, *sitem;
881    GtkTreeIter *iter = NULL;
882    GtkTreePath *path;
883    gint *new_order;
884    gint len_model, len_seq;
885    gint i;
886
887    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
888				     "OOO:GtkTreeModel.rows_reordered", kwlist,
889				     &py_path, &py_iter, &py_new_order))
890        return NULL;
891
892    if (py_path == Py_None ||
893        (PyTuple_Check(py_path) && PyTuple_Size(py_path) == 0) ||
894        (PyString_Check(py_path) && PyString_Size(py_path) == 0))
895        path = gtk_tree_path_new();
896    else
897        path = pygtk_tree_path_from_pyobject(py_path);
898    if (!path) {
899        PyErr_SetString(PyExc_TypeError,
900	    "could not convert path to a GtkTreePath");
901        return NULL;
902    }
903
904    if (py_iter == Py_None)
905        iter = NULL;
906    else if (pyg_boxed_check(py_iter, GTK_TYPE_TREE_ITER))
907        iter = pyg_boxed_get(py_iter, GtkTreeIter);
908    else {
909        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTreeIter");
910        gtk_tree_path_free(path);
911        return NULL;
912    }
913
914    if (!PySequence_Check(py_new_order)) {
915        PyErr_SetString(PyExc_TypeError,
916	    "new_order must be a sequence of ints");
917        gtk_tree_path_free(path);
918        return NULL;
919    }
920
921    len_model = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(self->obj), iter);
922    len_seq = PySequence_Size(py_new_order);
923    if (len_model != len_seq) {
924        PyErr_Format(PyExc_ValueError,
925	    "new_order should be a sequence with the same size as the "
926	    "number of children of iter (%d, is %d)", len_model, len_seq);
927        gtk_tree_path_free(path);
928        return NULL;
929    }
930
931    // Create on stack: much faster, no free() needed.
932    new_order = g_newa(gint, len_seq);
933    for (i = 0; i < len_seq; i++) {
934	sitem = PySequence_GetItem(py_new_order, i);
935	Py_DECREF(sitem);
936	sitem = PyNumber_Int(sitem);
937	if (sitem)
938	    new_order[i] = (gint) PyInt_AsLong(sitem);
939	else {
940	    PyErr_Clear();
941	    PyErr_SetString(PyExc_TypeError,
942			    "new_order sequence item not an int");
943	    gtk_tree_path_free(path);
944	    return NULL;
945	}
946	Py_DECREF(sitem);
947    }
948
949    gtk_tree_model_rows_reordered(GTK_TREE_MODEL(self->obj),
950				  path, iter, new_order);
951    gtk_tree_path_free(path);
952    Py_INCREF(Py_None);
953    return Py_None;
954}
955%%
956override-slot GtkTreeModel.tp_as_number
957static int
958_wrap_gtk_tree_model_tp_nonzero(PyGObject *self)
959{
960    return TRUE;
961}
962static PyNumberMethods _wrap_gtk_tree_model_tp_as_number = {
963    (binaryfunc)0,
964    (binaryfunc)0,
965    (binaryfunc)0,
966    (binaryfunc)0,
967    (binaryfunc)0,
968    (binaryfunc)0,
969    (ternaryfunc)0,
970    (unaryfunc)0,
971    (unaryfunc)0,
972    (unaryfunc)0,
973    (inquiry)_wrap_gtk_tree_model_tp_nonzero,
974    (unaryfunc)0,
975    (binaryfunc)0,
976    (binaryfunc)0,
977    (binaryfunc)0,
978    (binaryfunc)0,
979    (binaryfunc)0,
980    (coercion)0,
981    (unaryfunc)0,
982    (unaryfunc)0,
983    (unaryfunc)0,
984    (unaryfunc)0,
985    (unaryfunc)0
986};
987%%
988override-slot GtkTreeModel.tp_as_mapping
989static Py_ssize_t
990_wrap_gtk_tree_model_tp_length(PyGObject *self)
991{
992    return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(self->obj), NULL);
993}
994static PyObject *
995_wrap_gtk_tree_model_tp_getitem(PyGObject *self, PyObject *item)
996{
997    GtkTreePath *path = NULL;
998    GtkTreeIter iter;
999    PyObject *ret = NULL;
1000
1001    if (pyg_boxed_check(item, GTK_TYPE_TREE_ITER)) {
1002        return _pygtk_tree_model_row_new(GTK_TREE_MODEL(self->obj),
1003                                         pyg_boxed_get(item, GtkTreeIter));
1004    }
1005
1006    if (PyInt_Check(item)) {
1007	int value = PyInt_AsLong(item);
1008
1009	if (value < 0) {
1010            PyObject *inverse;
1011
1012            /* Since value is always negative at this point,
1013	     * we need to do an invertion.
1014	     */
1015            value = _wrap_gtk_tree_model_tp_length(self) - -value;
1016            inverse = PyInt_FromLong(value);
1017            if (!inverse)
1018                return NULL;
1019
1020            path = pygtk_tree_path_from_pyobject(inverse);
1021            Py_DECREF(inverse);
1022	}
1023    }
1024
1025    if (!path)
1026        path = pygtk_tree_path_from_pyobject(item);
1027
1028    if (!path) {
1029        PyErr_SetString(PyExc_TypeError,
1030                        "could not parse subscript as a tree path");
1031        return  NULL;
1032    }
1033    if (gtk_tree_model_get_iter(GTK_TREE_MODEL(self->obj), &iter, path)) {
1034        ret = _pygtk_tree_model_row_new(GTK_TREE_MODEL(self->obj), &iter);
1035    } else {
1036        PyErr_SetString(PyExc_IndexError, "could not find tree path");
1037        ret = NULL;
1038    }
1039    gtk_tree_path_free(path);
1040    return ret;
1041}
1042static int
1043_wrap_gtk_tree_model_tp_setitem(PyGObject *self, PyObject *item,
1044                                PyObject *value)
1045{
1046    GtkTreeIter *iter, iter2;
1047
1048    if (pyg_boxed_check(item, GTK_TYPE_TREE_ITER)) {
1049        iter = pyg_boxed_get(item, GtkTreeIter);
1050    } else {
1051        GtkTreePath *path = NULL;
1052
1053	if (PyInt_Check(item)) {
1054	    int value = PyInt_AsLong(item);
1055
1056	    if (value < 0) {
1057                PyObject *inverse;
1058
1059                /* Since value is always negative at this point,
1060		 * we need to do an invertion.
1061		 */
1062                value = _wrap_gtk_tree_model_tp_length(self) - -value;
1063                inverse = PyInt_FromLong(value);
1064                if (!inverse)
1065                    return -1;
1066
1067                path = pygtk_tree_path_from_pyobject(inverse);
1068                Py_DECREF(inverse);
1069	    }
1070	}
1071
1072        if (!path)
1073            path = pygtk_tree_path_from_pyobject(item);
1074
1075        if (!path) {
1076            PyErr_SetString(PyExc_TypeError,
1077                            "could not parse subscript as a tree path");
1078            return  -1;
1079        }
1080        if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(self->obj), &iter2,path)) {
1081            PyErr_SetString(PyExc_TypeError, "could not find tree path");
1082            gtk_tree_path_free(path);
1083            return -1;
1084        }
1085        iter = &iter2;
1086        gtk_tree_path_free(path);
1087    }
1088
1089    if (value == NULL) {
1090        return _pygtk_tree_model_remove_row(GTK_TREE_MODEL(self->obj), iter);
1091    } else {
1092        return _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj),
1093                                         iter, value);
1094    }
1095}
1096
1097static PyMappingMethods _wrap_gtk_tree_model_tp_as_mapping = {
1098    (lenfunc)_wrap_gtk_tree_model_tp_length,
1099    (binaryfunc)_wrap_gtk_tree_model_tp_getitem,
1100    (objobjargproc)_wrap_gtk_tree_model_tp_setitem
1101};
1102%%
1103override-slot GtkTreeModel.tp_iter
1104static PyObject *
1105_wrap_gtk_tree_model_tp_iter(PyGObject *self)
1106{
1107    return _pygtk_tree_model_row_iter_new(GTK_TREE_MODEL(self->obj), NULL);
1108}
1109%%
1110override gtk_tree_sortable_get_sort_column_id noargs
1111static PyObject *
1112_wrap_gtk_tree_sortable_get_sort_column_id(PyGObject *self)
1113{
1114    gboolean ret;
1115    gint sort_column_id;
1116    GtkSortType order;
1117
1118    ret = gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(self->obj),
1119                                               &sort_column_id, &order);
1120
1121    /* if we don't have a sort column set, return (None, None) */
1122    if (ret)
1123        return Py_BuildValue("(iN)", sort_column_id,
1124			     pyg_enum_from_gtype(GTK_TYPE_SORT_TYPE, order));
1125    else
1126        return Py_BuildValue("(OO)", Py_None, Py_None);
1127}
1128%%
1129override gtk_tree_sortable_set_sort_func
1130static gint
1131pygtk_tree_sortable_sort_cb(GtkTreeModel *model, GtkTreeIter *iter1,
1132                            GtkTreeIter *iter2, gpointer user_data)
1133{
1134    PyGILState_STATE state;
1135    PyGtkCustomNotify *cunote = user_data;
1136    PyObject *py_model, *py_iter2, *py_iter1, *retobj;
1137    gint ret = 0;
1138
1139    g_assert(cunote->func);
1140
1141    state = pyg_gil_state_ensure();
1142
1143    py_model = pygobject_new((GObject *)model);
1144    py_iter1 = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter1, FALSE, FALSE);
1145    py_iter2 = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter2,  FALSE, FALSE);
1146
1147    if (cunote->data) {
1148        retobj = PyEval_CallFunction(cunote->func, "(NOOO)", py_model,
1149                                     py_iter1, py_iter2, cunote->data);
1150    } else {
1151        retobj = PyEval_CallFunction(cunote->func, "(NOO)", py_model,
1152                                     py_iter1, py_iter2);
1153    }
1154    pygtk_boxed_unref_shared(py_iter1);
1155    pygtk_boxed_unref_shared(py_iter2);
1156    if (retobj)
1157        ret = PyInt_AsLong(retobj);
1158    if (PyErr_Occurred()) {
1159        PyErr_Print();
1160        ret = 0;
1161    }
1162    Py_XDECREF(retobj);
1163
1164    pyg_gil_state_release(state);
1165    return ret;
1166}
1167static PyObject *
1168_wrap_gtk_tree_sortable_set_sort_func(PyGObject *self, PyObject *args)
1169{
1170    gint column;
1171    PyObject *callback, *data = NULL;
1172    PyGtkCustomNotify *cunote;
1173
1174    if (!PyArg_ParseTuple(args, "iO|O:GtkTreeSortable.set_sort_func",
1175                          &column, &callback, &data))
1176        return NULL;
1177
1178    if (!PyCallable_Check(callback)) {
1179        PyErr_SetString(PyExc_TypeError, "callback must be a callable object");
1180        return NULL;
1181    }
1182    cunote = g_new(PyGtkCustomNotify, 1);
1183    Py_INCREF(callback);
1184    cunote->func = callback;
1185    Py_XINCREF(data);
1186    cunote->data = data;
1187
1188    gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(self->obj), column,
1189                                    pygtk_tree_sortable_sort_cb, cunote,
1190                                    pygtk_custom_destroy_notify);
1191
1192    Py_INCREF(Py_None);
1193    return Py_None;
1194}
1195%%
1196override gtk_tree_sortable_set_default_sort_func
1197static PyObject *
1198_wrap_gtk_tree_sortable_set_default_sort_func(PyGObject *self, PyObject *args)
1199{
1200    PyObject *callback, *data = NULL;
1201    PyGtkCustomNotify *cunote;
1202
1203    if (!PyArg_ParseTuple(args, "O|O:GtkTreeSortable.set_default_sort_func",
1204                          &callback, &data))
1205        return NULL;
1206
1207    if (callback == Py_None) {
1208	gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(self->obj),
1209						NULL,
1210						NULL,
1211						NULL);
1212	goto beach;
1213    }
1214
1215    if (!PyCallable_Check(callback)) {
1216        PyErr_SetString(PyExc_TypeError, "callback must be a callable object");
1217        return NULL;
1218    }
1219    cunote = g_new(PyGtkCustomNotify, 1);
1220    Py_INCREF(callback);
1221    cunote->func = callback;
1222    Py_XINCREF(data);
1223    cunote->data = data;
1224
1225    gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(self->obj),
1226                                            pygtk_tree_sortable_sort_cb,
1227                                            cunote,
1228                                            pygtk_custom_destroy_notify);
1229 beach:
1230    Py_INCREF(Py_None);
1231    return Py_None;
1232}
1233%%
1234override GtkTreeSortable__do_get_sort_column_id kwargs
1235static PyObject *
1236_wrap_GtkTreeSortable__do_get_sort_column_id(PyObject *cls, PyObject *args, PyObject *kwargs)
1237{
1238    static char *kwlist[] = { "self", NULL };
1239    GtkTreeSortableIface *iface;
1240    PyGObject *self;
1241    gint sort_column_id;
1242    GtkSortType order;
1243
1244    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!:gtk.TreeSortable.do_get_sort_column_id", kwlist, &PyGtkTreeSortable_Type, &self))
1245        return NULL;
1246    iface = g_type_interface_peek(g_type_class_peek(pyg_type_from_object(cls)), GTK_TYPE_TREE_SORTABLE);
1247    if (iface->get_sort_column_id)
1248        iface->get_sort_column_id(GTK_TREE_SORTABLE(self->obj), &sort_column_id, &order);
1249    else {
1250        PyErr_SetString(PyExc_NotImplementedError, "interface method gtk.TreeSortable.get_sort_column_id not implemented");
1251        return NULL;
1252    }
1253
1254    return Py_BuildValue("(iN)", sort_column_id, pyg_enum_from_gtype(GTK_TYPE_SORT_TYPE, order));
1255}
1256%%
1257override GtkTreeSortable__proxy_do_get_sort_column_id
1258static gboolean
1259_wrap_GtkTreeSortable__proxy_do_get_sort_column_id(GtkTreeSortable *self, gint *sort_column_id, GtkSortType *order)
1260{
1261    PyGILState_STATE __py_state;
1262    PyObject *py_self;
1263    PyObject *py_retval;
1264    PyObject *py_method;
1265    gint py_sort_column_id;
1266    PyObject *py_order;
1267
1268    __py_state = pyg_gil_state_ensure();
1269    py_self = pygobject_new((GObject *) self);
1270    if (!py_self) {
1271        if (PyErr_Occurred())
1272            PyErr_Print();
1273        pyg_gil_state_release(__py_state);
1274        return FALSE;
1275    }
1276
1277    py_method = PyObject_GetAttrString(py_self, "do_get_sort_column_id");
1278    if (!py_method) {
1279        if (PyErr_Occurred())
1280            PyErr_Print();
1281        Py_DECREF(py_self);
1282        pyg_gil_state_release(__py_state);
1283        return FALSE;
1284    }
1285    py_retval = PyObject_CallObject(py_method, NULL);
1286    if (!py_retval) {
1287        if (PyErr_Occurred())
1288            PyErr_Print();
1289        Py_XDECREF(py_retval);
1290        Py_DECREF(py_method);
1291        Py_DECREF(py_self);
1292        pyg_gil_state_release(__py_state);
1293        return FALSE;
1294    }
1295    if (!PyArg_ParseTuple(py_retval, "iO", &py_sort_column_id, &py_order)) {
1296        PyErr_Print();
1297        Py_XDECREF(py_retval);
1298        Py_DECREF(py_method);
1299        Py_DECREF(py_self);
1300        pyg_gil_state_release(__py_state);
1301        return FALSE;
1302    }
1303    if (sort_column_id)
1304        *sort_column_id = py_sort_column_id;
1305    if (order && pyg_enum_get_value(GTK_TYPE_SORT_TYPE, py_order, (gint *) order)) {
1306        PyErr_Print();
1307        Py_XDECREF(py_retval);
1308        Py_DECREF(py_method);
1309        Py_DECREF(py_self);
1310        pyg_gil_state_release(__py_state);
1311        return FALSE;
1312    }
1313
1314    Py_XDECREF(py_retval);
1315    Py_DECREF(py_method);
1316    Py_DECREF(py_self);
1317    pyg_gil_state_release(__py_state);
1318
1319    return py_order >= 0;
1320}
1321%%
1322override GtkTreeSortable__do_set_sort_func
1323static PyObject *
1324_wrap_GtkTreeSortable__do_set_sort_func(PyObject *cls, PyObject *args, PyObject *kwargs)
1325{
1326    static char *kwlist[] = { "self", "sort_column_id", "func", "user_data", NULL };
1327    GtkTreeSortableIface *iface;
1328    PyGObject *self;
1329    gint sort_column_id;
1330    PyObject *func;
1331    PyObject *user_data;
1332    PyGtkCustomNotify *func_wrapper;
1333
1334    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iO|O:gtk.TreeSortable.do_set_sort_func", kwlist,
1335                                     &PyGtkTreeSortable_Type, &self,
1336                                     &sort_column_id, &func, &user_data))
1337        return NULL;
1338
1339    if (!PyCallable_Check(func)) {
1340        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
1341        return NULL;
1342    }
1343
1344    iface = g_type_interface_peek(g_type_class_peek(pyg_type_from_object(cls)), GTK_TYPE_TREE_SORTABLE);
1345    if (!iface->set_sort_func) {
1346        PyErr_SetString(PyExc_NotImplementedError,
1347                        "interface method gtk.TreeSortable.set_sort_func not implemented");
1348        return NULL;
1349    }
1350
1351    func_wrapper = g_new(PyGtkCustomNotify, 1);
1352    func_wrapper->func = func;
1353    Py_INCREF(func_wrapper->func);
1354    func_wrapper->data = user_data;
1355    Py_XINCREF(func_wrapper->data);
1356
1357    iface->set_sort_func(GTK_TREE_SORTABLE(self->obj), sort_column_id,
1358                         pygtk_tree_sortable_sort_cb, func_wrapper, pygtk_custom_destroy_notify);
1359
1360    Py_INCREF(Py_None);
1361    return Py_None;
1362}
1363%%
1364override GtkTreeSortable__do_set_default_sort_func
1365static PyObject *
1366_wrap_GtkTreeSortable__do_set_default_sort_func(PyObject *cls, PyObject *args, PyObject *kwargs)
1367{
1368    static char *kwlist[] = { "self", "func", "user_data", NULL };
1369    GtkTreeSortableIface *iface;
1370    PyGObject *self;
1371    PyObject *func;
1372    PyObject *user_data;
1373    PyGtkCustomNotify *func_wrapper;
1374
1375    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1376                                     "O!iO|O:gtk.TreeSortable.do_set_default_sort_func", kwlist,
1377                                     &PyGtkTreeSortable_Type, &self,
1378                                     &func, &user_data))
1379        return NULL;
1380
1381    if (!PyCallable_Check(func)) {
1382        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
1383        return NULL;
1384    }
1385
1386    iface = g_type_interface_peek(g_type_class_peek(pyg_type_from_object(cls)), GTK_TYPE_TREE_SORTABLE);
1387    if (!iface->set_default_sort_func) {
1388        PyErr_SetString(PyExc_NotImplementedError,
1389                        "interface method gtk.TreeSortable.set_default_sort_func not implemented");
1390        return NULL;
1391    }
1392
1393    func_wrapper = g_new(PyGtkCustomNotify, 1);
1394    func_wrapper->func = func;
1395    Py_INCREF(func_wrapper->func);
1396    func_wrapper->data = user_data;
1397    Py_XINCREF(func_wrapper->data);
1398
1399    iface->set_default_sort_func(GTK_TREE_SORTABLE(self->obj),
1400                                 pygtk_tree_sortable_sort_cb, func_wrapper, pygtk_custom_destroy_notify);
1401
1402    Py_INCREF(Py_None);
1403    return Py_None;
1404}
1405%%
1406override GtkTreeSortable__proxy_do_set_sort_func
1407
1408typedef struct {
1409  GtkTreeIterCompareFunc func;
1410  gpointer               data;
1411  GDestroyNotify         destroy;
1412} _PyGTKIterCompareFuncWrapper;
1413
1414static PyObject *
1415_pygtk_tree_iter_compare_func_wrapper__call(PyObject *self, PyObject *args, PyObject *kwargs)
1416{
1417    static char *kwlist[] = { "model", "iter1", "iter2", NULL };
1418
1419    PyObject *py_model;
1420    PyObject *py_iter1;
1421    PyObject *py_iter2;
1422    _PyGTKIterCompareFuncWrapper *wrapper;
1423    int result;
1424
1425    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!O!", kwlist,
1426                                     &PyGtkTreeModel_Type, &py_model,
1427                                     &PyGtkTreeIter_Type, &py_iter1,
1428                                     &PyGtkTreeIter_Type, &py_iter2))
1429        return NULL;
1430
1431    wrapper = (_PyGTKIterCompareFuncWrapper *) PyCObject_AsVoidPtr(self);
1432    result = (*wrapper->func) (GTK_TREE_MODEL(((PyGObject *) py_model)->obj),
1433                               pyg_boxed_get(py_iter1, GtkTreeIter),
1434                               pyg_boxed_get(py_iter2, GtkTreeIter),
1435                               wrapper->data);
1436
1437    return PyInt_FromLong(result);
1438}
1439
1440static void
1441_pygtk_tree_iter_compare_func_wrapper__destroy(void *wrapper_)
1442{
1443    _PyGTKIterCompareFuncWrapper *wrapper = (_PyGTKIterCompareFuncWrapper *) wrapper_;
1444
1445    if (wrapper->destroy)
1446        (*wrapper->destroy) (wrapper->data);
1447
1448    g_slice_free(_PyGTKIterCompareFuncWrapper, wrapper);
1449}
1450
1451static PyObject *
1452_wrap_tree_iter_compare_func(GtkTreeIterCompareFunc func, gpointer data, GDestroyNotify destroy)
1453{
1454    static PyMethodDef wrapper_method
1455        = { "_iter_compare", (PyCFunction) _pygtk_tree_iter_compare_func_wrapper__call,
1456            METH_VARARGS | METH_KEYWORDS, NULL };
1457
1458    _PyGTKIterCompareFuncWrapper *wrapper;
1459    PyObject *py_wrapper;
1460    PyObject *result;
1461
1462    if (!func) {
1463        if (destroy)
1464            (*destroy) (data);
1465
1466        Py_INCREF(Py_None);
1467        return Py_None;
1468    }
1469
1470    wrapper = g_slice_new(_PyGTKIterCompareFuncWrapper);
1471    wrapper->func = func;
1472    wrapper->data = data;
1473    wrapper->destroy = destroy;
1474
1475    py_wrapper = PyCObject_FromVoidPtr(wrapper, _pygtk_tree_iter_compare_func_wrapper__destroy);
1476    if (!py_wrapper) {
1477        _pygtk_tree_iter_compare_func_wrapper__destroy(wrapper);
1478        return NULL;
1479    }
1480
1481    result = PyCFunction_New(&wrapper_method, py_wrapper);
1482    Py_DECREF(py_wrapper);
1483
1484    return result;
1485}
1486
1487static void
1488_do_proxy_do_set_sort_func(GtkTreeSortable *self, gboolean default_,
1489                           gint sort_column_id,
1490                           GtkTreeIterCompareFunc func,
1491                           gpointer data,
1492                           GDestroyNotify destroy)
1493{
1494    PyGILState_STATE py_state = pyg_gil_state_ensure ();
1495    PyObject *py_self = NULL;
1496    PyObject *py_func = NULL;
1497    PyObject *result = NULL;
1498
1499    py_self = pygobject_new(G_OBJECT(self));
1500    if (!py_self)
1501        goto error;
1502
1503    py_func = _wrap_tree_iter_compare_func(func, data, destroy);
1504    if (!py_func)
1505        goto error;
1506
1507    if (default_)
1508        result = PyObject_CallMethod(py_self, "do_set_default_sort_func", "O", py_func);
1509    else
1510        result = PyObject_CallMethod(py_self, "do_set_sort_func", "iO", sort_column_id, py_func);
1511
1512    if (!result)
1513        goto error;
1514
1515 done:
1516    Py_XDECREF(py_self);
1517    Py_XDECREF(py_func);
1518    Py_XDECREF(result);
1519
1520    pyg_gil_state_release (py_state);
1521
1522    return;
1523
1524 error:
1525    if (PyErr_Occurred ())
1526        PyErr_Print ();
1527
1528    goto done;
1529}
1530
1531static void
1532_wrap_GtkTreeSortable__proxy_do_set_sort_func(GtkTreeSortable *self,
1533                                              gint sort_column_id,
1534                                              GtkTreeIterCompareFunc func,
1535                                              gpointer data,
1536                                              GDestroyNotify destroy)
1537{
1538    _do_proxy_do_set_sort_func(self, FALSE, sort_column_id, func, data, destroy);
1539}
1540%%
1541override GtkTreeSortable__proxy_do_set_default_sort_func
1542static void
1543_wrap_GtkTreeSortable__proxy_do_set_default_sort_func(GtkTreeSortable *self,
1544                                                      GtkTreeIterCompareFunc func,
1545                                                      gpointer data,
1546                                                      GDestroyNotify destroy)
1547{
1548    _do_proxy_do_set_sort_func(self, TRUE, 0, func, data, destroy);
1549}
1550
1551%%
1552ignore gtk_list_store_newv
1553%%
1554new-constructor GTK_TYPE_LIST_STORE
1555%%
1556override gtk_list_store_new
1557static int
1558_wrap_gtk_list_store_new(PyGObject *self, PyObject *args)
1559{
1560    guint len, i;
1561    GType *column_types;
1562
1563    len = PyTuple_Size(args);
1564    if (len == 0) {
1565        PyErr_SetString(PyExc_TypeError,
1566                        "GtkListStore requires at least one argument");
1567        return -1;
1568    }
1569
1570    column_types = g_new(GType, len);
1571    for (i = 0; i < len; i++) {
1572        PyObject *item = PyTuple_GetItem(args, i);
1573
1574        column_types[i] = pyg_type_from_object(item);
1575        if (column_types[i] == 0) {
1576            g_free(column_types);
1577            return -1;
1578        }
1579    }
1580
1581    pygobject_construct(self, NULL);
1582    gtk_list_store_set_column_types(GTK_LIST_STORE(self->obj), len, column_types);
1583    g_free(column_types);
1584
1585    if (!self->obj) {
1586        PyErr_SetString(PyExc_RuntimeError,
1587                        "could not create GtkListStore object");
1588        return -1;
1589    }
1590    return 0;
1591}
1592%%
1593override gtk_list_store_set_column_types args
1594static PyObject*
1595_wrap_gtk_list_store_set_column_types(PyGObject *self, PyObject *args)
1596{
1597    guint len, i;
1598    GType *column_types;
1599
1600    len = PyTuple_Size(args);
1601    if (len == 0) {
1602        PyErr_SetString(PyExc_TypeError,
1603                        "GtkListStore set_column_types requires at least one argument");
1604        return NULL;
1605    }
1606
1607    column_types = g_new(GType, len);
1608    for (i = 0; i < len; i++) {
1609        PyObject *item = PyTuple_GetItem(args, i);
1610
1611        column_types[i] = pyg_type_from_object(item);
1612        if (column_types[i] == 0) {
1613            g_free(column_types);
1614	    return NULL;
1615        }
1616    }
1617
1618    gtk_list_store_set_column_types(GTK_LIST_STORE(self->obj), len, column_types);
1619    g_free(column_types);
1620
1621    Py_INCREF(Py_None);
1622    return Py_None;
1623}
1624%%
1625ignore gtk_list_store_set_valist
1626%%
1627override gtk_list_store_set
1628static PyObject *
1629_wrap_gtk_list_store_set(PyGObject *self, PyObject *args)
1630{
1631    PyObject *iter;
1632    int len, i;
1633
1634    len = PyTuple_Size(args);
1635    if (len == 0) {
1636        PyErr_SetString(PyExc_TypeError, "GtkListStore.set requires at least three arguments");
1637        return NULL;
1638    }
1639
1640    iter = PyTuple_GetItem(args, 0);
1641    if (!pyg_boxed_check(iter, GTK_TYPE_TREE_ITER)) {
1642        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTreeIter");
1643        return NULL;
1644    }
1645
1646    if ((len - 1) % 2) {
1647        PyErr_SetString(PyExc_TypeError,
1648                        "Argument list must be column, value pairs.  No -1 "
1649                        "termination is needed.");
1650        return NULL;
1651    }
1652    for (i = 1; i < len; i+=2) {
1653        gint column;
1654        GValue value = { 0 };
1655        PyObject *py_column = PyTuple_GetItem(args, i);
1656        PyObject *py_value = PyTuple_GetItem(args, i + 1);
1657
1658        if (!PyInt_Check(py_column)) {
1659            PyErr_SetString(PyExc_TypeError,
1660                            "Expected numeric argument for column.");
1661            return NULL;
1662        }
1663        column = PyInt_AsLong(py_column);
1664        if (column < 0 ||
1665            column >= gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj))) {
1666            PyErr_SetString(PyExc_ValueError, "column number is out of range");
1667            return NULL;
1668        }
1669        g_value_init(&value,
1670                     gtk_tree_model_get_column_type(GTK_TREE_MODEL(self->obj),
1671                                                    column));
1672        if (pyg_value_from_pyobject(&value, py_value)) {
1673            PyErr_SetString(PyExc_TypeError,
1674                            "value is of the wrong type for this column");
1675            return NULL;
1676        }
1677        gtk_list_store_set_value(GTK_LIST_STORE(self->obj),
1678                                 pyg_boxed_get(iter, GtkTreeIter), column, &value);
1679        g_value_unset(&value);
1680    }
1681    Py_INCREF(Py_None);
1682    return Py_None;
1683}
1684%%
1685override gtk_list_store_set_value kwargs
1686static PyObject *
1687_wrap_gtk_list_store_set_value(PyGObject *self, PyObject *args,
1688                               PyObject *kwargs)
1689{
1690    static char *kwlist[] = { "iter", "column", "value", NULL };
1691    PyObject *iter, *pyvalue;
1692    gint column;
1693    GValue value = { 0 };
1694
1695    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1696                                     "OiO:GtkListStore.set_value",
1697                                     kwlist, &iter, &column, &pyvalue))
1698        return NULL;
1699    if (column < 0 ||
1700        column >= gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj))) {
1701        PyErr_SetString(PyExc_ValueError, "column number is out of range");
1702        return NULL;
1703    }
1704    if (!pyg_boxed_check(iter, GTK_TYPE_TREE_ITER)) {
1705        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTreeIter");
1706        return NULL;
1707    }
1708    g_value_init(&value,
1709                 gtk_tree_model_get_column_type(GTK_TREE_MODEL(self->obj),
1710                                                column));
1711    if (pyg_value_from_pyobject(&value, pyvalue)) {
1712        PyErr_SetString(PyExc_TypeError,
1713                        "value is of the wrong type for this column");
1714        return NULL;
1715    }
1716    gtk_list_store_set_value(GTK_LIST_STORE(self->obj),
1717                             pyg_boxed_get(iter, GtkTreeIter), column, &value);
1718    g_value_unset(&value);
1719    Py_INCREF(Py_None);
1720    return Py_None;
1721}
1722%%
1723ignore
1724  gtk_list_store_setv
1725%%
1726override gtk_list_store_insert kwargs
1727static PyObject *
1728_wrap_gtk_list_store_insert(PyGObject *self, PyObject *args, PyObject *kwargs)
1729{
1730    static char *kwlist[] = { "position", "row", NULL };
1731    GtkTreeIter iter;
1732    gint position;
1733    PyObject *items = NULL;
1734    gint n_columns = 0;
1735    gint *columns = NULL;
1736    GValue *values = NULL;
1737    gint i;
1738
1739    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|O:GtkListStore.insert",
1740                                     kwlist, &position, &items)) {
1741        return NULL;
1742    }
1743
1744    if (items) {
1745	if (!PySequence_Check(items)) {
1746	    PyErr_SetString(PyExc_TypeError, "expecting a sequence");
1747	    return NULL;
1748	}
1749
1750	n_columns = gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj));
1751	if (PySequence_Length(items) != n_columns) {
1752	    PyErr_SetString(PyExc_ValueError, "row sequence has wrong length");
1753	    return NULL;
1754	}
1755    }
1756
1757    columns = g_new0(gint, n_columns);
1758    values = g_new0(GValue, n_columns);
1759    for (i = 0; i < n_columns; i++) {
1760	PyObject *item;
1761
1762	item = PySequence_GetItem(items, i);
1763	if (!item)
1764	    return NULL;
1765
1766	g_value_init(&values[i], gtk_tree_model_get_column_type(GTK_TREE_MODEL(self->obj), i));
1767
1768	if (pyg_value_from_pyobject(&values[i], item)) {
1769	    Py_DECREF(item);
1770	    PyErr_SetString(PyExc_TypeError,
1771			    "value is of wrong type for this column");
1772	    return NULL;
1773	}
1774
1775	columns[i] = i;
1776
1777	Py_DECREF(item);
1778    }
1779
1780    gtk_list_store_insert_with_valuesv(GTK_LIST_STORE(self->obj), &iter, position,
1781				       columns,
1782				       values,
1783				       n_columns);
1784
1785    for (i = 0; i < n_columns; i++) {
1786	g_value_unset(&values[i]);
1787    }
1788    if (values)
1789	g_free(values);
1790    if (columns)
1791	g_free(columns);
1792
1793    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
1794}
1795%%
1796override gtk_list_store_insert_before kwargs
1797static PyObject *
1798_wrap_gtk_list_store_insert_before(PyGObject *self, PyObject *args,
1799                                   PyObject *kwargs)
1800{
1801    static char *kwlist[] = { "sibling", "row", NULL };
1802    PyObject *py_sibling;
1803    GtkTreeIter iter, *sibling = NULL;
1804    PyObject *row = Py_None;
1805
1806    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1807                                     "O|O:GtkListStore.insert_before",
1808                                     kwlist, &py_sibling, &row)) {
1809        return NULL;
1810    }
1811
1812    if (pyg_boxed_check(py_sibling, GTK_TYPE_TREE_ITER))
1813        sibling = pyg_boxed_get(py_sibling, GtkTreeIter);
1814    else if (py_sibling != Py_None) {
1815        PyErr_SetString(PyExc_TypeError,
1816                        "sibling must be a GtkTreeIter or None");
1817        return NULL;
1818    }
1819    gtk_list_store_insert_before(GTK_LIST_STORE(self->obj), &iter, sibling);
1820
1821    /* optionally set items in the new row */
1822    if (row != Py_None &&
1823        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
1824        return NULL;
1825
1826    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
1827}
1828%%
1829override gtk_list_store_insert_after kwargs
1830static PyObject *
1831_wrap_gtk_list_store_insert_after(PyGObject *self, PyObject *args,
1832                                  PyObject *kwargs)
1833{
1834    static char *kwlist[] = { "sibling", "row", NULL };
1835    PyObject *py_sibling;
1836    GtkTreeIter iter, *sibling = NULL;
1837    PyObject *row = Py_None;
1838
1839    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1840                                     "O|O:GtkListStore.insert_after",
1841                                     kwlist, &py_sibling, &row))
1842        return NULL;
1843    if (pyg_boxed_check(py_sibling, GTK_TYPE_TREE_ITER))
1844        sibling = pyg_boxed_get(py_sibling, GtkTreeIter);
1845    else if (py_sibling != Py_None) {
1846        PyErr_SetString(PyExc_TypeError,
1847                        "sibling must be a GtkTreeIter or None");
1848        return NULL;
1849    }
1850    gtk_list_store_insert_after(GTK_LIST_STORE(self->obj), &iter, sibling);
1851
1852    /* optionally set items in the new row */
1853    if (row != Py_None &&
1854        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
1855        return NULL;
1856
1857    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
1858}
1859%%
1860override gtk_list_store_prepend kwargs
1861static PyObject *
1862_wrap_gtk_list_store_prepend(PyGObject *self, PyObject *args, PyObject *kwargs)
1863{
1864    static char *kwlist[] = { "row", NULL };
1865    GtkTreeIter iter;
1866    PyObject *row = Py_None;
1867
1868    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:GtkListStore.prepend",
1869				     kwlist, &row))
1870	return NULL;
1871
1872    gtk_list_store_prepend(GTK_LIST_STORE(self->obj), &iter);
1873
1874    /* optionally set items in the new row */
1875    if (row != Py_None &&
1876        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
1877        return NULL;
1878
1879    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
1880}
1881%%
1882override gtk_list_store_append kwargs
1883static PyObject *
1884_wrap_gtk_list_store_append(PyGObject *self, PyObject *args, PyObject *kwargs)
1885{
1886    static char *kwlist[] = { "row", NULL };
1887    GtkTreeIter iter;
1888    PyObject *row = Py_None;
1889
1890    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:GtkListStore.append",
1891				     kwlist, &row))
1892	return NULL;
1893
1894    gtk_list_store_append(GTK_LIST_STORE(self->obj), &iter);
1895
1896    /* optionally set items in the new row */
1897    if (row != Py_None &&
1898        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
1899        return NULL;
1900
1901    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
1902}
1903%%
1904override gtk_list_store_reorder args
1905static PyObject *
1906_wrap_gtk_list_store_reorder(PyGObject *self, PyObject *args)
1907{
1908    PyObject *list;
1909    gint *new_order;
1910    GtkListStore *store;
1911    int i;
1912    int length;
1913
1914    if (!PyArg_ParseTuple(args, "O:GtkListStore.reorder", &list))
1915	return NULL;
1916
1917    if (!PyList_Check(list)) {
1918        PyErr_SetString(PyExc_TypeError, "first argument should be a list");
1919        return NULL;
1920    }
1921    store = GTK_LIST_STORE(self->obj);
1922    length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(store), NULL);
1923
1924    if (PyList_Size(list) < length) {
1925        PyErr_SetString(PyExc_TypeError, "list must at least have the same size as the number of items in the store");
1926        return NULL;
1927    }
1928
1929    new_order = g_new0(gint, length);
1930    for (i = 0; i < length; i++) {
1931	PyObject *item = PyList_GetItem(list, i);
1932	int index;
1933	if (!PyInt_Check(item)) {
1934	    PyErr_SetString(PyExc_TypeError, "all items must be of type int");
1935	    g_free(new_order);
1936	    return NULL;
1937	}
1938	index = PyInt_AsLong(item);
1939	if (index < 0 || index >= length) {
1940	    PyErr_SetString(PyExc_ValueError, "position index out of range");
1941	    g_free(new_order);
1942	    return NULL;
1943	}
1944	new_order[i] = index;
1945    }
1946    gtk_list_store_reorder(GTK_LIST_STORE(self->obj), new_order);
1947
1948    g_free(new_order);
1949
1950    Py_INCREF(Py_None);
1951    return Py_None;
1952}
1953%%
1954ignore gtk_tree_store_newv
1955%%
1956new-constructor GTK_TYPE_TREE_STORE
1957%%
1958override gtk_tree_store_new
1959static int
1960_wrap_gtk_tree_store_new(PyGObject *self, PyObject *args)
1961{
1962    guint len, i;
1963    GType *column_types;
1964
1965    len = PyTuple_Size(args);
1966    if (len == 0) {
1967        PyErr_SetString(PyExc_TypeError, "GtkTreeStore requires at least one argument");
1968        return -1;
1969    }
1970
1971    column_types = g_new(GType, len);
1972    for (i = 0; i < len; i++) {
1973        PyObject *item = PyTuple_GetItem(args, i);
1974
1975        column_types[i] = pyg_type_from_object(item);
1976        if (column_types[i] == 0) {
1977            g_free(column_types);
1978            return -1;
1979        }
1980    }
1981
1982    pygobject_construct(self, NULL);
1983    gtk_tree_store_set_column_types(GTK_TREE_STORE(self->obj), len, column_types);
1984    g_free(column_types);
1985
1986    if (!self->obj) {
1987        PyErr_SetString(PyExc_RuntimeError,
1988                        "could not create GtkTreeStore object");
1989        return -1;
1990    }
1991    return 0;
1992}
1993%%
1994ignore gtk_tree_store_set_valist
1995%%
1996override gtk_tree_store_set
1997static PyObject *
1998_wrap_gtk_tree_store_set(PyGObject *self, PyObject *args)
1999{
2000    PyObject *iter;
2001    int len, i;
2002
2003    len = PyTuple_Size(args);
2004    if (len == 0) {
2005        PyErr_SetString(PyExc_TypeError, "GtkTreeStore.set requires at least three arguments");
2006        return NULL;
2007    }
2008
2009    iter = PyTuple_GetItem(args, 0);
2010    if (!pyg_boxed_check(iter, GTK_TYPE_TREE_ITER)) {
2011        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTreeIter");
2012        return NULL;
2013    }
2014
2015    if ((len - 1) % 2) {
2016        PyErr_SetString(PyExc_TypeError,
2017                        "Argument list must be column, value pairs.  No -1 "
2018                        "termination is needed.");
2019        return NULL;
2020    }
2021    for (i = 1; i < len; i+=2) {
2022        gint column;
2023        GValue value = { 0 };
2024        PyObject *py_column = PyTuple_GetItem(args, i);
2025        PyObject *py_value = PyTuple_GetItem(args, i + 1);
2026
2027        if (!PyInt_Check(py_column)) {
2028            PyErr_SetString(PyExc_TypeError,
2029                            "Expected numeric argument for column.");
2030            return NULL;
2031        }
2032        column = PyInt_AsLong(py_column);
2033        if (column < 0 ||
2034            column >= gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj))) {
2035            PyErr_SetString(PyExc_ValueError, "column number is out of range");
2036            return NULL;
2037        }
2038        g_value_init(&value,
2039                     gtk_tree_model_get_column_type(GTK_TREE_MODEL(self->obj),
2040                                                    column));
2041        if (pyg_value_from_pyobject(&value, py_value)) {
2042            PyErr_SetString(PyExc_TypeError,
2043                            "value is of the wrong type for this column");
2044            return NULL;
2045        }
2046        gtk_tree_store_set_value(GTK_TREE_STORE(self->obj),
2047                                 pyg_boxed_get(iter, GtkTreeIter), column,
2048                                 &value);
2049        g_value_unset(&value);
2050    }
2051    Py_INCREF(Py_None);
2052    return Py_None;
2053}
2054%%
2055override gtk_tree_store_set_value kwargs
2056static PyObject *
2057_wrap_gtk_tree_store_set_value(PyGObject *self, PyObject *args,
2058                               PyObject *kwargs)
2059{
2060    static char *kwlist[] = { "iter", "column", "value", NULL };
2061    PyObject *iter, *pyvalue;
2062    gint column;
2063    GValue value = { 0 };
2064
2065    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2066                                     "OiO:GtkTreeStore.set_value",
2067                                     kwlist, &iter, &column, &pyvalue))
2068        return NULL;
2069    if (column < 0 ||
2070        column >= gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj))) {
2071        PyErr_SetString(PyExc_ValueError, "column number is out of range");
2072        return NULL;
2073    }
2074    if (!pyg_boxed_check(iter, GTK_TYPE_TREE_ITER)) {
2075        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTreeIter");
2076        return NULL;
2077    }
2078    g_value_init(&value,
2079                 gtk_tree_model_get_column_type(GTK_TREE_MODEL(self->obj),
2080                                                column));
2081    if (pyg_value_from_pyobject(&value, pyvalue)) {
2082        PyErr_SetString(PyExc_TypeError,
2083                        "value is of the wrong type for this column");
2084        return NULL;
2085    }
2086    gtk_tree_store_set_value(GTK_TREE_STORE(self->obj),
2087                             pyg_boxed_get(iter, GtkTreeIter), column, &value);
2088    g_value_unset(&value);
2089    Py_INCREF(Py_None);
2090    return Py_None;
2091}
2092%%
2093ignore
2094  gtk_tree_store_setv
2095%%
2096override gtk_tree_store_insert kwargs
2097#if GTK_CHECK_VERSION(2, 10, 0)
2098static PyObject *
2099_wrap_gtk_tree_store_insert(PyGObject *self, PyObject *args, PyObject *kwargs)
2100{
2101    static char *kwlist[] = { "parent", "position", "row", NULL };
2102    PyObject *py_parent;
2103    GtkTreeIter iter, *parent = NULL;
2104    gint position;
2105    PyObject *items = NULL;
2106    gint n_columns = 0;
2107    gint *columns = NULL;
2108    GValue *values = NULL;
2109    gint i;
2110
2111    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|O:GtkTreeStore.insert",
2112                                     kwlist, &py_parent, &position, &items))
2113        return NULL;
2114    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2115        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2116    else if (py_parent != Py_None) {
2117        PyErr_SetString(PyExc_TypeError,
2118                        "parent must be a GtkTreeIter or None");
2119        return NULL;
2120    }
2121    if (items) {
2122	if (!PySequence_Check(items)) {
2123	    PyErr_SetString(PyExc_TypeError, "expecting a sequence");
2124	    return NULL;
2125	}
2126
2127	n_columns = gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj));
2128	if (PySequence_Length(items) != n_columns) {
2129	    PyErr_SetString(PyExc_ValueError, "row sequence has wrong length");
2130	    return NULL;
2131	}
2132    }
2133
2134    columns = g_new0(gint, n_columns);
2135    values = g_new0(GValue, n_columns);
2136    for (i = 0; i < n_columns; i++) {
2137	PyObject *item;
2138
2139	item = PySequence_GetItem(items, i);
2140	if (!item)
2141	    return NULL;
2142
2143	g_value_init(&values[i],
2144                     gtk_tree_model_get_column_type(GTK_TREE_MODEL(self->obj),
2145                                                    i));
2146
2147	if (pyg_value_from_pyobject(&values[i], item)) {
2148	    Py_DECREF(item);
2149	    PyErr_SetString(PyExc_TypeError,
2150			    "value is of wrong type for this column");
2151	    return NULL;
2152	}
2153
2154	columns[i] = i;
2155
2156	Py_DECREF(item);
2157    }
2158
2159    gtk_tree_store_insert_with_valuesv(GTK_TREE_STORE(self->obj), &iter,
2160                                       parent, position, columns, values,
2161				       n_columns);
2162
2163    for (i = 0; i < n_columns; i++) {
2164	g_value_unset(&values[i]);
2165    }
2166    if (values)
2167	g_free(values);
2168    if (columns)
2169	g_free(columns);
2170
2171    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2172}
2173#else
2174static PyObject *
2175_wrap_gtk_tree_store_insert(PyGObject *self, PyObject *args, PyObject *kwargs)
2176{
2177    static char *kwlist[] = { "parent", "position", "row", NULL };
2178    PyObject *py_parent;
2179    GtkTreeIter iter, *parent = NULL;
2180    gint position;
2181    PyObject *row = Py_None;
2182
2183    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|O:GtkTreeStore.insert",
2184                                     kwlist, &py_parent, &position, &row))
2185        return NULL;
2186    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2187        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2188    else if (py_parent != Py_None) {
2189        PyErr_SetString(PyExc_TypeError,
2190                        "parent must be a GtkTreeIter or None");
2191        return NULL;
2192    }
2193    gtk_tree_store_insert(GTK_TREE_STORE(self->obj), &iter, parent, position);
2194
2195    /* optionally set items in the new row */
2196    if (row != Py_None &&
2197        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
2198        return NULL;
2199
2200    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2201}
2202#endif
2203%%
2204override gtk_tree_store_insert_before kwargs
2205static PyObject *
2206_wrap_gtk_tree_store_insert_before(PyGObject *self, PyObject *args,
2207                                   PyObject *kwargs)
2208{
2209    static char *kwlist[] = { "parent", "sibling", "row", NULL };
2210    PyObject *py_parent, *py_sibling;
2211    GtkTreeIter iter, *parent = NULL, *sibling = NULL;
2212    PyObject *row = Py_None;
2213
2214    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2215                                     "OO|O:GtkTreeStore.insert_before",
2216                                     kwlist, &py_parent, &py_sibling, &row))
2217        return NULL;
2218    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2219        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2220    else if (py_parent != Py_None) {
2221        PyErr_SetString(PyExc_TypeError,
2222                        "parent must be a GtkTreeIter or None");
2223        return NULL;
2224    }
2225    if (pyg_boxed_check(py_sibling, GTK_TYPE_TREE_ITER))
2226        sibling = pyg_boxed_get(py_sibling, GtkTreeIter);
2227    else if (py_sibling != Py_None) {
2228        PyErr_SetString(PyExc_TypeError,
2229                        "sibling must be a GtkTreeIter or None");
2230        return NULL;
2231    }
2232    gtk_tree_store_insert_before(GTK_TREE_STORE(self->obj), &iter, parent,
2233                                 sibling);
2234
2235    /* optionally set items in the new row */
2236    if (row != Py_None &&
2237        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
2238        return NULL;
2239
2240    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2241}
2242%%
2243override gtk_tree_store_insert_after kwargs
2244static PyObject *
2245_wrap_gtk_tree_store_insert_after(PyGObject *self, PyObject *args,
2246                                  PyObject *kwargs)
2247{
2248    static char *kwlist[] = { "parent", "sibling", "row", NULL };
2249    PyObject *py_parent, *py_sibling;
2250    GtkTreeIter iter, *parent = NULL, *sibling = NULL;
2251    PyObject *row = Py_None;
2252
2253    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2254                                     "OO|O:GtkTreeStore.insert_after",
2255                                     kwlist, &py_parent, &py_sibling, &row))
2256        return NULL;
2257    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2258        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2259    else if (py_parent != Py_None) {
2260        PyErr_SetString(PyExc_TypeError,
2261                        "parent must be a GtkTreeIter or None");
2262        return NULL;
2263    }
2264    if (pyg_boxed_check(py_sibling, GTK_TYPE_TREE_ITER))
2265        sibling = pyg_boxed_get(py_sibling, GtkTreeIter);
2266    else if (py_sibling != Py_None) {
2267        PyErr_SetString(PyExc_TypeError,
2268                        "sibling must be a GtkTreeIter or None");
2269        return NULL;
2270    }
2271    gtk_tree_store_insert_after(GTK_TREE_STORE(self->obj), &iter, parent,
2272                                sibling);
2273
2274    /* optionally set items in the new row */
2275    if (row != Py_None &&
2276        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
2277        return NULL;
2278
2279    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2280}
2281%%
2282override gtk_tree_store_prepend kwargs
2283static PyObject *
2284_wrap_gtk_tree_store_prepend(PyGObject *self, PyObject *args, PyObject *kwargs)
2285{
2286    static char *kwlist[] = { "parent", "row", NULL };
2287    PyObject *py_parent;
2288    GtkTreeIter iter, *parent = NULL;
2289    PyObject *row = Py_None;
2290
2291    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:GtkTreeStore.prepend",
2292                                     kwlist, &py_parent, &row))
2293        return NULL;
2294    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2295        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2296    else if (py_parent != Py_None) {
2297        PyErr_SetString(PyExc_TypeError,
2298                        "parent must be a GtkTreeIter or None");
2299        return NULL;
2300    }
2301    gtk_tree_store_prepend(GTK_TREE_STORE(self->obj), &iter, parent);
2302
2303    /* optionally set items in the new row */
2304    if (row != Py_None &&
2305        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
2306        return NULL;
2307
2308    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2309}
2310%%
2311override gtk_tree_store_append kwargs
2312static PyObject *
2313_wrap_gtk_tree_store_append(PyGObject *self, PyObject *args, PyObject *kwargs)
2314{
2315    static char *kwlist[] = { "parent", "row", NULL };
2316    PyObject *py_parent;
2317    GtkTreeIter iter, *parent = NULL;
2318    PyObject *row = Py_None;
2319
2320    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:GtkTreeStore.append",
2321                                     kwlist, &py_parent, &row))
2322        return NULL;
2323    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2324        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2325    else if (py_parent != Py_None) {
2326        PyErr_SetString(PyExc_TypeError,
2327                        "parent must be a GtkTreeIter or None");
2328        return NULL;
2329    }
2330    gtk_tree_store_append(GTK_TREE_STORE(self->obj), &iter, parent);
2331
2332    /* optionally set items in the new row */
2333    if (row != Py_None &&
2334        _pygtk_tree_model_set_row(GTK_TREE_MODEL(self->obj), &iter, row) < 0)
2335        return NULL;
2336
2337    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2338}
2339%%
2340override gtk_tree_model_get_iter_first noargs
2341static PyObject *
2342_wrap_gtk_tree_model_get_iter_first(PyGObject *self)
2343{
2344    GtkTreeIter iter;
2345
2346    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(self->obj), &iter))
2347        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2348    else {
2349        Py_INCREF(Py_None);
2350        return Py_None;
2351    }
2352}
2353%%
2354override gtk_tree_model_iter_next kwargs
2355static PyObject *
2356_wrap_gtk_tree_model_iter_next(PyGObject *self, PyObject *args,
2357                               PyObject *kwargs)
2358{
2359    static char *kwlist[] = { "iter", NULL };
2360    PyObject *py_iter;
2361    GtkTreeIter iter;
2362
2363    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2364                                     "O:GtkTreeModel.iter_next", kwlist,
2365                                     &py_iter))
2366        return NULL;
2367    if (pyg_boxed_check(py_iter, GTK_TYPE_TREE_ITER))
2368        iter = *pyg_boxed_get(py_iter, GtkTreeIter);
2369    else {
2370        PyErr_SetString(PyExc_TypeError, "iter should be a GtkTreeIter");
2371        return NULL;
2372    }
2373
2374    if (gtk_tree_model_iter_next(GTK_TREE_MODEL(self->obj), &iter))
2375        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2376    else {
2377        Py_INCREF(Py_None);
2378        return Py_None;
2379    }
2380}
2381%%
2382override gtk_tree_model_iter_children kwargs
2383static PyObject *
2384_wrap_gtk_tree_model_iter_children(PyGObject *self, PyObject *args,
2385                                   PyObject *kwargs)
2386{
2387    static char *kwlist[] = { "parent", NULL };
2388    PyObject *py_parent;
2389    GtkTreeIter iter, *parent = NULL;
2390
2391    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2392                                     "O:GtkTreeModel.iter_children", kwlist,
2393                                     &py_parent))
2394        return NULL;
2395    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2396        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2397    else if (py_parent == Py_None)
2398        parent = NULL;
2399    else {
2400        PyErr_SetString(PyExc_TypeError, "parent should be a GtkTreeIter or None");
2401        return NULL;
2402    }
2403
2404    if (gtk_tree_model_iter_children(GTK_TREE_MODEL(self->obj),
2405                                     &iter, parent))
2406        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2407    else {
2408        Py_INCREF(Py_None);
2409        return Py_None;
2410    }
2411}
2412%%
2413override gtk_tree_model_iter_nth_child kwargs
2414static PyObject *
2415_wrap_gtk_tree_model_iter_nth_child(PyGObject *self, PyObject *args,
2416                                    PyObject *kwargs)
2417{
2418    static char *kwlist[] = { "parent", "n", NULL };
2419    PyObject *py_parent;
2420    gint n;
2421    GtkTreeIter iter, *parent = NULL;
2422
2423    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2424                                     "Oi:GtkTreeModel.iter_nth_child", kwlist,
2425                                     &py_parent, &n))
2426        return NULL;
2427    if (pyg_boxed_check(py_parent, GTK_TYPE_TREE_ITER))
2428        parent = pyg_boxed_get(py_parent, GtkTreeIter);
2429    else if (py_parent == Py_None)
2430        parent = NULL;
2431    else {
2432        PyErr_SetString(PyExc_TypeError, "parent should be a GtkTreeIter or None");
2433        return NULL;
2434    }
2435
2436    if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(self->obj),
2437                                     &iter, parent, n))
2438        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2439    else {
2440        Py_INCREF(Py_None);
2441        return Py_None;
2442    }
2443}
2444%%
2445override gtk_tree_model_iter_parent kwargs
2446static PyObject *
2447_wrap_gtk_tree_model_iter_parent(PyGObject *self, PyObject *args,
2448                                   PyObject *kwargs)
2449{
2450    static char *kwlist[] = { "child", NULL };
2451    PyObject *py_child;
2452    GtkTreeIter iter, *child = NULL;
2453
2454    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2455                                     "O:GtkTreeModel.iter_parent", kwlist,
2456                                     &py_child))
2457        return NULL;
2458    if (pyg_boxed_check(py_child, GTK_TYPE_TREE_ITER))
2459        child = pyg_boxed_get(py_child, GtkTreeIter);
2460    else {
2461        PyErr_SetString(PyExc_TypeError, "child should be a GtkTreeIter");
2462        return NULL;
2463    }
2464
2465    if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(self->obj),
2466                                   &iter, child))
2467        return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2468    else {
2469        Py_INCREF(Py_None);
2470        return Py_None;
2471    }
2472}
2473%%
2474override gtk_tree_model_foreach
2475static gboolean
2476pygtk_tree_foreach_marshal(GtkTreeModel *model,
2477                           GtkTreePath *path,
2478                           GtkTreeIter *iter,
2479                           gpointer data)
2480{
2481    PyGILState_STATE state;
2482    PyGtkCustomNotify *cunote = data;
2483    PyObject *py_model, *py_path, *py_iter, *retobj;
2484    gboolean ret;
2485
2486    g_assert(cunote->func);
2487
2488    state = pyg_gil_state_ensure();
2489
2490    py_model = pygobject_new((GObject *)model);
2491    py_path = pygtk_tree_path_to_pyobject(path);
2492    py_iter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter,  FALSE, FALSE);
2493    if (cunote->data)
2494        retobj = PyEval_CallFunction(cunote->func, "(NNOO)",
2495                                     py_model, py_path, py_iter,
2496                                     cunote->data);
2497    else
2498        retobj = PyEval_CallFunction(cunote->func, "(NNO)",
2499                                     py_model, py_path, py_iter);
2500
2501    if (retobj != NULL) {
2502        ret = PyObject_IsTrue(retobj);
2503        Py_DECREF(retobj);
2504    } else {
2505        ret = TRUE;
2506    }
2507    pygtk_boxed_unref_shared(py_iter);
2508    pyg_gil_state_release(state);
2509    return ret;
2510}
2511static PyObject *
2512_wrap_gtk_tree_model_foreach(PyGObject *self, PyObject *args)
2513{
2514    gboolean pygtk_tree_foreach_marshal(GtkTreeModel *model,
2515                                           GtkTreePath *path,
2516                                           GtkTreeIter *iter,
2517                                           gpointer data);
2518    PyObject *pyfunc, *pyarg = NULL;
2519    PyGtkCustomNotify cunote;
2520
2521    if(!PyArg_ParseTuple(args, "O|O:GtkTreeModel.foreach",
2522                         &pyfunc, &pyarg))
2523        return NULL;
2524
2525    cunote.func = pyfunc;
2526    cunote.data = pyarg;
2527    gtk_tree_model_foreach(GTK_TREE_MODEL(self->obj),
2528                           pygtk_tree_foreach_marshal, &cunote);
2529
2530    if (PyErr_Occurred())
2531        return NULL;
2532
2533    Py_INCREF(Py_None);
2534    return Py_None;
2535}
2536%%
2537override gtk_cell_renderer_get_size kwargs
2538static PyObject *
2539_wrap_gtk_cell_renderer_get_size(PyGObject *self, PyObject *args,
2540                                 PyObject *kwargs)
2541{
2542    static char *kwlist[] = { "widget", "cell_area", NULL };
2543    gint x_offset = 0, y_offset = 0, width = 0, height = 0;
2544    GdkRectangle cell_area;
2545    PyObject *py_widget, *py_cell_area = Py_None;
2546
2547    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2548                                     "O|O:GtkCellRenderer.get_size", kwlist,
2549                                     &py_widget, &py_cell_area))
2550        return NULL;
2551
2552    if (!pygobject_check(py_widget, &PyGtkWidget_Type)) {
2553        PyErr_SetString(PyExc_TypeError, "widget must be a GtkWidget");
2554        return NULL;
2555    }
2556    if (py_cell_area != Py_None) {
2557        if (!pygdk_rectangle_from_pyobject(py_cell_area, &cell_area))
2558            return NULL;
2559    }
2560
2561    gtk_cell_renderer_get_size(GTK_CELL_RENDERER(self->obj),
2562                               GTK_WIDGET(pygobject_get(py_widget)),
2563                               (py_cell_area == Py_None) ? NULL : &cell_area,
2564                               &x_offset, &y_offset, &width, &height);
2565
2566    return Py_BuildValue("(iiii)", x_offset, y_offset, width, height);
2567}
2568%%
2569override gtk_cell_renderer_get_fixed_size noargs
2570static PyObject *
2571_wrap_gtk_cell_renderer_get_fixed_size(PyGObject *self)
2572{
2573    gint width, height;
2574
2575    gtk_cell_renderer_get_fixed_size(GTK_CELL_RENDERER(self->obj),
2576                                     &width, &height);
2577
2578    return Py_BuildValue("(ii)", width, height);
2579}
2580%%
2581override gtk_tree_model_sort_convert_child_iter_to_iter kwargs
2582static PyObject *
2583_wrap_gtk_tree_model_sort_convert_child_iter_to_iter(PyGObject *self,
2584						     PyObject *args,
2585						     PyObject *kwargs)
2586{
2587    static char *kwlist[] = { "sort_iter", "child_iter", NULL };
2588    PyObject *py_sort_iter = Py_None, *py_child_iter;
2589    GtkTreeIter iter, *sort_iter, *child_iter = NULL;
2590
2591    sort_iter = &iter;
2592    if (!PyArg_ParseTupleAndKeywords(
2593	args, kwargs, "OO:GtkTreeModelSort.convert_child_iter_to_iter",
2594	kwlist, &py_sort_iter, &py_child_iter))
2595        return NULL;
2596    if (pyg_boxed_check(py_sort_iter, GTK_TYPE_TREE_ITER))
2597        sort_iter = pyg_boxed_get(py_sort_iter, GtkTreeIter);
2598    else if (py_sort_iter != Py_None) {
2599        PyErr_SetString(PyExc_TypeError,
2600			"sort_iter should be a GtkTreeIter or None");
2601        return NULL;
2602    }
2603    if (pyg_boxed_check(py_child_iter, GTK_TYPE_TREE_ITER))
2604        child_iter = pyg_boxed_get(py_child_iter, GtkTreeIter);
2605    else {
2606        PyErr_SetString(PyExc_TypeError, "child_iter should be a GtkTreeIter");
2607        return NULL;
2608    }
2609    gtk_tree_model_sort_convert_child_iter_to_iter(
2610	GTK_TREE_MODEL_SORT(self->obj), sort_iter, child_iter);
2611    return pyg_boxed_new(GTK_TYPE_TREE_ITER, sort_iter, TRUE, TRUE);
2612}
2613%%
2614override gtk_tree_model_sort_convert_iter_to_child_iter kwargs
2615static PyObject *
2616_wrap_gtk_tree_model_sort_convert_iter_to_child_iter(PyGObject *self,
2617						     PyObject *args,
2618						     PyObject *kwargs)
2619{
2620    static char *kwlist[] = { "child_iter", "sorted_iter", NULL };
2621    PyObject *py_child_iter = Py_None, *py_sorted_iter;
2622    GtkTreeIter iter, *child_iter, *sorted_iter = NULL;
2623
2624    child_iter = &iter;
2625    if (!PyArg_ParseTupleAndKeywords(
2626	args, kwargs, "OO:GtkTreeModelSort.convert_iter_to_child_iter",
2627	kwlist, &py_child_iter, &py_sorted_iter))
2628        return NULL;
2629    if (pyg_boxed_check(py_child_iter, GTK_TYPE_TREE_ITER))
2630        child_iter = pyg_boxed_get(py_child_iter, GtkTreeIter);
2631    else if (py_child_iter != Py_None) {
2632        PyErr_SetString(PyExc_TypeError,
2633			"child_iter should be a GtkTreeIter or None");
2634        return NULL;
2635    }
2636    if (pyg_boxed_check(py_sorted_iter, GTK_TYPE_TREE_ITER))
2637        sorted_iter = pyg_boxed_get(py_sorted_iter, GtkTreeIter);
2638    else {
2639        PyErr_SetString(PyExc_TypeError,
2640			"sorted_iter should be a GtkTreeIter");
2641        return NULL;
2642    }
2643    gtk_tree_model_sort_convert_iter_to_child_iter(
2644	GTK_TREE_MODEL_SORT(self->obj), child_iter, sorted_iter);
2645    return pyg_boxed_new(GTK_TYPE_TREE_ITER, child_iter, TRUE, TRUE);
2646}
2647%%
2648override gtk_tree_view_enable_model_drag_source kwargs
2649static PyObject *
2650_wrap_gtk_tree_view_enable_model_drag_source(PyGObject *self, PyObject *args,
2651                                             PyObject *kwargs)
2652{
2653    static char *kwlist[] = { "start_button_mask", "targets", "actions", NULL };
2654    PyObject *py_sbmask, *py_targets, *py_actions;
2655    GdkModifierType sbmask;
2656    GtkTargetEntry *targets;
2657    GdkDragAction actions;
2658    gint n_targets, i;
2659
2660    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2661                                     "OOO:GtkTreeView.enable_model_drag_source",
2662                                     kwlist,
2663                                     &py_sbmask, &py_targets, &py_actions))
2664        return NULL;
2665    if (pyg_flags_get_value(GDK_TYPE_MODIFIER_TYPE,
2666                             py_sbmask, (gint *)&sbmask))
2667        return NULL;
2668    if (pyg_flags_get_value(GDK_TYPE_DRAG_ACTION,
2669                             py_actions, (gint *)&actions))
2670        return NULL;
2671    if (!PySequence_Check(py_targets)) {
2672        PyErr_SetString(PyExc_TypeError, "targets must be a sequence");
2673        return NULL;
2674    }
2675    n_targets = PySequence_Length(py_targets);
2676    targets = g_new(GtkTargetEntry, n_targets);
2677    for (i = 0; i < n_targets; i++) {
2678        PyObject *item = PySequence_GetItem(py_targets, i);
2679        Py_DECREF(item);
2680        if (!PyArg_ParseTuple(item, "zii", &targets[i].target,
2681                              &targets[i].flags, &targets[i].info)) {
2682            PyErr_Clear();
2683            PyErr_SetString(PyExc_TypeError,
2684                            "list items should be of form (string,int,int)");
2685            g_free(targets);
2686            return NULL;
2687        }
2688    }
2689    gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(self->obj),
2690                                           sbmask, targets, n_targets, actions);
2691    g_free(targets);
2692    Py_INCREF(Py_None);
2693    return Py_None;
2694}
2695%%
2696override gtk_tree_view_enable_model_drag_dest kwargs
2697static PyObject *
2698_wrap_gtk_tree_view_enable_model_drag_dest(PyGObject *self, PyObject *args,
2699                                           PyObject *kwargs)
2700{
2701    static char *kwlist[] = { "targets", "actions", NULL };
2702    PyObject *py_targets, *py_actions;
2703    GtkTargetEntry *targets;
2704    GdkDragAction actions;
2705    gint n_targets, i;
2706
2707    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2708                                     "OO:GtkTreeView.enable_model_drag_dest",
2709                                     kwlist,
2710                                     &py_targets, &py_actions))
2711        return NULL;
2712    if (pyg_flags_get_value(GDK_TYPE_DRAG_ACTION,
2713                             py_actions, (gint *)&actions))
2714        return NULL;
2715    if (!PySequence_Check(py_targets)) {
2716        PyErr_SetString(PyExc_TypeError, "targets must be a sequence");
2717        return NULL;
2718    }
2719    n_targets = PySequence_Length(py_targets);
2720    targets = g_new(GtkTargetEntry, n_targets);
2721    for (i = 0; i < n_targets; i++) {
2722        PyObject *item = PySequence_GetItem(py_targets, i);
2723        Py_DECREF(item);
2724        if (!PyArg_ParseTuple(item, "zii", &targets[i].target,
2725                              &targets[i].flags, &targets[i].info)) {
2726            PyErr_Clear();
2727            PyErr_SetString(PyExc_TypeError,
2728                            "list items should be of form (string,int,int)");
2729            g_free(targets);
2730            return NULL;
2731        }
2732    }
2733    gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(self->obj),
2734                                         targets, n_targets, actions);
2735    g_free(targets);
2736    Py_INCREF(Py_None);
2737    return Py_None;
2738}
2739%%
2740override gtk_tree_view_get_drag_dest_row noargs
2741static PyObject *
2742_wrap_gtk_tree_view_get_drag_dest_row(PyGObject *self)
2743{
2744    GtkTreePath *path;
2745    GtkTreeViewDropPosition pos;
2746
2747    gtk_tree_view_get_drag_dest_row(GTK_TREE_VIEW(self->obj), &path, &pos);
2748    if (path) {
2749        PyObject *py_path = pygtk_tree_path_to_pyobject(path);
2750        gint py_pos = (gint) pos;
2751        gtk_tree_path_free(path);
2752        return Py_BuildValue("(NN)", py_path,
2753			     pyg_enum_from_gtype(GTK_TYPE_TREE_VIEW_DROP_POSITION, py_pos));
2754    } else {
2755        Py_INCREF(Py_None);
2756        return Py_None;
2757    }
2758}
2759%%
2760override gtk_tree_view_set_drag_dest_row kwargs
2761static PyObject *
2762_wrap_gtk_tree_view_set_drag_dest_row(PyGObject *self, PyObject *args,
2763                                      PyObject *kwargs)
2764{
2765    static char *kwlist[] = { "path", "pos", NULL };
2766    PyObject *py_path;
2767    gint py_pos;
2768    GtkTreePath *path;
2769    GtkTreeViewDropPosition pos;
2770
2771    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2772                                     "Oi:GtkTreeView.set_drag_dest_row",
2773                                     kwlist,
2774                                     &py_path, &py_pos))
2775        return NULL;
2776
2777    if (py_path == Py_None)
2778        path = NULL;
2779    else {
2780        path = pygtk_tree_path_from_pyobject(py_path);
2781        if (!path) {
2782            PyErr_SetString(PyExc_TypeError,
2783                            "set_drag_dest_row must be a TreePath");
2784            return NULL;
2785        }
2786    }
2787    pos = (GtkTreeViewDropPosition) py_pos;
2788    gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(self->obj), path, pos);
2789    gtk_tree_path_free(path);
2790
2791    Py_INCREF(Py_None);
2792    return Py_None;
2793}
2794%%
2795override gtk_tree_view_get_dest_row_at_pos kwargs
2796static PyObject *
2797_wrap_gtk_tree_view_get_dest_row_at_pos(PyGObject *self, PyObject *args,
2798					PyObject *kwargs)
2799{
2800    static char *kwlist[] = { "x", "y", NULL };
2801    GtkTreePath *path;
2802    GtkTreeViewDropPosition pos;
2803
2804    gint x,y;
2805    gboolean r;
2806
2807    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2808                                     "ii:GtkTreeView.get_drag_dest_row_at_pos",
2809                                     kwlist,
2810                                     &x, &y))
2811        return NULL;
2812
2813
2814    r = gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(self->obj), x, y, &path, &pos);
2815    if (r && path) {
2816        PyObject *py_path = pygtk_tree_path_to_pyobject(path);
2817        gint py_pos = (gint) pos;
2818        gtk_tree_path_free(path);
2819        return Py_BuildValue("(NN)", py_path,
2820			     pyg_enum_from_gtype(GTK_TYPE_TREE_VIEW_DROP_POSITION, py_pos));
2821    }
2822
2823    Py_INCREF(Py_None);
2824    return Py_None;
2825}
2826%%
2827override gtk_tree_view_map_expanded_rows kwargs
2828
2829typedef struct {
2830    PyObject *func;
2831    PyObject *user_data;
2832} _map_expanded_rows_data_t;
2833
2834static void map_expanded_rows_cb(GtkTreeView *tree_view, GtkTreePath *path,
2835			         gpointer user_data)
2836{
2837    PyObject *py_path, *py_view, *ret;
2838    _map_expanded_rows_data_t *data =
2839	(_map_expanded_rows_data_t *) user_data;
2840
2841    /* If exception is pending, just return */
2842    if (PyErr_Occurred())
2843        return;
2844
2845    py_path = pygtk_tree_path_to_pyobject(path);
2846    if (py_path == NULL)
2847        return;
2848    py_view = pygobject_new((GObject *)tree_view);
2849    if (py_view == NULL) {
2850        Py_DECREF(py_path);
2851        return;
2852    }
2853    if (data->user_data)
2854	ret = PyObject_CallFunction(data->func, "NNO", py_view, py_path, data->user_data);
2855    else
2856	ret = PyObject_CallFunction(data->func, "NN", py_view, py_path);
2857    Py_XDECREF(ret);
2858}
2859
2860static PyObject *
2861_wrap_gtk_tree_view_map_expanded_rows(PyGObject *self, PyObject *args,
2862                                      PyObject *kwargs)
2863{
2864    static char *kwlist[] = { "func", "data", NULL };
2865    _map_expanded_rows_data_t data = { NULL, NULL };
2866
2867    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2868                                     "O|O:GtkTreeView.map_expanded_rows",
2869                                     kwlist,
2870                                     &data.func, &data.user_data))
2871        return NULL;
2872
2873    if (!PyCallable_Check(data.func)) {
2874        PyErr_SetString(PyExc_TypeError, "func must be callable");
2875	return NULL;
2876    }
2877
2878    gtk_tree_view_map_expanded_rows(GTK_TREE_VIEW(self->obj), map_expanded_rows_cb,
2879                                    &data);
2880
2881    /* Return NULL if exception occurred in the callback */
2882    if (PyErr_Occurred())
2883        return NULL;
2884
2885    Py_INCREF(Py_None);
2886    return Py_None;
2887}
2888%%
2889override gtk_tree_model_filter_set_visible_func kwargs
2890static gboolean
2891pygtk_tree_model_filter_visible_cb(GtkTreeModel *model, GtkTreeIter *iter,
2892				   gpointer data)
2893{
2894    PyGILState_STATE state;
2895    PyGtkCustomNotify *cunote = data;
2896    PyObject *py_model, *py_iter, *retobj;
2897    gboolean ret = FALSE;
2898
2899    g_assert(cunote->func);
2900
2901    state = pyg_gil_state_ensure();
2902
2903    py_model = pygobject_new((GObject *)model);
2904    py_iter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter,  FALSE, FALSE);
2905
2906    if (cunote->data) {
2907        retobj = PyEval_CallFunction(cunote->func, "(NNO)", py_model,
2908                                     py_iter, cunote->data);
2909    } else {
2910        retobj = PyEval_CallFunction(cunote->func, "(NN)", py_model,
2911                                     py_iter);
2912    }
2913    if (retobj)
2914        ret = retobj == Py_True ? TRUE : FALSE;
2915    if (PyErr_Occurred()) {
2916        PyErr_Print();
2917    }
2918    Py_XDECREF(retobj);
2919
2920    pyg_gil_state_release(state);
2921    return ret;
2922}
2923static PyObject *
2924_wrap_gtk_tree_model_filter_set_visible_func(PyGObject *self, PyObject *args,
2925					     PyObject *kwargs)
2926{
2927    static char *kwlist[] = { "func", "data", NULL };
2928    PyObject *pyfunc, *pyarg = NULL;
2929    PyGtkCustomNotify *cunote;
2930
2931    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2932				     "O|O:GtkTreeModelFilter.set_visible_func",
2933				     kwlist, &pyfunc, &pyarg))
2934        return NULL;
2935
2936    if (!PyCallable_Check(pyfunc)) {
2937        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
2938        return NULL;
2939    }
2940    cunote = g_new(PyGtkCustomNotify, 1);
2941    Py_INCREF(pyfunc);
2942    cunote->func = pyfunc;
2943    Py_XINCREF(pyarg);
2944    cunote->data = pyarg;
2945
2946    gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(self->obj),
2947					   pygtk_tree_model_filter_visible_cb,
2948					   (gpointer)cunote,
2949					   pygtk_custom_destroy_notify);
2950    Py_INCREF(Py_None);
2951    return Py_None;
2952}
2953%%
2954override gtk_tree_model_filter_convert_child_iter_to_iter kwargs
2955static PyObject *
2956_wrap_gtk_tree_model_filter_convert_child_iter_to_iter(PyGObject *self,
2957						     PyObject *args,
2958						     PyObject *kwargs)
2959{
2960    static char *kwlist[] = { "child_iter", NULL };
2961    PyObject *py_child_iter;
2962    GtkTreeIter iter, *child_iter;
2963    GtkTreePath *child_path, *path;
2964    GtkTreeModel *child_model;
2965    GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER(self->obj);
2966
2967    if (!PyArg_ParseTupleAndKeywords(
2968	args, kwargs, "O:GtkTreeModelFilter.convert_child_iter_to_iter",
2969	kwlist, &py_child_iter))
2970        return NULL;
2971    if (pyg_boxed_check(py_child_iter, GTK_TYPE_TREE_ITER))
2972        child_iter = pyg_boxed_get(py_child_iter, GtkTreeIter);
2973    else {
2974        PyErr_SetString(PyExc_TypeError, "child_iter should be a GtkTreeIter");
2975        return NULL;
2976    }
2977
2978    child_model = gtk_tree_model_filter_get_model(filter);
2979    child_path = gtk_tree_model_get_path(child_model, child_iter);
2980    if (child_path == NULL) {
2981        PyErr_SetString(PyExc_ValueError, "child_iter invalid");
2982        return NULL;
2983    }
2984
2985    path = gtk_tree_model_filter_convert_child_path_to_path(filter,
2986							    child_path);
2987    gtk_tree_path_free (child_path);
2988    if (path == NULL) {
2989        PyErr_SetString(PyExc_RuntimeError, "couldn't convert child_iter");
2990        return NULL;
2991    }
2992
2993    gtk_tree_model_filter_convert_child_iter_to_iter(
2994	GTK_TREE_MODEL_FILTER(self->obj), &iter, child_iter);
2995    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
2996}
2997%%
2998override gtk_tree_model_filter_convert_iter_to_child_iter kwargs
2999static PyObject *
3000_wrap_gtk_tree_model_filter_convert_iter_to_child_iter(PyGObject *self,
3001						     PyObject *args,
3002						     PyObject *kwargs)
3003{
3004    static char *kwlist[] = { "filter_iter", NULL };
3005    PyObject *py_filter_iter;
3006    GtkTreeIter iter, *filter_iter;
3007
3008    if (!PyArg_ParseTupleAndKeywords(
3009	args, kwargs, "O:GtkTreeModelFilter.convert_iter_to_child_iter",
3010	kwlist, &py_filter_iter))
3011        return NULL;
3012    if (pyg_boxed_check(py_filter_iter, GTK_TYPE_TREE_ITER))
3013        filter_iter = pyg_boxed_get(py_filter_iter, GtkTreeIter);
3014    else {
3015        PyErr_SetString(PyExc_TypeError,
3016			"filter_iter should be a GtkTreeIter");
3017        return NULL;
3018    }
3019    gtk_tree_model_filter_convert_iter_to_child_iter(
3020	GTK_TREE_MODEL_FILTER(self->obj), &iter, filter_iter);
3021    return pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter, TRUE, TRUE);
3022}
3023%%
3024override gtk_tree_view_column_cell_get_position kwargs
3025static PyObject *
3026_wrap_gtk_tree_view_column_cell_get_position(PyGObject *self, PyObject *args,
3027					     PyObject *kwargs)
3028{
3029    static char *kwlist[] = { "cell_renderer", NULL };
3030    PyGObject *py_cell;
3031    gint start, width;
3032
3033
3034    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3035				     "O!:GtkTreeViewColumn.cell_get_position",
3036				     kwlist, &PyGtkCellRenderer_Type,
3037				     &py_cell))
3038        return NULL;
3039
3040    if (gtk_tree_view_column_cell_get_position(GTK_TREE_VIEW_COLUMN(self->obj),
3041					       GTK_CELL_RENDERER(py_cell->obj),
3042					       &start, &width))
3043	return Py_BuildValue("(ii)", start, width);
3044
3045    Py_INCREF(Py_None);
3046    return Py_None;
3047}
3048%%
3049override gtk_tree_store_reorder kwargs
3050static PyObject *
3051_wrap_gtk_tree_store_reorder(PyGObject *self, PyObject *args, PyObject *kwargs)
3052{
3053    static char *kwlist[] = { "parent", "new_order", NULL };
3054    PyObject *list, *pyparent;
3055    gint *new_order;
3056    GtkTreeStore *store;
3057    GtkTreeIter *parent = NULL;
3058    int i, slen;
3059
3060    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3061				     "OO!:gtk.TreeStore.reorder", kwlist,
3062				     &pyparent, &PyList_Type, &list))
3063	return NULL;
3064
3065    if (pyparent != Py_None) {
3066	if (pyg_boxed_check(pyparent, GTK_TYPE_TREE_ITER)) {
3067	    parent = pyg_boxed_get(pyparent, GtkTreeIter);
3068	} else {
3069	    PyErr_SetString(PyExc_TypeError,
3070			    "parent must be a valid gtk.TreeIter or None");
3071	    return NULL;
3072	}
3073    }
3074    store = GTK_TREE_STORE(self->obj);
3075    slen = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(self->obj), parent);
3076    if (PyList_Size(list) < slen) {
3077        PyErr_SetString(PyExc_TypeError,
3078			"list size must be >= the number of "
3079			"children of parent");
3080        return NULL;
3081    }
3082
3083    new_order = g_new0(gint, slen);
3084    for (i = 0; i < slen; i++) {
3085	PyObject *item = PyList_GetItem(list, i);
3086	int index;
3087	if (!PyInt_Check(item)) {
3088	    PyErr_SetString(PyExc_TypeError, "all items must be of type int");
3089	    g_free(new_order);
3090	    return NULL;
3091	}
3092	index = PyInt_AsLong(item);
3093	if (index < 0 || index >= slen) {
3094	    PyErr_SetString(PyExc_ValueError, "position index out of range");
3095	    g_free(new_order);
3096	    return NULL;
3097	}
3098	new_order[i] = index;
3099    }
3100    gtk_tree_store_reorder(GTK_TREE_STORE(self->obj), parent, new_order);
3101
3102    g_free(new_order);
3103
3104    Py_INCREF(Py_None);
3105    return Py_None;
3106}
3107%%
3108override gtk_tree_model_get args
3109static PyObject *
3110_wrap_gtk_tree_model_get(PyGObject *self, PyObject *args)
3111{
3112    PyObject *py_iter, *ret;
3113    gint len, i, n_columns;
3114    GtkTreeIter *iter;
3115
3116    len = PyTuple_Size(args) - 1;
3117
3118    if (len < 1) {
3119	PyErr_SetString(PyExc_TypeError,
3120			"gtk.TreeModel.get requires at least two arguments");
3121	return NULL;
3122    }
3123
3124    py_iter = PyTuple_GetItem(args, 0);
3125
3126    if (!pyg_boxed_check(py_iter, GTK_TYPE_TREE_ITER)) {
3127        PyErr_SetString(PyExc_TypeError, "iter must be a GtkTreeIter");
3128        return NULL;
3129    }
3130    iter = pyg_boxed_get(py_iter, GtkTreeIter);
3131
3132    ret = PyTuple_New(len);
3133
3134    n_columns = gtk_tree_model_get_n_columns(GTK_TREE_MODEL(self->obj));
3135    for (i = 0; i < len; i++) {
3136	GValue value = { 0, };
3137	gint column;
3138	PyObject *py_column = PyTuple_GetItem(args, i+1);
3139
3140	if (!PyInt_Check(py_column)) {
3141	    PyErr_SetString(PyExc_TypeError, "column numbers must be ints");
3142	    Py_DECREF(ret);
3143	    return NULL;
3144	}
3145	column = PyInt_AsLong(py_column);
3146	if (column < 0 || column >= n_columns) {
3147	    PyErr_SetString(PyExc_ValueError, "column number is out of range");
3148	    Py_DECREF(ret);
3149	    return NULL;
3150	}
3151	gtk_tree_model_get_value(GTK_TREE_MODEL(self->obj), iter,
3152				 column, &value);
3153	PyTuple_SetItem(ret, i, pyg_value_as_pyobject(&value, TRUE));
3154	g_value_unset(&value);
3155    }
3156    return ret;
3157}
3158%%
3159override gtk_tree_selection_select_all noargs
3160static PyObject *
3161_wrap_gtk_tree_selection_select_all(PyGObject *self)
3162{
3163    GtkSelectionMode mode;
3164
3165    mode = gtk_tree_selection_get_mode(GTK_TREE_SELECTION(self->obj));
3166    if (mode != GTK_SELECTION_MULTIPLE) {
3167        PyErr_SetString(PyExc_TypeError,
3168                        "gtk.TreeSelection.select_all requires that"
3169                        " selection mode is gtk.SELECTION_MULTIPLE");
3170        return NULL;
3171    }
3172
3173    gtk_tree_selection_select_all(GTK_TREE_SELECTION(self->obj));
3174    Py_INCREF(Py_None);
3175    return Py_None;
3176}
3177%%
3178override gtk_tree_selection_select_range kwargs
3179static PyObject *
3180_wrap_gtk_tree_selection_select_range(PyGObject *self, PyObject *args,
3181                                      PyObject *kwargs)
3182{
3183    static char *kwlist[] = { "start_path", "end_path", NULL };
3184    PyObject *py_start_path, *py_end_path;
3185    GtkTreePath *start_path, *end_path;
3186    GtkSelectionMode mode;
3187
3188    mode = gtk_tree_selection_get_mode(GTK_TREE_SELECTION(self->obj));
3189    if (mode != GTK_SELECTION_MULTIPLE) {
3190        PyErr_SetString(PyExc_TypeError,
3191                        "gtk.TreeSelection.select_range requires that"
3192                        " selection mode is gtk.SELECTION_MULTIPLE");
3193        return NULL;
3194    }
3195
3196    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3197                                     "OO:GtkTreeSelection.select_range",
3198                                     kwlist, &py_start_path, &py_end_path))
3199        return NULL;
3200    start_path = pygtk_tree_path_from_pyobject(py_start_path);
3201    if (!start_path) {
3202        PyErr_SetString(PyExc_TypeError,
3203                        "could not convert start_path to a GtkTreePath");
3204        return NULL;
3205    }
3206    end_path = pygtk_tree_path_from_pyobject(py_end_path);
3207    if (!end_path) {
3208        gtk_tree_path_free(start_path);
3209        PyErr_SetString(PyExc_TypeError,
3210                        "could not convert end_path to a GtkTreePath");
3211        return NULL;
3212    }
3213    gtk_tree_selection_select_range(GTK_TREE_SELECTION(self->obj),
3214                                    start_path, end_path);
3215
3216    gtk_tree_path_free(start_path);
3217    gtk_tree_path_free(end_path);
3218
3219    Py_INCREF(Py_None);
3220    return Py_None;
3221}
3222%%
3223override gtk_tree_model_filter_set_modify_func kwargs
3224static void
3225pygtk_filter_modify_func_marshal(GtkTreeModel *model, GtkTreeIter *iter,
3226                                 GValue *value, gint column, gpointer data)
3227{
3228    PyGILState_STATE state;
3229    PyGtkCustomNotify *cunote = data;
3230    PyObject *py_value, *py_model, *py_iter;
3231
3232    g_assert (cunote->func);
3233
3234    state = pyg_gil_state_ensure();
3235
3236    py_model = pygobject_new((GObject *)model);
3237    py_iter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter,  FALSE, FALSE);
3238    if (cunote->data)
3239        py_value = PyEval_CallFunction(cunote->func, "(NNiO)",
3240                                     py_model, py_iter, column, cunote->data);
3241    else
3242        py_value = PyEval_CallFunction(cunote->func, "(NNi)",
3243                                     py_model, py_iter, column);
3244
3245    if (PyErr_Occurred()) {
3246        PyErr_Print();
3247    } else if (pyg_value_from_pyobject(value, py_value)) {
3248        PyErr_Format(PyExc_TypeError,
3249                     "value is of the wrong type for column %i", column);
3250        PyErr_Print();
3251    }
3252
3253    Py_XDECREF(py_value);
3254
3255    pyg_gil_state_release(state);
3256}
3257
3258static PyObject *
3259_wrap_gtk_tree_model_filter_set_modify_func(PyGObject *self, PyObject *args,
3260                                            PyObject *kwargs)
3261{
3262    static char *kwlist[] = { "types", "func", "data", NULL };
3263    GType *types;
3264    PyObject *py_types, *py_func, *py_arg = NULL;
3265    PyGtkCustomNotify *cunote;
3266    gint tlen, i;
3267
3268    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3269				     "OO|O:GtkTreeModelFilter.set_modify_func",
3270				     kwlist, &py_types, &py_func, &py_arg))
3271        return NULL;
3272
3273    if (!PyCallable_Check(py_func)) {
3274        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
3275        return NULL;
3276    }
3277    if (!PySequence_Check(py_types) || (tlen = PySequence_Size(py_types)) <= 0) {
3278        PyErr_SetString(PyExc_TypeError,
3279                        "types must be a tuple containing one or more arguments");
3280        return NULL;
3281    }
3282
3283    types = g_new0(GType, tlen);
3284    for (i = 0; i < tlen; i++) {
3285        PyObject *item = PySequence_GetItem(py_types, i);
3286
3287        types[i] = pyg_type_from_object(item);
3288        if (types[i] == 0) {
3289            Py_DECREF(item);
3290            g_free(types);
3291            return NULL;
3292        }
3293        Py_DECREF(item);
3294    }
3295
3296    cunote = g_new(PyGtkCustomNotify, 1);
3297    Py_INCREF(py_func);
3298    cunote->func = py_func;
3299    Py_XINCREF(py_arg);
3300    cunote->data = py_arg;
3301
3302    gtk_tree_model_filter_set_modify_func(GTK_TREE_MODEL_FILTER(self->obj),
3303                                          tlen, types,
3304                                          pygtk_filter_modify_func_marshal,
3305                                          cunote,
3306                                          pygtk_custom_destroy_notify);
3307
3308    g_free(types);
3309
3310    Py_INCREF(Py_None);
3311    return Py_None;
3312}
3313%%
3314override gtk_tree_view_set_column_drag_function kwargs
3315static gboolean
3316pygtk_column_drag_func_marshal(GtkTreeView *tree_view,
3317                               GtkTreeViewColumn *column,
3318                               GtkTreeViewColumn *prev_column,
3319                               GtkTreeViewColumn *next_column,
3320                               gpointer data)
3321{
3322    PyGILState_STATE state;
3323    PyGtkCustomNotify *cunote = data;
3324    PyObject *py_tree_view, *py_column, *py_prev_column, *py_next_column;
3325    PyObject *retobj;
3326    gboolean ret = FALSE;
3327
3328    g_assert (cunote->func);
3329
3330    state = pyg_gil_state_ensure();
3331
3332    py_tree_view = pygobject_new((GObject *)tree_view);
3333    py_column = pygobject_new((GObject *)column);
3334    py_prev_column = pygobject_new((GObject *)prev_column);
3335    /* Workaround for drag part of GTK+ bug #143355 */
3336    if (prev_column == next_column)
3337        next_column = NULL;
3338    py_next_column = pygobject_new((GObject *)next_column);
3339    if (cunote->data)
3340        retobj = PyEval_CallFunction(cunote->func, "(NNNNO)",
3341                                     py_tree_view, py_column, py_prev_column,
3342                                     py_next_column, cunote->data);
3343    else
3344        retobj = PyEval_CallFunction(cunote->func, "(NNNN)",
3345                                     py_tree_view, py_column, py_prev_column,
3346                                     py_next_column);
3347
3348    if (retobj)
3349        ret = retobj == Py_True ? TRUE : FALSE;
3350    if (PyErr_Occurred()) {
3351        PyErr_Print();
3352    }
3353    Py_XDECREF(retobj);
3354
3355    pyg_gil_state_release(state);
3356    return ret;
3357}
3358static PyObject *
3359_wrap_gtk_tree_view_set_column_drag_function(PyGObject *self, PyObject *args,
3360                                             PyObject *kwargs)
3361{
3362    static char *kwlist[] = { "func", "user_data", NULL };
3363    PyObject *py_func = NULL, *py_arg = NULL;
3364    PyGtkCustomNotify *cunote;
3365
3366    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3367				     "|OO:GtkTreeView.set_column_drag_func",
3368				     kwlist, &py_func, &py_arg))
3369        return NULL;
3370
3371    if (!py_func || py_func == Py_None) {
3372        gtk_tree_view_set_column_drag_function(GTK_TREE_VIEW(self->obj),
3373                                               NULL, NULL, NULL);
3374        Py_INCREF(Py_None);
3375        return Py_None;
3376    }
3377
3378    if (!PyCallable_Check(py_func)) {
3379        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
3380        return NULL;
3381    }
3382
3383    cunote = g_new(PyGtkCustomNotify, 1);
3384    Py_INCREF(py_func);
3385    cunote->func = py_func;
3386    Py_XINCREF(py_arg);
3387    cunote->data = py_arg;
3388
3389    gtk_tree_view_set_column_drag_function(GTK_TREE_VIEW(self->obj),
3390                                           pygtk_column_drag_func_marshal,
3391                                           cunote,
3392                                           pygtk_custom_destroy_notify);
3393    Py_INCREF(Py_None);
3394    return Py_None;
3395}
3396%%
3397override gtk_tree_view_set_search_equal_func kwargs
3398static gboolean
3399pygtk_set_search_equal_func_marshal(GtkTreeModel *model,
3400                                    gint column,
3401                                    const gchar *key,
3402                                    GtkTreeIter *iter,
3403                                    gpointer data)
3404{
3405    PyGILState_STATE state;
3406    PyGtkCustomNotify *cunote = data;
3407    PyObject *py_model, *py_column, *py_key, *py_iter;
3408    PyObject *retobj;
3409    gboolean ret = FALSE;
3410
3411      /* gracefully guard against NULL values */
3412    g_return_val_if_fail(cunote->func, TRUE);
3413    g_return_val_if_fail(key, TRUE);
3414    g_return_val_if_fail(iter, TRUE);
3415
3416    state = pyg_gil_state_ensure();
3417
3418    py_model = pygobject_new((GObject *)model);
3419    py_column = PyInt_FromLong(column);
3420    py_key = PyString_FromString(key);
3421    py_iter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter,  FALSE, FALSE);
3422
3423    if (cunote->data)
3424        retobj = PyEval_CallFunction(cunote->func, "(NNNNO)",
3425                                     py_model, py_column, py_key, py_iter,
3426                                     cunote->data);
3427    else
3428        retobj = PyEval_CallFunction(cunote->func, "(NNNN)",
3429                                     py_model, py_column, py_key, py_iter);
3430
3431    if (retobj)
3432        ret = (PyObject_IsTrue(retobj)? TRUE : FALSE);
3433    if (PyErr_Occurred()) {
3434        PyErr_Print();
3435    }
3436    Py_XDECREF(retobj);
3437
3438    pyg_gil_state_release(state);
3439    return ret;
3440}
3441
3442static PyObject *
3443_wrap_gtk_tree_view_set_search_equal_func(PyGObject *self, PyObject *args,
3444                                          PyObject *kwargs)
3445{
3446    static char *kwlist[] = { "func", "user_data", NULL };
3447    PyObject *py_func = NULL, *py_arg = NULL;
3448    PyGtkCustomNotify *cunote;
3449
3450    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3451				     "|OO:GtkTreeView.set_search_equal_func",
3452				     kwlist, &py_func, &py_arg))
3453        return NULL;
3454
3455    if (!py_func || py_func == Py_None) {
3456        gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(self->obj),
3457                                               NULL, NULL, NULL);
3458        Py_INCREF(Py_None);
3459        return Py_None;
3460    }
3461
3462    if (!PyCallable_Check(py_func)) {
3463        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
3464        return NULL;
3465    }
3466
3467    cunote = g_new(PyGtkCustomNotify, 1);
3468    Py_INCREF(py_func);
3469    cunote->func = py_func;
3470    Py_XINCREF(py_arg);
3471    cunote->data = py_arg;
3472
3473    gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(self->obj),
3474                                        pygtk_set_search_equal_func_marshal,
3475                                        cunote,
3476                                        pygtk_custom_destroy_notify);
3477    Py_INCREF(Py_None);
3478    return Py_None;
3479}
3480%%
3481override gtk_tree_view_set_row_separator_func kwargs
3482static gboolean
3483pygtk_set_row_separator_func_marshal(GtkTreeModel *model,
3484                                     GtkTreeIter *iter,
3485                                     gpointer data)
3486{
3487    PyGILState_STATE state;
3488    PyGtkCustomNotify *cunote = data;
3489    PyObject *py_model, *py_iter;
3490    PyObject *retobj;
3491    gboolean ret = FALSE;
3492
3493    g_assert (cunote->func);
3494
3495    state = pyg_gil_state_ensure();
3496
3497    py_model = pygobject_new((GObject *)model);
3498    py_iter = pyg_boxed_new(GTK_TYPE_TREE_ITER, iter,  FALSE, FALSE);
3499
3500    if (cunote->data)
3501        retobj = PyEval_CallFunction(cunote->func, "(NNO)",
3502                                     py_model, py_iter, cunote->data);
3503    else
3504        retobj = PyEval_CallFunction(cunote->func, "(NN)",
3505                                     py_model, py_iter);
3506
3507    if (retobj)
3508        ret = retobj == Py_True ? TRUE : FALSE;
3509    if (PyErr_Occurred()) {
3510        PyErr_Print();
3511    }
3512    Py_XDECREF(retobj);
3513
3514    pyg_gil_state_release(state);
3515    return ret;
3516}
3517
3518static PyObject *
3519_wrap_gtk_tree_view_set_row_separator_func(PyGObject *self, PyObject *args,
3520                                           PyObject *kwargs)
3521{
3522    static char *kwlist[] = { "func", "user_data", NULL };
3523    PyObject *py_func = NULL, *py_arg = NULL;
3524    PyGtkCustomNotify *cunote;
3525
3526    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3527				     "|OO:GtkTreeView.set_row_separator_func",
3528				     kwlist, &py_func, &py_arg))
3529        return NULL;
3530
3531    if (!py_func || py_func == Py_None) {
3532        gtk_tree_view_set_row_separator_func(GTK_TREE_VIEW(self->obj),
3533                                             NULL, NULL, NULL);
3534        Py_INCREF(Py_None);
3535        return Py_None;
3536    }
3537
3538    if (!PyCallable_Check(py_func)) {
3539        PyErr_SetString(PyExc_TypeError, "func must be a callable object");
3540        return NULL;
3541    }
3542
3543    cunote = g_new(PyGtkCustomNotify, 1);
3544    Py_INCREF(py_func);
3545    cunote->func = py_func;
3546    Py_XINCREF(py_arg);
3547    cunote->data = py_arg;
3548
3549    gtk_tree_view_set_row_separator_func(GTK_TREE_VIEW(self->obj),
3550                                         pygtk_set_row_separator_func_marshal,
3551                                         cunote,
3552                                         pygtk_custom_destroy_notify);
3553    Py_INCREF(Py_None);
3554    return Py_None;
3555}
3556%%
3557override gtk_tree_view_get_visible_range noargs
3558static PyObject *
3559_wrap_gtk_tree_view_get_visible_range(PyGObject *self)
3560{
3561    GtkTreePath *start_path, *end_path;
3562    gboolean r;
3563
3564    r = gtk_tree_view_get_visible_range(GTK_TREE_VIEW(self->obj),
3565					&start_path, &end_path);
3566    if (r) {
3567        PyObject *py_start_path = pygtk_tree_path_to_pyobject(start_path);
3568        PyObject *py_end_path = pygtk_tree_path_to_pyobject(end_path);
3569        gtk_tree_path_free(start_path);
3570        gtk_tree_path_free(end_path);
3571       return Py_BuildValue("(NN)", py_start_path, py_end_path);
3572    }
3573
3574    Py_INCREF(Py_None);
3575    return Py_None;
3576}
3577%%
3578override gtk_tree_view_set_search_position_func
3579static void
3580pygtk_tree_view_set_search_position_func_cb(GtkTreeView *treeview,
3581                                            GtkWidget *search_dialog,
3582                                            gpointer data)
3583{
3584    PyGILState_STATE state;
3585    PyGtkCustomNotify *cunote = data;
3586    PyObject *retobj;
3587
3588    g_assert(cunote->func);
3589
3590    state = pyg_gil_state_ensure();
3591
3592    if (cunote->data)
3593        retobj = PyEval_CallFunction(cunote->func, "(NNO)",
3594                                     pygobject_new((GObject*)treeview),
3595                                     pygobject_new((GObject*)search_dialog),
3596                                     cunote->data);
3597    else
3598        retobj = PyEval_CallFunction(cunote->func, "(NN)",
3599                                     pygobject_new((GObject*)treeview),
3600                                     pygobject_new((GObject*)search_dialog));
3601
3602    if (retobj == NULL) {
3603        PyErr_Print();
3604    }
3605
3606    Py_XDECREF(retobj);
3607
3608    pyg_gil_state_release(state);
3609}
3610static PyObject *
3611_wrap_gtk_tree_view_set_search_position_func(PyGObject *self, PyObject *args)
3612{
3613    PyObject *pyfunc, *pyarg = NULL;
3614    PyGtkCustomNotify *cunote;
3615
3616    if(!PyArg_ParseTuple(args, "O|O:GtkTreeView.set_search_position_func",
3617                         &pyfunc, &pyarg))
3618        return NULL;
3619
3620    if (pyfunc != Py_None) {
3621        cunote = g_new0(PyGtkCustomNotify, 1);
3622        cunote->func = pyfunc;
3623        cunote->data = pyarg;
3624        Py_INCREF(cunote->func);
3625        Py_XINCREF(cunote->data);
3626        gtk_tree_view_set_search_position_func(
3627            GTK_TREE_VIEW(self->obj),
3628            pygtk_tree_view_set_search_position_func_cb, cunote,
3629            pygtk_custom_destroy_notify);
3630    } else
3631        gtk_tree_view_set_search_position_func(GTK_TREE_VIEW(self->obj),
3632                                               NULL, NULL, NULL);
3633    Py_INCREF(Py_None);
3634    return Py_None;
3635}
3636%%
3637override gtk_tree_store_set_column_types args
3638static PyObject*
3639_wrap_gtk_tree_store_set_column_types(PyGObject *self, PyObject *args)
3640{
3641    guint len, i;
3642    GType *column_types;
3643
3644    len = PyTuple_Size(args);
3645    if (len == 0) {
3646        PyErr_SetString(PyExc_TypeError,
3647                        "GtkTreeStore set_column_types requires at least one argument");
3648        return NULL;
3649    }
3650
3651    column_types = g_new(GType, len);
3652    for (i = 0; i < len; i++) {
3653        PyObject *item = PyTuple_GetItem(args, i);
3654
3655        column_types[i] = pyg_type_from_object(item);
3656        if (column_types[i] == 0) {
3657            g_free(column_types);
3658	    return NULL;
3659        }
3660    }
3661
3662    gtk_tree_store_set_column_types(GTK_TREE_STORE(self->obj), len,
3663                                    column_types);
3664    g_free(column_types);
3665
3666    Py_INCREF(Py_None);
3667    return Py_None;
3668}
3669%%
3670override gtk_tree_view_convert_widget_to_bin_window_coords kwargs
3671static PyObject*
3672_wrap_gtk_tree_view_convert_widget_to_bin_window_coords(PyGObject *self,
3673                                                        PyObject *args,
3674                                                        PyObject *kwargs)
3675{
3676    static char *kwlist[] = { "widget_x", "widget_y", NULL };
3677    gint widget_x, widget_y, window_x = 0, window_y = 0;
3678
3679    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3680                        "ii:GtkTreeView.convert_widget_to_bin_window_coords",
3681                        kwlist, &widget_x, &widget_y))
3682        return NULL;
3683
3684    gtk_tree_view_convert_widget_to_bin_window_coords(GTK_TREE_VIEW(self->obj),
3685                                          widget_x, widget_y,
3686                                          &window_x, &window_y);
3687
3688    return Py_BuildValue("(ii)", window_x, window_y);
3689}
3690%%
3691override gtk_tree_view_convert_widget_to_tree_coords kwargs
3692static PyObject*
3693_wrap_gtk_tree_view_convert_widget_to_tree_coords(PyGObject *self,
3694                                                  PyObject *args,
3695                                                  PyObject *kwargs)
3696{
3697    static char *kwlist[] = { "widget_x", "widget_y", NULL };
3698    gint widget_x, widget_y, tree_x = 0, tree_y = 0;
3699
3700    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3701                        "ii:GtkTreeView.convert_widget_to_tree_coords",
3702                        kwlist, &widget_x, &widget_y))
3703        return NULL;
3704
3705    gtk_tree_view_convert_widget_to_tree_coords(GTK_TREE_VIEW(self->obj),
3706                                                widget_x, widget_y,
3707                                                &tree_x, &tree_y);
3708
3709    return Py_BuildValue("(ii)", tree_x, tree_y);
3710}
3711%%
3712override gtk_tree_view_convert_tree_to_widget_coords kwargs
3713static PyObject*
3714_wrap_gtk_tree_view_convert_tree_to_widget_coords(PyGObject *self,
3715                                                  PyObject *args,
3716                                                  PyObject *kwargs)
3717{
3718    static char *kwlist[] = { "tree_x", "tree_y", NULL };
3719    gint tree_x, tree_y, widget_x = 0, widget_y = 0;
3720
3721    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3722                        "ii:GtkTreeView.convert_tree_to_widget_coords",
3723                        kwlist, &tree_x, &tree_y))
3724        return NULL;
3725
3726    gtk_tree_view_convert_tree_to_widget_coords(GTK_TREE_VIEW(self->obj),
3727                                                tree_x, tree_y,
3728                                                &widget_x, &widget_y);
3729
3730    return Py_BuildValue("(ii)", widget_x, widget_y);
3731}
3732%%
3733override gtk_tree_view_convert_tree_to_bin_window_coords kwargs
3734static PyObject*
3735_wrap_gtk_tree_view_convert_tree_to_bin_window_coords(PyGObject *self,
3736                                                      PyObject *args,
3737                                                      PyObject *kwargs)
3738{
3739    static char *kwlist[] = { "tree_x", "tree_y", NULL };
3740    gint tree_x, tree_y, window_x = 0, window_y = 0;
3741
3742    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3743                        "ii:GtkTreeView.convert_tree_to_bin_window_coords",
3744                        kwlist, &tree_x, &tree_y))
3745        return NULL;
3746
3747    gtk_tree_view_convert_tree_to_bin_window_coords(GTK_TREE_VIEW(self->obj),
3748                                                    tree_x, tree_y,
3749                                                    &window_x, &window_y);
3750
3751    return Py_BuildValue("(ii)", window_x, window_y);
3752}
3753%%
3754override gtk_tree_view_convert_bin_window_to_widget_coords kwargs
3755static PyObject*
3756_wrap_gtk_tree_view_convert_bin_window_to_widget_coords(PyGObject *self,
3757                                                        PyObject *args,
3758                                                        PyObject *kwargs)
3759{
3760    static char *kwlist[] = { "window_x", "window_y", NULL };
3761    gint window_x, window_y, widget_x = 0, widget_y = 0;
3762
3763    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3764                        "ii:GtkTreeView.convert_bin_window_to_widget_coords",
3765                        kwlist, &window_x, &window_y))
3766        return NULL;
3767
3768    gtk_tree_view_convert_bin_window_to_widget_coords(GTK_TREE_VIEW(self->obj),
3769                                                      window_x, window_y,
3770                                                      &widget_x, &widget_y);
3771
3772    return Py_BuildValue("(ii)", widget_x, widget_y);
3773}
3774%%
3775override gtk_tree_view_convert_bin_window_to_tree_coords kwargs
3776static PyObject*
3777_wrap_gtk_tree_view_convert_bin_window_to_tree_coords(PyGObject *self,
3778                                                      PyObject *args,
3779                                                      PyObject *kwargs)
3780{
3781    static char *kwlist[] = { "window_x", "window_y", NULL };
3782    gint window_x, window_y, tree_x = 0, tree_y = 0;
3783
3784    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3785                        "ii:GtkTreeView.convert_bin_window_to_tree_coords",
3786                        kwlist, &window_x, &window_y))
3787        return NULL;
3788
3789    gtk_tree_view_convert_bin_window_to_tree_coords(GTK_TREE_VIEW(self->obj),
3790                                                    window_x, window_y,
3791                                                    &tree_x, &tree_y);
3792
3793    return Py_BuildValue("(ii)", tree_x, tree_y);
3794}
3795%%
3796override gtk_tree_view_get_tooltip_context kwargs
3797static PyObject *
3798_wrap_gtk_tree_view_get_tooltip_context(PyGObject *self,
3799                                        PyObject *args,
3800                                        PyObject *kwargs)
3801{
3802    static char *kwlist[] = { "x", "y", "keyboard_tip", NULL };
3803
3804    gboolean        ret;
3805    PyObject        *py_ret = Py_None, *py_keyboard_tip = Py_True;
3806    gint            x, y;
3807    GtkTreeModel    *tree_model;
3808    GtkTreePath     *path;
3809    GtkTreeIter     iter;
3810
3811    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3812                        "iiO:GtkTreeView.get_tooltip_context",
3813                        kwlist, &x, &y, &py_keyboard_tip))
3814        return NULL;
3815
3816    ret = gtk_tree_view_get_tooltip_context(GTK_TREE_VIEW(self->obj), &x, &y,
3817                                            PyObject_IsTrue(py_keyboard_tip),
3818                                            &tree_model,
3819                                            &path, &iter);
3820    if (ret) {
3821        py_ret = Py_BuildValue("(NNN)",
3822                               pygobject_new((GObject *)tree_model),
3823                               pygtk_tree_path_to_pyobject(path),
3824                               pyg_boxed_new(GTK_TYPE_TREE_ITER, &iter,
3825                                             TRUE, TRUE));
3826
3827        gtk_tree_path_free(path);
3828        return py_ret;
3829    }
3830    Py_INCREF(py_ret);
3831    return py_ret;
3832}
3833