[glib/new-gsettings] Add support for common types in the default mapping functions for bind



commit d02558fbf311838a299c8a5027ea85b5c3f8e4a6
Author: Vincent Untz <vuntz gnome org>
Date:   Fri Apr 16 12:55:12 2010 -0400

    Add support for common types in the default mapping functions for bind

 gio/gsettings.c |  349 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 328 insertions(+), 21 deletions(-)
---
diff --git a/gio/gsettings.c b/gio/gsettings.c
index adbf11b..a28e7f1 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -1163,14 +1163,264 @@ g_settings_binding_property_changed (GObject          *object,
 }
 
 static GVariant *
+g_settings_set_mapping_numeric (const GValue       *value,
+                                const GVariantType *expected_type)
+{
+  GVariant *variant = NULL;
+  glong l;
+
+  if (G_VALUE_HOLDS_INT (value))
+    l = g_value_get_int (value);
+  else if (G_VALUE_HOLDS_INT64 (value))
+    l = g_value_get_int64 (value);
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    l = g_value_get_double (value);
+  else
+    return NULL;
+
+  if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT16))
+    {
+      if (G_MININT16 <= l && l <= G_MAXINT16)
+        variant = g_variant_new_int16 ((gint16) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT16))
+    {
+      if (0 <= l && l <= G_MAXUINT16)
+        variant = g_variant_new_uint16 ((guint16) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT32))
+    {
+      if (G_MININT32 <= l && l <= G_MAXINT32)
+        variant = g_variant_new_int32 ((gint) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT32))
+    {
+      if (0 <= l && l <= G_MAXUINT32)
+        variant = g_variant_new_uint32 ((guint) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT64))
+    {
+      if (G_MININT64 <= l && l <= G_MAXINT64)
+        variant = g_variant_new_int64 ((gint64) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT64))
+    {
+      if (0 <= l && l <= G_MAXUINT64)
+        variant = g_variant_new_uint64 ((guint64) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_HANDLE))
+    {
+      if (0 <= l && l <= G_MAXUINT32)
+        variant = g_variant_new_handle ((guint) l);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_DOUBLE))
+    variant = g_variant_new_double ((double) l);
+
+  return variant;
+}
+
+static GVariant *
+g_settings_set_mapping_unsigned_numeric (const GValue       *value,
+                                         const GVariantType *expected_type)
+{
+  GVariant *variant = NULL;
+  gulong u;
+
+  if (G_VALUE_HOLDS_UINT (value))
+    u = g_value_get_uint (value);
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    u = g_value_get_uint64 (value);
+  else
+    return NULL;
+
+  if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT16))
+    {
+      if (u <= G_MAXINT16)
+        variant = g_variant_new_int16 ((gint16) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT16))
+    {
+      if (u <= G_MAXUINT16)
+        variant = g_variant_new_uint16 ((guint16) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT32))
+    {
+      if (u <= G_MAXINT32)
+        variant = g_variant_new_int32 ((gint) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT32))
+    {
+      if (u <= G_MAXUINT32)
+        variant = g_variant_new_uint32 ((guint) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT64))
+    {
+      if (u <= G_MAXINT64)
+        variant = g_variant_new_int64 ((gint64) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT64))
+    {
+      if (u <= G_MAXUINT64)
+        variant = g_variant_new_uint64 ((guint64) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_HANDLE))
+    {
+      if (u <= G_MAXUINT32)
+        variant = g_variant_new_handle ((guint) u);
+    }
+  else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_DOUBLE))
+    variant = g_variant_new_double ((double) u);
+
+  return variant;
+}
+
+static gboolean
+g_settings_get_mapping_numeric (GValue   *value,
+                                GVariant *variant)
+{
+  const GVariantType *type;
+  glong l;
+
+  type = g_variant_get_type (variant);
+
+  if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_INT16))
+    l = g_variant_get_int16 (variant);
+  else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_INT32))
+    l = g_variant_get_int32 (variant);
+  else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_INT64))
+    l = g_variant_get_int64 (variant);
+  else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DOUBLE))
+    l = g_variant_get_double (variant);
+  else
+    return FALSE;
+
+  if (G_VALUE_HOLDS_INT (value))
+    {
+      g_value_set_int (value, l);
+      return (G_MININT32 <= l && l <= G_MAXINT32);
+    }
+  else if (G_VALUE_HOLDS_UINT (value))
+    {
+      g_value_set_uint (value, l);
+      return (0 <= l && l <= G_MAXUINT32);
+    }
+  else if (G_VALUE_HOLDS_INT64 (value))
+    {
+      g_value_set_int64 (value, l);
+      return (G_MININT64 <= l && l <= G_MAXINT64);
+    }
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    {
+      g_value_set_uint64 (value, l);
+      return (0 <= l && l <= G_MAXUINT64);
+    }
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    {
+      g_value_set_double (value, l);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+g_settings_get_mapping_unsigned_numeric (GValue   *value,
+                                         GVariant *variant)
+{
+  const GVariantType *type;
+  gulong u;
+
+  type = g_variant_get_type (variant);
+
+  if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT16))
+    u = g_variant_get_uint16 (variant);
+  else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT32))
+    u = g_variant_get_uint32 (variant);
+  else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT64))
+    u = g_variant_get_uint64 (variant);
+  else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_HANDLE))
+    u = g_variant_get_handle (variant);
+  else
+    return FALSE;
+
+  if (G_VALUE_HOLDS_INT (value))
+    {
+      g_value_set_int (value, u);
+      return (u <= G_MAXINT32);
+    }
+  else if (G_VALUE_HOLDS_UINT (value))
+    {
+      g_value_set_uint (value, u);
+      return (u <= G_MAXUINT32);
+    }
+  else if (G_VALUE_HOLDS_INT64 (value))
+    {
+      g_value_set_int64 (value, u);
+      return (u <= G_MAXINT64);
+    }
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    {
+      g_value_set_uint64 (value, u);
+      return (u <= G_MAXUINT64);
+    }
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    {
+      g_value_set_double (value, u);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static GVariant *
 g_settings_set_mapping (const GValue       *value,
                         const GVariantType *expected_type,
                         gpointer            user_data)
 {
-  if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_BOOLEAN))
-    return g_variant_new_boolean (g_value_get_boolean (value));
+  gchar *type_string;
 
-  g_error ("Sorry; non-boolean bindings are not supported\n");
+  if (G_VALUE_HOLDS_BOOLEAN (value))
+    {
+      if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_BOOLEAN))
+        return g_variant_new_boolean (g_value_get_boolean (value));
+    }
+
+  else if (G_VALUE_HOLDS_CHAR (value)  ||
+           G_VALUE_HOLDS_UCHAR (value))
+    {
+      if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_BYTE))
+        {
+          if (G_VALUE_HOLDS_CHAR (value))
+            return g_variant_new_byte (g_value_get_char (value));
+          else
+            return g_variant_new_byte (g_value_get_uchar (value));
+        }
+    }
+
+  else if (G_VALUE_HOLDS_INT (value)   ||
+           G_VALUE_HOLDS_INT64 (value) ||
+           G_VALUE_HOLDS_DOUBLE (value))
+    return g_settings_set_mapping_numeric (value, expected_type);
+
+  else if (G_VALUE_HOLDS_UINT (value)  ||
+           G_VALUE_HOLDS_UINT64 (value))
+    return g_settings_set_mapping_unsigned_numeric (value, expected_type);
+
+  else if (G_VALUE_HOLDS_STRING (value))
+    {
+      if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_STRING))
+        return g_variant_new_string (g_value_get_string (value));
+      else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
+        return g_variant_new_object_path (g_value_get_string (value));
+      else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_SIGNATURE))
+        return g_variant_new_signature (g_value_get_string (value));
+    }
+
+  type_string = g_variant_type_dup_string (expected_type);
+  g_critical ("No GSettings bind handler for type \"%s\".", type_string);
+  g_free (type_string);
+
+  return NULL;
 }
 
 static gboolean
@@ -1179,11 +1429,47 @@ g_settings_get_mapping (GValue   *value,
                         gpointer  user_data)
 {
   if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
-    g_value_set_boolean (value, g_variant_get_boolean (variant));
-  else
-    g_error ("Sorry; non-boolean bindings are not supported\n");
+    {
+      if (!G_VALUE_HOLDS_BOOLEAN (value))
+        return FALSE;
+      g_value_set_boolean (value, g_variant_get_boolean (variant));
+      return TRUE;
+    }
 
-  return TRUE;
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
+    {
+      if (G_VALUE_HOLDS_UCHAR (value))
+        g_value_set_uchar (value, g_variant_get_byte (variant));
+      else if (G_VALUE_HOLDS_CHAR (value))
+        g_value_set_char (value, (gchar) g_variant_get_byte (variant));
+      else
+        return FALSE;
+      return TRUE;
+    }
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16)  ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32)  ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64)  ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
+    return g_settings_get_mapping_numeric (value, variant);
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
+    return g_settings_get_mapping_unsigned_numeric (value, variant);
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)      ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
+    {
+      g_value_set_string (value, g_variant_get_string (variant, NULL));
+      return TRUE;
+    }
+
+  g_critical ("No GSettings bind handler for type \"%s\".", g_variant_get_type_string (variant));
+
+  return FALSE;
 }
 
 void
@@ -1252,20 +1538,41 @@ g_settings_bind_with_mapping (GSettings               *settings,
 
   if (get_mapping == NULL || set_mapping == NULL)
     {
-      /* XXX do some simple checks for type compatibility 
-
-  if (!g_type_serialiser_check (G_PARAM_SPEC_VALUE_TYPE (binding->property),
-                                binding->type))
-    {
-      g_critical ("g_settings_bind: property '%s' on class '%s' has type"
-                  "'%s' which is not compatible with type '%s' of key '%s'"
-                  "on schema '%s'", property, G_OBJECT_TYPE_NAME (object),
-                  g_type_name (binding->property->value_type),
-                  g_variant_type_dup_string (binding->type), key,
-                  settings->priv->schema_name);
-      return;
-    }
-*/
+      gboolean ok = FALSE;
+
+      if (binding->property->value_type == G_TYPE_BOOLEAN)
+        ok = g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_BOOLEAN);
+      else if (binding->property->value_type == G_TYPE_CHAR  ||
+               binding->property->value_type == G_TYPE_UCHAR)
+        ok = g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_BYTE);
+      else if (binding->property->value_type == G_TYPE_INT    ||
+               binding->property->value_type == G_TYPE_UINT   ||
+               binding->property->value_type == G_TYPE_INT64  ||
+               binding->property->value_type == G_TYPE_UINT64 ||
+               binding->property->value_type == G_TYPE_DOUBLE)
+        ok = (g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_INT16)  ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_UINT16) ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_INT32)  ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_UINT32) ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_INT64)  ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_UINT64) ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_HANDLE) ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_DOUBLE));
+      else if (binding->property->value_type == G_TYPE_STRING)
+        ok = (g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_STRING)      ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_OBJECT_PATH) ||
+              g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_SIGNATURE));
+
+      if (!ok)
+        {
+          g_critical ("g_settings_bind: property '%s' on class '%s' has type"
+                      "'%s' which is not compatible with type '%s' of key '%s'"
+                      "on schema '%s'", property, G_OBJECT_TYPE_NAME (object),
+                      g_type_name (binding->property->value_type),
+                      g_variant_type_dup_string (binding->type), key,
+                      settings->priv->schema_name);
+          return;
+        }
     }
 
   if (~flags & G_SETTINGS_BIND_NO_SENSITIVITY)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]