[glib/new-gsettings] g_settings_bind() fixes
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/new-gsettings] g_settings_bind() fixes
- Date: Sat, 17 Apr 2010 03:05:30 +0000 (UTC)
commit eedfbdf80f8f074f4374e34f2af4d5b6966aac9b
Author: Ryan Lortie <desrt desrt ca>
Date: Fri Apr 16 22:49:35 2010 -0400
g_settings_bind() fixes
- track sensitivity changes
- move vuntz-mapping code to new file
- option to only get initial value from settings
gio/Makefile.am | 2 +
gio/gsettings-mapping.c | 367 ++++++++++++++++++++++++++++++++++++++
gio/gsettings-mapping.h | 39 ++++
gio/gsettings.c | 446 ++++++++---------------------------------------
gio/gsettings.h | 3 +-
5 files changed, 485 insertions(+), 372 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 272695f..8b61721 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -97,6 +97,8 @@ settings_sources = \
gsettingsbackend.c \
gsettingsschema.h \
gsettingsschema.c \
+ gsettings-mapping.h \
+ gsettings-mapping.c \
gsettings.c
local_sources = \
diff --git a/gio/gsettings-mapping.c b/gio/gsettings-mapping.c
new file mode 100644
index 0000000..e7f1ba5
--- /dev/null
+++ b/gio/gsettings-mapping.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright © 2010 Novell, Inc.
+ *
+ * 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 licence, 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.
+ *
+ * Author: Vincent Untz <vuntz gnome org>
+ */
+
+#include "config.h"
+
+#include "gsettings-mapping.h"
+
+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_equal (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_equal (expected_type, G_VARIANT_TYPE_UINT16))
+ {
+ if (0 <= l && l <= G_MAXUINT16)
+ variant = g_variant_new_uint16 ((guint16) l);
+ }
+ else if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_UINT32))
+ {
+ if (0 <= l && l <= G_MAXUINT32)
+ variant = g_variant_new_uint32 ((guint) l);
+ }
+ else if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_UINT64))
+ {
+ if (0 <= l && l <= G_MAXUINT64)
+ variant = g_variant_new_uint64 ((guint64) l);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
+ {
+ if (0 <= l && l <= G_MAXUINT32)
+ variant = g_variant_new_handle ((guint) l);
+ }
+ else if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_INT16))
+ {
+ if (u <= G_MAXINT16)
+ variant = g_variant_new_int16 ((gint16) u);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
+ {
+ if (u <= G_MAXUINT16)
+ variant = g_variant_new_uint16 ((guint16) u);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
+ {
+ if (u <= G_MAXINT32)
+ variant = g_variant_new_int32 ((gint) u);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
+ {
+ if (u <= G_MAXUINT32)
+ variant = g_variant_new_uint32 ((guint) u);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
+ {
+ if (u <= G_MAXINT64)
+ variant = g_variant_new_int64 ((gint64) u);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
+ {
+ if (u <= G_MAXUINT64)
+ variant = g_variant_new_uint64 ((guint64) u);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
+ {
+ if (u <= G_MAXUINT32)
+ variant = g_variant_new_handle ((guint) u);
+ }
+ else if (g_variant_type_equal (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_equal (type, G_VARIANT_TYPE_INT16))
+ l = g_variant_get_int16 (variant);
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
+ l = g_variant_get_int32 (variant);
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
+ l = g_variant_get_int64 (variant);
+ else if (g_variant_type_equal (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_equal (type, G_VARIANT_TYPE_UINT16))
+ u = g_variant_get_uint16 (variant);
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
+ u = g_variant_get_uint32 (variant);
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
+ u = g_variant_get_uint64 (variant);
+ else if (g_variant_type_equal (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;
+}
+
+GVariant *
+g_settings_set_mapping (const GValue *value,
+ const GVariantType *expected_type,
+ gpointer user_data)
+{
+ gchar *type_string;
+
+ if (G_VALUE_HOLDS_BOOLEAN (value))
+ {
+ if (g_variant_type_equal (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_equal (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_equal (expected_type, G_VARIANT_TYPE_STRING))
+ return g_variant_new_string (g_value_get_string (value));
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
+ return g_variant_new_object_path (g_value_get_string (value));
+ else if (g_variant_type_equal (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;
+}
+
+gboolean
+g_settings_get_mapping (GValue *value,
+ GVariant *variant,
+ gpointer user_data)
+{
+ if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
+ {
+ if (!G_VALUE_HOLDS_BOOLEAN (value))
+ return FALSE;
+ g_value_set_boolean (value, g_variant_get_boolean (variant));
+ 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;
+}
+
+gboolean
+g_settings_mapping_is_compatible (GType gvalue_type,
+ const GVariantType *variant_type)
+{
+ gboolean ok = FALSE;
+
+ if (gvalue_type == G_TYPE_BOOLEAN)
+ ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN);
+ else if (gvalue_type == G_TYPE_CHAR ||
+ gvalue_type == G_TYPE_UCHAR)
+ ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE);
+ else if (gvalue_type == G_TYPE_INT ||
+ gvalue_type == G_TYPE_UINT ||
+ gvalue_type == G_TYPE_INT64 ||
+ gvalue_type == G_TYPE_UINT64 ||
+ gvalue_type == G_TYPE_DOUBLE)
+ ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE));
+ else if (gvalue_type == G_TYPE_STRING)
+ ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE));
+
+ return ok;
+}
diff --git a/gio/gsettings-mapping.h b/gio/gsettings-mapping.h
new file mode 100644
index 0000000..18ce318
--- /dev/null
+++ b/gio/gsettings-mapping.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2010 Novell, Inc.
+ *
+ * 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 licence, 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.
+ *
+ * Author: Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef __G_SETTINGS_MAPPING_H__
+#define __G_SETTINGS_MAPPING_H__
+
+#include <glib-object.h>
+
+G_GNUC_INTERNAL
+GVariant * g_settings_set_mapping (const GValue *value,
+ const GVariantType *expected_type,
+ gpointer user_data);
+G_GNUC_INTERNAL
+gboolean g_settings_get_mapping (GValue *value,
+ GVariant *variant,
+ gpointer user_data);
+G_GNUC_INTERNAL
+gboolean g_settings_mapping_is_compatible (GType gvalue_type,
+ const GVariantType *variant_type);
+
+#endif /* __G_SETTINGS_MAPPING_H__ */
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 92ae788..4d42838 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -1,11 +1,22 @@
/*
- * Copyright © 2009 Codethink Limited
+ * Copyright © 2009, 2010 Codethink Limited
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of version 3 of the GNU General Public License as
- * published by the Free Software Foundation.
+ * 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 licence, or (at your option) any later version.
*
- * See the included COPYING file for more information.
+ * 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.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
*/
#include "config.h"
@@ -17,6 +28,7 @@
#include "gdelayedsettingsbackend.h"
#include "gsettingsbackendinternal.h"
+#include "gsettings-mapping.h"
#include "gio-marshal.h"
#include "gsettingsschema.h"
@@ -1086,6 +1098,7 @@ typedef struct
gpointer user_data;
GDestroyNotify destroy;
+ guint writable_handler_id;
guint property_handler_id;
const GParamSpec *property;
guint key_handler_id;
@@ -1103,8 +1116,11 @@ g_settings_binding_free (gpointer data)
g_assert (!binding->running);
- if (g_signal_handler_is_connected (binding->settings,
- binding->key_handler_id))
+ if (binding->writable_handler_id)
+ g_signal_handler_disconnect (binding->settings,
+ binding->writable_handler_id);
+
+ if (binding->key_handler_id)
g_signal_handler_disconnect (binding->settings,
binding->key_handler_id);
@@ -1164,6 +1180,21 @@ g_settings_binding_key_changed (GSettings *settings,
}
static void
+g_settings_binding_writable_changed (GSettings *settings,
+ const gchar *key,
+ gpointer user_data)
+{
+ GSettingsBinding *binding = user_data;
+ gboolean writable;
+
+ g_assert (settings == binding->settings);
+ g_assert (key == binding->key);
+
+ writable = g_settings_is_writable (settings, key);
+ g_object_set (binding->object, "sensitive", writable, NULL);
+}
+
+static void
g_settings_binding_property_changed (GObject *object,
const GParamSpec *pspec,
gpointer user_data)
@@ -1195,316 +1226,6 @@ g_settings_binding_property_changed (GObject *object,
binding->running = FALSE;
}
-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)
-{
- gchar *type_string;
-
- 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
-g_settings_get_mapping (GValue *value,
- GVariant *variant,
- gpointer user_data)
-{
- if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
- {
- if (!G_VALUE_HOLDS_BOOLEAN (value))
- return FALSE;
- g_value_set_boolean (value, g_variant_get_boolean (variant));
- 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;
-}
-
/**
* g_settings_bind:
* @settings: a #GSettings object
@@ -1581,18 +1302,17 @@ g_settings_bind_with_mapping (GSettings *settings,
{
GSettingsBinding *binding;
GObjectClass *objectclass;
+ gboolean bind_sensitive;
gchar *detailed_signal;
GQuark binding_quark;
- gboolean insensitive;
objectclass = G_OBJECT_GET_CLASS (object);
- binding = g_slice_new (GSettingsBinding);
+ binding = g_slice_new0 (GSettingsBinding);
binding->settings = g_object_ref (settings);
binding->object = object;
binding->key = g_intern_string (key);
binding->property = g_object_class_find_property (objectclass, property);
- binding->running = FALSE;
binding->user_data = user_data;
binding->destroy = destroy;
binding->get_mapping = get_mapping ? get_mapping : g_settings_get_mapping;
@@ -1624,63 +1344,32 @@ g_settings_bind_with_mapping (GSettings *settings,
return;
}
- if ((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) ||
- (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET)))
+ if (((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) ||
+ (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET))) &&
+ !g_settings_mapping_is_compatible (binding->property->value_type,
+ binding->type))
{
- 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;
- }
+ 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)
+ if ((flags & G_SETTINGS_BIND_SET) &&
+ (~flags & G_SETTINGS_BIND_NO_SENSITIVITY))
{
GParamSpec *sensitive;
sensitive = g_object_class_find_property (objectclass, "sensitive");
- if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN)
- {
- insensitive = !g_settings_is_writable (settings, key);
- g_object_set (object, "sensitive", !insensitive, NULL);
- }
- else
- insensitive = FALSE;
+ bind_sensitive = sensitive && sensitive->value_type == G_TYPE_BOOLEAN;
}
else
- insensitive = FALSE;
+ bind_sensitive = FALSE;
- if (!insensitive && (flags & G_SETTINGS_BIND_SET))
+ if (flags & G_SETTINGS_BIND_SET)
{
detailed_signal = g_strdup_printf ("notify::%s", property);
binding->property_handler_id =
@@ -1697,14 +1386,29 @@ g_settings_bind_with_mapping (GSettings *settings,
if (flags & G_SETTINGS_BIND_GET)
{
- detailed_signal = g_strdup_printf ("changed::%s", key);
- binding->key_handler_id =
+ if (~flags & G_SETTINGS_BIND_GET_NO_CHANGES)
+ {
+ detailed_signal = g_strdup_printf ("changed::%s", key);
+ binding->key_handler_id =
+ g_signal_connect (settings, detailed_signal,
+ G_CALLBACK (g_settings_binding_key_changed),
+ binding);
+ g_free (detailed_signal);
+ }
+
+ g_settings_binding_key_changed (settings, binding->key, binding);
+ }
+
+ if (bind_sensitive)
+ {
+ detailed_signal = g_strdup_printf ("writable-changed::%s", key);
+ binding->writable_handler_id =
g_signal_connect (settings, detailed_signal,
- G_CALLBACK (g_settings_binding_key_changed),
+ G_CALLBACK (g_settings_binding_writable_changed),
binding);
g_free (detailed_signal);
- g_settings_binding_key_changed (settings, binding->key, binding);
+ g_settings_binding_writable_changed (settings, binding->key, binding);
}
binding_quark = g_settings_binding_quark (property);
diff --git a/gio/gsettings.h b/gio/gsettings.h
index 7902922..5a70b5d 100644
--- a/gio/gsettings.h
+++ b/gio/gsettings.h
@@ -177,7 +177,8 @@ typedef enum
G_SETTINGS_BIND_DEFAULT,
G_SETTINGS_BIND_GET = (1<<0),
G_SETTINGS_BIND_SET = (1<<1),
- G_SETTINGS_BIND_NO_SENSITIVITY = (1<<2)
+ G_SETTINGS_BIND_NO_SENSITIVITY = (1<<2),
+ G_SETTINGS_BIND_GET_NO_CHANGES = (1<<3)
} GSettingsBindFlags;
void g_settings_bind (GSettings *settings,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]