? g-object-set-properties.diff
? tests/gobject/deftype
? tests/gobject/singleton
Index: docs/reference/gobject/tmpl/objects.sgml
===================================================================
RCS file: /cvs/gnome/glib/docs/reference/gobject/tmpl/objects.sgml,v
retrieving revision 1.47
diff -u -d -r1.47 objects.sgml
--- docs/reference/gobject/tmpl/objects.sgml	5 Jun 2006 17:34:49 -0000	1.47
+++ docs/reference/gobject/tmpl/objects.sgml	25 Oct 2006 14:14:50 -0000
@@ -999,6 +999,19 @@
 @value: return location for the property value
 
 
+<!-- ##### FUNCTION g_object_set_properties ##### -->
+<para>
+Sets properties on an object.
+</para>
+<para>
+Note that g_object_set_properties() is really intended for language
+bindings, g_object_set() is much more convenient for C programming.
+</para>
+
+@object: a #GObject
+@n_parameters: number of parameters to set
+@parameters: parameters
+
 <!-- ##### FUNCTION g_object_new_valist ##### -->
 <para>
 Creates a new instance of a #GObject subtype and sets its properties.
Index: gobject/gobject.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.c,v
retrieving revision 1.82
diff -u -d -r1.82 gobject.c
--- gobject/gobject.c	30 Sep 2006 13:59:01 -0000	1.82
+++ gobject/gobject.c	25 Oct 2006 14:14:52 -0000
@@ -1325,6 +1325,59 @@
   g_object_unref (object);
 }
 
+void
+g_object_set_properties (GObject    *object,
+                         guint       n_parameters,
+                         GParameter *parameters)
+{
+  GObjectNotifyQueue *nqueue;
+  int i;
+
+  g_return_if_fail (G_IS_OBJECT (object));
+  
+  g_object_ref (object);
+  nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
+  
+  for (i = 0; i < n_parameters; i++)
+    {
+      GValue *value = &parameters[i].value;
+      const gchar *name = parameters[i].name;
+      GParamSpec *pspec;
+      
+      pspec = g_param_spec_pool_lookup (pspec_pool,
+                                        name,
+                                        G_OBJECT_TYPE (object),
+                                        TRUE);
+      if (!pspec)
+        {
+          g_warning ("%s: object class `%s' has no property named `%s'",
+                     G_STRFUNC,
+                     G_OBJECT_TYPE_NAME (object),
+                     name);
+          break;
+        }
+      if (!(pspec->flags & G_PARAM_WRITABLE))
+        {
+          g_warning ("%s: property `%s' of object class `%s' is not writable",
+                     G_STRFUNC,
+                     pspec->name,
+                     G_OBJECT_TYPE_NAME (object));
+          break;
+        }
+      if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
+        {
+          g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
+                     G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
+          break;
+        }
+
+      object_set_property (object, pspec, value, nqueue);
+    }
+
+  g_object_notify_queue_thaw (object, nqueue);
+  g_object_unref (object);
+}
+
 gpointer
 g_object_connect (gpointer     _object,
 		  const gchar *signal_spec,
Index: gobject/gobject.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.h,v
retrieving revision 1.38
diff -u -d -r1.38 gobject.h
--- gobject/gobject.h	23 Aug 2006 08:46:21 -0000	1.38
+++ gobject/gobject.h	25 Oct 2006 14:14:52 -0000
@@ -174,6 +174,9 @@
 void        g_object_get_property             (GObject        *object,
 					       const gchar    *property_name,
 					       GValue         *value);
+void        g_object_set_properties           (GObject        *object,
+					       guint	       n_parameters,
+					       GParameter     *properties);
 void        g_object_freeze_notify            (GObject        *object);
 void        g_object_notify                   (GObject        *object,
 					       const gchar    *property_name);
Index: gobject/gobject.symbols
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.symbols,v
retrieving revision 1.18
diff -u -d -r1.18 gobject.symbols
--- gobject/gobject.symbols	23 Apr 2006 04:21:08 -0000	1.18
+++ gobject/gobject.symbols	25 Oct 2006 14:14:52 -0000
@@ -144,6 +144,7 @@
 g_object_set_data
 g_object_set_data_full
 g_object_set_property
+g_object_set_properties
 g_object_set_qdata
 g_object_set_qdata_full
 g_object_set_valist
Index: tests/gobject/.cvsignore
===================================================================
RCS file: /cvs/gnome/glib/tests/gobject/.cvsignore,v
retrieving revision 1.6
diff -u -d -r1.6 .cvsignore
--- tests/gobject/.cvsignore	5 Apr 2006 04:50:48 -0000	1.6
+++ tests/gobject/.cvsignore	25 Oct 2006 14:14:52 -0000
@@ -13,3 +13,4 @@
 testmarshal.h
 stamp-testmarshal.h
 paramspec-test
+properties
Index: tests/gobject/Makefile.am
===================================================================
RCS file: /cvs/gnome/glib/tests/gobject/Makefile.am,v
retrieving revision 1.13
diff -u -d -r1.13 Makefile.am
--- tests/gobject/Makefile.am	16 Aug 2006 12:11:03 -0000	1.13
+++ tests/gobject/Makefile.am	25 Oct 2006 14:14:52 -0000
@@ -57,7 +57,8 @@
 	ifaceproperties				\
 	override				\
 	singleton				\
-	references
+	references				\
+	properties
 
 check_PROGRAMS = $(test_programs)
 
Index: tests/gobject/properties.c
===================================================================
RCS file: tests/gobject/properties.c
diff -N tests/gobject/properties.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/gobject/properties.c	25 Oct 2006 14:14:52 -0000
@@ -0,0 +1,185 @@
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (C) 2006 Johan Dahlin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <glib-object.h>
+
+#define TEST_TYPE_OBJECT          (test_object_get_type ())
+typedef struct _TestObject        TestObject;
+typedef struct _TestObjectClass   TestObjectClass;
+
+enum {
+  PROP_0,
+  PROP_STRING,
+  PROP_INT,
+};
+
+struct _TestObject
+{
+  GObject parent_instance;
+  gchar * prop_string;
+  int prop_int;
+};
+
+struct _TestObjectClass
+{
+  GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
+
+static void
+test_set_property (GObject         *object,
+                   guint            prop_id,
+                   const GValue    *value,
+                   GParamSpec      *pspec)
+{
+  TestObject *test = (TestObject*)object;
+
+  switch (prop_id)
+    {
+    case PROP_STRING:
+      test->prop_string = g_strdup (g_value_get_string (value));
+      break;
+    case PROP_INT:
+      test->prop_int = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+test_get_property (GObject         *object,
+                   guint            prop_id,
+                   GValue          *value,
+                   GParamSpec      *pspec)
+{
+  TestObject *test = (TestObject*)object;
+  
+  switch (prop_id)
+    {
+    case PROP_STRING:
+      g_value_set_string (value, test->prop_string);
+      break;
+    case PROP_INT:
+      g_value_set_int (value, test->prop_int);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+test_finalize (GObject *object)
+{
+  TestObject *test = (TestObject*)object;
+
+  g_free (test->prop_string);
+  
+  G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
+}
+
+static void
+test_object_class_init (TestObjectClass *class)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+  gobject_class->finalize = test_finalize;
+  gobject_class->set_property = test_set_property;
+  gobject_class->get_property = test_get_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_STRING,
+                                   g_param_spec_string ("string", NULL, NULL, NULL,
+                                                        G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_INT,
+                                   g_param_spec_int ("int", NULL, NULL,
+                                                     G_MININT, G_MAXINT, 0,
+                                                     G_PARAM_READWRITE));
+}
+
+static void
+test_object_init (TestObject *test_object)
+{
+}
+
+static void
+test_set_properties (GObject *test)
+{
+  GParameter *parameters;
+  GValue *values;
+
+  parameters = g_new0 (GParameter, 2);
+  values = g_new0 (GValue, 2);
+
+  g_value_init (&values[0], G_TYPE_STRING);
+  g_value_set_static_string (&values[0], "foobar");
+  parameters[0].name = "string";
+  parameters[0].value = values[0];
+    
+  g_value_init (&values[1], G_TYPE_INT);
+  g_value_set_int (&values[1], 42);
+  parameters[1].name = "int";
+  parameters[1].value = values[1];
+
+  g_object_set_properties (test, 2, parameters);
+
+  g_value_unset (&values[0]);
+  g_value_unset (&values[1]);
+  g_free (values);
+  g_free (parameters);
+  
+  g_assert (((TestObject*)test)->prop_int == 42);
+  g_assert (!strcmp (((TestObject*)test)->prop_string, "foobar"));
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  GObject *obj;
+  char *s;
+  int i;
+  
+  g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
+                          G_LOG_LEVEL_WARNING |
+                          G_LOG_LEVEL_CRITICAL);
+  g_type_init ();
+
+  obj = g_object_new (TEST_TYPE_OBJECT, NULL);
+
+  /* Default values */
+  g_object_get (obj, "int", &i, NULL);
+  g_assert (i == 0);
+  
+  g_object_get (obj, "string", &s, NULL);
+  g_assert (s == NULL);
+
+  test_set_properties (obj);
+  
+  g_object_unref (obj);
+  
+  return 0;
+}
