1/* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygtk- Python bindings for the GTK toolkit.
3 * Copyright (C) 1998-2003  James Henstridge
4 *
5 *   gtkcontainer.override: overrides for various container widgets.
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
24  gtk_container_get_toplevels
25  gtk_container_add_child_arg_type
26  gtk_container_query_child_args
27  gtk_container_child_args_collect
28  gtk_container_child_arg_get_info
29  gtk_container_foreach_full
30  gtk_container_add_with_args
31  gtk_container_addv
32  gtk_container_child_set_valist
33  gtk_container_child_get_valist
34  gtk_container_class_find_child_property
35%%
36override gtk_container_children noargs
37static PyObject *
38_wrap_gtk_container_children(PyGObject *self)
39{
40    if (PyErr_Warn(PyExc_DeprecationWarning, "use GtkContainer.get_children"))
41        return NULL;
42    return _wrap_gtk_container_get_children(self);
43}
44%%
45override gtk_container_get_children noargs
46static PyObject *
47_wrap_gtk_container_get_children(PyGObject *self)
48{
49    GList *list, *tmp;
50    PyObject *py_list;
51
52    list = gtk_container_get_children(GTK_CONTAINER(self->obj));
53
54    if ((py_list = PyList_New(0)) == NULL) {
55        g_list_free(list);
56        return NULL;
57    }
58    for (tmp = list; tmp != NULL; tmp = tmp->next) {
59        PyObject *gtk_obj = pygobject_new(G_OBJECT(tmp->data));
60
61        if (gtk_obj == NULL) {
62            g_list_free(list);
63            Py_DECREF(py_list);
64            return NULL;
65        }
66        PyList_Append(py_list, gtk_obj);
67        Py_DECREF(gtk_obj);
68    }
69    g_list_free(list);
70    return py_list;
71}
72%%
73override gtk_container_set_focus_chain kwargs
74static PyObject *
75_wrap_gtk_container_set_focus_chain(PyGObject *self, PyObject *args,
76                                    PyObject *kwargs)
77{
78    static char *kwlist[] = { "focusable_widgets", NULL };
79    PyObject *py_focusable_widgets;
80    gint len, i;
81    GList *focusable_widgets = NULL;
82
83    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
84                                     "O:GtkContainer.set_focus_chain", kwlist,
85                                     &py_focusable_widgets))
86        return NULL;
87    if (!PySequence_Check(py_focusable_widgets)) {
88        PyErr_SetString(PyExc_TypeError,
89                        "focusable_widgets must be a sequence");
90        return NULL;
91    }
92    len = PySequence_Length(py_focusable_widgets);
93    for (i = 0; i < len; i++) {
94        PyObject *item = PySequence_GetItem(py_focusable_widgets, i);
95
96        if (!pygobject_check(item, &PyGtkWidget_Type)) {
97            PyErr_SetString(PyExc_TypeError,
98                            "focusable_widgets members must be GtkWidgets");
99            Py_DECREF(item);
100            return NULL;
101        }
102        focusable_widgets = g_list_prepend(focusable_widgets,
103                                           pygobject_get(item));
104        Py_DECREF(item);
105    }
106    focusable_widgets = g_list_reverse(focusable_widgets);
107    gtk_container_set_focus_chain(GTK_CONTAINER(self->obj), focusable_widgets);
108    g_list_free(focusable_widgets);
109    Py_INCREF(Py_None);
110    return Py_None;
111}
112%%
113override gtk_container_get_focus_chain noargs
114static PyObject *
115_wrap_gtk_container_get_focus_chain(PyGObject *self)
116{
117    GList *list = NULL;
118
119    if (gtk_container_get_focus_chain(GTK_CONTAINER(self->obj), &list)) {
120        PyObject *py_list;
121        GList *tmp;
122
123        if ((py_list = PyList_New(0)) == NULL) {
124            g_list_free(list);
125            return NULL;
126        }
127        for (tmp = list; tmp != NULL; tmp = tmp->next) {
128            PyObject *gtk_obj = pygobject_new(G_OBJECT(tmp->data));
129
130            if (gtk_obj == NULL) {
131                g_list_free(list);
132                Py_DECREF(py_list);
133                return NULL;
134            }
135            PyList_Append(py_list, gtk_obj);
136            Py_DECREF(gtk_obj);
137        }
138        g_list_free(list);
139        return py_list;
140    }
141    Py_INCREF(Py_None);
142    return Py_None;
143}
144%%
145override gtk_container_child_get_property
146static PyObject *
147_wrap_gtk_container_child_get_property(PyGObject *self, PyObject *args)
148{
149    PyGObject *pychild;
150    gchar *property_name;
151    GtkContainer *container;
152    GtkWidget *child;
153    GList *children;
154    GObjectClass *class;
155    GParamSpec *pspec;
156    GValue value = { 0, } ;
157    PyObject *ret;
158
159    if (!PyArg_ParseTuple(args, "O!s:GtkContainer.child_get_property",
160                          &PyGtkWidget_Type, &pychild,
161                          &property_name)) {
162        return NULL;
163    }
164
165    container = GTK_CONTAINER(self->obj);
166    child = GTK_WIDGET(pychild->obj);
167
168    children = gtk_container_get_children(container);
169    if (g_list_find(children, child) == NULL) {
170        PyErr_SetString(PyExc_TypeError,
171                        "first argument must be a child");
172        return NULL;
173    }
174
175    class = G_OBJECT_GET_CLASS(container);
176    pspec = gtk_container_class_find_child_property(class, property_name);
177    if (!pspec) {
178        gchar buf[512];
179        g_snprintf(buf, sizeof(buf),
180                   "container does not support property `%s'",
181                   property_name);
182
183        PyErr_SetString(PyExc_TypeError, buf);
184        return NULL;
185    }
186
187    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
188
189    gtk_container_child_get_property(container,
190                                     child,
191                                     property_name,
192                                     &value);
193
194    ret = pyg_value_as_pyobject(&value, TRUE);
195    g_value_unset(&value);
196
197    return ret;
198}
199%%
200override gtk_container_child_set_property
201static PyObject *
202_wrap_gtk_container_child_set_property(PyGObject *self, PyObject *args)
203{
204    gchar *property_name;
205    PyGObject *pychild;
206    GtkContainer *container;
207    GtkWidget *child;
208    GList *children;
209    PyGObject *pyvalue;
210    GObjectClass *class;
211    GParamSpec *pspec;
212    GValue value = { 0, } ;
213
214    if (!PyArg_ParseTuple(args, "O!sO:GtkContainer.child_set_property",
215                          &PyGtkWidget_Type, &pychild,
216                          &property_name, &pyvalue)) {
217        return NULL;
218    }
219
220    container = GTK_CONTAINER(self->obj);
221    child = GTK_WIDGET(pychild->obj);
222
223    children = gtk_container_get_children(container);
224    if (g_list_find(children, child) == NULL) {
225        PyErr_SetString(PyExc_TypeError,
226                        "first argument must be a child");
227        return NULL;
228    }
229
230    class = G_OBJECT_GET_CLASS(self->obj);
231    pspec = gtk_container_class_find_child_property(class, property_name);
232    if (!pspec) {
233        gchar buf[512];
234        g_snprintf(buf, sizeof(buf),
235                   "container does not support property `%s'",
236                   property_name);
237        PyErr_SetString(PyExc_TypeError, buf);
238
239        return NULL;
240    }
241
242    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
243
244    pyg_value_from_pyobject(&value, (PyObject*)pyvalue);
245
246    gtk_container_child_set_property(container,
247                                     child,
248                                     property_name,
249                                     &value);
250    g_value_unset(&value);
251    Py_INCREF(Py_None);
252    return Py_None;
253}
254%%
255override gtk_container_child_set
256static PyObject *
257_wrap_gtk_container_child_set(PyGObject *self, PyObject *args)
258{
259    PyGObject *pychild;
260    GtkContainer *container;
261    GtkWidget *child;
262    GList *children;
263    GObjectClass *class;
264    int len, i;
265
266    if ((len = PyTuple_Size(args)) < 1) {
267        PyErr_SetString(PyExc_TypeError, "requires at least one argument");
268        return NULL;
269    }
270    pychild = (PyGObject*)PyTuple_GetItem(args, 0);
271    if (!pygobject_check(pychild, &PyGtkWidget_Type)) {
272        PyErr_SetString(PyExc_TypeError,
273                        "first argument should be a GtkWidget");
274        return NULL;
275    }
276
277    container = GTK_CONTAINER(self->obj);
278    child = GTK_WIDGET(pychild->obj);
279
280    children = gtk_container_get_children(container);
281    if (g_list_find(children, child) == NULL) {
282        PyErr_SetString(PyExc_TypeError,
283                        "first argument must be a child");
284        return NULL;
285    }
286
287    if ((len - 1) % 2) {
288        PyErr_SetString(PyExc_TypeError,
289                        "Argument list must be column, value pairs.  No -1 "
290                        "termination is needed.");
291        return NULL;
292    }
293
294    class = G_OBJECT_GET_CLASS(self->obj);
295    for (i = 1; i < len; i+=2) {
296        PyObject *py_property = PyTuple_GetItem(args, i);
297        PyObject *py_value = PyTuple_GetItem(args, i + 1);
298        gchar *property_name;
299        GParamSpec *pspec;
300        GValue value = { 0 };
301
302        if (!PyString_Check(py_property)) {
303            PyErr_SetString(PyExc_TypeError,
304                            "Expected string argument for property.");
305            return NULL;
306        }
307
308        property_name = PyString_AsString(py_property);
309
310        pspec = gtk_container_class_find_child_property(class, property_name);
311        if (!pspec) {
312            gchar buf[512];
313            g_snprintf(buf, sizeof(buf),
314                       "container does not support property `%s'",
315                       property_name);
316            PyErr_SetString(PyExc_TypeError, buf);
317
318            return NULL;
319        }
320
321        g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
322
323        pyg_value_from_pyobject(&value, (PyObject*)py_value);
324
325        gtk_container_child_set_property(container, child, property_name, &value);
326
327        g_value_unset(&value);
328    }
329    Py_INCREF(Py_None);
330    return Py_None;
331}
332%%
333override gtk_container_child_get
334static PyObject *
335_wrap_gtk_container_child_get(PyGObject *self, PyObject *args)
336{
337    PyGObject *pychild;
338    GtkContainer *container;
339    GtkWidget *child;
340    GList *children;
341    GObjectClass *class;
342    int len, i;
343    PyObject *tuple;
344
345    if ((len = PyTuple_Size(args)) < 1) {
346        PyErr_SetString(PyExc_TypeError, "requires at least one argument");
347        return NULL;
348    }
349    pychild = (PyGObject*)PyTuple_GetItem(args, 0);
350    if (!pygobject_check(pychild, &PyGtkWidget_Type)) {
351        PyErr_SetString(PyExc_TypeError,
352                        "first argument should be a GtkWidget");
353        return NULL;
354    }
355
356    container = GTK_CONTAINER(self->obj);
357    child = GTK_WIDGET(pychild->obj);
358
359    children = gtk_container_get_children(container);
360    if (g_list_find(children, child) == NULL) {
361        PyErr_SetString(PyExc_TypeError,
362                        "first argument must be a child");
363        return NULL;
364    }
365
366    tuple = PyTuple_New(len-1);
367    class = G_OBJECT_GET_CLASS(self->obj);
368    for (i = 1; i < len; i++) {
369        PyObject *py_property = PyTuple_GetItem(args, i);
370        gchar *property_name;
371        GParamSpec *pspec;
372        GValue value = { 0 };
373        PyObject *item;
374
375        if (!PyString_Check(py_property)) {
376            PyErr_SetString(PyExc_TypeError,
377                            "Expected string argument for property.");
378            return NULL;
379        }
380
381        property_name = PyString_AsString(py_property);
382
383        pspec = gtk_container_class_find_child_property(class, property_name);
384        if (!pspec) {
385            gchar buf[512];
386            g_snprintf(buf, sizeof(buf),
387                       "container does not support property `%s'",
388                       property_name);
389            PyErr_SetString(PyExc_TypeError, buf);
390
391            return NULL;
392        }
393
394        g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
395
396        gtk_container_child_get_property(container, child, property_name, &value);
397
398        item = pyg_value_as_pyobject(&value, TRUE);
399        PyTuple_SetItem(tuple, i-1, item);
400
401        g_value_unset(&value);
402    }
403    return tuple;
404}
405%%
406override gtk_container_add_with_properties
407static PyObject *
408_wrap_gtk_container_add_with_properties(PyGObject *self, PyObject *args)
409{
410    PyGObject *pychild;
411    GtkContainer *container;
412    GtkWidget *child;
413    GObjectClass *class;
414    int len, i;
415
416    if ((len = PyTuple_Size(args)) < 1) {
417        PyErr_SetString(PyExc_TypeError, "requires at least one argument");
418        return NULL;
419    }
420    pychild = (PyGObject*)PyTuple_GetItem(args, 0);
421    if (!pygobject_check(pychild, &PyGtkWidget_Type)) {
422        PyErr_SetString(PyExc_TypeError,
423                        "first argument should be a GtkWidget");
424        return NULL;
425    }
426
427    container = GTK_CONTAINER(self->obj);
428    child = GTK_WIDGET(pychild->obj);
429
430    if ((len - 1) % 2) {
431        PyErr_SetString(PyExc_TypeError,
432                        "Argument list must be column, value pairs.  No -1 "
433                        "termination is needed.");
434        return NULL;
435    }
436
437    gtk_widget_freeze_child_notify(child);
438
439    gtk_container_add(container, child);
440
441    class = G_OBJECT_GET_CLASS(self->obj);
442    for (i = 1; i < len; i+=2) {
443        PyObject *py_property = PyTuple_GetItem(args, i);
444        PyObject *py_value = PyTuple_GetItem(args, i + 1);
445        gchar *property_name;
446        GParamSpec *pspec;
447        GValue value = { 0 };
448
449        if (!PyString_Check(py_property)) {
450            PyErr_SetString(PyExc_TypeError,
451                            "Expected string argument for property.");
452            return NULL;
453        }
454
455        property_name = PyString_AsString(py_property);
456
457        pspec = gtk_container_class_find_child_property(class, property_name);
458        if (!pspec) {
459            gchar buf[512];
460            g_snprintf(buf, sizeof(buf),
461                       "container does not support property `%s'",
462                       property_name);
463            PyErr_SetString(PyExc_TypeError, buf);
464
465            return NULL;
466        }
467
468        g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
469
470        pyg_value_from_pyobject(&value, (PyObject*)py_value);
471
472        gtk_container_child_set_property(container, child, property_name, &value);
473
474        g_value_unset(&value);
475    }
476
477    gtk_widget_thaw_child_notify(child);
478
479    Py_INCREF(Py_None);
480    return Py_None;
481}
482%%
483override gtk_container_foreach
484static void
485pygtk_container_for_common_marshal(GtkWidget *widget,
486				   gpointer data)
487{
488    PyGILState_STATE state;
489    PyGtkCustomNotify *cunote = data;
490    PyObject *py_widget, *retobj;
491
492    g_assert(cunote->func);
493
494    state = pyg_gil_state_ensure();
495
496    py_widget = pygobject_new((GObject*)widget);
497    if (cunote->data)
498        retobj = PyEval_CallFunction(cunote->func, "(NO)",
499                                     py_widget, cunote->data);
500    else
501        retobj = PyEval_CallFunction(cunote->func, "(N)",
502                                     py_widget);
503
504    if (retobj == NULL) {
505        PyErr_Print();
506    }
507
508    Py_XDECREF(retobj);
509
510    pyg_gil_state_release(state);
511}
512static PyObject *
513pygtk_container_for_common(PyGObject *self, PyObject *args, unsigned for_index)
514{
515    PyObject *pyfunc, *pyarg = NULL;
516    PyGtkCustomNotify cunote;
517    static struct {
518        char *parse_arg;
519        void (*for_func)(GtkContainer *container, GtkCallback callback,
520                          gpointer callback_data);
521    } table[] = {
522            { "O|O:GtkContainer.foreach", gtk_container_foreach },
523            { "O|O:GtkContainer.forall", gtk_container_forall }
524    };
525
526    if (for_index >= countof(table)) {
527	PyErr_SetString(PyExc_TypeError, "for_index > 2");
528	return NULL;
529    }
530
531    if (!PyArg_ParseTuple(args, table[for_index].parse_arg,
532                          &pyfunc, &pyarg))
533         return NULL;
534
535    cunote.func = pyfunc;
536    cunote.data = pyarg;
537    table[for_index].for_func(GTK_CONTAINER(self->obj),
538			      pygtk_container_for_common_marshal,
539			      &cunote);
540    Py_INCREF(Py_None);
541    return Py_None;
542}
543static PyObject *
544_wrap_gtk_container_foreach(PyGObject *self, PyObject *args)
545{
546    return pygtk_container_for_common(self, args, PYGTK_CONTAINER_FOREACH);
547}
548%%
549override gtk_container_forall
550static PyObject *
551_wrap_gtk_container_forall(PyGObject *self, PyObject *args)
552{
553    return pygtk_container_for_common(self, args, PYGTK_CONTAINER_FORALL);
554}
555%%
556override gtk_container_class_list_child_properties kwargs
557static PyObject *
558_wrap_gtk_container_class_list_child_properties (PyObject *self, PyObject *args,
559					      PyObject*kwargs)
560{
561    static char *kwlist[] = { "klass", NULL };
562    GParamSpec **specs;
563    PyObject *py_itype, *list;
564    GType itype;
565    GObjectClass *class;
566    guint nprops;
567    guint i;
568
569    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
570				     "O:gtk.container_class_list_child_properties", kwlist,
571				     &py_itype))
572	return NULL;
573
574    if ((itype = pyg_type_from_object(py_itype)) == 0)
575	return NULL;
576
577    if (!g_type_is_a(itype, G_TYPE_OBJECT)) {
578	PyErr_SetString(PyExc_TypeError, "type must be derived from GObject");
579	return NULL;
580    }
581
582    class = g_type_class_ref(itype);
583    if (!class) {
584	PyErr_SetString(PyExc_RuntimeError,
585			"could not get a reference to type class");
586	return NULL;
587    }
588
589    specs = gtk_container_class_list_child_properties(class, &nprops);
590    list = PyTuple_New(nprops);
591    if (list == NULL) {
592	g_free(specs);
593	g_type_class_unref(class);
594	return NULL;
595    }
596
597    for (i = 0; i < nprops; i++) {
598	PyTuple_SetItem(list, i, pyg_param_spec_new(specs[i]));
599    }
600
601    g_free(specs);
602    g_type_class_unref(class);
603
604    return list;
605}
606%%
607define GtkContainer.list_child_properties noargs classmethod
608static PyObject *
609_wrap_gtk_container_list_child_properties (PyObject *self, PyObject *args,
610                                           PyObject*kwargs)
611{
612    GParamSpec **specs;
613    PyObject *list;
614    GType itype;
615    GObjectClass *class;
616    guint nprops;
617    guint i;
618
619    if ((itype = pyg_type_from_object(self)) == 0)
620	return NULL;
621
622    class = g_type_class_ref(itype);
623    if (!class) {
624	PyErr_SetString(PyExc_RuntimeError,
625			"could not get a reference to type class");
626	return NULL;
627    }
628
629    specs = gtk_container_class_list_child_properties(class, &nprops);
630    list = PyList_New(nprops);
631    if (list == NULL) {
632	g_free(specs);
633	g_type_class_unref(class);
634	return NULL;
635    }
636
637    for (i = 0; i < nprops; i++) {
638	PyList_SetItem(list, i, pyg_param_spec_new(specs[i]));
639    }
640
641    g_free(specs);
642    g_type_class_unref(class);
643
644    return list;
645}
646
647%%
648override gtk_container_class_install_child_property kwargs
649static PyObject *
650_wrap_gtk_container_class_install_child_property (PyObject *self,
651					       PyObject *args,
652					       PyObject* kwargs)
653{
654    static char *kwlist[] = { "klass", "property_id", "pspec", NULL };
655    PyObject *py_itype, *property;
656    GType itype;
657    GtkContainerClass *class;
658    guint property_id;
659    GParamSpec *pspec;
660
661    if (PyErr_Warn(PyExc_DeprecationWarning, "use the gtk.Container.install_child_property classmethod"))
662        return NULL;
663
664    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
665				     "OiO:container_class_install_child_property",
666				     kwlist,
667				     &py_itype, &property_id, &property))
668	return NULL;
669
670
671    if ((itype = pyg_type_from_object(py_itype)) == 0)
672	return NULL;
673
674    if (!g_type_is_a(itype, GTK_TYPE_CONTAINER)) {
675	PyErr_SetString(PyExc_TypeError, "type must be derived from GtkContainer");
676	return NULL;
677    }
678
679    class = g_type_class_ref(itype);
680    if (!class) {
681	PyErr_SetString(PyExc_RuntimeError,
682			"could not get a reference to type class");
683	return NULL;
684    }
685
686    pspec = pyg_param_spec_from_object(property);
687    if(!pspec) {
688	g_type_class_unref(class);
689	return NULL;
690    }
691
692    if (gtk_container_class_find_child_property(G_OBJECT_CLASS(class), pspec->name)) {
693	PyErr_Format(PyExc_TypeError,
694		     "there is already a '%s' property installed", pspec->name);
695	g_type_class_unref(class);
696	return NULL;
697    }
698
699    gtk_container_class_install_child_property(class, property_id, pspec);
700
701    g_type_class_unref(class);
702
703    Py_INCREF(Py_None);
704    return Py_None;
705}
706
707%%
708define GtkContainer.install_child_property kwargs classmethod
709static PyObject *
710_wrap_gtk_container_install_child_property (PyObject *self,
711                                            PyObject *args,
712                                            PyObject* kwargs)
713{
714    static char *kwlist[] = { "property_id", "pspec", NULL };
715    PyObject *property;
716    GType itype;
717    GtkContainerClass *class;
718    guint property_id;
719    GParamSpec *pspec;
720
721    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
722				     "iO:container_class_install_child_property",
723				     kwlist,
724				     &property_id, &property))
725	return NULL;
726
727
728    if ((itype = pyg_type_from_object(self)) == 0)
729	return NULL;
730
731    class = g_type_class_ref(itype);
732    if (!class) {
733	PyErr_SetString(PyExc_RuntimeError,
734			"could not get a reference to type class");
735	return NULL;
736    }
737
738    pspec = pyg_param_spec_from_object(property);
739    if(!pspec) {
740	g_type_class_unref(class);
741	return NULL;
742    }
743
744    if (gtk_container_class_find_child_property(G_OBJECT_CLASS(class), pspec->name)) {
745	PyErr_Format(PyExc_TypeError,
746		     "there is already a '%s' property installed", pspec->name);
747	g_type_class_unref(class);
748	return NULL;
749    }
750
751    gtk_container_class_install_child_property(class, property_id, pspec);
752
753    g_type_class_unref(class);
754
755    Py_INCREF(Py_None);
756    return Py_None;
757}
758
759%%
760override-slot GtkContainer.tp_iter
761
762typedef struct {
763    PyObject_HEAD
764    GList *list;
765} PyGContainerIter;
766
767static void
768pyg_container_iter_dealloc(PyGContainerIter *self)
769{
770    g_list_free(self->list);
771    PyObject_Del((PyObject*) self);
772}
773
774static PyObject*
775pygobject_container_iter_next(PyGContainerIter *iter)
776{
777    PyObject *child;
778
779    if (!iter->list) {
780        PyErr_SetNone(PyExc_StopIteration);
781        return NULL;
782    }
783
784    child = pygobject_new((GObject*)iter->list->data);
785    iter->list = g_list_next(iter->list);
786    return child;
787}
788
789static PyTypeObject PyGContainerIter_Type = {
790	PyObject_HEAD_INIT(NULL)
791	0,					/* ob_size */
792	"gobject.GContainerIter",		/* tp_name */
793	sizeof(PyGContainerIter),		/* tp_basicsize */
794	0,					/* tp_itemsize */
795	(destructor)pyg_container_iter_dealloc,	/* tp_dealloc */
796	0,					/* tp_print */
797	0,					/* tp_getattr */
798	0,					/* tp_setattr */
799	0,					/* tp_compare */
800	0,					/* tp_repr */
801	0,					/* tp_as_number */
802	0,					/* tp_as_sequence */
803	0,		       			/* tp_as_mapping */
804	0,					/* tp_hash */
805	0,					/* tp_call */
806	0,					/* tp_str */
807	0,					/* tp_getattro */
808	0,					/* tp_setattro */
809	0,					/* tp_as_buffer */
810	Py_TPFLAGS_DEFAULT,			/* tp_flags */
811 	"GtkContainer child iterator",		/* tp_doc */
812	0,					/* tp_traverse */
813 	0,					/* tp_clear */
814	0,					/* tp_richcompare */
815	0,					/* tp_weaklistoffset */
816	0,					/* tp_iter */
817	(iternextfunc)pygobject_container_iter_next, /* tp_iternext */
818};
819
820static PyObject*
821_wrap_gtk_container_tp_iter(PyGObject *self)
822{
823    PyGContainerIter *iter;
824    iter = PyObject_NEW(PyGContainerIter, &PyGContainerIter_Type);
825    iter->list = gtk_container_get_children(GTK_CONTAINER(self->obj));
826    return (PyObject *) iter;
827}
828%%
829override-slot GtkContainer.tp_as_sequence
830static Py_ssize_t
831_wrap_gtk_container_sq_length(PyGObject *self)
832{
833    return g_list_length(gtk_container_get_children(GTK_CONTAINER(self->obj)));
834}
835
836static PySequenceMethods _wrap_gtk_container_tp_as_sequence = {
837    (lenfunc)_wrap_gtk_container_sq_length,
838    0,
839    0,
840    0,
841    0,
842    0,
843    0,
844};
845%%
846override-slot GtkContainer.tp_as_number
847static int
848_wrap_gtk_container_nb_nonzero(PyGObject *self)
849{
850    return 1;
851}
852
853static PyNumberMethods _wrap_gtk_container_tp_as_number = {
854    (binaryfunc)0,
855    (binaryfunc)0,
856    (binaryfunc)0,
857    (binaryfunc)0,
858    (binaryfunc)0,
859    (binaryfunc)0,
860    (ternaryfunc)0,
861    (unaryfunc)0,
862    (unaryfunc)0,
863    (unaryfunc)0,
864    (inquiry)_wrap_gtk_container_nb_nonzero
865};
866
867%%
868override GtkContainer__proxy_do_forall
869
870typedef struct {
871    GtkCallback    func;
872    gpointer       func_data;
873} PyGtkContainerDataFuncData;
874
875
876static PyObject *
877_wrap_GtkContainerDataFunc(PyObject *self, PyObject *args)
878{
879    PyObject *py_widget;
880    PyObject *py_data;
881    PyGtkContainerDataFuncData *data;
882
883    if (!PyArg_ParseTuple(args, "O!O!",
884			  &PyGtkWidget_Type, &py_widget,
885                          &PyCObject_Type, &py_data))
886        return NULL;
887
888    data = PyCObject_AsVoidPtr(py_data);
889    data->func(GTK_WIDGET(pygobject_get(py_widget)), data->func_data);
890
891    Py_INCREF(Py_None);
892    return Py_None;
893}
894
895static void
896_wrap_GtkContainer__proxy_do_forall (GtkContainer *container,
897				     gboolean      include_internals,
898				     GtkCallback   callback,
899				     gpointer      callback_data)
900{
901    PyGILState_STATE state;
902    PyObject *self, *py_func, *py_func_data;
903    PyMethodDef pyfunc_def = { "GtkContainer.do_forall callback",
904			       (PyCFunction)_wrap_GtkContainerDataFunc,
905                               METH_VARARGS|METH_KEYWORDS };
906    PyGtkContainerDataFuncData *data;
907
908    state = pyg_gil_state_ensure();
909
910    self = pygobject_new((GObject *)container);
911    py_func = PyCFunction_NewEx(&pyfunc_def, NULL, NULL);
912
913    data = g_new(PyGtkContainerDataFuncData, 1);
914    data->func = callback;
915    data->func_data = callback_data;
916    PyObject_Repr(self);
917    PyObject_Repr(py_func);
918    py_func_data = PyCObject_FromVoidPtr(data, g_free);
919    if (!PyObject_CallMethod(self, "do_forall", "ONN",
920			     include_internals ? Py_True : Py_False, py_func,
921			     py_func_data))
922	PyErr_Print();
923
924    pyg_gil_state_release(state);
925}
926%%
927override GtkContainer__proxy_do_set_child_property
928static void
929_wrap_GtkContainer__proxy_do_set_child_property (GtkContainer *container,
930                                                 GtkWidget *child,
931                                                 guint property_id,
932                                                 const GValue *value,
933                                                 GParamSpec *pspec)
934{
935    PyGILState_STATE state;
936    PyObject *self, *py_ret;
937
938    state = pyg_gil_state_ensure();
939    self = pygobject_new((GObject *) container);
940
941    py_ret = PyObject_CallMethod(self, "do_set_child_property", "NNNN",
942                                 pygobject_new((GObject *) child),
943                                 PyLong_FromUnsignedLong(property_id),
944                                 pyg_value_as_pyobject(value, FALSE),
945                                 pyg_param_spec_new(pspec));
946    if (!py_ret) {
947	PyErr_Print();
948	Py_DECREF(self);
949	pyg_gil_state_release(state);
950	return;
951    }
952    Py_DECREF(self);
953    if (py_ret != Py_None)
954        PyErr_Warn(PyExc_Warning, "do_set_child_property must return None");
955    Py_DECREF(py_ret);
956
957    pyg_gil_state_release(state);
958}
959
960%%
961override GtkContainer__proxy_do_get_child_property
962static void
963_wrap_GtkContainer__proxy_do_get_child_property (GtkContainer *container,
964                                                 GtkWidget *child,
965                                                 guint property_id,
966                                                 GValue *value,
967                                                 GParamSpec *pspec)
968{
969    PyGILState_STATE state;
970    PyObject *self, *py_ret;
971
972    state = pyg_gil_state_ensure();
973
974    self = pygobject_new((GObject*)container);
975    py_ret = PyObject_CallMethod(self, "do_get_child_property", "NNN",
976                                 pygobject_new((GObject *) child),
977                                 PyLong_FromUnsignedLong(property_id),
978                                 pyg_param_spec_new(pspec));
979    if (!py_ret) {
980	PyErr_Print();
981	Py_DECREF(self);
982	pyg_gil_state_release(state);
983	return;
984    }
985    Py_DECREF(self);
986    pyg_value_from_pyobject(value, py_ret);
987    Py_DECREF(py_ret);
988
989    pyg_gil_state_release(state);
990}
991
992%%
993override GtkContainer__do_set_child_property kwargs
994static PyObject *
995_wrap_GtkContainer__do_set_child_property(PyObject *cls, PyObject *args, PyObject *kwargs)
996{
997    gpointer klass;
998    static char *kwlist[] = { "self", "child", "property_id", "value", "pspec", NULL };
999    PyGObject *self, *child;
1000    PyObject *py_property_id = NULL, *py_value, *py_pspec;
1001    guint property_id = 0;
1002    GValue value = {0, };
1003
1004    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!OOO!:GtkContainer.set_child_property",
1005                                     kwlist, &PyGtkContainer_Type, &self,
1006                                     &PyGtkWidget_Type, &child,
1007                                     &py_property_id,
1008                                     &py_value,
1009                                     &PyGParamSpec_Type, &py_pspec))
1010        return NULL;
1011
1012    if (pyg_value_from_pyobject(&value, py_value)) {
1013        PyErr_SetString(PyExc_TypeError, "unable to convert value");
1014        return NULL;
1015    }
1016
1017    if (py_property_id) {
1018        if (PyLong_Check(py_property_id))
1019            property_id = PyLong_AsUnsignedLong(py_property_id);
1020        else if (PyInt_Check(py_property_id))
1021            property_id = PyInt_AsLong(py_property_id);
1022        else
1023            PyErr_SetString(PyExc_TypeError, "Parameter 'property_id' must be an int or a long");
1024        if (PyErr_Occurred())
1025            return NULL;
1026    }
1027    klass = g_type_class_ref(pyg_type_from_object(cls));
1028    if (GTK_CONTAINER_CLASS(klass)->set_child_property)
1029        GTK_CONTAINER_CLASS(klass)->set_child_property(GTK_CONTAINER(self->obj), GTK_WIDGET(child->obj), property_id,
1030                                                       &value, ((PyGParamSpec *)py_pspec)->pspec);
1031    else {
1032        PyErr_SetString(PyExc_NotImplementedError, "virtual method GtkContainer.set_child_property not implemented");
1033        g_type_class_unref(klass);
1034        return NULL;
1035    }
1036    g_type_class_unref(klass);
1037    Py_INCREF(Py_None);
1038    return Py_None;
1039}
1040
1041%%
1042override GtkContainer__do_get_child_property kwargs
1043static PyObject *
1044_wrap_GtkContainer__do_get_child_property(PyObject *cls, PyObject *args, PyObject *kwargs)
1045{
1046    gpointer klass;
1047    static char *kwlist[] = { "self", "child", "property_id", "pspec", NULL };
1048    PyGObject *self, *child;
1049    PyObject *py_property_id = NULL;
1050    guint property_id = 0;
1051    GValue value = {0, };
1052    PyObject *py_value, *py_pspec;
1053
1054    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O!O!OO!:GtkContainer.get_child_property", kwlist,
1055                                     &PyGtkContainer_Type, &self,
1056                                     &PyGtkWidget_Type, &child,
1057                                     &py_property_id,
1058                                     &PyGParamSpec_Type, &py_pspec))
1059        return NULL;
1060    if (py_property_id) {
1061        if (PyLong_Check(py_property_id))
1062            property_id = PyLong_AsUnsignedLong(py_property_id);
1063        else if (PyInt_Check(py_property_id))
1064            property_id = PyInt_AsLong(py_property_id);
1065        else
1066            PyErr_SetString(PyExc_TypeError, "Parameter 'property_id' must be an int or a long");
1067        if (PyErr_Occurred())
1068            return NULL;
1069    }
1070    klass = g_type_class_ref(pyg_type_from_object(cls));
1071    if (GTK_CONTAINER_CLASS(klass)->get_child_property)
1072        GTK_CONTAINER_CLASS(klass)->get_child_property(GTK_CONTAINER(self->obj), GTK_WIDGET(child->obj), property_id,
1073                                                       &value, ((PyGParamSpec *)py_pspec)->pspec);
1074    else {
1075        PyErr_SetString(PyExc_NotImplementedError, "virtual method GtkContainer.get_child_property not implemented");
1076        g_type_class_unref(klass);
1077        return NULL;
1078    }
1079    g_type_class_unref(klass);
1080
1081    py_value = pyg_value_as_pyobject(&value, TRUE);
1082    g_value_unset(&value);
1083    return py_value;
1084}
1085
1086%%
1087override GtkContainer__do_forall kwargs
1088
1089typedef struct {
1090    PyObject *callback;
1091    PyObject *callback_data;
1092} PyGtkContainerPyCallbackData;
1093
1094static void
1095_wrap_GtkContainer__do_forall_callback(GtkWidget *child, PyGtkContainerPyCallbackData *data)
1096{
1097    PyObject *pychild = pygobject_new((GObject *) child);
1098    PyObject *result;
1099
1100    result = PyObject_CallFunctionObjArgs(data->callback, pychild, data->callback_data, NULL);
1101    /* Just discard it. */
1102    Py_DECREF(result);
1103}
1104
1105static PyObject *
1106_wrap_GtkContainer__do_forall(PyObject *cls, PyObject *args, PyObject *kwargs)
1107{
1108    gpointer klass;
1109    static char *kwlist[] = { "self", "include_internals", "callback", "callback_data", NULL };
1110    PyGObject *self;
1111    char include_internals;
1112    PyObject *callback;
1113    PyObject *callback_data = NULL;
1114
1115    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!bO|O:GtkContainer.forall", kwlist,
1116                                     &PyGtkContainer_Type, &self,
1117                                     &include_internals,
1118                                     &callback, &callback_data))
1119        return NULL;
1120
1121    klass = g_type_class_ref(pyg_type_from_object(cls));
1122    if (GTK_CONTAINER_CLASS(klass)->forall) {
1123	PyGtkContainerPyCallbackData *data = g_new(PyGtkContainerPyCallbackData, 1);
1124	data->callback = callback;
1125	data->callback_data = callback_data;
1126
1127	GTK_CONTAINER_CLASS(klass)->forall(GTK_CONTAINER(self->obj),
1128					   include_internals,
1129					   (GtkCallback)_wrap_GtkContainer__do_forall_callback,
1130					   data);
1131	g_free(data);
1132        g_type_class_unref(klass);
1133	Py_INCREF(Py_None);
1134	return Py_None;
1135    }
1136    else {
1137        PyErr_SetString(PyExc_NotImplementedError, "virtual method GtkContainer.forall not implemented");
1138        g_type_class_unref(klass);
1139        return NULL;
1140    }
1141}
1142