[glib/new-gsettings] add reset virtual method



commit d04bc3b39dabd72b3d84b9fbca9471dbce639c21
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu Apr 15 09:56:54 2010 -0400

    add reset virtual method

 gio/gsettings.c                |   26 +----------
 gio/gsettings.h                |    4 ++
 gio/gsettingsbackend.c         |   97 +++++++++++++++++++++++++++++++++++-----
 gio/gsettingsbackend.h         |    3 +
 gio/gsettingsbackendinternal.h |    3 +
 5 files changed, 97 insertions(+), 36 deletions(-)
---
diff --git a/gio/gsettings.c b/gio/gsettings.c
index bb334ca..f408f2a 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 1805466..17b53f1 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 fa4b6e6..2202af8 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);
 }
 
+typedef struct
+{
+  gint prefix_len;
+  gchar *prefix;
+  gchar **items;
+} GetKeysState;
+
 static gboolean
-g_settings_backend_append_to_list (gpointer key,
-                                   gpointer value,
-                                   gpointer user_data)
+tree_get_keys (gpointer key,
+               gpointer value,
+               gpointer user_data)
 {
-  return (*((*((gchar ***) user_data))++) = key, FALSE);
+  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);
@@ -503,9 +554,31 @@ g_settings_backend_write_keys (GSettingsBackend *backend,
 }
 
 /*< 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 b32d918..0938cd0 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 4a2c105..c6b515a 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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]