--- ../pygobject.c	Thu Jul 31 15:10:16 2003
+++ pygobject.c	Sun Aug 10 20:28:51 2003
@@ -80,6 +80,87 @@
     g_array_append_val(sink_funcs, sf);
 }
 
+static PyObject *
+pygobject_get_prop_descr(PyGObject *self, char *param_name)
+{
+    GParamSpec *pspec;
+    GValue value = { 0, };
+    PyObject *ret;
+
+    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
+					 param_name);
+    if (!pspec) {
+	PyErr_SetString(PyExc_TypeError,
+			"the object does not support the given parameter");
+	return NULL;
+    }
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+    g_object_get_property(self->obj, param_name, &value);
+    ret = pyg_value_as_pyobject(&value, TRUE);
+    g_value_unset(&value);
+    return ret;
+}
+
+static int
+pygobject_set_prop_descr(PyGObject *self, PyObject *pvalue, char *param_name)
+{
+    GParamSpec *pspec;
+    GValue value = { 0, };
+
+    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
+					 param_name);
+    if (!pspec) {
+	PyErr_SetString(PyExc_TypeError,
+			"the object does not support the given parameter");
+	return -1;
+    }
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+    if (pyg_value_from_pyobject(&value, pvalue) < 0) {
+	PyErr_SetString(PyExc_TypeError,
+			"could not convert argument to correct param type");
+	return -1;
+    }
+    g_object_set_property(self->obj, param_name, &value);
+    g_value_unset(&value);
+    return 0;
+}
+
+static void
+pygobject_add_class_properties_as_descriptors (GType gtype,
+					       PyTypeObject *type)
+{
+    GObjectClass *class;
+    GParamSpec **props;
+    guint n_props = 0, i;
+    PyObject *descr;
+    char *name, *prop_name;
+    PyGetSetDef *def;
+
+    class = g_type_class_ref(gtype);
+    props = g_object_class_list_properties(class, &n_props);
+    for (i=0; i<n_props; i++) {
+	if (props[i]->owner_type != gtype)
+	    continue;
+
+	/* Python won't make a copy so we need the strdup */
+	prop_name = g_strdup(g_param_spec_get_name(props[i]));
+	name = g_strdup(prop_name);
+	/* Convert '-' to '_' */
+	g_strdelimit(name, "-", '_');
+	def = g_new(struct PyGetSetDef, 1);
+	def->name = name;
+	def->doc = g_strdup(g_param_spec_get_blurb(props[i]));
+	def->closure = prop_name;
+	def->get = (getter)pygobject_get_prop_descr;
+	def->set = (setter)pygobject_set_prop_descr;
+	descr = PyDescr_NewGetSet(type, def);
+	PyDict_SetItemString(type->tp_dict, name, descr);
+	Py_DECREF(descr);
+    }
+    g_free (props);
+    g_type_class_unref (class);
+}
+
 /**
  * pygobject_register_class:
  * @dict: the module dictionary.  A reference to the type will be stored here.
@@ -122,6 +203,7 @@
     type->tp_weaklistoffset = offsetof(PyGObject, weakreflist);
     type->tp_dictoffset = offsetof(PyGObject, inst_dict);
 
+
     if (PyType_Ready(type) < 0) {
 	g_warning ("couldn't make the type `%s' ready", type->tp_name);
 	return;
@@ -135,6 +217,9 @@
 	/* stash a pointer to the python class with the GType */
 	Py_INCREF(type);
 	g_type_set_qdata(gtype, pygobject_class_key, type);
+
+	/* add the class properties as member descriptors */
+	pygobject_add_class_properties_as_descriptors(gtype, type);
     }
 
     /* set up __doc__ descriptor on type */
@@ -508,52 +593,26 @@
 pygobject_get_property(PyGObject *self, PyObject *args)
 {
     gchar *param_name;
-    GParamSpec *pspec;
-    GValue value = { 0, };
-    PyObject *ret;
 
     if (!PyArg_ParseTuple(args, "s:GObject.get_property", &param_name))
 	return NULL;
-    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
-					 param_name);
-    if (!pspec) {
-	PyErr_SetString(PyExc_TypeError,
-			"the object does not support the given parameter");
-	return NULL;
-    }
-    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
-    g_object_get_property(self->obj, param_name, &value);
-    ret = pyg_value_as_pyobject(&value, TRUE);
-    g_value_unset(&value);
-    return ret;
+    
+    return pygobject_get_prop_descr(self, param_name);
 }
 
 static PyObject *
 pygobject_set_property(PyGObject *self, PyObject *args)
 {
     gchar *param_name;
-    GParamSpec *pspec;
-    GValue value = { 0, };
     PyObject *pvalue;
 
     if (!PyArg_ParseTuple(args, "sO:GObject.set_property", &param_name,
 			  &pvalue))
 	return NULL;
-    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
-					 param_name);
-    if (!pspec) {
-	PyErr_SetString(PyExc_TypeError,
-			"the object does not support the given parameter");
-	return NULL;
-    }
-    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
-    if (pyg_value_from_pyobject(&value, pvalue) < 0) {
-	PyErr_SetString(PyExc_TypeError,
-			"could not convert argument to correct param type");
+
+    if (pygobject_set_prop_descr(self, pvalue, param_name))
 	return NULL;
-    }
-    g_object_set_property(self->obj, param_name, &value);
-    g_value_unset(&value);
+
     Py_INCREF(Py_None);
     return Py_None;
 }
