add backend setup APIs
authorRyan Lortie <desrt@desrt.ca>
Sat, 17 Apr 2010 14:26:10 +0000 (10:26 -0400)
committerRyan Lortie <desrt@desrt.ca>
Sat, 17 Apr 2010 14:26:51 +0000 (10:26 -0400)
gio/gio.symbols
gio/gkeyfilesettingsbackend.c
gio/gsettingsbackend.c
gio/gsettingsbackend.h

index 0842ade0733117b8dd74ee836d6aae177624ae33..42a569d84764be587a60ea9be9baeac2f69ff69d 100644 (file)
@@ -1343,7 +1343,12 @@ g_file_descriptor_based_get_fd
 #endif
 
 #if IN_HEADER(__G_SETTINGS_BACKEND_H__)
+#if IN_FILE(__G_KEYFILE_SETTINGS_BACKEND_C__)
+g_settings_backend_setup_keyfile
+#endif
+
 #if IN_FILE(__G_SETTINGS_BACKEND_C__)
+g_settings_backend_setup
 g_settings_backend_get_type
 g_settings_backend_changed
 g_settings_backend_keys_changed
index dddb566631f9f80f607d58a40778d124292ec61d..11cd9a2141ab7f481752cae4f59210e03a0bb0db 100644 (file)
 
 #include "gioalias.h"
 
-G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend,
-                         g_keyfile_settings_backend,
-                         G_TYPE_SETTINGS_BACKEND,
-                         g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
-                                                         g_define_type_id, "keyfile", 0))
+G_DEFINE_TYPE (GKeyfileSettingsBackend,
+               g_keyfile_settings_backend,
+               G_TYPE_SETTINGS_BACKEND)
 
 struct _GKeyfileSettingsBackendPrivate
 {
@@ -242,12 +240,6 @@ g_keyfile_settings_backend_get_writable (GSettingsBackend *backend,
   return kf_backend->priv->writable;
 }
 
-static gboolean
-g_keyfile_settings_backend_supports_context (const gchar *context)
-{
-  return TRUE;
-}
-
 static void
 g_keyfile_settings_backend_keyfile_reload (GKeyfileSettingsBackend *kf_backend)
 {
@@ -472,46 +464,6 @@ g_keyfile_settings_backend_finalize (GObject *object)
     ->finalize (object);
 }
 
-static void
-g_keyfile_settings_backend_constructed (GObject *object)
-{
-  GKeyfileSettingsBackend *kf_backend = G_KEYFILE_SETTINGS_BACKEND (object);
-  const gchar             *envvar_path;
-  gchar                   *path;
-  gchar                   *context;
-  GFile                   *file;
-
-  envvar_path = g_getenv ("GSETTINGS_KEYFILE_BACKEND_STORE");
-  if (envvar_path != NULL && envvar_path[0] != '\0')
-    path = g_strdup (envvar_path);
-  else
-    path = g_build_filename (g_get_user_config_dir (),
-                             "gsettings", "store", NULL);
-
-  context = NULL;
-  g_object_get (kf_backend, "context", &context, NULL);
-  if (context && context[0] != '\0')
-    {
-      kf_backend->priv->file_path = g_strdup_printf ("%s.%s", path, context);
-      g_free (context);
-      g_free (path);
-    }
-  else
-    kf_backend->priv->file_path = path;
-
-  file = g_file_new_for_path (kf_backend->priv->file_path);
-
-  kf_backend->priv->writable = g_keyfile_settings_backend_keyfile_writable (file);
-
-  kf_backend->priv->monitor = g_file_monitor_file (file, G_FILE_MONITOR_SEND_MOVED, NULL, NULL);
-  g_signal_connect (kf_backend->priv->monitor, "changed",
-                    (GCallback)g_keyfile_settings_backend_keyfile_changed, kf_backend);
-
-  g_object_unref (file);
-
-  g_keyfile_settings_backend_keyfile_reload (kf_backend);
-}
-
 static void
 g_keyfile_settings_backend_init (GKeyfileSettingsBackend *kf_backend)
 {
@@ -535,7 +487,6 @@ g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class)
   GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class);
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-  object_class->constructed = g_keyfile_settings_backend_constructed;
   object_class->finalize = g_keyfile_settings_backend_finalize;
 
   backend_class->read = g_keyfile_settings_backend_read;
@@ -547,7 +498,66 @@ g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class)
   /* No need to implement subscribed/unsubscribe: the only point would be to
    * stop monitoring the file when there's no GSettings anymore, which is no
    * big win. */
-  backend_class->supports_context = g_keyfile_settings_backend_supports_context;
 
   g_type_class_add_private (class, sizeof (GKeyfileSettingsBackendPrivate));
 }
+
+static GKeyfileSettingsBackend *
+g_keyfile_settings_backend_new (const gchar *filename)
+{
+  GKeyfileSettingsBackend *kf_backend;
+  GFile *file;
+
+  kf_backend = g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, NULL);
+  kf_backend->priv->file_path = g_strdup (filename);
+
+  file = g_file_new_for_path (kf_backend->priv->file_path);
+
+  kf_backend->priv->writable = g_keyfile_settings_backend_keyfile_writable (file);
+
+  kf_backend->priv->monitor = g_file_monitor_file (file, G_FILE_MONITOR_SEND_MOVED, NULL, NULL);
+  g_signal_connect (kf_backend->priv->monitor, "changed",
+                    (GCallback)g_keyfile_settings_backend_keyfile_changed, kf_backend);
+
+  g_object_unref (file);
+
+  g_keyfile_settings_backend_keyfile_reload (kf_backend);
+
+  return kf_backend;
+}
+
+/**
+ * g_settings_backend_setup_keyfile:
+ * @context: a context string (not %NULL or "")
+ * @filename: a filename
+ *
+ * Sets up a keyfile for use with #GSettings.
+ *
+ * If you create a #GSettings with its context property set to @context
+ * then the settings will be stored in the keyfile at @filename.  See
+ * g_settings_new_with_context().
+ *
+ * The keyfile must be setup before any settings objects are created
+ * for the named context.
+ *
+ * It is not possible to specify a keyfile for the default context.
+ *
+ * If the path leading up to @filename does not exist, it will be
+ * recursively created with user-only permissions.  If the keyfile is
+ * not writable, any #GSettings objects created using @context will
+ * return %FALSE for any calls to g_settings_is_writable() and any
+ * attempts to write will fail.
+ */
+void
+g_settings_backend_setup_keyfile (const gchar *context,
+                                  const gchar *filename)
+{
+  GKeyfileSettingsBackend *kf_backend;
+
+  kf_backend = g_keyfile_settings_backend_new (filename);
+  g_settings_backend_setup (context, G_SETTINGS_BACKEND (kf_backend));
+  g_object_unref (kf_backend);
+}
+
+#define __G_KEYFILE_SETTINGS_BACKEND_C__
+#include "gioaliasdef.c"
index b8bd7ea2db8ffefa73eb4255df346b37e0bef863..28bdd34cbcba07e2f6d995ad6e396535b4bd698e 100644 (file)
@@ -813,6 +813,8 @@ get_default_backend (const gchar *context)
   return g_object_new (type, "context", context, NULL);
 }
 
+static GHashTable *g_settings_backends;
+
 /*< private >
  * g_settings_backend_get_with_context:
  * @context: a context that might be used by the backend to determine
@@ -836,17 +838,16 @@ get_default_backend (const gchar *context)
 GSettingsBackend *
 g_settings_backend_get_with_context (const gchar *context)
 {
-  static GHashTable *backends;
   GSettingsBackend *backend;
 
   g_return_val_if_fail (context != NULL, NULL);
 
   _g_io_modules_ensure_extension_points_registered ();
 
-  if (!backends)
-    backends = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  if (g_settings_backends == NULL)
+    g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
 
-  backend = g_hash_table_lookup (backends, context);
+  backend = g_hash_table_lookup (g_settings_backends, context);
 
   if (!backend)
     {
@@ -855,7 +856,7 @@ g_settings_backend_get_with_context (const gchar *context)
       if (!backend)
         backend = g_null_settings_backend_new ();
 
-      g_hash_table_insert (backends, g_strdup (context), backend);
+      g_hash_table_insert (g_settings_backends, g_strdup (context), backend);
     }
 
   return g_object_ref (backend);
@@ -888,5 +889,40 @@ g_settings_backend_supports_context (const gchar *context)
   return FALSE;
 }
 
+/**
+ * g_settings_backend_setup:
+ * @context: a context string (not %NULL or "")
+ * @backend: a #GSettingsBackend
+ *
+ * Sets up @backend for use with #GSettings.
+ *
+ * If you create a #GSettings with its context property set to @context
+ * then it will use the backend given to this function.  See
+ * g_settings_new_with_context().
+ *
+ * The backend must be set up before any settings objects are created
+ * for the named context.
+ *
+ * It is not possible to specify a backend for the default context.
+ *
+ * This function takes a reference on @backend and never releases it.
+ **/
+void
+g_settings_backend_setup (const gchar      *context,
+                          GSettingsBackend *backend)
+{
+  g_return_if_fail (context[0] != '\0');
+
+  if (g_settings_backends == NULL)
+    g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
+
+  if (g_hash_table_lookup (g_settings_backends, context))
+    g_error ("A GSettingsBackend already exists for context '%s'", context);
+
+  g_hash_table_insert (g_settings_backends,
+                       g_strdup (context),
+                       g_object_ref (backend));
+}
+
 #define __G_SETTINGS_BACKEND_C__
 #include "gioaliasdef.c"
index 04848a5c9b0c75ca87c4590f2cc6556b50f84753..6aa33450d1d5b707aa7a3091fa4e82031fc570fa 100644 (file)
@@ -101,6 +101,11 @@ struct _GSettingsBackend
 
 GType                           g_settings_backend_get_type             (void);
 
+void                            g_settings_backend_setup                (const gchar         *context,
+                                                                         GSettingsBackend    *backend);
+void                            g_settings_backend_setup_keyfile        (const gchar         *context,
+                                                                         const gchar         *filename);
+
 void                            g_settings_backend_changed              (GSettingsBackend    *backend,
                                                                          const gchar         *key,
                                                                          gpointer             origin_tag);