? foo.diff
? log
? pango-coverage.txt
? patches
? tst.py
? codegen/check-oldstyle-constructors.py
? examples/gobject/log
? examples/gtk/log
? examples/pango/foo.png
? examples/pango/output.pdf
? examples/pango/output.png
? examples/pygtk-demo/vgcore.pid19418
? gobject/foo
? gobject/gobject-contruction.txt
? gobject/test.py
? gtk/log
Index: gobject/gobjectmodule.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/gobjectmodule.c,v
retrieving revision 1.174
diff -u -p -d -r1.174 gobjectmodule.c
--- gobject/gobjectmodule.c	1 Jul 2005 15:07:14 -0000	1.174
+++ gobject/gobjectmodule.c	2 Jul 2005 16:04:46 -0000
@@ -2499,6 +2499,7 @@ DL_EXPORT(void)
 initgobject(void)
 {
     PyObject *m, *d, *o, *tuple;
+    PyObject *descr;
 
     PyGTypeWrapper_Type.ob_type = &PyType_Type;
     PyGParamSpec_Type.ob_type = &PyType_Type;
@@ -2533,13 +2534,21 @@ initgobject(void)
     PyGObject_MetaType.tp_is_gc = PyType_Type.tp_is_gc;
     PyType_Ready(&PyGObject_MetaType);
     PyDict_SetItemString(d, "GObjectMeta", (PyObject *) &PyGObject_MetaType);
-    
+
     PyGObject_Type.tp_alloc = PyType_GenericAlloc;
     PyGObject_Type.tp_new = PyType_GenericNew;
     pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
 			     &PyGObject_Type, NULL);
     PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__",
 			 pyg_object_descr_doc_get());
+
+      /* GObject properties descriptor */
+    if (PyType_Ready(&PyGProps_Type) < 0)
+        return;
+    if (PyType_Ready(&PyGPropsDescr_Type) < 0)
+        return;
+    descr = PyObject_New(PyObject, &PyGPropsDescr_Type);
+    PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr);
 
     REGISTER_GTYPE(d, PyGInterface_Type, "GInterface", G_TYPE_INTERFACE);
     PyDict_SetItemString(PyGInterface_Type.tp_dict, "__doc__",
Index: gobject/pygobject-private.h
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject-private.h,v
retrieving revision 1.33
diff -u -p -d -r1.33 pygobject-private.h
--- gobject/pygobject-private.h	28 May 2005 15:42:06 -0000	1.33
+++ gobject/pygobject-private.h	2 Jul 2005 16:04:46 -0000
@@ -93,6 +93,8 @@ extern PyTypeObject PyGObject_MetaType;
 /* from pygobject.h */
 extern PyTypeObject PyGObject_Type;
 extern PyTypeObject PyGInterface_Type;
+extern PyTypeObject PyGProps_Type;
+extern PyTypeObject PyGPropsDescr_Type;
 
 void          pygobject_register_class   (PyObject *dict,
 					  const gchar *type_name,
Index: gobject/pygobject.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/gobject/pygobject.c,v
retrieving revision 1.45
diff -u -p -d -r1.45 pygobject.c
--- gobject/pygobject.c	20 Jun 2005 13:21:34 -0000	1.45
+++ gobject/pygobject.c	2 Jul 2005 16:04:47 -0000
@@ -80,6 +80,244 @@ pygobject_register_sinkfunc(GType type, 
     g_array_append_val(sink_funcs, sf);
 }
 
+typedef struct {
+    PyObject_HEAD
+    /* a reference to the object containing the properties */
+    PyGObject *pygobject;
+    GType      gtype;
+} PyGProps;
+
+static void
+PyGProps_dealloc(PyGProps* self)
+{
+    PyGObject *tmp;
+
+    PyObject_GC_UnTrack((PyObject*)self);
+
+    tmp = self->pygobject;
+    self->pygobject = NULL;
+    Py_XDECREF(tmp);
+
+    PyObject_GC_Del((PyObject*)self);
+}
+
+static PyObject*
+build_parameter_list(GType gtype)
+{
+    GObjectClass *class;
+    GParamSpec **props;
+    guint n_props = 0, i;
+    PyObject *prop_str;
+    char *name;
+    PyObject *props_list;
+
+    class = g_type_class_ref(gtype);
+    props = g_object_class_list_properties(class, &n_props);
+    props_list = PyList_New(n_props);
+    for (i = 0; i < n_props; i++) {
+	name = g_strdup(g_param_spec_get_name(props[i]));
+	/* hyphens cannot belong in identifiers */
+	g_strdelimit(name, "-", '_');
+	prop_str = PyString_FromString(name);
+	
+	PyList_SetItem(props_list, i, prop_str);
+    }
+    g_free (props);
+    g_type_class_unref (class);
+    
+    return props_list;
+}
+
+static PyObject*
+PyGProps_getattro(PyGProps *gprops, PyObject *attr)
+{
+    GParamSpec *pspec;
+    GValue value = { 0, };
+    char *attr_name;
+    PyObject *ret;
+
+    if (PyString_Check(attr))
+        attr_name = PyString_AsString(attr);
+    else
+	return PyObject_GenericGetAttr((PyObject *)gprops, attr);
+
+    if (!strcmp(attr_name, "__members__")) {
+	return build_parameter_list(gprops->gtype);
+    }
+
+    if (!gprops->pygobject) {
+        PyErr_SetString(PyExc_TypeError, "cannot get GOject properties without an instance");
+        return NULL;
+    }
+
+    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(gprops->pygobject->obj), attr_name);
+
+    if (!pspec) {
+	return PyObject_GenericGetAttr((PyObject *)gprops, attr);
+    }
+
+    if (!(pspec->flags & G_PARAM_READABLE)) {
+	PyErr_Format(PyExc_TypeError,
+		     "property '%s' is not readable", attr_name);
+	return NULL;
+    }
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+    g_object_get_property(gprops->pygobject->obj, attr_name, &value);
+    ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec);
+    g_value_unset(&value);
+    return ret;
+}
+
+static int
+PyGProps_setattro(PyGProps *gprops, PyObject *attr, PyObject *pvalue)
+{
+    GParamSpec *pspec;
+    GValue value = { 0, };
+    char *attr_name;
+
+    if (pvalue == NULL) {
+	PyErr_SetString(PyExc_TypeError, "properties cannot be "
+			"deleted");
+	return -1;
+    }
+    if (PyString_Check(attr))
+        attr_name = PyString_AsString(attr);
+    else
+        return PyObject_GenericSetAttr((PyObject *)gprops, attr, pvalue);
+
+    if (!gprops->pygobject) {
+        PyErr_SetString(PyExc_TypeError, "cannot set GOject properties without an instance");
+        return -1;
+    }
+
+    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(gprops->pygobject->obj), attr_name);
+
+    if (!pspec) {
+	return PyObject_GenericSetAttr((PyObject *)gprops, attr, pvalue);
+    }
+
+    if (!(pspec->flags & G_PARAM_WRITABLE)) {
+	PyErr_Format(PyExc_TypeError,
+		     "property '%s' is not writable", attr_name);
+	return -1;
+    }	
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+    if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) {
+	PyErr_SetString(PyExc_TypeError,
+			"could not convert argument to correct param type");
+	return -1;
+    }
+
+    g_object_set_property(gprops->pygobject->obj, attr_name, &value);
+    g_value_unset(&value);
+    return 0;
+}
+
+static int
+pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg)
+{
+    if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0)
+        return -1;
+    return 0;
+}
+
+PyTypeObject PyGProps_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "gobject.GProps",          /*tp_name*/
+    sizeof(PyGProps),	       /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)PyGProps_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,			       /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    (getattrofunc)PyGProps_getattro, /*tp_getattro*/
+    (setattrofunc)PyGProps_setattro, /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+    "The properties of the GObject accessible as "
+    "Python attributes.",      /* tp_doc */
+    (traverseproc)pygobject_props_traverse, /* tp_traverse */
+    0,                 		/* tp_clear */
+};
+
+
+static PyObject *
+pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    PyGProps *gprops;
+
+    gprops = PyObject_GC_New(PyGProps, &PyGProps_Type);
+    if (obj == NULL || obj == Py_None) {
+        gprops->pygobject = NULL;
+        gprops->gtype = pyg_type_from_object(type);
+    } else {
+        if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) {
+            PyErr_SetString(PyExc_TypeError, "cannot use GObject property"
+                            " descriptor on non-GObject instances");
+            return NULL;
+        }
+        Py_INCREF(obj);
+        gprops->pygobject = (PyGObject *) obj;
+        gprops->gtype = pyg_type_from_object(obj);
+    }
+    return (PyObject *) gprops;
+}
+
+PyTypeObject PyGPropsDescr_Type = {
+	PyObject_HEAD_INIT(NULL)
+	sizeof(PyObject),			/* ob_size */
+	"gobject.GPropsDescr",			/* tp_name */
+	0,					/* tp_basicsize */
+	0,					/* tp_itemsize */
+	0,	 				/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,		       			/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	0,					/* tp_doc */
+	0,					/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	pyg_props_descr_descr_get,		/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	0,					/* tp_new */
+	0,               			/* tp_free */
+};
+
+
 /**
  * pygobject_register_class:
  * @dict: the module dictionary.  A reference to the type will be stored here.
