Jonathan Blandford <[EMAIL PROTECTED]> writes:

> Hi,
> 
> I spent the weekend taking a look at the pygtk code while trying to
> write a widget from scratch.  Some comments:

I sent the wrong patch first time I wrote this message.  You probably
all were wondering what I was talking about S-:

Here's the real patch.
-Jonathan
? core.13010
? core.13293
? core.13706
? core.14415
? core.14712
? pygtk/examples/gobject/core.1209
? pygtk/examples/gobject/core.4087
Index: pygtk/ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/ChangeLog,v
retrieving revision 1.419
diff -u -p -r1.419 ChangeLog
--- pygtk/ChangeLog	20 Jun 2002 03:31:38 -0000	1.419
+++ pygtk/ChangeLog	21 Jun 2002 13:05:59 -0000
@@ -1,3 +1,8 @@
+Mon Jun 17 13:16:26 2002  Jonathan Blandford  <[EMAIL PROTECTED]>
+
+	* pygobject.c (pygobject_init): take kwargs so we can pass
+	construct-only arguments to our initialization function.
+
 2002-06-19  Matt Wilson  <[EMAIL PROTECTED]>
 
 	* gtk/gtk.override (_wrap_gtk_ctree_insert_node): check the
Index: pygtk/pygboxed.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/pygboxed.c,v
retrieving revision 1.2
diff -u -p -r1.2 pygboxed.c
--- pygtk/pygboxed.c	5 Feb 2002 07:13:20 -0000	1.2
+++ pygtk/pygboxed.c	21 Jun 2002 13:05:59 -0000
@@ -61,6 +61,21 @@ pyg_boxed_free(PyObject *op)
   PyObject_FREE(op);
 }
 
+static PyObject *
+pyg_boxed_copy(PyGBoxed *self)
+{
+    return pyg_boxed_new (self->gtype, self->boxed, TRUE, TRUE);
+}
+
+
+
+static PyMethodDef pygboxed_methods[] = {
+    { "copy", (PyCFunction) pyg_boxed_copy, METH_NOARGS },
+    { NULL, NULL, 0 }
+};
+
+
+
 PyTypeObject PyGBoxed_Type = {
     PyObject_HEAD_INIT(NULL)
     0,                                  /* ob_size */
@@ -91,7 +106,7 @@ PyTypeObject PyGBoxed_Type = {
     0,					/* tp_weaklistoffset */
     (getiterfunc)0,			/* tp_iter */
     (iternextfunc)0,			/* tp_iternext */
-    0,					/* tp_methods */
+    pygboxed_methods,                   /* tp_methods */
     0,					/* tp_members */
     0,					/* tp_getset */
     (PyTypeObject *)0,			/* tp_base */
Index: pygtk/pygobject.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/pygobject.c,v
retrieving revision 1.2
diff -u -p -r1.2 pygobject.c
--- pygtk/pygobject.c	28 Jan 2002 00:46:55 -0000	1.2
+++ pygtk/pygobject.c	21 Jun 2002 13:05:59 -0000
@@ -229,11 +229,26 @@ pygobject_free(PyObject *op)
 
 /* ---------------- PyGObject methods ----------------- */
 
+static void
+parameter_list_free (GParameter *parameters, guint n_parameters)
+{
+	gint i;
+	for (i = 0; i < n_parameters; i ++){
+		g_free ((char *)parameters[i].name);
+		g_value_unset (&(parameters[i].value));
+	}
+	g_free (parameters);
+}
+
 static int
 pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
     GType object_type;
-
+    guint n_parameters = 0;
+    GParameter *parameters = NULL;
+    PyObject *key, *item;
+    gint pos = 0;
+    
     if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
 	return -1;
 
@@ -241,7 +256,47 @@ pygobject_init(PyGObject *self, PyObject
     if (!object_type)
 	return -1;
 
-    self->obj = g_object_new(object_type, NULL);
+    if (kwargs) {
+        while (PyDict_Next(kwargs, &pos, &key, &item)) {
+	    gchar *param_name;
+	    GParamSpec *pspec;
+	    GValue value = { 0, };
+	    GObjectClass *class;
+	    class = g_type_class_peek (object_type);
+	    param_name = PyString_AsString(key);
+	    pspec = g_object_class_find_property(class, param_name);
+
+	    if (pspec == NULL) {
+		    gchar buf[128];
+		    
+		    g_snprintf(buf, sizeof(buf),
+			       "Unknown parameter '%s' used in type initialization arguments",
+			       param_name);
+		    PyErr_SetString(PyExc_AttributeError, buf);
+		    parameter_list_free (parameters, n_parameters);
+		    return -1;
+	    }
+	    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+	    if (pyg_value_from_pyobject(&value, item) < 0) {
+		    PyErr_SetString(PyExc_TypeError,
+			"could not convert argument to correct param type");
+		    parameter_list_free (parameters, n_parameters);
+		    return -1;
+	    }
+
+	    n_parameters ++;
+	    if (parameters == NULL) {
+		    parameters = g_new (GParameter, 1);
+	    } else {
+		    parameters = g_renew (GParameter, parameters, n_parameters);
+	    }
+	    parameters[n_parameters - 1].name = g_strdup (param_name);
+	    parameters[n_parameters - 1].value = value;
+	}
+    }
+
+    self->obj = g_object_newv(object_type, n_parameters, parameters);
+    parameter_list_free (parameters, n_parameters);
     if (!self->obj) {
 	PyErr_SetString(PyExc_RuntimeError, "could not create object");
 	return -1;
Index: pygtk/pygtype.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/pygtype.c,v
retrieving revision 1.11
diff -u -p -r1.11 pygtype.c
--- pygtk/pygtype.c	17 Jun 2002 18:28:38 -0000	1.11
+++ pygtk/pygtype.c	21 Jun 2002 13:06:00 -0000
@@ -579,7 +579,7 @@ pyg_value_as_pyobject(const GValue *valu
 		return bm->fromvalue(value);
 	    else
 		return pyg_boxed_new(G_VALUE_TYPE(value),
-				     g_value_get_boxed(value), TRUE, TRUE);
+				     g_value_get_boxed(value), FALSE, FALSE);/* How much will this make us leak?? */
 	}
     case G_TYPE_PARAM:
 	return pyg_param_spec_new(g_value_get_param(value));

Reply via email to