mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
GSettings seems to work now
This commit is contained in:
parent
23907aaae8
commit
14173184a7
@ -83,8 +83,16 @@ settings_sources = \
|
|||||||
gvdb/gvdb-format.h \
|
gvdb/gvdb-format.h \
|
||||||
gvdb/gvdb-reader.h \
|
gvdb/gvdb-reader.h \
|
||||||
gvdb/gvdb-reader.c \
|
gvdb/gvdb-reader.c \
|
||||||
|
gdelayedsettingsbackend.h \
|
||||||
|
gdelayedsettingsbackend.c \
|
||||||
|
gmemorysettingsbackend.h \
|
||||||
|
gmemorysettingsbackend.c \
|
||||||
|
gsettingsbackend.h \
|
||||||
|
gsettingsbackend.c \
|
||||||
gsettingsschema.h \
|
gsettingsschema.h \
|
||||||
gsettingsschema.c
|
gsettingsschema.c \
|
||||||
|
gsettings.h \
|
||||||
|
gsettings.c
|
||||||
|
|
||||||
local_sources = \
|
local_sources = \
|
||||||
glocaldirectorymonitor.c \
|
glocaldirectorymonitor.c \
|
||||||
@ -257,9 +265,6 @@ libgio_2_0_la_SOURCES = \
|
|||||||
gpollfilemonitor.h \
|
gpollfilemonitor.h \
|
||||||
gresolver.c \
|
gresolver.c \
|
||||||
gseekable.c \
|
gseekable.c \
|
||||||
gdelayedsettingsbackend.c\
|
|
||||||
gsettingsbackend.c \
|
|
||||||
gmemorysettingsbackend.c\
|
|
||||||
gsimpleasyncresult.c \
|
gsimpleasyncresult.c \
|
||||||
gsocket.c \
|
gsocket.c \
|
||||||
gsocketaddress.c \
|
gsocketaddress.c \
|
||||||
|
@ -95,6 +95,7 @@
|
|||||||
#include <gio/gvolumemonitor.h>
|
#include <gio/gvolumemonitor.h>
|
||||||
#include <gio/gzlibcompressor.h>
|
#include <gio/gzlibcompressor.h>
|
||||||
#include <gio/gzlibdecompressor.h>
|
#include <gio/gzlibdecompressor.h>
|
||||||
|
#include <gio/gsettings.h>
|
||||||
|
|
||||||
#undef __GIO_GIO_H_INSIDE__
|
#undef __GIO_GIO_H_INSIDE__
|
||||||
|
|
||||||
|
848
gio/gsettings.c
Normal file
848
gio/gsettings.c
Normal file
@ -0,0 +1,848 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2009 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.
|
||||||
|
*
|
||||||
|
* See the included COPYING file for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gsettings.h"
|
||||||
|
|
||||||
|
#include "gdelayedsettingsbackend.h"
|
||||||
|
#include "gio-marshal.h"
|
||||||
|
#include "gsettingsschema.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gioalias.h"
|
||||||
|
|
||||||
|
struct _GSettingsPrivate {
|
||||||
|
GSettingsBackend *backend;
|
||||||
|
gchar *base_path;
|
||||||
|
|
||||||
|
GSettingsSchema *schema;
|
||||||
|
gchar *schema_name;
|
||||||
|
|
||||||
|
guint handler_id;
|
||||||
|
guint unapplied_handler;
|
||||||
|
gboolean locked;
|
||||||
|
gboolean delayed;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_SCHEMA_NAME,
|
||||||
|
PROP_SCHEMA,
|
||||||
|
PROP_DELAY_APPLY,
|
||||||
|
PROP_STORAGE,
|
||||||
|
PROP_BASE_PATH,
|
||||||
|
PROP_HAS_UNAPPLIED,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SIGNAL_CHANGES,
|
||||||
|
SIGNAL_CHANGED,
|
||||||
|
SIGNAL_DESTROYED,
|
||||||
|
N_SIGNALS
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint g_settings_signals[N_SIGNALS];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GSettings, g_settings, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_storage_changed (GSettingsBackend *backend,
|
||||||
|
const gchar *prefix,
|
||||||
|
gchar const * const *names,
|
||||||
|
gint n_names,
|
||||||
|
gpointer origin_tag,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GSettings *settings = G_SETTINGS (user_data);
|
||||||
|
gchar **changes;
|
||||||
|
GQuark *quarks;
|
||||||
|
gint i, c;
|
||||||
|
|
||||||
|
g_assert (settings->priv->backend == backend);
|
||||||
|
|
||||||
|
/* slow and stupid. */
|
||||||
|
changes = g_new (gchar *, n_names);
|
||||||
|
quarks = g_new (GQuark, n_names);
|
||||||
|
for (i = 0; i < n_names; i++)
|
||||||
|
changes[i] = g_strconcat (prefix, names[i], NULL);
|
||||||
|
|
||||||
|
/* check which are for us */
|
||||||
|
c = 0;
|
||||||
|
for (i = 0; i < n_names; i++)
|
||||||
|
if (g_str_has_prefix (changes[i], settings->priv->base_path))
|
||||||
|
{
|
||||||
|
const gchar *rel = changes[i] + strlen (settings->priv->base_path);
|
||||||
|
|
||||||
|
if (strchr (rel, '/') == NULL)
|
||||||
|
/* XXX also check schema to ensure it's really a key */
|
||||||
|
quarks[c++] = g_quark_from_string (rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_settings_changes (settings, quarks, c);
|
||||||
|
|
||||||
|
for (i = 0; i < n_names; i++)
|
||||||
|
g_free (changes[i]);
|
||||||
|
g_free (changes);
|
||||||
|
g_free (quarks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_settings_changes:
|
||||||
|
* @settings: a #GSettings object
|
||||||
|
* @keys: an array of #GQuark key names
|
||||||
|
* @n_keys: the length of @keys
|
||||||
|
*
|
||||||
|
* Emits the "changes" signal on a #GSettings object.
|
||||||
|
*
|
||||||
|
* It is an error to call this function with a quark in @keys that is
|
||||||
|
* not a valid key for @settings (according to its schema).
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
g_settings_changes (GSettings *settings,
|
||||||
|
const GQuark *keys,
|
||||||
|
gint n_keys)
|
||||||
|
{
|
||||||
|
g_return_if_fail (settings != NULL);
|
||||||
|
|
||||||
|
if (n_keys == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_return_if_fail (keys != NULL);
|
||||||
|
g_return_if_fail (n_keys > 0);
|
||||||
|
|
||||||
|
g_signal_emit (settings,
|
||||||
|
g_settings_signals[SIGNAL_CHANGES], 0,
|
||||||
|
keys, n_keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_real_changes (GSettings *settings,
|
||||||
|
const GQuark *keys,
|
||||||
|
gint n_keys)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_keys; i++)
|
||||||
|
g_signal_emit (settings,
|
||||||
|
g_settings_signals[SIGNAL_CHANGED],
|
||||||
|
keys[i], g_quark_to_string (keys[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_init (GSettings *settings)
|
||||||
|
{
|
||||||
|
settings->priv = G_TYPE_INSTANCE_GET_PRIVATE (settings,
|
||||||
|
G_TYPE_SETTINGS,
|
||||||
|
GSettingsPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_notify_unapplied (GSettings *settings)
|
||||||
|
{
|
||||||
|
g_object_notify (G_OBJECT (settings), "has-unapplied");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_settings_set_delay_apply (GSettings *settings,
|
||||||
|
gboolean delayed)
|
||||||
|
{
|
||||||
|
delayed = !!delayed;
|
||||||
|
|
||||||
|
if (delayed != settings->priv->delayed)
|
||||||
|
{
|
||||||
|
GSettingsBackend *backend;
|
||||||
|
|
||||||
|
if G_UNLIKELY (settings->priv->locked)
|
||||||
|
g_error ("Can only set delayed-apply attribute on "
|
||||||
|
"freshly-created GSettings instances");
|
||||||
|
|
||||||
|
g_assert (delayed);
|
||||||
|
|
||||||
|
backend = g_delayed_settings_backend_new (settings->priv->backend,
|
||||||
|
settings->priv->base_path);
|
||||||
|
g_settings_backend_subscribe (backend, "");
|
||||||
|
g_settings_backend_unsubscribe (settings->priv->backend,
|
||||||
|
settings->priv->base_path);
|
||||||
|
g_signal_handler_disconnect (settings->priv->backend,
|
||||||
|
settings->priv->handler_id);
|
||||||
|
g_object_unref (settings->priv->backend);
|
||||||
|
|
||||||
|
settings->priv->backend = backend;
|
||||||
|
settings->priv->unapplied_handler =
|
||||||
|
g_signal_connect_swapped (backend, "notify::has-unapplied",
|
||||||
|
G_CALLBACK (g_settings_notify_unapplied),
|
||||||
|
settings);
|
||||||
|
settings->priv->handler_id =
|
||||||
|
g_signal_connect (settings->priv->backend, "changed",
|
||||||
|
G_CALLBACK (g_settings_storage_changed),
|
||||||
|
settings);
|
||||||
|
|
||||||
|
g_free (settings->priv->base_path);
|
||||||
|
settings->priv->base_path = g_strdup ("");
|
||||||
|
|
||||||
|
settings->priv->delayed = TRUE;
|
||||||
|
settings->priv->locked = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_settings_get_delay_apply (GSettings *settings)
|
||||||
|
{
|
||||||
|
return settings->priv->delayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_settings_apply:
|
||||||
|
* @settings: a #GSettings instance
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
g_settings_apply (GSettings *settings)
|
||||||
|
{
|
||||||
|
if (settings->priv->delayed)
|
||||||
|
{
|
||||||
|
GDelayedSettingsBackend *delayed;
|
||||||
|
|
||||||
|
delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
|
||||||
|
g_delayed_settings_backend_apply (delayed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_settings_revert:
|
||||||
|
* @settings: a #GSettings instance
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Change notifications will be emitted for affected keys.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
g_settings_revert (GSettings *settings)
|
||||||
|
{
|
||||||
|
if (settings->priv->delayed)
|
||||||
|
{
|
||||||
|
GDelayedSettingsBackend *delayed;
|
||||||
|
|
||||||
|
delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
|
||||||
|
g_delayed_settings_backend_revert (delayed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GSettings *settings = G_SETTINGS (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SCHEMA_NAME:
|
||||||
|
g_assert (settings->priv->schema_name == NULL);
|
||||||
|
settings->priv->schema_name = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SCHEMA:
|
||||||
|
g_assert (settings->priv->schema == NULL);
|
||||||
|
settings->priv->schema = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_DELAY_APPLY:
|
||||||
|
g_settings_set_delay_apply (settings, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BASE_PATH:
|
||||||
|
settings->priv->base_path = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_STORAGE:
|
||||||
|
settings->priv->backend = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_settings_get_has_unapplied (GSettings *settings)
|
||||||
|
{
|
||||||
|
return settings->priv->delayed &&
|
||||||
|
g_delayed_settings_backend_get_has_unapplied (
|
||||||
|
G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_get_property (GObject *object, guint prop_id,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GSettings *settings = G_SETTINGS (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SCHEMA:
|
||||||
|
g_value_set_object (value, settings->priv->schema);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_HAS_UNAPPLIED:
|
||||||
|
g_value_set_boolean (value, g_settings_get_has_unapplied (settings));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GSettings *settings = G_SETTINGS (object);
|
||||||
|
|
||||||
|
g_signal_handler_disconnect (settings->priv->backend, settings->priv->handler_id);
|
||||||
|
g_object_unref (settings->priv->backend);
|
||||||
|
g_object_unref (settings->priv->schema);
|
||||||
|
g_free (settings->priv->schema_name);
|
||||||
|
g_free (settings->priv->base_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
GSettings *settings = G_SETTINGS (object);
|
||||||
|
|
||||||
|
if (settings->priv->backend == NULL)
|
||||||
|
settings->priv->backend = g_settings_backend_get_with_context (NULL);
|
||||||
|
|
||||||
|
settings->priv->handler_id =
|
||||||
|
g_signal_connect (settings->priv->backend, "changed",
|
||||||
|
G_CALLBACK (g_settings_storage_changed),
|
||||||
|
settings);
|
||||||
|
|
||||||
|
if (settings->priv->schema != NULL && settings->priv->schema_name != NULL)
|
||||||
|
g_error ("Schema and schema name specified");
|
||||||
|
|
||||||
|
if (settings->priv->schema == NULL && settings->priv->schema_name != NULL)
|
||||||
|
settings->priv->schema = g_settings_schema_new (settings->priv->schema_name);
|
||||||
|
|
||||||
|
if (settings->priv->schema == NULL)
|
||||||
|
settings->priv->schema = g_settings_schema_new ("empty");
|
||||||
|
|
||||||
|
if (settings->priv->base_path == NULL && settings->priv->schema == NULL)
|
||||||
|
g_error ("Attempting to make settings with no schema or path");
|
||||||
|
|
||||||
|
if (settings->priv->base_path != NULL && settings->priv->schema != NULL)
|
||||||
|
{
|
||||||
|
const gchar *schema_path, *given_path;
|
||||||
|
|
||||||
|
schema_path = g_settings_schema_get_path (settings->priv->schema);
|
||||||
|
given_path = settings->priv->base_path;
|
||||||
|
|
||||||
|
if (schema_path && strcmp (schema_path, given_path) != 0)
|
||||||
|
g_error ("Specified path of '%s' but schema says '%s'",
|
||||||
|
given_path, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->priv->base_path == NULL)
|
||||||
|
settings->priv->base_path = g_strdup (
|
||||||
|
g_settings_schema_get_path (settings->priv->schema));
|
||||||
|
|
||||||
|
if (settings->priv->base_path == NULL)
|
||||||
|
g_error ("No base path given and none from schema");
|
||||||
|
|
||||||
|
g_settings_backend_subscribe (settings->priv->backend,
|
||||||
|
settings->priv->base_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSettings *
|
||||||
|
g_settings_new (const gchar *schema)
|
||||||
|
{
|
||||||
|
return g_object_new (G_TYPE_SETTINGS, "schema-name", schema, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSettings *
|
||||||
|
g_settings_new_from_path (const gchar *path)
|
||||||
|
{
|
||||||
|
return g_object_new (G_TYPE_SETTINGS, "base-path", path, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static GType
|
||||||
|
g_settings_get_gtype_for_schema (GSettingsSchema *schema)
|
||||||
|
{
|
||||||
|
GVariantIter iter;
|
||||||
|
const gchar *item;
|
||||||
|
GVariant *list;
|
||||||
|
|
||||||
|
list = g_settings_schema_get_inheritance (schema);
|
||||||
|
g_variant_iter_init (&iter, list);
|
||||||
|
g_variant_unref (list);
|
||||||
|
|
||||||
|
while (g_variant_iter_next (&iter, "s", &item))
|
||||||
|
if (strcmp (item, "list") == 0)
|
||||||
|
return G_TYPE_SETTINGS_LIST;
|
||||||
|
|
||||||
|
return G_TYPE_SETTINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
GSettings *
|
||||||
|
g_settings_get_settings (GSettings *settings,
|
||||||
|
const gchar *name)
|
||||||
|
{
|
||||||
|
const gchar *schema_name;
|
||||||
|
GSettingsSchema *schema;
|
||||||
|
GSettings *child;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
schema_name = g_settings_schema_get_schema (settings->priv->schema, name);
|
||||||
|
|
||||||
|
if (schema_name == NULL)
|
||||||
|
{
|
||||||
|
schema_name = g_settings_schema_get_schema (settings->priv->schema,
|
||||||
|
"/default");
|
||||||
|
|
||||||
|
if G_UNLIKELY (schema_name == NULL)
|
||||||
|
g_error ("Schema has no child schema named '%s' and no "
|
||||||
|
"default child schema", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
schema = g_settings_schema_new (schema_name);
|
||||||
|
path = g_strdup_printf ("%s%s/", settings->priv->base_path, name);
|
||||||
|
|
||||||
|
child = g_object_new (g_settings_get_gtype_for_schema (schema),
|
||||||
|
"schema", schema,
|
||||||
|
"backend", settings->priv->backend,
|
||||||
|
"base-path", path,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_class_init (GSettingsClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
|
||||||
|
class->changes = g_settings_real_changes;
|
||||||
|
|
||||||
|
object_class->set_property = g_settings_set_property;
|
||||||
|
object_class->get_property = g_settings_get_property;
|
||||||
|
object_class->constructed = g_settings_constructed;
|
||||||
|
object_class->finalize = g_settings_finalize;
|
||||||
|
|
||||||
|
g_type_class_add_private (object_class, sizeof (GSettingsPrivate));
|
||||||
|
|
||||||
|
g_settings_signals[SIGNAL_CHANGES] =
|
||||||
|
g_signal_new ("changes", G_TYPE_SETTINGS,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GSettingsClass, changes),
|
||||||
|
NULL, NULL,
|
||||||
|
_gio_marshal_VOID__POINTER_INT,
|
||||||
|
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT);
|
||||||
|
|
||||||
|
g_settings_signals[SIGNAL_CHANGED] =
|
||||||
|
g_signal_new ("changed", G_TYPE_SETTINGS,
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
|
||||||
|
G_STRUCT_OFFSET (GSettingsClass, changed),
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__STRING,
|
||||||
|
G_TYPE_NONE, 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
|
g_settings_signals[SIGNAL_DESTROYED] =
|
||||||
|
g_signal_new ("destroyed", G_TYPE_SETTINGS,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GSettingsClass, destroyed),
|
||||||
|
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_STORAGE,
|
||||||
|
g_param_spec_object ("backend", "backend storage",
|
||||||
|
"The GSettingsBackend object for this GSettings",
|
||||||
|
G_TYPE_SETTINGS_BACKEND, G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_NICK |
|
||||||
|
G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_SCHEMA_NAME,
|
||||||
|
g_param_spec_string ("schema-name", "schema name",
|
||||||
|
"The name of the schema for this settings object",
|
||||||
|
NULL, G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_NICK |
|
||||||
|
G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_DELAY_APPLY,
|
||||||
|
g_param_spec_boolean ("delay-apply", "delayed apply",
|
||||||
|
"If TRUE, you must call apply() to write changes",
|
||||||
|
FALSE, G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_NICK |
|
||||||
|
G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_HAS_UNAPPLIED,
|
||||||
|
g_param_spec_boolean ("has-unapplied", "has unapplied changes",
|
||||||
|
"TRUE if there are outstanding changes to apply()",
|
||||||
|
FALSE, G_PARAM_READABLE | G_PARAM_STATIC_NICK |
|
||||||
|
G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_SCHEMA,
|
||||||
|
g_param_spec_object ("schema", "schema",
|
||||||
|
"The GSettingsSchema object for this GSettings",
|
||||||
|
G_TYPE_OBJECT, G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_NICK |
|
||||||
|
G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_BASE_PATH,
|
||||||
|
g_param_spec_string ("base-path", "base path",
|
||||||
|
"the path within the backend where the settings are",
|
||||||
|
NULL, G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_NICK |
|
||||||
|
G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB));
|
||||||
|
}
|
||||||
|
|
||||||
|
GVariant *
|
||||||
|
g_settings_get_value (GSettings *settings,
|
||||||
|
const gchar *key)
|
||||||
|
{
|
||||||
|
const GVariantType *type;
|
||||||
|
const gchar *format;
|
||||||
|
GVariant *value;
|
||||||
|
GVariant *sval;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
path = g_strconcat (settings->priv->base_path, key, NULL);
|
||||||
|
sval = g_settings_schema_get_value (settings->priv->schema, key, NULL);
|
||||||
|
type = g_variant_get_type (sval);
|
||||||
|
value = g_settings_backend_read (settings->priv->backend, path, type);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
if (value && !g_variant_is_of_type (value, type))
|
||||||
|
{
|
||||||
|
g_variant_unref (value);
|
||||||
|
value = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == NULL)
|
||||||
|
value = g_variant_ref (sval);
|
||||||
|
|
||||||
|
g_variant_unref (sval);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_settings_set_value:
|
||||||
|
* @settings: a #GSettings object
|
||||||
|
* @key: the name of the key to set
|
||||||
|
* @value: a #GVariant of the correct type
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* If @value is floating then this function consumes the reference.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
g_settings_set_value (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
GVariant *value)
|
||||||
|
{
|
||||||
|
GTree *tree;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
tree = g_settings_backend_create_tree ();
|
||||||
|
path = g_strconcat (settings->priv->base_path, key, NULL);
|
||||||
|
g_tree_insert (tree, g_strdup (""), g_variant_ref_sink (value));
|
||||||
|
g_settings_backend_write (settings->priv->backend, path, tree, NULL);
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_settings_get (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
const gchar *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
GVariant *value;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
value = g_settings_get_value (settings, key);
|
||||||
|
|
||||||
|
va_start (ap, format);
|
||||||
|
g_variant_get_va (value, format, NULL, &ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
g_variant_unref (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_settings_set (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
const gchar *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
GVariant *value;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start (ap, format);
|
||||||
|
value = g_variant_new_va (format, NULL, &ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
g_settings_set_value (settings, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_settings_is_writable (GSettings *settings,
|
||||||
|
const gchar *name)
|
||||||
|
{
|
||||||
|
gboolean writable;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
path = g_strconcat (settings->priv->base_path, name, NULL);
|
||||||
|
writable = g_settings_backend_get_writable (settings->priv->backend, path);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_settings_destroy (GSettings *settings)
|
||||||
|
{
|
||||||
|
g_signal_emit (settings, g_settings_signals[SIGNAL_DESTROYED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GSettings *settings;
|
||||||
|
GObject *object;
|
||||||
|
|
||||||
|
guint property_handler_id;
|
||||||
|
const GParamSpec *property;
|
||||||
|
guint key_handler_id;
|
||||||
|
const GVariantType *type;
|
||||||
|
const gchar *key;
|
||||||
|
|
||||||
|
/* prevent recursion */
|
||||||
|
gboolean running;
|
||||||
|
} GSettingsBinding;
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_binding_free (gpointer data)
|
||||||
|
{
|
||||||
|
GSettingsBinding *binding = data;
|
||||||
|
|
||||||
|
g_assert (!binding->running);
|
||||||
|
|
||||||
|
if (binding->key_handler_id)
|
||||||
|
g_signal_handler_disconnect (binding->settings,
|
||||||
|
binding->key_handler_id);
|
||||||
|
|
||||||
|
if (binding->property_handler_id)
|
||||||
|
g_signal_handler_disconnect (binding->object,
|
||||||
|
binding->property_handler_id);
|
||||||
|
|
||||||
|
g_object_unref (binding->settings);
|
||||||
|
|
||||||
|
g_slice_free (GSettingsBinding, binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GQuark
|
||||||
|
g_settings_binding_quark (const char *property)
|
||||||
|
{
|
||||||
|
GQuark quark;
|
||||||
|
gchar *tmp;
|
||||||
|
|
||||||
|
tmp = g_strdup_printf ("gsettingsbinding-%s", property);
|
||||||
|
quark = g_quark_from_string (tmp);
|
||||||
|
g_free (tmp);
|
||||||
|
|
||||||
|
return quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_binding_key_changed (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GSettingsBinding *binding = user_data;
|
||||||
|
GValue value = { };
|
||||||
|
GVariant *variant;
|
||||||
|
|
||||||
|
g_assert (settings == binding->settings);
|
||||||
|
g_assert (key == binding->key);
|
||||||
|
|
||||||
|
if (binding->running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
binding->running = TRUE;
|
||||||
|
|
||||||
|
g_value_init (&value, binding->property->value_type);
|
||||||
|
variant = g_settings_get_value (settings, key);
|
||||||
|
if (g_value_deserialise (&value, variant))
|
||||||
|
g_object_set_property (binding->object,
|
||||||
|
binding->property->name,
|
||||||
|
&value);
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
binding->running = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_settings_binding_property_changed (GObject *object,
|
||||||
|
const GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GSettingsBinding *binding = user_data;
|
||||||
|
GValue value = { };
|
||||||
|
GVariant *variant;
|
||||||
|
|
||||||
|
g_assert (object == binding->object);
|
||||||
|
g_assert (pspec == binding->property);
|
||||||
|
|
||||||
|
if (binding->running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
binding->running = TRUE;
|
||||||
|
|
||||||
|
g_value_init (&value, pspec->value_type);
|
||||||
|
g_object_get_property (object, pspec->name, &value);
|
||||||
|
if ((variant = g_value_serialise (&value, binding->type)))
|
||||||
|
{
|
||||||
|
g_settings_set_value (binding->settings,
|
||||||
|
binding->key,
|
||||||
|
variant);
|
||||||
|
g_variant_unref (variant);
|
||||||
|
}
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
binding->running = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_settings_bind (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
gpointer object,
|
||||||
|
const gchar *property,
|
||||||
|
GSettingsBindFlags flags)
|
||||||
|
{
|
||||||
|
GSettingsBinding *binding;
|
||||||
|
GObjectClass *objectclass;
|
||||||
|
gchar *detailed_signal;
|
||||||
|
GQuark binding_quark;
|
||||||
|
gboolean insensitive;
|
||||||
|
|
||||||
|
objectclass = G_OBJECT_GET_CLASS (object);
|
||||||
|
|
||||||
|
binding = g_slice_new (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;
|
||||||
|
|
||||||
|
if (!(flags & (G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET)))
|
||||||
|
flags |= G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET;
|
||||||
|
|
||||||
|
if (binding->property == NULL)
|
||||||
|
{
|
||||||
|
g_critical ("g_settings_bind: no property '%s' on class '%s'",
|
||||||
|
property, G_OBJECT_TYPE_NAME (object));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding->type = g_settings_schema_get_key_type (settings->priv->schema,
|
||||||
|
key);
|
||||||
|
|
||||||
|
if (binding->type == NULL)
|
||||||
|
{
|
||||||
|
g_critical ("g_settings_bind: no key '%s' on schema '%s'",
|
||||||
|
key, settings->priv->schema_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (~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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
insensitive = FALSE;
|
||||||
|
|
||||||
|
if (!insensitive && (flags & G_SETTINGS_BIND_SET))
|
||||||
|
{
|
||||||
|
detailed_signal = g_strdup_printf ("notify::%s", property);
|
||||||
|
binding->property_handler_id =
|
||||||
|
g_signal_connect (object, detailed_signal,
|
||||||
|
G_CALLBACK (g_settings_binding_property_changed),
|
||||||
|
binding);
|
||||||
|
g_free (detailed_signal);
|
||||||
|
|
||||||
|
if (~flags & G_SETTINGS_BIND_GET)
|
||||||
|
g_settings_binding_property_changed (object,
|
||||||
|
binding->property,
|
||||||
|
binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & G_SETTINGS_BIND_GET)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
binding_quark = g_settings_binding_quark (property);
|
||||||
|
g_object_set_qdata_full (object, binding_quark,
|
||||||
|
binding, g_settings_binding_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_settings_unbind (gpointer object,
|
||||||
|
const gchar *property)
|
||||||
|
{
|
||||||
|
GQuark binding_quark;
|
||||||
|
|
||||||
|
binding_quark = g_settings_binding_quark (property);
|
||||||
|
g_object_set_qdata (object, binding_quark, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
114
gio/gsettings.h
Normal file
114
gio/gsettings.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2009 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.
|
||||||
|
*
|
||||||
|
* See the included COPYING file for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _gsettings_h_
|
||||||
|
#define _gsettings_h_
|
||||||
|
|
||||||
|
#include "gsettingsbackend.h"
|
||||||
|
|
||||||
|
#define G_TYPE_SETTINGS (g_settings_get_type ())
|
||||||
|
#define G_SETTINGS(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||||
|
G_TYPE_SETTINGS, GSettings))
|
||||||
|
#define G_SETTINGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
|
||||||
|
G_TYPE_SETTINGS, GSettingsClass))
|
||||||
|
#define G_IS_SETTINGS(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_SETTINGS))
|
||||||
|
#define G_IS_SETTINGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_SETTINGS))
|
||||||
|
#define G_SETTINGS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
|
||||||
|
G_TYPE_SETTINGS, GSettingsClass))
|
||||||
|
|
||||||
|
typedef struct _GSettingsPrivate GSettingsPrivate;
|
||||||
|
typedef struct _GSettingsClass GSettingsClass;
|
||||||
|
typedef struct _GSettings GSettings;
|
||||||
|
|
||||||
|
struct _GSettingsClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
|
||||||
|
GSettings * (*get_settings) (GSettings *settings,
|
||||||
|
const gchar *name);
|
||||||
|
|
||||||
|
|
||||||
|
void (*changes) (GSettings *settings,
|
||||||
|
const GQuark *keys,
|
||||||
|
gint n_keys);
|
||||||
|
void (*changed) (GSettings *settings,
|
||||||
|
const gchar *key);
|
||||||
|
void (*destroyed) (GSettings *settings);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GSettings
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
GSettingsPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
} GSettingsBindFlags;
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GType g_settings_get_type (void);
|
||||||
|
void g_settings_revert (GSettings *settings);
|
||||||
|
void g_settings_apply (GSettings *settings);
|
||||||
|
|
||||||
|
gboolean g_settings_get_delay_apply (GSettings *settings);
|
||||||
|
gboolean g_settings_get_has_unapplied (GSettings *settings);
|
||||||
|
void g_settings_set_delay_apply (GSettings *settings,
|
||||||
|
gboolean delay_apply);
|
||||||
|
gboolean g_settings_get_locked (GSettings *settings);
|
||||||
|
void g_settings_lock (GSettings *settings);
|
||||||
|
|
||||||
|
GSettings * g_settings_new (const gchar *schema);
|
||||||
|
GSettings * g_settings_new_from_path (const gchar *path);
|
||||||
|
|
||||||
|
void g_settings_set_value (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
GVariant *value);
|
||||||
|
|
||||||
|
GVariant * g_settings_get_value (GSettings *settings,
|
||||||
|
const gchar *key);
|
||||||
|
|
||||||
|
void g_settings_set (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
const gchar *format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
void g_settings_get (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
const gchar *format_string,
|
||||||
|
...);
|
||||||
|
|
||||||
|
GSettings * g_settings_get_settings (GSettings *settings,
|
||||||
|
const gchar *name);
|
||||||
|
|
||||||
|
gboolean g_settings_is_writable (GSettings *settings,
|
||||||
|
const gchar *name);
|
||||||
|
void g_settings_changes (GSettings *settings,
|
||||||
|
const GQuark *keys,
|
||||||
|
gint n_keys);
|
||||||
|
void g_settings_destroy (GSettings *settings);
|
||||||
|
|
||||||
|
void g_settings_bind (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
gpointer object,
|
||||||
|
const gchar *property,
|
||||||
|
GSettingsBindFlags flags);
|
||||||
|
void g_settings_unbind (gpointer object,
|
||||||
|
const gchar *key);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* _gsettings_h_ */
|
@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gsettingsbackend.h"
|
#include "gsettingsbackend.h"
|
||||||
|
#include "gmemorysettingsbackend.h"
|
||||||
#include "giomodule-priv.h"
|
#include "giomodule-priv.h"
|
||||||
#include "gio-marshal.h"
|
#include "gio-marshal.h"
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ G_DEFINE_ABSTRACT_TYPE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
|
|||||||
static guint changed_signal;
|
static guint changed_signal;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
PROP_ZERO,
|
||||||
PROP_CONTEXT
|
PROP_CONTEXT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -321,11 +322,20 @@ g_settings_backend_finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (g_settings_backend_parent_class)->finalize (object);
|
G_OBJECT_CLASS (g_settings_backend_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ignore_subscription (GSettingsBackend *backend,
|
||||||
|
const gchar *key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_settings_backend_class_init (GSettingsBackendClass *class)
|
g_settings_backend_class_init (GSettingsBackendClass *class)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||||
|
|
||||||
|
class->subscribe = ignore_subscription;
|
||||||
|
class->unsubscribe = ignore_subscription;
|
||||||
|
|
||||||
gobject_class->get_property = g_settings_backend_get_property;
|
gobject_class->get_property = g_settings_backend_get_property;
|
||||||
gobject_class->set_property = g_settings_backend_set_property;
|
gobject_class->set_property = g_settings_backend_set_property;
|
||||||
gobject_class->finalize = g_settings_backend_finalize;
|
gobject_class->finalize = g_settings_backend_finalize;
|
||||||
@ -485,6 +495,13 @@ g_settings_backend_get_with_context (const gchar *context)
|
|||||||
static GHashTable *backends;
|
static GHashTable *backends;
|
||||||
GSettingsBackend *backend;
|
GSettingsBackend *backend;
|
||||||
|
|
||||||
|
_g_io_modules_ensure_extension_points_registered ();
|
||||||
|
G_TYPE_MEMORY_SETTINGS_BACKEND;
|
||||||
|
|
||||||
|
/* FIXME: hash null properly? */
|
||||||
|
if (!context)
|
||||||
|
context = "";
|
||||||
|
|
||||||
if (!backends)
|
if (!backends)
|
||||||
backends = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
backends = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ g_settings_schema_class_init (GSettingsSchemaClass *class)
|
|||||||
GSettingsSchema *
|
GSettingsSchema *
|
||||||
g_settings_schema_new (const gchar *name)
|
g_settings_schema_new (const gchar *name)
|
||||||
{
|
{
|
||||||
GSettingsSchema *schema = NULL;
|
GSettingsSchema *schema;
|
||||||
GvdbTable *table = NULL;
|
GvdbTable *table = NULL;
|
||||||
GSList *source;
|
GSList *source;
|
||||||
|
|
||||||
@ -108,12 +108,12 @@ g_settings_schema_new (const gchar *name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table != NULL)
|
if (table == NULL)
|
||||||
{
|
g_error ("Settings schema '%s' is not installed\n", name);
|
||||||
schema = g_object_new (G_TYPE_SETTINGS_SCHEMA, NULL);
|
|
||||||
schema->priv->name = g_strdup (name);
|
schema = g_object_new (G_TYPE_SETTINGS_SCHEMA, NULL);
|
||||||
schema->priv->table = table;
|
schema->priv->name = g_strdup (name);
|
||||||
}
|
schema->priv->table = table;
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
@ -125,3 +125,22 @@ g_settings_schema_get_value (GSettingsSchema *schema,
|
|||||||
{
|
{
|
||||||
return gvdb_table_get_value (schema->priv->table, key, options);
|
return gvdb_table_get_value (schema->priv->table, key, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
g_settings_schema_get_path (GSettingsSchema *schema)
|
||||||
|
{
|
||||||
|
const gchar *result;
|
||||||
|
GVariant *value;
|
||||||
|
|
||||||
|
value = gvdb_table_get_value (schema->priv->table, ".path", NULL);
|
||||||
|
|
||||||
|
if (value && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||||
|
{
|
||||||
|
result = g_variant_get_string (value, NULL);
|
||||||
|
g_variant_unref (value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = NULL;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -53,7 +53,11 @@ struct _GSettingsSchema
|
|||||||
GSettingsSchemaPrivate *priv;
|
GSettingsSchemaPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
GSettingsSchema * g_settings_schema_new (const gchar *name);
|
GSettingsSchema * g_settings_schema_new (const gchar *name);
|
||||||
|
const gchar * g_settings_schema_get_path (GSettingsSchema *schema);
|
||||||
|
GVariant * g_settings_schema_get_value (GSettingsSchema *schema,
|
||||||
|
const gchar *key,
|
||||||
|
GVariant **options);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -224,6 +224,7 @@ gvdb_table_lookup (GvdbTable *file,
|
|||||||
{
|
{
|
||||||
guint32 hash_value = 5381;
|
guint32 hash_value = 5381;
|
||||||
guint key_length;
|
guint key_length;
|
||||||
|
guint32 lastno;
|
||||||
guint32 itemno;
|
guint32 itemno;
|
||||||
|
|
||||||
if G_UNLIKELY (file->n_buckets == 0 || file->n_hash_items == 0)
|
if G_UNLIKELY (file->n_buckets == 0 || file->n_hash_items == 0)
|
||||||
@ -236,20 +237,21 @@ gvdb_table_lookup (GvdbTable *file,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
itemno = file->hash_buckets[hash_value % file->n_buckets];
|
itemno = file->hash_buckets[hash_value % file->n_buckets];
|
||||||
hash_value &= ~(1u << 31);
|
|
||||||
|
|
||||||
while G_LIKELY (itemno < file->n_hash_items)
|
if (hash_value % file->n_buckets != file->n_buckets - 1)
|
||||||
|
lastno = file->hash_buckets[hash_value % file->n_buckets + 1];
|
||||||
|
else
|
||||||
|
lastno = file->n_hash_items;
|
||||||
|
|
||||||
|
while G_LIKELY (itemno < lastno)
|
||||||
{
|
{
|
||||||
struct gvdb_hash_item *item = &file->hash_items[itemno];
|
struct gvdb_hash_item *item = &file->hash_items[itemno];
|
||||||
|
|
||||||
if (hash_value == (guint32_from_le (item->hash_value) & ~(1u << 31)))
|
if (hash_value == guint32_from_le (item->hash_value))
|
||||||
if G_LIKELY (gvdb_table_check_name (file, item, key, key_length))
|
if G_LIKELY (gvdb_table_check_name (file, item, key, key_length))
|
||||||
if G_LIKELY (item->type == type)
|
if G_LIKELY (item->type == type)
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
if (guint32_from_le (item->hash_value) & (1u << 31))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
itemno++;
|
itemno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
gio/tests/.gitignore
vendored
1
gio/tests/.gitignore
vendored
@ -11,6 +11,7 @@ filter-streams
|
|||||||
g-file
|
g-file
|
||||||
g-file-info
|
g-file-info
|
||||||
g-icon
|
g-icon
|
||||||
|
gsettings
|
||||||
httpd
|
httpd
|
||||||
live-g-file
|
live-g-file
|
||||||
memory-input-stream
|
memory-input-stream
|
||||||
|
@ -32,7 +32,8 @@ TEST_PROGS += \
|
|||||||
filter-streams \
|
filter-streams \
|
||||||
simple-async-result \
|
simple-async-result \
|
||||||
srvtarget \
|
srvtarget \
|
||||||
contexts
|
contexts \
|
||||||
|
gsettings
|
||||||
|
|
||||||
SAMPLE_PROGS = \
|
SAMPLE_PROGS = \
|
||||||
resolver \
|
resolver \
|
||||||
@ -133,4 +134,6 @@ contexts_SOURCES = contexts.c
|
|||||||
contexts_LDADD = $(progs_ldadd) \
|
contexts_LDADD = $(progs_ldadd) \
|
||||||
$(top_builddir)/gthread/libgthread-2.0.la
|
$(top_builddir)/gthread/libgthread-2.0.la
|
||||||
|
|
||||||
|
gsettings_LDADD = $(progs_ldadd)
|
||||||
|
|
||||||
DISTCLEAN_FILES = applications/mimeinfo.cache
|
DISTCLEAN_FILES = applications/mimeinfo.cache
|
||||||
|
25
gio/tests/gsettings.c
Normal file
25
gio/tests/gsettings.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <gio.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
GSettings *settings;
|
||||||
|
gchar *str = NULL;
|
||||||
|
|
||||||
|
g_type_init ();
|
||||||
|
|
||||||
|
settings = g_settings_new ("org.gtk.test");
|
||||||
|
|
||||||
|
g_settings_get (settings, "greeting", "s", &str);
|
||||||
|
g_print ("it was '%s'\n", str);
|
||||||
|
|
||||||
|
g_settings_set (settings, "greeting", "s", "goodbye world");
|
||||||
|
|
||||||
|
g_settings_get (settings, "greeting", "s", &str);
|
||||||
|
g_print ("it is now '%s'\n", str);
|
||||||
|
|
||||||
|
g_settings_set (settings, "greeting", "i", 555);
|
||||||
|
|
||||||
|
g_settings_get (settings, "greeting", "s", &str);
|
||||||
|
g_print ("finally, it is '%s'\n", str);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user