#include <string.h>
-#include "gioalias.h"
#include "strinfo.c"
* <choice value='Joe'/>
* </choices>
* <aliases>
- * <alias value="Annabeth" alias="Anna"/>
- * <alias value="Elisabeth" alias="Beth"/>
+ * <alias value='Anna' target='Annabeth'/>
+ * <alias value='Beth' target='Elisabeth'/>
* </aliases>
* <default>'Joe'</default>
* </key>
*
- * <key name="enumerated-key" enum="myenum">
+ * <key name='enumerated-key' enum='myenum'>
* <default>'first'</default>
* </key>
*
GSettingsBackend *backend;
GSettingsSchema *schema;
gchar *schema_name;
- gchar *context;
gchar *path;
GDelayedSettingsBackend *delayed;
enum
{
PROP_0,
- PROP_BACKEND,
PROP_SCHEMA,
- PROP_CONTEXT,
+ PROP_BACKEND,
PROP_PATH,
PROP_HAS_UNAPPLIED,
};
settings->priv->path = g_value_dup_string (value);
break;
- case PROP_CONTEXT:
- settings->priv->context = g_value_dup_string (value);
+ case PROP_BACKEND:
+ settings->priv->backend = g_value_dup_object (value);
break;
default:
switch (prop_id)
{
case PROP_SCHEMA:
- g_value_set_object (value, settings->priv->schema);
+ g_value_set_string (value, settings->priv->schema_name);
break;
case PROP_HAS_UNAPPLIED:
settings->priv->path = g_strdup (schema_path);
}
- settings->priv->backend = g_settings_backend_get_with_context (settings->priv->context);
+ if (settings->priv->backend == NULL)
+ settings->priv->backend = g_settings_backend_get_default ();
+
g_settings_backend_watch (settings->priv->backend, G_OBJECT (settings),
settings->priv->main_context,
settings_backend_changed,
g_object_unref (settings->priv->backend);
g_object_unref (settings->priv->schema);
g_free (settings->priv->schema_name);
- g_free (settings->priv->context);
g_free (settings->priv->path);
}
*
* The name of the context that the settings are stored in.
*/
- g_object_class_install_property (object_class, PROP_CONTEXT,
- g_param_spec_string ("context",
- P_("Context name"),
- P_("The name of the context for this settings object"),
- "", G_PARAM_CONSTRUCT_ONLY |
+ g_object_class_install_property (object_class, PROP_BACKEND,
+ g_param_spec_object ("backend",
+ P_("GSettingsBackend"),
+ P_("The GSettingsBackend for this settings object"),
+ G_TYPE_SETTINGS_BACKEND, G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
}
/**
- * g_settings_new_with_context:
+ * g_settings_new_with_backend:
* @schema: the name of the schema
- * @context: the context to use
+ * @backend: the #GSettingsBackend to use
* @returns: a new #GSettings object
*
- * Creates a new #GSettings object with a given schema and context.
+ * Creates a new #GSettings object with a given schema and backend.
*
- * Creating settings objects with a context allow accessing settings
+ * Creating settings objects with an different backend allows accessing settings
* from a database other than the usual one. For example, it may make
- * sense to specify "defaults" in order to get a settings object that
- * modifies the system default settings instead of the settings for this
- * user.
- *
- * It is a programmer error to call this function for an unsupported
- * context. Use g_settings_supports_context() to determine if a context
- * is supported if you are unsure.
+ * sense to pass a backend corresponding to the "defaults" settings database on
+ * the system to get a settings object that modifies the system default
+ * settings instead of the settings for this user.
*
* Since: 2.26
*/
GSettings *
-g_settings_new_with_context (const gchar *schema,
- const gchar *context)
+g_settings_new_with_backend (const gchar *schema,
+ GSettingsBackend *backend)
{
g_return_val_if_fail (schema != NULL, NULL);
- g_return_val_if_fail (context != NULL, NULL);
+ g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
return g_object_new (G_TYPE_SETTINGS,
"schema", schema,
- "context", context,
+ "backend", backend,
NULL);
}
/**
- * g_settings_new_with_context_and_path:
+ * g_settings_new_with_backend_and_path:
* @schema: the name of the schema
+ * @backend: the #GSettingsBackend to use
* @path: the path to use
* @returns: a new #GSettings object
*
- * Creates a new #GSettings object with a given schema, context and
+ * Creates a new #GSettings object with a given schema, backend and
* path.
*
- * This is a mix of g_settings_new_with_context() and
+ * This is a mix of g_settings_new_with_backend() and
* g_settings_new_with_path().
*
* Since: 2.26
*/
GSettings *
-g_settings_new_with_context_and_path (const gchar *schema,
- const gchar *context,
- const gchar *path)
+g_settings_new_with_backend_and_path (const gchar *schema,
+ GSettingsBackend *backend,
+ const gchar *path)
{
g_return_val_if_fail (schema != NULL, NULL);
- g_return_val_if_fail (context != NULL, NULL);
+ g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
g_return_val_if_fail (path != NULL, NULL);
return g_object_new (G_TYPE_SETTINGS,
"schema", schema,
- "context", context,
- "path", path,
- NULL);
+ "backend", backend,
+ "path", path,
+ NULL);
}
-/* Internal read/write utilities, enum conversion, validation {{{1 */
+/* Internal read/write utilities, enum/flags conversion, validation {{{1 */
typedef struct
{
GSettings *settings;
GSettingsSchema *schema;
- gboolean is_enum;
+ guint is_flags : 1;
+ guint is_enum : 1;
+
const guint32 *strinfo;
gsize strinfo_length;
info->default_value = g_variant_iter_next_value (iter);
info->type = g_variant_get_type (info->default_value);
- info->schema = settings->priv->schema;
- info->settings = settings;
- info->key = key;
+ info->settings = g_object_ref (settings);
+ info->key = g_intern_string (key);
while (g_variant_iter_next (iter, "(y*)", &code, &data))
{
break;
case 'e':
- /* enumerated types, ... */
+ /* enumerated types... */
info->is_enum = TRUE;
- case 'c':
+ goto choice;
+
+ case 'f':
+ /* flags... */
+ info->is_flags = TRUE;
+ goto choice;
+
+ choice: case 'c':
/* ..., choices, aliases */
info->strinfo = g_variant_get_fixed_array (data,
&info->strinfo_length,
g_variant_unref (info->maximum);
g_variant_unref (info->default_value);
+ g_object_unref (info->settings);
}
static gboolean
g_variant_iter_init (&iter, value);
while (ok && (child = g_variant_iter_next_value (&iter)))
{
- ok = g_settings_range_check (info, value);
+ ok = g_settings_range_check (info, child);
g_variant_unref (child);
}
GVariantIter iter;
GVariant *child;
+ g_variant_iter_init (&iter, value);
g_variant_builder_init (&builder, g_variant_get_type (value));
while ((child = g_variant_iter_next_value (&iter)))
/* translation not requested for this key */
return NULL;
- domain = g_settings_schema_get_gettext_domain (info->schema);
+ domain = g_settings_schema_get_gettext_domain (info->settings->priv->schema);
if (info->lc_char == 't')
translated = g_dcgettext (domain, info->unparsed, LC_TIME);
if (string == NULL)
return NULL;
- return g_variant_ref_sink (g_variant_new_string (string));
+ return g_variant_new_string (string);
}
-/* Public Get/Set API {{{1 (get, get_value, set, set_value) */
+static guint
+g_settings_to_flags (GSettingsKeyInfo *info,
+ GVariant *value)
+{
+ GVariantIter iter;
+ const gchar *flag;
+ guint result;
+
+ result = 0;
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "&s", &flag))
+ {
+ gboolean it_worked;
+ guint flag_value;
+
+ it_worked = strinfo_enum_from_string (info->strinfo,
+ info->strinfo_length,
+ flag, &flag_value);
+ /* as in g_settings_to_enum() */
+ g_assert (it_worked);
+
+ result |= flag_value;
+ }
+
+ return result;
+}
+
+static GVariant *
+g_settings_from_flags (GSettingsKeyInfo *info,
+ guint value)
+{
+ GVariantBuilder builder;
+ gint i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+
+ for (i = 0; i < 32; i++)
+ if (value & (1u << i))
+ {
+ const gchar *string;
+
+ string = strinfo_string_from_enum (info->strinfo,
+ info->strinfo_length,
+ 1u << i);
+
+ if (string == NULL)
+ {
+ g_variant_builder_clear (&builder);
+ return NULL;
+ }
+
+ g_variant_builder_add (&builder, "s", string);
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
/**
* g_settings_get_value:
* @settings: a #GSettings object
*
* Gets the value that is stored in @settings for @key.
*
- * It is a programmer error to give a @key that isn't valid for
- * @settings.
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings.
*
* Since: 2.26
*/
* In order to use this function the type of the value must be a string
* and it must be marked in the schema file as an enumerated type.
*
- * It is a programmer error to give a @key that isn't valid for
- * @settings, or is not marked as an enumerated type in the schema.
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or is not marked as an enumerated type.
*
* If the value stored in the configuration database is not a valid
* value for the enumerated type then this function will return the
* @settings: a #GSettings object
* @key: a key, within @settings
* @value: an enumerated value
- * Returns: %TRUE, if the set succeeds
+ * @returns: %TRUE, if the set succeeds
*
* Looks up the enumerated type nick for @value and writes it to @key,
* within @settings.
*
- * It is a programmer error for @key to not be listed in the schema or
- * for it not to be tagged as an enumerated type, or for @value not to
- * be a valid value for the named type.
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or is not marked as an enumerated type, or for
+ * @value not to be a valid value for the named type.
*
- * After performing the write, accessing @key directly
+ * After performing the write, accessing @key directly with
* g_settings_get_string() will return the 'nick' associated with
* @value.
**/
success = g_settings_write_to_backend (&info, variant);
g_settings_free_key_info (&info);
- g_variant_unref (variant);
+
+ return success;
+}
+
+/**
+ * g_settings_get_flags:
+ * @settings: a #GSettings object
+ * @key: the key to get the value for
+ * @returns: the flags value
+ *
+ * Gets the value that is stored in @settings for @key and converts it
+ * to the flags value that it represents.
+ *
+ * In order to use this function the type of the value must be an array
+ * of strings and it must be marked in the schema file as an flags type.
+ *
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or is not marked as a flags type.
+ *
+ * If the value stored in the configuration database is not a valid
+ * value for the flags type then this function will return the default
+ * value.
+ *
+ * Since: 2.26
+ **/
+guint
+g_settings_get_flags (GSettings *settings,
+ const gchar *key)
+{
+ GSettingsKeyInfo info;
+ GVariant *value;
+ guint result;
+
+ g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
+ g_return_val_if_fail (key != NULL, -1);
+
+ g_settings_get_key_info (&info, settings, key);
+
+ if (!info.is_flags)
+ {
+ g_critical ("g_settings_get_flags() called on key `%s' which is not "
+ "associated with a flags type", info.key);
+ g_settings_free_key_info (&info);
+ return -1;
+ }
+
+ value = g_settings_read_from_backend (&info);
+
+ if (value == NULL)
+ value = g_settings_get_translated_default (&info);
+
+ if (value == NULL)
+ value = g_variant_ref (info.default_value);
+
+ result = g_settings_to_flags (&info, value);
+ g_settings_free_key_info (&info);
+ g_variant_unref (value);
+
+ return result;
+}
+
+/**
+ * g_settings_set_flags:
+ * @settings: a #GSettings object
+ * @key: a key, within @settings
+ * @value: a flags value
+ * @returns: %TRUE, if the set succeeds
+ *
+ * Looks up the flags type nicks for the bits specified by @value, puts
+ * them in an array of strings and writes the array to @key, withing
+ * @settings.
+ *
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or is not marked as a flags type, or for @value
+ * to contain any bits that are not value for the named type.
+ *
+ * After performing the write, accessing @key directly with
+ * g_settings_get_strv() will return an array of 'nicks'; one for each
+ * bit in @value.
+ **/
+gboolean
+g_settings_set_flags (GSettings *settings,
+ const gchar *key,
+ guint value)
+{
+ GSettingsKeyInfo info;
+ GVariant *variant;
+ gboolean success;
+
+ g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ g_settings_get_key_info (&info, settings, key);
+
+ if (!info.is_flags)
+ {
+ g_critical ("g_settings_set_flags() called on key `%s' which is not "
+ "associated with a flags type", info.key);
+ return FALSE;
+ }
+
+ if (!(variant = g_settings_from_flags (&info, value)))
+ {
+ g_critical ("g_settings_set_flags(): invalid flags value 0x%08x "
+ "for key `%s' in schema `%s'. Doing nothing.",
+ value, info.key, info.settings->priv->schema_name);
+ g_settings_free_key_info (&info);
+ return FALSE;
+ }
+
+ success = g_settings_write_to_backend (&info, variant);
+ g_settings_free_key_info (&info);
return success;
}
*
* Sets @key in @settings to @value.
*
- * It is a programmer error to give a @key that isn't valid for
- * @settings. It is a programmer error to give a @value of the
- * incorrect type.
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or for @value to have the incorrect type, per
+ * the schema.
*
* If @value is floating then this function consumes the reference.
*
* A convenience function that combines g_settings_get_value() with
* g_variant_get().
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or a @format_string that doesn't match the type of @key according
- * to the schema of @settings.
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or for the #GVariantType of @format to mismatch
+ * the type given in the schema.
*
* Since: 2.26
*/
* A convenience function that combines g_settings_set_value() with
* g_variant_new().
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or a @format that doesn't match the type of @key according
- * to the schema of @settings.
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or for the #GVariantType of @format to mismatch
+ * the type given in the schema.
*
* Since: 2.26
*/
return g_settings_set_value (settings, key, value);
}
+/**
+ * g_settings_get_mapped:
+ * @settings: a #GSettings object
+ * @key: the key to get the value for
+ * @mapping: the function to map the value in the settings database to
+ * the value used by the application
+ * @user_data: user data for @mapping
+ *
+ * Gets the value that is stored at @key in @settings, subject to
+ * application-level validation/mapping.
+ *
+ * You should use this function when the application needs to perform
+ * some processing on the value of the key (for example, parsing). The
+ * @mapping function performs that processing. If the function
+ * indicates that the processing was unsuccessful (due to a parse error,
+ * for example) then the mapping is tried again with another value.
+
+ * This allows a robust 'fall back to defaults' behaviour to be
+ * implemented somewhat automatically.
+ *
+ * The first value that is tried is the user's setting for the key. If
+ * the mapping function fails to map this value, other values may be
+ * tried in an unspecified order (system or site defaults, translated
+ * schema default values, untranslated schema default values, etc).
+ *
+ * If the mapping function fails for all possible values, one additional
+ * attempt is made: the mapping function is called with a %NULL value.
+ * If the mapping function still indicates failure at this point then
+ * the application will be aborted.
+ *
+ * The result parameter for the @mapping function is pointed to a
+ * #gpointer which is initially set to %NULL. The same pointer is given
+ * to each invocation of @mapping. The final value of that #gpointer is
+ * what is returned by this function. %NULL is valid; it is returned
+ * just as any other value would be.
+ **/
+gpointer
+g_settings_get_mapped (GSettings *settings,
+ const gchar *key,
+ GSettingsGetMapping mapping,
+ gpointer user_data)
+{
+ gpointer result = NULL;
+ GSettingsKeyInfo info;
+ GVariant *value;
+ gboolean okay;
+
+ g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+ g_return_val_if_fail (mapping != NULL, NULL);
+
+ g_settings_get_key_info (&info, settings, key);
+
+ if ((value = g_settings_read_from_backend (&info)))
+ {
+ okay = mapping (value, &result, user_data);
+ g_variant_unref (value);
+ if (okay) goto okay;
+ }
+
+ if ((value = g_settings_get_translated_default (&info)))
+ {
+ okay = mapping (value, &result, user_data);
+ g_variant_unref (value);
+ if (okay) goto okay;
+ }
+
+ if (mapping (info.default_value, &result, user_data))
+ goto okay;
+
+ if (!mapping (NULL, &result, user_data))
+ g_error ("The mapping function given to g_settings_get_mapped() for key "
+ "`%s' in schema `%s' returned FALSE when given a NULL value.",
+ key, settings->priv->schema_name);
+
+ okay:
+ g_settings_free_key_info (&info);
+
+ return result;
+}
+
/* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */
/**
* g_settings_get_string:
*
* A convenience variant of g_settings_get() for strings.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type string.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a string type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_set() for strings.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type string.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a string type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_get() for 32-bit integers.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type int32.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a int32 type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_set() for 32-bit integers.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type int32.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a int32 type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_get() for doubles.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type double.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a 'double' type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_set() for doubles.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type double.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a 'double' type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_get() for booleans.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type boolean.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a boolean type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_set() for booleans.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type boolean.
+ * It is a programmer error to give a @key that isn't specified as
+ * having a boolean type in the schema for @settings.
*
* Since: 2.26
*/
*
* A convenience variant of g_settings_get() for string arrays.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type 'string array'.
+ * It is a programmer error to give a @key that isn't specified as
+ * having an array of strings type in the schema for @settings.
*
* Since: 2.26
*/
* A convenience variant of g_settings_set() for string arrays. If
* @value is %NULL, then @key is set to be the empty array.
*
- * It is a programmer error to pass a @key that isn't valid for
- * @settings or is not of type 'string array'.
+ * It is a programmer error to give a @key that isn't specified as
+ * having an array of strings type in the schema for @settings.
*
* Since: 2.26
*/
return g_settings_set_value (settings, key, array);
}
+
/* Delayed apply (delay, apply, revert, get_has_unapplied) {{{1 */
/**
* g_settings_delay:
*
* Applies any changes that have been made to the settings. This
* function does nothing unless @settings is in 'delay-apply' mode;
- * see g_settings_set_delay_apply(). In the normal case settings are
- * always applied immediately.
+ * see g_settings_delay(). In the normal case settings are always
+ * applied immediately.
**/
void
g_settings_apply (GSettings *settings)
*
* Reverts all non-applied changes to the settings. This function
* does nothing unless @settings is in 'delay-apply' mode; see
- * g_settings_set_delay_apply(). In the normal case settings are
- * always applied immediately.
+ * g_settings_delay(). In the normal case settings are always applied
+ * immediately.
*
* Change notifications will be emitted for affected keys.
**/
G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
}
-/* Extra API (sync, get_child, is_writable) {{{1 */
+/* Extra API (sync, get_child, is_writable, list_items) {{{1 */
/**
* g_settings_sync:
* @context: the context to sync, or %NULL
* time the call is done).
**/
void
-g_settings_sync (const gchar *context)
+g_settings_sync (void)
{
- GSettingsBackend *backend;
-
- if (context == NULL)
- context = "";
-
- backend = g_settings_backend_get_with_context (context);
- g_settings_backend_sync (backend);
+ g_settings_backend_sync_default ();
}
/**
return child;
}
+/**
+ * g_settings_list_items:
+ * @settings: a #GSettings object
+ * Returns: a list of the keys on @settings
+ *
+ * Introspects the list of keys and children on @settings.
+ *
+ * The list that is returned is a mix of the keys and children. The
+ * names of the children are suffixed with '/'. The names of the keys
+ * are not.
+ *
+ * You should probably not be calling this function from "normal" code
+ * (since you should already know what keys are in your schema). This
+ * function is intended for introspection reasons.
+ *
+ * You should free the return value with g_free() when you are done with
+ * it.
+ */
+const gchar **
+g_settings_list_items (GSettings *settings)
+{
+ const GQuark *keys;
+ const gchar **strv;
+ gint n_keys;
+ gint i;
+
+ keys = g_settings_schema_list (settings->priv->schema, &n_keys);
+ strv = g_new (const gchar *, n_keys + 1);
+ for (i = 0; i < n_keys; i++)
+ strv[i] = g_quark_to_string (keys[i]);
+ strv[i] = NULL;
+
+ return strv;
+}
+
/* Binding {{{1 */
typedef struct
{
- GSettings *settings;
+ GSettingsKeyInfo info;
GObject *object;
GSettingsBindGetMapping get_mapping;
guint property_handler_id;
const GParamSpec *property;
guint key_handler_id;
- GVariantType *type;
- const gchar *key;
/* prevent recursion */
gboolean running;
g_assert (!binding->running);
if (binding->writable_handler_id)
- g_signal_handler_disconnect (binding->settings,
+ g_signal_handler_disconnect (binding->info.settings,
binding->writable_handler_id);
if (binding->key_handler_id)
- g_signal_handler_disconnect (binding->settings,
+ g_signal_handler_disconnect (binding->info.settings,
binding->key_handler_id);
if (g_signal_handler_is_connected (binding->object,
g_signal_handler_disconnect (binding->object,
binding->property_handler_id);
- g_variant_type_free (binding->type);
- g_object_unref (binding->settings);
+ g_settings_free_key_info (&binding->info);
if (binding->destroy)
binding->destroy (binding->user_data);
GValue value = { 0, };
GVariant *variant;
- g_assert (settings == binding->settings);
- g_assert (key == binding->key);
+ g_assert (settings == binding->info.settings);
+ g_assert (key == binding->info.key);
if (binding->running)
return;
binding->running = TRUE;
g_value_init (&value, binding->property->value_type);
- variant = g_settings_get_value (settings, key);
- if (binding->get_mapping (&value, variant, binding->user_data))
- g_object_set_property (binding->object,
- binding->property->name,
- &value);
+
+ variant = g_settings_read_from_backend (&binding->info);
+ if (variant && !binding->get_mapping (&value, variant, binding->user_data))
+ {
+ /* silently ignore errors in the user's config database */
+ g_variant_unref (variant);
+ variant = NULL;
+ }
+
+ if (variant == NULL)
+ {
+ variant = g_settings_get_translated_default (&binding->info);
+ if (variant &&
+ !binding->get_mapping (&value, variant, binding->user_data))
+ {
+ /* flag translation errors with a warning */
+ g_warning ("Translated default `%s' for key `%s' in schema `%s' "
+ "was rejected by the binding mapping function",
+ binding->info.unparsed, binding->info.key,
+ binding->info.settings->priv->schema_name);
+ g_variant_unref (variant);
+ variant = NULL;
+ }
+ }
+
+ if (variant == NULL)
+ {
+ variant = g_variant_ref (binding->info.default_value);
+ if (!binding->get_mapping (&value, variant, binding->user_data))
+ g_error ("The schema default value for key `%s' in schema `%s' "
+ "was rejected by the binding mapping function.",
+ binding->info.key,
+ binding->info.settings->priv->schema_name);
+ }
+
+ g_object_set_property (binding->object, binding->property->name, &value);
g_variant_unref (variant);
g_value_unset (&value);
g_value_init (&value, pspec->value_type);
g_object_get_property (object, pspec->name, &value);
- if ((variant = binding->set_mapping (&value, binding->type,
+ if ((variant = binding->set_mapping (&value, binding->info.type,
binding->user_data)))
{
- g_settings_set_value (binding->settings,
- binding->key,
- g_variant_ref_sink (variant));
+ if (g_variant_is_floating (variant))
+ g_variant_ref_sink (variant);
+
+ if (!g_settings_type_check (&binding->info, variant))
+ {
+ g_critical ("binding mapping function for key `%s' returned "
+ "GVariant of type `%s' when type `%s' was requested",
+ binding->info.key, g_variant_get_type_string (variant),
+ g_variant_type_dup_string (binding->info.type));
+ return;
+ }
+
+ if (!g_settings_range_check (&binding->info, variant))
+ {
+ g_critical ("GObject property `%s' on a `%s' object is out of "
+ "schema-specified range for key `%s' of `%s': %s",
+ binding->property->name,
+ g_type_name (binding->property->owner_type),
+ binding->info.key,
+ binding->info.settings->priv->schema_name,
+ g_variant_print (variant, TRUE));
+ return;
+ }
+
+ g_settings_write_to_backend (&binding->info, variant);
g_variant_unref (variant);
}
g_value_unset (&value);
objectclass = G_OBJECT_GET_CLASS (object);
binding = g_slice_new0 (GSettingsBinding);
- binding->settings = g_object_ref (settings);
+ g_settings_get_key_info (&binding->info, settings, key);
binding->object = object;
- binding->key = g_intern_string (key);
binding->property = g_object_class_find_property (objectclass, property);
binding->user_data = user_data;
binding->destroy = destroy;
return;
}
- if ((flags & G_SETTINGS_BIND_GET) && (binding->property->flags & G_PARAM_WRITABLE) == 0)
- {
- g_critical ("g_settings_bind: property '%s' on class '%s' is not writable",
- property, G_OBJECT_TYPE_NAME (object));
- return;
- }
- if ((flags & G_SETTINGS_BIND_SET) && (binding->property->flags & G_PARAM_READABLE) == 0)
+ if ((flags & G_SETTINGS_BIND_GET) &&
+ (binding->property->flags & G_PARAM_WRITABLE) == 0)
{
- g_critical ("g_settings_bind: property '%s' on class '%s' is not readable",
- property, G_OBJECT_TYPE_NAME (object));
+ g_critical ("g_settings_bind: property '%s' on class '%s' is not "
+ "writable", property, G_OBJECT_TYPE_NAME (object));
return;
}
-
- {
- GVariantIter *iter;
- GVariant *value;
-
- iter = g_settings_schema_get_value (settings->priv->schema, key);
- value = g_variant_iter_next_value (iter);
- binding->type = g_variant_type_copy (g_variant_get_type (value));
- g_variant_iter_free (iter);
- g_variant_unref (value);
- }
-
- if (binding->type == NULL)
+ if ((flags & G_SETTINGS_BIND_SET) &&
+ (binding->property->flags & G_PARAM_READABLE) == 0)
{
- g_critical ("g_settings_bind: no key '%s' on schema '%s'",
- key, settings->priv->schema_name);
+ g_critical ("g_settings_bind: property '%s' on class '%s' is not "
+ "readable", property, G_OBJECT_TYPE_NAME (object));
return;
}
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))
+ binding->info.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,
+ g_variant_type_dup_string (binding->info.type), key,
settings->priv->schema_name);
return;
}
if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN &&
(sensitive->flags & G_PARAM_WRITABLE))
- g_settings_bind_writable (settings, binding->key,
+ g_settings_bind_writable (settings, binding->info.key,
object, "sensitive", FALSE);
}
g_free (detailed_signal);
}
- g_settings_binding_key_changed (settings, binding->key, binding);
+ g_settings_binding_key_changed (settings, binding->info.key, binding);
}
binding_quark = g_settings_binding_quark (property);
}
/* Epilogue {{{1 */
-#define __G_SETTINGS_C__
-#include "gioaliasdef.c"
/* vim:set foldmethod=marker: */