diff --git a/gio/gsettings.c b/gio/gsettings.c index bb334ca82..f408f2a7b 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -679,32 +679,10 @@ g_settings_get_value (GSettings *settings, { const gchar *category = g_variant_get_string (value, NULL); - if (strcmp (category, "ctype") == 0) - lc_category = LC_CTYPE; - else if (strcmp (category, "numeric") == 0) - lc_category = LC_NUMERIC; + if (strcmp (category, "message") == 0) + lc_category = LC_MESSAGES; else if (strcmp (category, "time") == 0) lc_category = LC_TIME; - else if (strcmp (category, "collate") == 0) - lc_category = LC_COLLATE; - else if (strcmp (category, "monetary") == 0) - lc_category = LC_MONETARY; - else if (strcmp (category, "messages") == 0) - lc_category = LC_MESSAGES; - else if (strcmp (category, "all") == 0) - lc_category = LC_ALL; - else if (strcmp (category, "paper") == 0) - lc_category = LC_PAPER; - else if (strcmp (category, "name") == 0) - lc_category = LC_NAME; - else if (strcmp (category, "address") == 0) - lc_category = LC_ADDRESS; - else if (strcmp (category, "telephone") == 0) - lc_category = LC_TELEPHONE; - else if (strcmp (category, "measurement") == 0) - lc_category = LC_MEASUREMENT; - else if (strcmp (category, "identification") == 0) - lc_category = LC_IDENTIFICATION; else g_error ("schema requests unsupported l10n category: %s", category); diff --git a/gio/gsettings.h b/gio/gsettings.h index 180546650..17b53f13b 100644 --- a/gio/gsettings.h +++ b/gio/gsettings.h @@ -93,6 +93,10 @@ void g_settings_get (GSettin GSettings * g_settings_get_child (GSettings *settings, const gchar *name); +void g_settings_reset (GSettings *settings, + const gchar *key); +void g_settings_reset_all (GSettings *settings); + gboolean g_settings_is_writable (GSettings *settings, const gchar *name); diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c index fa4b6e66a..2202af806 100644 --- a/gio/gsettingsbackend.c +++ b/gio/gsettingsbackend.c @@ -367,12 +367,62 @@ g_settings_backend_path_writable_changed (GSettingsBackend *backend, watch->path_writable_changed (backend, path, watch->user_data); } -static gboolean -g_settings_backend_append_to_list (gpointer key, - gpointer value, - gpointer user_data) +typedef struct { - return (*((*((gchar ***) user_data))++) = key, FALSE); + gint prefix_len; + gchar *prefix; + gchar **items; +} GetKeysState; + +static gboolean +tree_get_keys (gpointer key, + gpointer value, + gpointer user_data) +{ + GetKeysState *state = user_data; + const gchar *skey = key; + gint i; + + g_return_val_if_fail (is_key (key), TRUE); + + /* calculate longest common prefix */ + if (state->prefix == NULL) + { + gchar *last_byte; + + /* first key? just take the prefix up to the last '/' */ + state->prefix = g_strdup (skey); + last_byte = strrchr (state->prefix, '/') + 1; + state->prefix_len = last_byte - state->prefix; + *last_byte = '\0'; + } + else + { + /* find the first character that does not match. we will + * definitely find one because the prefix ends in '/' and the key + * does not. also: no two keys in the tree are the same. + */ + for (i = 0; state->prefix[i] == skey[i]; i++); + + /* check if we need to shorten the prefix */ + if (state->prefix[i] != '\0') + { + /* find the nearest '/', terminate after it */ + while (state->prefix[i - 1] != '/') + i--; + + state->prefix[i] = '\0'; + state->prefix_len = i; + } + } + + + /* save the entire item into the array. + * the prefixes will be removed later. + */ + *state->items++ = key; + + return FALSE; } /** @@ -393,20 +443,21 @@ g_settings_backend_changed_tree (GSettingsBackend *backend, gpointer origin_tag) { GSettingsBackendWatch *watch; + GetKeysState state = { 0, }; gchar **list; list = g_new (gchar *, g_tree_nnodes (tree) + 1); + state.items = list; - { - gchar **ptr = list; - g_tree_foreach (tree, g_settings_backend_append_to_list, &ptr); - *ptr = NULL; + g_tree_foreach (tree, tree_get_keys, &state); + g_return_if_fail (list + g_tree_nnodes (tree) == state.items); + *state.items = NULL; - g_assert (list + g_tree_nnodes (tree) == ptr); - } + while (state.items-- != list) + *state.items += state.prefix_len; for (watch = backend->priv->watches; watch; watch = watch->next) - watch->keys_changed (backend, "/", + watch->keys_changed (backend, state.prefix, (const gchar * const *) list, origin_tag, watch->user_data); g_free (list); @@ -502,10 +553,32 @@ g_settings_backend_write_keys (GSettingsBackend *backend, ->write_keys (backend, tree, origin_tag); } +/*< private > + * g_settings_backend_reset: + * @backend: a #GSettingsBackend implementation + * @name: the name of a key or path + * @origin_tag: the origin tag + * + * "Resets" the named key or path. For a key this means that it is + * reverted to its "default" value (ie: after system-wide defaults, + * mandatory keys, etc. have been taken into account) or possibly unsets + * it. + * + * For paths, it means that every key under the path is reset. + */ +void +g_settings_backend_reset (GSettingsBackend *backend, + const gchar *name, + gpointer origin_tag) +{ + G_SETTINGS_BACKEND_GET_CLASS (backend) + ->reset (backend, name, origin_tag); +} + /*< private > * g_settings_backend_get_writable: * @backend: a #GSettingsBackend implementation - * @name: the name of a key, relative to the root of the backend + * @name: the name of a key * @returns: %TRUE if the key is writable * * Finds out if a key is available for writing to. This is the diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h index b32d91801..0938cd0b3 100644 --- a/gio/gsettingsbackend.h +++ b/gio/gsettingsbackend.h @@ -77,6 +77,9 @@ struct _GSettingsBackendClass void (*write_keys) (GSettingsBackend *backend, GTree *tree, gpointer origin_tag); + void (*reset) (GSettingsBackend *backend, + const gchar *name, + gpointer origin_tag); gboolean (*get_writable) (GSettingsBackend *backend, const gchar *name); void (*subscribe) (GSettingsBackend *backend, diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h index 4a2c105f8..c6b515a12 100644 --- a/gio/gsettingsbackendinternal.h +++ b/gio/gsettingsbackendinternal.h @@ -69,6 +69,9 @@ void g_settings_backend_write (GSettin void g_settings_backend_write_keys (GSettingsBackend *backend, GTree *tree, gpointer origin_tag); +void g_settings_backend_reset (GSettingsBackend *backend, + const gchar *name, + gpointer origin_tag); gboolean g_settings_backend_get_writable (GSettingsBackend *backend, const char *name);