[gnome-builder] libide/core: simplify IdeSettings



commit cf5d699e27964a49ad1dc87fa8549c3b54248bfd
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jul 26 22:06:02 2022 -0700

    libide/core: simplify IdeSettings
    
    We always use org.gnome.builer. as a prefix (except for org.gnome.builder)
    so we can codify that into our requirements here. That makes things a lot
    easier to use since we can drop all this relative path madness and
    discover app vs project settings via the presence of the schema path.

 .../org.gnome.builder.workbench.gschema.xml        |   4 +-
 src/libide/code/ide-gsettings-file-settings.c      |  15 +-
 src/libide/core/ide-context.c                      |  46 ++++-
 src/libide/core/ide-settings.c                     | 225 +++++++++------------
 src/libide/core/ide-settings.h                     |  10 +-
 5 files changed, 154 insertions(+), 146 deletions(-)
---
diff --git a/data/gsettings/org.gnome.builder.workbench.gschema.xml 
b/data/gsettings/org.gnome.builder.workbench.gschema.xml
index 3bd065627..9fac2a848 100644
--- a/data/gsettings/org.gnome.builder.workbench.gschema.xml
+++ b/data/gsettings/org.gnome.builder.workbench.gschema.xml
@@ -1,5 +1,5 @@
 <schemalist>
-  <schema id="org.gnome.builder.workbench" path="/org/gnome/builder/workbench/" 
gettext-domain="gnome-builder">
+  <schema id="org.gnome.builder.workbench" gettext-domain="gnome-builder">
     <key name="left-visible" type="b">
       <default>true</default>
       <summary>Show Left Panel</summary>
@@ -11,7 +11,6 @@
       <summary>Left Panel Position</summary>
       <description>The width in pixel units of the left panel.</description>
     </key>
-
     <key name="right-visible" type="b">
       <default>false</default>
       <summary>Show Right Panel</summary>
@@ -23,7 +22,6 @@
       <summary>Right Panel Position</summary>
       <description>The width in pixel units of the right panel.</description>
     </key>
-
     <key name="bottom-visible" type="b">
       <default>false</default>
       <summary>Show Bottom Panel</summary>
diff --git a/src/libide/code/ide-gsettings-file-settings.c b/src/libide/code/ide-gsettings-file-settings.c
index cf4288e0f..414beb570 100644
--- a/src/libide/code/ide-gsettings-file-settings.c
+++ b/src/libide/code/ide-gsettings-file-settings.c
@@ -106,9 +106,9 @@ static SettingsMapping language_mappings [] = {
 static void
 ide_gsettings_file_settings_apply (IdeGsettingsFileSettings *self)
 {
-  g_autofree gchar *relative_path = NULL;
-  g_autofree gchar *project_id = NULL;
-  const gchar *lang_id;
+  g_autofree char *project_id = NULL;
+  g_autofree char *path = NULL;
+  const char *lang_id;
   IdeContext *context;
 
   g_assert (IDE_IS_GSETTINGS_FILE_SETTINGS (self));
@@ -122,11 +122,10 @@ ide_gsettings_file_settings_apply (IdeGsettingsFileSettings *self)
 
   context = ide_object_get_context (IDE_OBJECT (self));
   project_id = ide_context_dup_project_id (context);
-  relative_path = g_strdup_printf ("/editor/language/%s/", lang_id);
-  self->language_settings = ide_settings_new (project_id,
-                                              "org.gnome.builder.editor.language",
-                                              relative_path,
-                                              FALSE);
+  path = g_strdup_printf ("/org/gnome/builder/editor/language/%s/", lang_id);
+  self->language_settings = ide_settings_new_with_path (project_id,
+                                                        "org.gnome.builder.editor.language",
+                                                        path);
 
   for (guint i = 0; i < G_N_ELEMENTS (language_mappings); i++)
     {
diff --git a/src/libide/core/ide-context.c b/src/libide/core/ide-context.c
index c813f8a1a..8365c3ee7 100644
--- a/src/libide/core/ide-context.c
+++ b/src/libide/core/ide-context.c
@@ -28,6 +28,7 @@
 
 #include "ide-context.h"
 #include "ide-context-private.h"
+#include "ide-debug.h"
 #include "ide-gsettings-action-group.h"
 #include "ide-macros.h"
 #include "ide-notifications.h"
@@ -69,6 +70,19 @@ G_DEFINE_FINAL_TYPE (IdeContext, ide_context, IDE_TYPE_OBJECT)
 
 static GParamSpec *properties [N_PROPS];
 static guint signals [N_SIGNALS];
+static const char *app_schema_ids[] = {
+  "org.gnome.builder",
+  "org.gnome.builder.code-insight",
+  "org.gnome.builder.editor",
+  "org.gnome.builder.project-tree",
+  "org.gnome.builder.spelling",
+  "org.gnome.builder.terminal",
+};
+static const char *project_schema_ids[] = {
+  "org.gnome.builder.debug",
+  "org.gnome.builder.project",
+  "org.gnome.builder.workbench",
+};
 
 static void
 ide_context_real_log (IdeContext     *self,
@@ -90,6 +104,28 @@ ide_context_repr (IdeObject *object)
                           self->project_loaded);
 }
 
+static void
+ide_context_constructed (GObject *object)
+{
+  IdeContext *self = (IdeContext *)object;
+
+  IDE_ENTRY;
+
+  G_OBJECT_CLASS (ide_context_parent_class)->constructed (object);
+
+  for (guint i = 0; i < G_N_ELEMENTS (app_schema_ids); i++)
+    {
+      g_autoptr(IdeSettings) settings = ide_settings_new (NULL, app_schema_ids[i]);
+      g_autofree char *prefix = g_strconcat ("settings.app:", app_schema_ids[i], NULL);
+
+      ide_action_muxer_insert_action_group (self->action_muxer,
+                                            prefix,
+                                            G_ACTION_GROUP (settings));
+    }
+
+  IDE_EXIT;
+}
+
 static void
 ide_context_destroy (IdeObject *object)
 {
@@ -181,6 +217,7 @@ ide_context_class_init (IdeContextClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   IdeObjectClass *i_object_class = IDE_OBJECT_CLASS (klass);
 
+  object_class->constructed = ide_context_constructed;
   object_class->finalize = ide_context_finalize;
   object_class->get_property = ide_context_get_property;
   object_class->set_property = ide_context_set_property;
@@ -402,7 +439,10 @@ ide_context_set_project_id (IdeContext *self,
   ide_object_unlock (IDE_OBJECT (self));
 
   if (register_settings)
-    ide_context_register_settings (self, "org.gnome.builder.project");
+    {
+      for (guint i = 0; i < G_N_ELEMENTS (project_schema_ids); i++)
+        ide_context_register_settings (self, project_schema_ids[i]);
+    }
 }
 
 /**
@@ -827,8 +867,8 @@ ide_context_register_settings (IdeContext *self,
   if ((muxer = ide_context_ref_action_muxer (self)) &&
       (project_id = ide_context_dup_project_id (self)))
     {
-      g_autoptr(IdeSettings) project_settings = ide_settings_new (project_id, schema_id, NULL, FALSE);
-      g_autoptr(IdeSettings) app_settings = ide_settings_new (project_id, schema_id, NULL, TRUE);
+      g_autoptr(IdeSettings) project_settings = ide_settings_new (project_id, schema_id);
+      g_autoptr(IdeSettings) app_settings = ide_settings_new (NULL, schema_id);
       g_autofree char *project_group = g_strconcat ("settings.project:", schema_id, NULL);
       g_autofree char *app_group = g_strconcat ("settings.app:", schema_id, NULL);
 
diff --git a/src/libide/core/ide-settings.c b/src/libide/core/ide-settings.c
index d0ebd72a2..b61e8fd51 100644
--- a/src/libide/core/ide-settings.c
+++ b/src/libide/core/ide-settings.c
@@ -50,10 +50,9 @@ struct _IdeSettings
 {
   GObject             parent_instance;
   IdeLayeredSettings *layered_settings;
-  char               *relative_path;
   char               *schema_id;
   char               *project_id;
-  guint               ignore_project_settings : 1;
+  char               *path;
 };
 
 static void action_group_iface_init (GActionGroupInterface *iface);
@@ -63,10 +62,9 @@ G_DEFINE_FINAL_TYPE_WITH_CODE (IdeSettings, ide_settings, G_TYPE_OBJECT,
 
 enum {
   PROP_0,
-  PROP_RELATIVE_PATH,
-  PROP_SCHEMA_ID,
-  PROP_IGNORE_PROJECT_SETTINGS,
+  PROP_PATH,
   PROP_PROJECT_ID,
+  PROP_SCHEMA_ID,
   N_PROPS
 };
 
@@ -78,39 +76,6 @@ enum {
 static GParamSpec *properties [N_PROPS];
 static guint signals [N_SIGNALS];
 
-static void
-ide_settings_set_ignore_project_settings (IdeSettings *self,
-                                          gboolean     ignore_project_settings)
-{
-  g_return_if_fail (IDE_IS_SETTINGS (self));
-
-  ignore_project_settings = !!ignore_project_settings;
-
-  if (ignore_project_settings != self->ignore_project_settings)
-    {
-      self->ignore_project_settings = ignore_project_settings;
-      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IGNORE_PROJECT_SETTINGS]);
-    }
-}
-
-static void
-ide_settings_set_relative_path (IdeSettings *self,
-                                const char  *relative_path)
-{
-  g_assert (IDE_IS_SETTINGS (self));
-  g_assert (ide_str_empty0 (relative_path) || g_str_has_suffix (relative_path, "/"));
-
-  if (relative_path && *relative_path == '/')
-    relative_path++;
-
-  if (!ide_str_equal0 (relative_path, self->relative_path))
-    {
-      g_free (self->relative_path);
-      self->relative_path = g_strdup (relative_path);
-      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RELATIVE_PATH]);
-    }
-}
-
 static void
 ide_settings_set_schema_id (IdeSettings *self,
                             const char  *schema_id)
@@ -118,12 +83,8 @@ ide_settings_set_schema_id (IdeSettings *self,
   g_assert (IDE_IS_SETTINGS (self));
   g_assert (schema_id != NULL);
 
-  if (!ide_str_equal0 (schema_id, self->schema_id))
-    {
-      g_free (self->schema_id);
-      self->schema_id = g_strdup (schema_id);
-      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SCHEMA_ID]);
-    }
+  if (ide_set_string (&self->schema_id, schema_id))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SCHEMA_ID]);
 }
 
 static void
@@ -147,44 +108,76 @@ static void
 ide_settings_constructed (GObject *object)
 {
   IdeSettings *self = (IdeSettings *)object;
+  g_autoptr(GSettingsSchema) schema = NULL;
   g_autoptr(GSettings) app_settings = NULL;
-  g_autofree char *full_path = NULL;
+  GSettingsSchemaSource *source;
+  g_autofree char *app_path = NULL;
+  g_autofree char *project_path = NULL;
+  const char *schema_path;
 
   IDE_ENTRY;
 
   G_OBJECT_CLASS (ide_settings_parent_class)->constructed (object);
 
   if (self->schema_id == NULL)
-    g_error ("You must provide IdeSettings:schema-id");
+    g_error ("You must set %s:schema-id during construction", G_OBJECT_TYPE_NAME (self));
+
+  if (!ide_str_equal0 (self->schema_id, "org.gnome.builder") &&
+      !g_str_has_prefix (self->schema_id, "org.gnome.builder."))
+    g_error ("You mus use a schema prefixed with org.gnome.builder.");
 
-  if (self->relative_path == NULL)
+  if (self->path != NULL)
     {
-      g_autoptr(GSettingsSchema) schema = NULL;
-      GSettingsSchemaSource *source;
-      const char *schema_path;
+      if (!g_str_has_prefix (self->path, "/org/gnome/builder/"))
+        g_error ("You must use a path that begins with /org/gnome/builder/");
+      else if (!g_str_has_suffix (self->path, "/"))
+        g_error ("Settings paths must end in /");
+    }
 
-      source = g_settings_schema_source_get_default ();
+  source = g_settings_schema_source_get_default ();
+  if (!(schema = g_settings_schema_source_lookup (source, self->schema_id, TRUE)))
+    g_error ("Could not locate schema %s", self->schema_id);
 
-      if (!(schema = g_settings_schema_source_lookup (source, self->schema_id, TRUE)))
-        g_error ("Could not locate schema %s", self->schema_id);
+  if ((schema_path = g_settings_schema_get_path (schema)))
+    app_path = g_strdup (schema_path);
+  else if (self->path != NULL)
+    app_path = g_strdup (self->path);
 
-      schema_path = g_settings_schema_get_path (schema);
+  if (schema_path == NULL)
+    {
+      if (!g_str_has_prefix (self->schema_id, "org.gnome.builder."))
+        g_error ("Project schemes must have a prefix of org.gnome.builder.");
+    }
 
-      if ((schema_path != NULL) && !g_str_has_prefix (schema_path, "/org/gnome/builder/"))
-        g_error ("Schema path MUST be under /org/gnome/builder/");
+  if (app_path == NULL)
+    {
+      g_autofree char *suffix = g_strdelimit (g_strdup (self->schema_id), ".", '/');
+      app_path = g_strconcat ("/", suffix, "/", NULL);
+    }
 
-      if (schema_path == NULL)
-        self->relative_path = g_strdup ("");
+  if (schema_path == NULL && self->project_id != NULL)
+    {
+      if (self->path != NULL)
+        {
+          project_path = g_strdup_printf ("/org/gnome/builder/projects/%s/%s",
+                                          self->project_id,
+                                          self->path + strlen ("/org/gnome/builder/"));
+        }
       else
-        self->relative_path = g_strdup (schema_path + strlen ("/org/gnome/builder/"));
-    }
+        {
+          g_autofree char *suffix = g_strdup (self->schema_id + strlen ("org.gnome.builder."));
+          GString *str = g_string_new ("/org/gnome/builder/projects/");
 
-  g_assert (self->relative_path != NULL);
-  g_assert (self->relative_path [0] != '/');
-  g_assert ((self->relative_path [0] == 0) || g_str_has_suffix (self->relative_path, "/"));
+          g_string_append (str, self->project_id);
+          g_string_append_c (str, '/');
+          g_string_append (str, g_strdelimit (suffix, ".", '/'));
+          g_string_append_c (str, '/');
 
-  full_path = g_strdup_printf ("/org/gnome/builder/%s", self->relative_path);
-  self->layered_settings = ide_layered_settings_new (self->schema_id, full_path);
+          project_path = g_string_free (str, FALSE);
+        }
+    }
+
+  self->layered_settings = ide_layered_settings_new (self->schema_id, app_path);
 
   g_signal_connect_object (self->layered_settings,
                            "changed",
@@ -192,20 +185,15 @@ ide_settings_constructed (GObject *object)
                            self,
                            G_CONNECT_SWAPPED);
 
-  /* Add our project relative settings */
-  if (self->ignore_project_settings == FALSE)
+  /* Add project layer if we need one */
+  if (project_path != NULL)
     {
-      g_autoptr(GSettings) project_settings = NULL;
-      g_autofree char *path = NULL;
-
-      path = g_strdup_printf ("/org/gnome/builder/projects/%s/%s",
-                              self->project_id, self->relative_path);
-      project_settings = g_settings_new_with_path (self->schema_id, path);
+      g_autoptr(GSettings) project_settings = g_settings_new_with_path (self->schema_id, project_path);
       ide_layered_settings_append (self->layered_settings, project_settings);
     }
 
   /* Add our application global (user defaults) settings */
-  app_settings = g_settings_new_with_path (self->schema_id, full_path);
+  app_settings = g_settings_new_with_path (self->schema_id, app_path);
   ide_layered_settings_append (self->layered_settings, app_settings);
 
   IDE_EXIT;
@@ -217,9 +205,10 @@ ide_settings_finalize (GObject *object)
   IdeSettings *self = (IdeSettings *)object;
 
   g_clear_object (&self->layered_settings);
-  g_clear_pointer (&self->relative_path, g_free);
+
   g_clear_pointer (&self->schema_id, g_free);
   g_clear_pointer (&self->project_id, g_free);
+  g_clear_pointer (&self->path, g_free);
 
   G_OBJECT_CLASS (ide_settings_parent_class)->finalize (object);
 }
@@ -234,6 +223,10 @@ ide_settings_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_PATH:
+      g_value_set_string (value, self->path);
+      break;
+
     case PROP_PROJECT_ID:
       g_value_set_string (value, self->project_id);
       break;
@@ -242,14 +235,6 @@ ide_settings_get_property (GObject    *object,
       g_value_set_string (value, ide_settings_get_schema_id (self));
       break;
 
-    case PROP_RELATIVE_PATH:
-      g_value_set_string (value, ide_settings_get_relative_path (self));
-      break;
-
-    case PROP_IGNORE_PROJECT_SETTINGS:
-      g_value_set_boolean (value, ide_settings_get_ignore_project_settings (self));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -265,6 +250,10 @@ ide_settings_set_property (GObject      *object,
 
   switch (prop_id)
     {
+    case PROP_PATH:
+      self->path = g_value_dup_string (value);
+      break;
+
     case PROP_PROJECT_ID:
       self->project_id = g_value_dup_string (value);
       break;
@@ -273,14 +262,6 @@ ide_settings_set_property (GObject      *object,
       ide_settings_set_schema_id (self, g_value_get_string (value));
       break;
 
-    case PROP_RELATIVE_PATH:
-      ide_settings_set_relative_path (self, g_value_get_string (value));
-      break;
-
-    case PROP_IGNORE_PROJECT_SETTINGS:
-      ide_settings_set_ignore_project_settings (self, g_value_get_boolean (value));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -296,6 +277,13 @@ ide_settings_class_init (IdeSettingsClass *klass)
   object_class->get_property = ide_settings_get_property;
   object_class->set_property = ide_settings_set_property;
 
+  properties [PROP_PATH] =
+    g_param_spec_string ("path",
+                         "Path",
+                         "The path to use for for app settings",
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
   properties [PROP_PROJECT_ID] =
     g_param_spec_string ("project-id",
                          "Project Id",
@@ -303,20 +291,6 @@ ide_settings_class_init (IdeSettingsClass *klass)
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
 
-  properties [PROP_IGNORE_PROJECT_SETTINGS] =
-    g_param_spec_boolean ("ignore-project-settings",
-                         "Ignore Project Settings",
-                         "If project settings should be ignored.",
-                         FALSE,
-                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
-
-  properties [PROP_RELATIVE_PATH] =
-    g_param_spec_string ("relative-path",
-                         "Relative Path",
-                         "Relative Path",
-                         NULL,
-                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
-
   properties [PROP_SCHEMA_ID] =
     g_param_spec_string ("schema-id",
                          "Schema ID",
@@ -345,49 +319,48 @@ ide_settings_init (IdeSettings *self)
 
 IdeSettings *
 ide_settings_new (const char *project_id,
-                  const char *schema_id,
-                  const char *relative_path,
-                  gboolean    ignore_project_settings)
+                  const char *schema_id)
 {
   IdeSettings *ret;
 
   IDE_ENTRY;
 
-  g_return_val_if_fail (project_id != NULL, NULL);
   g_return_val_if_fail (schema_id != NULL, NULL);
 
   ret = g_object_new (IDE_TYPE_SETTINGS,
                       "project-id", project_id,
-                      "ignore-project-settings", ignore_project_settings,
-                      "relative-path", relative_path,
                       "schema-id", schema_id,
                       NULL);
 
   IDE_RETURN (ret);
 }
 
-const char *
-ide_settings_get_schema_id (IdeSettings *self)
+IdeSettings *
+ide_settings_new_with_path (const char *project_id,
+                            const char *schema_id,
+                            const char *path)
 {
-  g_return_val_if_fail (IDE_IS_SETTINGS (self), NULL);
+  IdeSettings *ret;
 
-  return self->schema_id;
-}
+  IDE_ENTRY;
 
-const char *
-ide_settings_get_relative_path (IdeSettings *self)
-{
-  g_return_val_if_fail (IDE_IS_SETTINGS (self), NULL);
+  g_return_val_if_fail (schema_id != NULL, NULL);
 
-  return self->relative_path;
+  ret = g_object_new (IDE_TYPE_SETTINGS,
+                      "project-id", project_id,
+                      "schema-id", schema_id,
+                      "path", path,
+                      NULL);
+
+  IDE_RETURN (ret);
 }
 
-gboolean
-ide_settings_get_ignore_project_settings (IdeSettings *self)
+const char *
+ide_settings_get_schema_id (IdeSettings *self)
 {
-  g_return_val_if_fail (IDE_IS_SETTINGS (self), FALSE);
+  g_return_val_if_fail (IDE_IS_SETTINGS (self), NULL);
 
-  return self->ignore_project_settings;
+  return self->schema_id;
 }
 
 GVariant *
@@ -585,7 +558,7 @@ ide_settings_bind_with_mapping (IdeSettings             *self,
   g_return_if_fail (property != NULL);
 
   ide_layered_settings_bind_with_mapping (self->layered_settings, key, object, property, flags,
-                                           get_mapping, set_mapping, user_data, destroy);
+                                          get_mapping, set_mapping, user_data, destroy);
 }
 
 void
diff --git a/src/libide/core/ide-settings.h b/src/libide/core/ide-settings.h
index 91064d777..1595e4534 100644
--- a/src/libide/core/ide-settings.h
+++ b/src/libide/core/ide-settings.h
@@ -37,16 +37,14 @@ G_DECLARE_FINAL_TYPE (IdeSettings, ide_settings, IDE, SETTINGS, GObject)
 
 IDE_AVAILABLE_IN_ALL
 IdeSettings *ide_settings_new                         (const char              *project_id,
-                                                       const char              *schema_id,
-                                                       const char              *relative_path,
-                                                       gboolean                 ignore_project_settings);
+                                                       const char              *schema_id);
 IDE_AVAILABLE_IN_ALL
-const char  *ide_settings_get_relative_path           (IdeSettings             *self);
+IdeSettings *ide_settings_new_with_path               (const char              *project_id,
+                                                       const char              *schema_id,
+                                                       const char              *path);
 IDE_AVAILABLE_IN_ALL
 const char  *ide_settings_get_schema_id               (IdeSettings             *self);
 IDE_AVAILABLE_IN_ALL
-gboolean     ide_settings_get_ignore_project_settings (IdeSettings             *self);
-IDE_AVAILABLE_IN_ALL
 GVariant    *ide_settings_get_default_value           (IdeSettings             *self,
                                                        const char              *key);
 IDE_AVAILABLE_IN_ALL


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