1/* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygtk- Python bindings for the GTK toolkit.
3 * Copyright (C) 1998-2003  James Henstridge
4 *
5 *   gtkctree.override: overrides for the gtk.CTree widget.
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%%
23ignore gtk_ctree_construct
24  gtk_ctree_insert_gnode
25  gtk_ctree_export_to_gnode
26  gtk_ctree_post_recursive
27  gtk_ctree_post_recursive_to_depth
28  gtk_ctree_pre_recursive
29  gtk_ctree_pre_recursive_to_depth
30  gtk_ctree_find_node_ptr
31%%
32ignore gtk_ctree_new
33%%
34override-attr GtkCTree.selection
35static PyObject *
36_wrap_gtk_ctree__get_selection(PyGObject *self, void *closure)
37{
38    GList *selection;
39    GtkCTreeNode *node;
40    PyObject *ret, *py_node;
41    if ((ret = PyList_New(0)) == NULL)
42        return NULL;
43
44    for (selection = GTK_CLIST(self->obj)->selection; selection != NULL;
45         selection = selection->next) {
46        node = selection->data;
47        if ((py_node = pyg_pointer_new(GTK_TYPE_CTREE_NODE, node)) == NULL) {
48            Py_DECREF(ret);
49            return NULL;
50        }
51        PyList_Append(ret, py_node);
52        Py_DECREF(py_node);
53    }
54
55    return ret;
56}
57%%
58override gtk_ctree_new_with_titles kwargs
59static int
60_wrap_gtk_ctree_new_with_titles(PyGObject *self, PyObject *args,
61                                PyObject *kwargs)
62{
63    static char *kwlist[] = { "columns", "tree_column", "titles", NULL };
64    int columns = 1, tree_column = 0;
65    PyObject *py_titles = NULL;
66
67    if (PyErr_Warn(PyExc_DeprecationWarning, "use gtk.TreeView") < 0)
68        return -1;
69
70    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiO:GtkCTree.__init__",
71                                     kwlist, &columns, &tree_column,
72                                     &py_titles))
73        return -1;
74    if (py_titles) {
75        gchar **titles;
76        gint i;
77
78        if (!PySequence_Check(py_titles)) {
79            PyErr_SetString(PyExc_TypeError, "titles must be a sequence");
80            return -1;
81        }
82        if (PySequence_Length(py_titles) < columns) {
83            PyErr_SetString(PyExc_TypeError, "titles too short");
84            return -1;
85        }
86        titles = g_new(gchar *, columns);
87        for (i = 0; i < columns; i++) {
88            PyObject *item = PySequence_GetItem(py_titles, i);
89
90            Py_DECREF(item);
91            if (!PyString_Check(item) && !PyUnicode_Check(item)) {
92                PyErr_SetString(PyExc_TypeError,
93                                "sequence item not a string or unicode object");
94                g_free(titles);
95                return -1;
96            }
97            titles[i] = PyString_AsString(item);
98        }
99        self->obj = (GObject *)gtk_ctree_new_with_titles(columns,
100                                                tree_column, titles);
101        g_free(titles);
102    } else
103        self->obj = (GObject *)gtk_ctree_new(columns, tree_column);
104    if (!self->obj) {
105        PyErr_SetString(PyExc_RuntimeError,"could not create GtkCTree object");
106        return -1;
107    }
108    pygobject_register_wrapper((PyObject *)self);
109    return 0;
110}
111%%
112override gtk_ctree_base_nodes
113static PyObject*
114_wrap_gtk_ctree_base_nodes(PyGObject *self, PyObject *args)
115{
116    PyObject *ret;
117    GtkCTreeNode *node;
118
119    /* the first row is always a base node */
120    node = GTK_CTREE_NODE(GTK_CLIST(self->obj)->row_list);
121    if ((ret = PyList_New(0)) == NULL)
122        return NULL;
123    while (node) {
124        PyObject *obj = pyg_pointer_new(GTK_TYPE_CTREE_NODE, node);
125        if (obj == NULL) {
126            Py_DECREF(ret);
127            return NULL;
128        }
129        PyList_Append(ret, obj);
130        Py_DECREF(obj);
131        node = GTK_CTREE_ROW(node)->sibling;
132    }
133    return ret;
134}
135%%
136override gtk_ctree_insert_node kwargs
137static PyObject *
138_wrap_gtk_ctree_insert_node(PyGObject *self, PyObject *args,
139                            PyObject *kwargs)
140{
141    static char *kwlist[] = { "parent", "sibling", "text", "spacing",
142                              "pixmap_closed", "mask_closed", "pixmap_opened",
143                              "mask_opened", "is_leaf", "expanded", NULL };
144    PyObject *py_text;
145    PyGPointer *py_parent, *py_sibling;
146    PyGObject *py_pixmap_closed = (PyGObject *) Py_None;
147    PyGObject *py_mask_closed = (PyGObject *) Py_None;
148    PyGObject *py_pixmap_opened = (PyGObject *) Py_None;
149    PyGObject *py_mask_opened = (PyGObject *) Py_None;
150    GtkCTreeNode *parent = NULL, *sibling = NULL, *ret;
151    gchar **text = NULL;
152    GdkPixmap *pixmap_closed = NULL, *pixmap_opened = NULL;
153    GdkBitmap *mask_closed = NULL, *mask_opened = NULL;
154    gint spacing = 5, is_leaf = 1, expanded = 0, columns, i;
155
156    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
157                                     "OOO|iOOOOii:GtkCTree.insert_node",
158                                     kwlist,
159                                     &py_parent, &py_sibling, &py_text,
160                                     &spacing, &py_pixmap_closed,
161                                     &py_mask_closed, &py_pixmap_opened,
162                                     &py_mask_opened, &is_leaf, &expanded))
163        return NULL;
164    if (pyg_pointer_check(py_parent, GTK_TYPE_CTREE_NODE))
165        parent = pyg_pointer_get(py_parent, GtkCTreeNode);
166    else if ((PyObject *)py_parent != Py_None) {
167        PyErr_SetString(PyExc_TypeError, "parent must be a CTreeNode or None");
168        return NULL;
169    }
170    if (pyg_pointer_check(py_sibling, GTK_TYPE_CTREE_NODE))
171        sibling = pyg_pointer_get(py_sibling, GtkCTreeNode);
172    else if ((PyObject *)py_sibling != Py_None) {
173        PyErr_SetString(PyExc_TypeError,"sibling must be a CTreeNode or None");
174        return NULL;
175    }
176    if (pygobject_check(py_pixmap_closed, &PyGdkPixmap_Type))
177        pixmap_closed = GDK_PIXMAP(py_pixmap_closed->obj);
178    else if ((PyObject *)py_pixmap_closed != Py_None) {
179        PyErr_SetString(PyExc_TypeError,
180                        "pixmap_closed must be a GdkPixmap or None");
181        return NULL;
182    }
183    if (pygobject_check(py_mask_closed, &PyGdkPixmap_Type))
184        mask_closed = GDK_PIXMAP(py_mask_closed->obj);
185    else if ((PyObject *)py_mask_closed != Py_None) {
186        PyErr_SetString(PyExc_TypeError,
187                        "mask_closed must be a GdkBitmap or None");
188        return NULL;
189    }
190    if (pygobject_check(py_pixmap_opened, &PyGdkPixmap_Type))
191        pixmap_opened = GDK_PIXMAP(py_pixmap_opened->obj);
192    else if ((PyObject *)py_pixmap_opened != Py_None) {
193        PyErr_SetString(PyExc_TypeError,
194                        "pixmap_opened must be a GdkPixmap or None");
195        return NULL;
196    }
197    if (pygobject_check(py_mask_opened, &PyGdkPixmap_Type))
198        mask_opened = GDK_PIXMAP(py_mask_opened->obj);
199    else if ((PyObject *)py_mask_opened != Py_None) {
200        PyErr_SetString(PyExc_TypeError,
201                        "mask_opened must be a GdkBitmap or None");
202        return NULL;
203    }
204    if (!PySequence_Check(py_text)) {
205        PyErr_SetString(PyExc_TypeError, "text must be a sequence");
206        return NULL;
207    }
208    columns = GTK_CLIST(self->obj)->columns;
209    if (PySequence_Length(py_text) < columns) {
210        PyErr_SetString(PyExc_TypeError, "text is too short");
211        return NULL;
212    }
213    text = g_new(gchar *, columns);
214    for (i = 0; i < columns; i++) {
215        PyObject *item = PySequence_GetItem(py_text, i);
216
217        Py_DECREF(item);
218        if (!PyString_Check(item) && !PyUnicode_Check(item)) {
219            PyErr_SetString(PyExc_TypeError,
220                            "sequence item not a string or unicode object");
221            g_free(text);
222            return NULL;
223        }
224        text[i] = PyString_AsString(item);
225    }
226    ret = gtk_ctree_insert_node(GTK_CTREE(self->obj), parent, sibling, text,
227                                spacing, pixmap_closed, mask_closed,
228                                pixmap_opened, mask_opened, is_leaf, expanded);
229    g_free(text);
230    return pyg_pointer_new(GTK_TYPE_CTREE_NODE, ret);
231}
232%%
233ignore gtk_ctree_find_by_row_data_custom gtk_ctree_find_all_by_row_data_custom
234%%
235override gtk_ctree_find_by_row_data kwargs
236static PyObject *
237_wrap_gtk_ctree_find_by_row_data(PyGObject *self, PyObject *args,
238                                PyObject *kwargs)
239{
240    static char *kwlist[] = { "node", "data", NULL };
241    PyObject *data;
242    PyGPointer *py_node;
243    GtkCTreeNode *node = NULL, *ret;
244
245    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
246                                    "OO:GtkCTree.find_by_row_data", kwlist,
247                                    &py_node, &data))
248       return NULL;
249    if (pyg_pointer_check(py_node, GTK_TYPE_CTREE_NODE))
250        node = pyg_pointer_get(py_node, GtkCTreeNode);
251    else if ((PyObject *)py_node != Py_None) {
252        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode or None");
253        return NULL;
254    }
255    ret = gtk_ctree_find_by_row_data(GTK_CTREE(self->obj), node, data);
256    if (ret)
257        return pyg_pointer_new(GTK_TYPE_CTREE_NODE, ret);
258    Py_INCREF(Py_None);
259    return Py_None;
260}
261%%
262override gtk_ctree_find_all_by_row_data kwargs
263static PyObject *
264_wrap_gtk_ctree_find_all_by_row_data(PyGObject *self, PyObject *args,
265                                     PyObject *kwargs)
266{
267    static char *kwlist[] = { "node", "data", NULL };
268    PyGPointer *py_node;
269    PyObject *data, *list;
270    GtkCTreeNode *node = NULL;
271    GList *ret, *tmp;
272
273    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
274                                     "OO:GtkCTree.find_all_by_row_data",kwlist,
275                                     &py_node, &data))
276        return NULL;
277    if (pyg_pointer_check(py_node, GTK_TYPE_CTREE_NODE))
278        node = pyg_pointer_get(py_node, GtkCTreeNode);
279    else if ((PyObject *)py_node != Py_None) {
280        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode or None");
281        return NULL;
282    }
283    ret = gtk_ctree_find_all_by_row_data(GTK_CTREE(self->obj), node, data);
284    if ((list = PyList_New(0)) == NULL)
285        return NULL;
286    for (tmp = ret; tmp != NULL; tmp = tmp->next) {
287        PyObject *item = pyg_pointer_new(GTK_TYPE_CTREE_NODE,
288                                         (GtkCTreeNode *) tmp->data);
289        if (item == NULL) {
290            Py_DECREF(list);
291            return NULL;
292        }
293        PyList_Append(list, item);
294        Py_DECREF(item);
295    }
296    g_list_free(ret);
297    return list;
298}
299%%
300override gtk_ctree_node_get_text kwargs
301static PyObject *
302_wrap_gtk_ctree_node_get_text(PyGObject *self, PyObject *args,
303                              PyObject *kwargs)
304{
305    static char *kwlist[] = { "node", "column", NULL };
306    PyGPointer *node;
307    int column;
308    char *text = NULL;
309
310    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
311                                     "Oi:GtkCTree.node_get_text", kwlist,
312                                     &node, &column))
313        return NULL;
314
315    if (!pyg_pointer_check(node, GTK_TYPE_CTREE_NODE)) {
316        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode");
317        return NULL;
318    }
319
320    if (!gtk_ctree_node_get_text(GTK_CTREE(self->obj),
321                                 pyg_pointer_get(node, GtkCTreeNode), column,
322                                 &text)) {
323        PyErr_SetString(PyExc_ValueError, "can't get text value");
324        return NULL;
325    }
326    return PyString_FromString(text);
327}
328%%
329override gtk_ctree_node_get_pixmap kwargs
330static PyObject *
331_wrap_gtk_ctree_node_get_pixmap(PyGObject *self, PyObject *args,
332                                PyObject *kwargs)
333{
334    static char *kwlist[] = { "node", "column", NULL };
335    PyObject *node;
336    int column;
337    GdkPixmap *pixmap = NULL;
338    GdkBitmap *mask = NULL;
339
340    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
341                                     "Oi:GtkCTree.node_get_pixmap", kwlist,
342                                     &node, &column))
343        return NULL;
344
345    if (!pyg_pointer_check(node, GTK_TYPE_CTREE_NODE)) {
346        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode");
347        return NULL;
348    }
349
350    if (!gtk_ctree_node_get_pixmap(GTK_CTREE(self->obj),
351                                   pyg_pointer_get(node, GtkCTreeNode), column,
352                                   &pixmap, &mask)) {
353        PyErr_SetString(PyExc_ValueError, "can't get pixmap value");
354        return NULL;
355    }
356    return Py_BuildValue("(NN)", pygobject_new((GObject *)pixmap),
357                         pygobject_new((GObject *)mask));
358}
359%%
360override gtk_ctree_node_get_pixtext kwargs
361static PyObject *
362_wrap_gtk_ctree_node_get_pixtext(PyGObject *self, PyObject *args,
363                                 PyObject *kwargs)
364{
365    static char *kwlist[] = { "node", "column", NULL };
366    PyObject *node;
367    int column;
368    gchar *text = NULL;
369    guint8 spacing;
370    GdkPixmap *pixmap = NULL;
371    GdkBitmap *mask = NULL;
372
373    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
374                                     "Oi:GtkCTree.node_get_pixtext", kwlist,
375                                     &node, &column))
376        return NULL;
377
378    if (!pyg_pointer_check(node, GTK_TYPE_CTREE_NODE)) {
379        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode");
380        return NULL;
381    }
382
383    if (!gtk_ctree_node_get_pixtext(GTK_CTREE(self->obj),
384                                    pyg_pointer_get(node, GtkCTreeNode), column,
385                                    &text, &spacing, &pixmap, &mask)) {
386        PyErr_SetString(PyExc_ValueError, "can't get pixtext value");
387        return NULL;
388    }
389    return Py_BuildValue("(siNN)", text, (int)spacing,
390                         pygobject_new((GObject *)pixmap),
391                         pygobject_new((GObject *)mask));
392}
393%%
394override gtk_ctree_get_node_info kwargs
395static PyObject *
396_wrap_gtk_ctree_get_node_info(PyGObject *self, PyObject *args,
397                              PyObject *kwargs)
398{
399    static char *kwlist[] = { "node", NULL };
400    PyObject *node;
401    gchar *text;
402    guint8 spacing;
403    GdkPixmap *pixmap_closed, *pixmap_opened;
404    GdkBitmap *mask_closed, *mask_opened;
405    gboolean is_leaf, expanded;
406
407    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GtkCTree.get_node_info",
408                                     kwlist, &node))
409        return NULL;
410
411    if (!pyg_pointer_check(node, GTK_TYPE_CTREE_NODE)) {
412        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode");
413        return NULL;
414    }
415
416    if (!gtk_ctree_get_node_info(GTK_CTREE(self->obj), pyg_pointer_get(node, GtkCTreeNode),
417                                 &text, &spacing, &pixmap_closed, &mask_closed,
418                                 &pixmap_opened, &mask_opened,
419                                 &is_leaf, &expanded)) {
420        PyErr_SetString(PyExc_ValueError, "can't get node info");
421        return NULL;
422    }
423    return Py_BuildValue("(siNNNNii)", text, (int)spacing,
424                         pygobject_new((GObject *)pixmap_opened),
425                         pygobject_new((GObject *)mask_closed),
426                         pygobject_new((GObject *)pixmap_opened),
427                         pygobject_new((GObject *)mask_opened),
428                         (int)is_leaf, (int)expanded);
429}
430%%
431ignore gtk_ctree_node_set_row_data_full
432%%
433override gtk_ctree_node_set_row_data kwargs
434static PyObject *
435_wrap_gtk_ctree_node_set_row_data(PyGObject *self, PyObject *args,
436                                  PyObject *kwargs)
437{
438    static char *kwlist[] = { "node", "data", NULL };
439    PyObject *node, *data;
440
441    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
442                                     "OO:GtkCTree.node_set_row_data", kwlist,
443                                     &node, &data))
444        return NULL;
445
446    if (!pyg_pointer_check(node, GTK_TYPE_CTREE_NODE)) {
447        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode");
448        return NULL;
449    }
450
451    Py_INCREF(data);
452    gtk_ctree_node_set_row_data_full(GTK_CTREE(self->obj),
453                                     pyg_pointer_get(node, GtkCTreeNode), data,
454                                     (GDestroyNotify)pyg_destroy_notify);
455    Py_INCREF(Py_None);
456    return Py_None;
457}
458%%
459override gtk_ctree_node_get_row_data kwargs
460static PyObject *
461_wrap_gtk_ctree_node_get_row_data(PyGObject *self, PyObject *args,
462                                  PyObject *kwargs)
463{
464    static char *kwlist[] = { "node", NULL };
465    PyObject *node, *data;
466
467    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
468                                     "O:GtkCTree.node_get_row_data", kwlist,
469                                     &node))
470        return NULL;
471
472    if (!pyg_pointer_check(node, GTK_TYPE_CTREE_NODE)) {
473        PyErr_SetString(PyExc_TypeError, "node must be a CTreeNode");
474        return NULL;
475    }
476
477    data = gtk_ctree_node_get_row_data(GTK_CTREE(self->obj),
478                                       pyg_pointer_get(node, GtkCTreeNode));
479    if (!data) data = Py_None;
480    Py_INCREF(data);
481    return data;
482}
483%%
484override-slot GtkCTreeNode.tp_getattr
485static PyObject *
486_wrap_gtk_ctree_node_tp_getattr(PyGPointer *self, char *attr)
487{
488    if (!strcmp(attr, "__members__"))
489        return Py_BuildValue("[ssssss]", "children", "expanded", "is_leaf",
490                             "level", "parent", "sibling");
491    if (!strcmp(attr, "parent")) {
492        GtkCTreeNode *node = GTK_CTREE_ROW(pyg_pointer_get(self, GtkCTreeNode))->parent;
493        if (node)
494            return pyg_pointer_new(GTK_TYPE_CTREE_NODE, node);
495        Py_INCREF(Py_None);
496        return Py_None;
497    } else if (!strcmp(attr, "sibling")) {
498        GtkCTreeNode *node = GTK_CTREE_ROW(pyg_pointer_get(self, GtkCTreeNode))->sibling;
499        if (node)
500            return pyg_pointer_new(GTK_TYPE_CTREE_NODE, node);
501        Py_INCREF(Py_None);
502        return Py_None;
503    } else if (!strcmp(attr, "children")) {
504        GtkCTreeNode *node = GTK_CTREE_ROW(pyg_pointer_get(self, GtkCTreeNode))->children;
505        PyObject *ret = PyList_New(0);
506        if (ret == NULL)
507            return NULL;
508        while (node) {
509            PyObject *py_node = pyg_pointer_new(GTK_TYPE_CTREE_NODE, node);
510            if (py_node == NULL) {
511                Py_DECREF(ret);
512                return NULL;
513            }
514            PyList_Append(ret, py_node);
515            Py_DECREF(py_node);
516            node = GTK_CTREE_ROW(node)->sibling;
517        }
518        return ret;
519    } else if (!strcmp(attr, "level"))
520        return PyInt_FromLong(GTK_CTREE_ROW(pyg_pointer_get(self, GtkCTreeNode))->level);
521    else if (!strcmp(attr, "is_leaf"))
522        return PyInt_FromLong(GTK_CTREE_ROW(pyg_pointer_get(self, GtkCTreeNode))->is_leaf);
523    else if (!strcmp(attr, "expanded"))
524        return PyInt_FromLong(GTK_CTREE_ROW(pyg_pointer_get(self, GtkCTreeNode))->expanded);
525    PyErr_SetString(PyExc_AttributeError, attr);
526    return NULL;
527}
528