[gnome-builder] libide/core: make flags action more useful



commit f71baf080ce9226490fb1027976bc6338c6dac0c
Author: Christian Hergert <chergert redhat com>
Date:   Mon Aug 15 17:29:08 2022 -0700

    libide/core: make flags action more useful
    
    This allows setting paths and ensures that the change state format works
    so we can use it with check buttons.

 src/libide/core/ide-settings-flag-action.c | 217 ++++++++++++++++++-----------
 src/libide/core/ide-settings-flag-action.h |   7 +-
 2 files changed, 136 insertions(+), 88 deletions(-)
---
diff --git a/src/libide/core/ide-settings-flag-action.c b/src/libide/core/ide-settings-flag-action.c
index e50608abb..6a8d86729 100644
--- a/src/libide/core/ide-settings-flag-action.c
+++ b/src/libide/core/ide-settings-flag-action.c
@@ -29,6 +29,7 @@ struct _IdeSettingsFlagAction
 
   GSettings *settings;
 
+  char *path;
   char *schema_id;
   char *schema_key;
   char *flag_nick;
@@ -44,8 +45,9 @@ enum {
   PROP_0,
   PROP_SCHEMA_ID,
   PROP_SCHEMA_KEY,
+  PROP_PATH,
   PROP_FLAG_NICK,
-  LAST_PROP,
+  N_PROPS,
 
   PROP_ENABLED,
   PROP_NAME,
@@ -54,38 +56,132 @@ enum {
   PROP_PARAMETER_TYPE,
 };
 
-static GParamSpec *properties [LAST_PROP];
+static GParamSpec *properties [N_PROPS];
 
 /**
  * ide_settings_flag_action_new:
+ * @schema_id: the settings schema
+ * @schema_key: the flags key with in @schema_id
+ * @path: (nullable):  the path for the schema or %NULL
+ * @flag_nick: the nick within the flag to toggle
  *
  * This creates a new action that can be used to toggle an individual flag in
  * a #GSettings key which is of a flags type.
  *
- * Returns: (transfer full): A new #GAction.
+ * Returns: (transfer full): A new #IdeSettingsFlagAction
  */
-GAction *
+IdeSettingsFlagAction *
 ide_settings_flag_action_new (const char *schema_id,
                               const char *schema_key,
+                              const char *path,
                               const char *flag_nick)
 {
+  g_return_val_if_fail (schema_id != NULL, NULL);
+  g_return_val_if_fail (schema_key != NULL, NULL);
+  g_return_val_if_fail (flag_nick != NULL, NULL);
+
   return g_object_new (IDE_TYPE_SETTINGS_FLAG_ACTION,
                        "schema-id", schema_id,
                        "schema-key", schema_key,
                        "flag-nick", flag_nick,
+                       "path", path,
                        NULL);
 }
 
+static GSettings *
+ide_settings_flag_action_get_settings (IdeSettingsFlagAction *self)
+{
+  g_assert (IDE_IS_SETTINGS_FLAG_ACTION (self));
+
+  if (self->settings == NULL)
+    {
+      if (self->path)
+        self->settings = g_settings_new_with_path (self->schema_id, self->path);
+      else
+        self->settings = g_settings_new (self->schema_id);
+    }
+
+  return self->settings;
+}
+
+static const GVariantType *
+ide_settings_flag_action_get_parameter_type (GAction *action)
+{
+  return NULL;
+}
+
+static const GVariantType *
+ide_settings_flag_action_get_state_type (GAction *action)
+{
+  return G_VARIANT_TYPE_BOOLEAN;
+}
+
+static GVariant *
+ide_settings_flag_action_get_state_hint (GAction *action)
+{
+  return NULL;
+}
+
 static void
-ide_settings_flag_action_finalize (GObject *object)
+ide_settings_flag_action_change_state (GAction  *action,
+                                       GVariant *value)
+{
+  IdeSettingsFlagAction *self = IDE_SETTINGS_FLAG_ACTION (action);
+  GSettings *settings = ide_settings_flag_action_get_settings (self);
+  g_auto(GStrv) flags = g_settings_get_strv (settings, self->schema_key);
+  gboolean val = g_variant_get_boolean (value);
+
+  if (val != g_strv_contains ((const char * const *)flags, self->flag_nick))
+    {
+      g_autoptr(GPtrArray) state = g_ptr_array_new ();
+
+      for (guint i = 0; flags[i]; i++)
+        {
+          if (!val && ide_str_equal0 (flags[i], self->flag_nick))
+            continue;
+          g_ptr_array_add (state, flags[i]);
+        }
+
+      if (val)
+        g_ptr_array_add (state, self->flag_nick);
+
+      g_ptr_array_add (state, NULL);
+
+      g_settings_set_strv (settings, self->schema_key, (const char * const *)state->pdata);
+
+      g_object_notify (G_OBJECT (self), "state");
+    }
+}
+
+static GVariant *
+ide_settings_flag_action_get_state (GAction *action)
+{
+  IdeSettingsFlagAction *self = (IdeSettingsFlagAction *)action;
+  GSettings *settings = ide_settings_flag_action_get_settings (self);
+  g_auto(GStrv) flags = g_settings_get_strv (settings, self->schema_key);
+  gboolean state = g_strv_contains ((const char * const *)flags, self->flag_nick);
+
+#if 0
+  g_print ("%s[%s].%s => %d\n", self->schema_id, self->path, self->flag_nick, state);
+#endif
+
+  return g_variant_ref_sink (g_variant_new_boolean (state));
+}
+
+static void
+ide_settings_flag_action_dispose (GObject *object)
 {
   IdeSettingsFlagAction *self = (IdeSettingsFlagAction *)object;
 
+  g_clear_pointer (&self->flag_nick, g_free);
+  g_clear_pointer (&self->name, g_free);
+  g_clear_pointer (&self->path, g_free);
   g_clear_pointer (&self->schema_id, g_free);
   g_clear_pointer (&self->schema_key, g_free);
-  g_clear_pointer (&self->flag_nick, g_free);
 
-  G_OBJECT_CLASS (ide_settings_flag_action_parent_class)->finalize (object);
+  g_clear_object (&self->settings);
+
+  G_OBJECT_CLASS (ide_settings_flag_action_parent_class)->dispose (object);
 }
 
 static void
@@ -99,13 +195,17 @@ ide_settings_flag_action_get_property (GObject    *object,
   switch (prop_id)
     {
     case PROP_ENABLED:
-      g_value_set_boolean (value, self->schema_id != NULL);
+      g_value_set_boolean (value, TRUE);
       break;
 
     case PROP_SCHEMA_ID:
       g_value_set_string (value, self->schema_id);
       break;
 
+    case PROP_PATH:
+      g_value_set_string (value, self->path);
+      break;
+
     case PROP_NAME:
       g_value_set_string (value, g_action_get_name (G_ACTION (self)));
       break;
@@ -119,8 +219,15 @@ ide_settings_flag_action_get_property (GObject    *object,
       break;
 
     case PROP_STATE:
+      g_value_take_variant (value, ide_settings_flag_action_get_state (G_ACTION (self)));
+      break;
+
     case PROP_STATE_TYPE:
+      g_value_set_boxed (value, ide_settings_flag_action_get_state_type (G_ACTION (self)));
+      break;
+
     case PROP_PARAMETER_TYPE:
+      g_value_set_boxed (value, ide_settings_flag_action_get_parameter_type (G_ACTION (self)));
       break;
 
     default:
@@ -148,6 +255,11 @@ ide_settings_flag_action_set_property (GObject      *object,
       self->schema_key = g_value_dup_string (value);
       break;
 
+    case PROP_PATH:
+      g_free (self->path);
+      self->path = g_value_dup_string (value);
+      break;
+
     case PROP_FLAG_NICK:
       g_free (self->flag_nick);
       self->flag_nick = g_value_dup_string (value);
@@ -163,7 +275,7 @@ ide_settings_flag_action_class_init (IdeSettingsFlagActionClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = ide_settings_flag_action_finalize;
+  object_class->dispose = ide_settings_flag_action_dispose;
   object_class->get_property = ide_settings_flag_action_get_property;
   object_class->set_property = ide_settings_flag_action_set_property;
 
@@ -180,6 +292,11 @@ ide_settings_flag_action_class_init (IdeSettingsFlagActionClass *klass)
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
 
+  properties [PROP_PATH] =
+    g_param_spec_string ("path", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
   properties [PROP_SCHEMA_KEY] =
     g_param_spec_string ("schema-key",
                          "Schema Key",
@@ -194,7 +311,7 @@ ide_settings_flag_action_class_init (IdeSettingsFlagActionClass *klass)
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_properties (object_class, LAST_PROP, properties);
+  g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static void
@@ -202,104 +319,34 @@ ide_settings_flag_action_init (IdeSettingsFlagAction *self)
 {
 }
 
-static GSettings *
-ide_settings_flag_action_get_settings (IdeSettingsFlagAction *self)
-{
-  g_assert (IDE_IS_SETTINGS_FLAG_ACTION (self));
-
-  if (self->settings == NULL)
-    self->settings = g_settings_new (self->schema_id);
-
-  return self->settings;
-}
-
 static const char *
 ide_settings_flag_action_get_name (GAction *action)
 {
   IdeSettingsFlagAction *self = (IdeSettingsFlagAction *)action;
 
   if (self->name == NULL)
-    self->name = g_strdup_printf ("%s-%s", self->schema_key, self->flag_nick);
+    self->name = g_strdup (self->flag_nick);
 
   return self->name;
 }
 
-static const GVariantType *
-ide_settings_flag_action_get_parameter_type (GAction *action)
-{
-  return NULL;
-}
-
-static const GVariantType *
-ide_settings_flag_action_get_state_type (GAction *action)
-{
-  return G_VARIANT_TYPE_BOOLEAN;
-}
-
-static GVariant *
-ide_settings_flag_action_get_state_hint (GAction *action)
-{
-  return NULL;
-}
-
-static void
-ide_settings_flag_action_change_state (GAction  *action,
-                                       GVariant *value)
-{
-}
-
-static GVariant *
-ide_settings_flag_action_get_state (GAction *action)
-{
-  IdeSettingsFlagAction *self = (IdeSettingsFlagAction *)action;
-  GSettings *settings = ide_settings_flag_action_get_settings (self);
-  g_auto(GStrv) flags = g_settings_get_strv (settings, self->schema_key);
-  gboolean state = g_strv_contains ((const char * const *)flags, self->flag_nick);
-  return g_variant_new_boolean (state);
-}
-
 static gboolean
 ide_settings_flag_action_get_enabled (GAction *action)
 {
-  IdeSettingsFlagAction *self = (IdeSettingsFlagAction *)action;
-
-  return self->schema_id && self->schema_key && self->flag_nick;
+  return TRUE;
 }
 
 static void
 ide_settings_flag_action_activate (GAction  *action,
                                    GVariant *parameter)
 {
-  IdeSettingsFlagAction *self = (IdeSettingsFlagAction *)action;
-  GSettings *settings;
-  GPtrArray *ar;
-  gboolean found = FALSE;
-  char **strv;
-  guint i;
+  g_autoptr(GVariant) old_state = NULL;
 
   g_assert (IDE_IS_SETTINGS_FLAG_ACTION (action));
   g_assert (parameter == NULL);
 
-  settings = ide_settings_flag_action_get_settings (self);
-  strv = g_settings_get_strv (settings, self->schema_key);
-  ar = g_ptr_array_new ();
-
-  for (i = 0; strv [i]; i++)
-    {
-      if (g_strcmp0 (strv [i], self->flag_nick) == 0)
-        found = TRUE;
-      else
-        g_ptr_array_add (ar, strv [i]);
-    }
-
-  if (!found)
-    g_ptr_array_add (ar, self->flag_nick);
-
-  g_ptr_array_add (ar, NULL);
-
-  g_settings_set_strv (settings, self->schema_key, (const char * const *)ar->pdata);
-
-  g_strfreev (strv);
+  old_state = ide_settings_flag_action_get_state (action);
+  ide_settings_flag_action_change_state (action, g_variant_new_boolean (!g_variant_get_boolean (old_state)));
 }
 
 static void
diff --git a/src/libide/core/ide-settings-flag-action.h b/src/libide/core/ide-settings-flag-action.h
index 19fc474aa..434a07b1f 100644
--- a/src/libide/core/ide-settings-flag-action.h
+++ b/src/libide/core/ide-settings-flag-action.h
@@ -30,8 +30,9 @@ IDE_AVAILABLE_IN_ALL
 G_DECLARE_FINAL_TYPE (IdeSettingsFlagAction, ide_settings_flag_action, IDE, SETTINGS_FLAG_ACTION, GObject)
 
 IDE_AVAILABLE_IN_ALL
-GAction *ide_settings_flag_action_new (const char *schema_id,
-                                       const char *schema_key,
-                                       const char *flag_nick);
+IdeSettingsFlagAction *ide_settings_flag_action_new (const char *schema_id,
+                                                     const char *schema_key,
+                                                     const char *path,
+                                                     const char *flag_nick);
 
 G_END_DECLS


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