diff --git a/gio/gsettings.c b/gio/gsettings.c index 80bb87b0d..676d979ec 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -224,20 +224,6 @@ settings_backend_keys_changed (GSettingsBackend *backend, } } -static void -settings_backend_path_writable_changed (GSettingsBackend *backend, - const gchar *path, - gpointer user_data) -{ - GSettings *settings = G_SETTINGS (user_data); - - g_assert (settings->priv->backend == backend); - - if (g_str_has_prefix (settings->priv->path, path)) - g_signal_emit (settings, - g_settings_signals[SIGNAL_ALL_WRITABLE_CHANGED], 0); -} - static void settings_backend_writable_changed (GSettingsBackend *backend, const gchar *key, @@ -253,14 +239,82 @@ settings_backend_writable_changed (GSettingsBackend *backend, if (settings->priv->path[i] == '\0' && g_settings_schema_has_key (settings->priv->schema, key + i)) { + const gchar *string; GQuark quark; + string = g_quark_to_string (quark); + quark = g_quark_from_string (key + i); + g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], + quark, string); + + /* if 'writeable' changes the key value may change as a + * side-effect (consider the admin setting a mandatory key over + * top of an existing key). so, signal that possibility. + */ g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], - quark, g_quark_to_string (quark)); + quark, string); } } +static void +settings_backend_path_writable_changed (GSettingsBackend *backend, + const gchar *path, + gpointer user_data) +{ + GSettings *settings = G_SETTINGS (user_data); + + g_assert (settings->priv->backend == backend); + + if (g_str_has_prefix (settings->priv->path, path)) + { + g_signal_emit (settings, + g_settings_signals[SIGNAL_ALL_WRITABLE_CHANGED], 0); + g_signal_emit (settings, g_settings_signals[SIGNAL_ALL_CHANGED], 0); + } +} + + +static void +real_all_writable_changed (GSettings *settings) +{ + const GQuark *list; + gint n_items; + gint i; + + list = g_settings_schema_list (settings->priv->schema, &n_items); + + for (i = 0; i < n_items; i++) + g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], + list[i], g_quark_to_string (list[i])); +} + +static void +real_all_changed (GSettings *settings) +{ + const GQuark *list; + gint n_items; + gint i; + + list = g_settings_schema_list (settings->priv->schema, &n_items); + + for (i = 0; i < n_items; i++) + g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], + list[i], g_quark_to_string (list[i])); +} + +static void +real_keys_changed (GSettings *settings, + const GQuark *items, + gint n_items) +{ + gint i; + + for (i = 0; i < n_items; i++) + g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], + items[i], g_quark_to_string (items[i])); +} + static void g_settings_constructed (GObject *object) { @@ -500,14 +554,10 @@ static void g_settings_class_init (GSettingsClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); -/* - class->all_writable_changed = g_settings_real_all_writable_changed; - class->all_changed = g_settings_real_all_changed; - class->keys_changed = g_settings_real_keys_changed; - class->writable_changed = g_settings_real_writable_changed; - class->changed = g_settings_real_changed; - class->destroyed = g_settings_real_destroyed; -*/ + class->all_writable_changed = real_all_writable_changed; + class->all_changed = real_all_changed; + class->keys_changed = real_keys_changed; + object_class->set_property = g_settings_set_property; object_class->get_property = g_settings_get_property; object_class->constructed = g_settings_constructed; diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c index 188201d37..af2c7d8fe 100644 --- a/gio/gsettingsschema.c +++ b/gio/gsettingsschema.c @@ -30,6 +30,8 @@ struct _GSettingsSchemaPrivate { const gchar *gettext_domain; const gchar *path; + GQuark *items; + gint n_items; GvdbTable *table; gchar *name; }; @@ -86,6 +88,7 @@ g_settings_schema_finalize (GObject *object) GSettingsSchema *schema = G_SETTINGS_SCHEMA (object); gvdb_table_unref (schema->priv->table); + g_free (schema->priv->items); g_free (schema->priv->name); G_OBJECT_CLASS (g_settings_schema_parent_class) @@ -203,3 +206,32 @@ g_settings_schema_has_key (GSettingsSchema *schema, { return gvdb_table_has_value (schema->priv->table, key); } + +const GQuark * +g_settings_schema_list (GSettingsSchema *schema, + gint *n_items) +{ + gint i, j; + + if (schema->priv->items == NULL) + { + gchar **list; + gint len; + + list = gvdb_table_list (schema->priv->table, ""); + len = g_strv_length (list); + + schema->priv->items = g_new (GQuark, len); + j = 0; + + for (i = 0; i < len; i++) + if (list[i][0] != '.') + schema->priv->items[j++] = g_quark_from_string (list[i]); + schema->priv->n_items = j; + + g_strfreev (list); + } + + *n_items = schema->priv->n_items; + return schema->priv->items; +} diff --git a/gio/gsettingsschema.h b/gio/gsettingsschema.h index a1a2d26f6..f99637033 100644 --- a/gio/gsettingsschema.h +++ b/gio/gsettingsschema.h @@ -61,6 +61,8 @@ GVariant * g_settings_schema_get_value (GSettin GVariant **options); gboolean g_settings_schema_has_key (GSettingsSchema *schema, const gchar *key); +const GQuark * g_settings_schema_list (GSettingsSchema *schema, + gint *n_items); G_END_DECLS