[gnome-builder] libide/tweaks: rename to IdeTweaksFactory



commit dbe87baf79db6875505f82158f463cc95e7ae79e
Author: Christian Hergert <chergert redhat com>
Date:   Tue Aug 2 14:14:38 2022 -0700

    libide/tweaks: rename to IdeTweaksFactory
    
    We can make this a bit more generic and use it in a few more places so
    that factory code need not be duplicated.
    
    Additionally, start on some private API to inflate items from the factory.
    We still need deep copy support in IdeTweaksItem so that we can snapshot
    the child of the factory.
    
    This will get used from IdeTweaksModel which will give us a GListModel of
    all the inflated items from an IdeTweaksItem including factory generated
    children (which do not get attached to the graph).

 src/libide/tweaks/ide-tweaks-factory-private.h     |  33 ++++
 src/libide/tweaks/ide-tweaks-factory.c             | 214 +++++++++++++++++++++
 ...eaks-subpage-factory.h => ide-tweaks-factory.h} |  14 +-
 src/libide/tweaks/ide-tweaks-init.c                |   2 +-
 src/libide/tweaks/ide-tweaks-item-private.h        |   7 +-
 src/libide/tweaks/ide-tweaks-item.c                |   8 +
 src/libide/tweaks/ide-tweaks-page.c                |   4 +-
 src/libide/tweaks/ide-tweaks-subpage-factory.c     | 147 --------------
 src/libide/tweaks/libide-tweaks.h                  |   2 +-
 src/libide/tweaks/meson.build                      |   4 +-
 src/libide/tweaks/tests/test2/0.ui                 |   2 +-
 src/libide/tweaks/tests/test2/1.ui                 |   7 +-
 src/libide/tweaks/tests/test2/expected.xml         |   4 +-
 13 files changed, 281 insertions(+), 167 deletions(-)
---
diff --git a/src/libide/tweaks/ide-tweaks-factory-private.h b/src/libide/tweaks/ide-tweaks-factory-private.h
new file mode 100644
index 000000000..7c5eb9f0c
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-factory-private.h
@@ -0,0 +1,33 @@
+/*
+ * ide-tweaks-factory-private.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ide-tweaks-factory.h"
+
+G_BEGIN_DECLS
+
+GPtrArray *_ide_tweaks_factory_inflate   (IdeTweaksFactory *factory);
+gboolean   _ide_tweaks_factory_is_one_of (IdeTweaksFactory *factory,
+                                          const GType      *allowed_types,
+                                          guint             n_allowed_types);
+
+G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-factory.c b/src/libide/tweaks/ide-tweaks-factory.c
new file mode 100644
index 000000000..574277ff5
--- /dev/null
+++ b/src/libide/tweaks/ide-tweaks-factory.c
@@ -0,0 +1,214 @@
+/* ide-tweaks-factory.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-tweaks-factory"
+
+#include "config.h"
+
+#include "ide-tweaks-factory-private.h"
+#include "ide-tweaks-item-private.h"
+
+struct _IdeTweaksFactory
+{
+  IdeTweaksItem  parent_instance;
+  GListModel    *model;
+  GObject       *item;
+};
+
+G_DEFINE_FINAL_TYPE (IdeTweaksFactory, ide_tweaks_factory, IDE_TYPE_TWEAKS_ITEM)
+
+enum {
+  PROP_0,
+  PROP_ITEM,
+  PROP_MODEL,
+  N_PROPS
+};
+
+static GParamSpec *properties[N_PROPS];
+
+static gboolean
+ide_tweaks_factory_accepts (IdeTweaksItem *item,
+                            IdeTweaksItem *child)
+{
+  return TRUE;
+}
+
+static void
+ide_tweaks_factory_dispose (GObject *object)
+{
+  IdeTweaksFactory *self = (IdeTweaksFactory *)object;
+
+  g_clear_object (&self->model);
+
+  G_OBJECT_CLASS (ide_tweaks_factory_parent_class)->dispose (object);
+}
+
+static void
+ide_tweaks_factory_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  IdeTweaksFactory *self = IDE_TWEAKS_FACTORY (object);
+
+  switch (prop_id)
+    {
+    case PROP_MODEL:
+      g_value_set_object (value, ide_tweaks_factory_get_model (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_factory_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  IdeTweaksFactory *self = IDE_TWEAKS_FACTORY (object);
+
+  switch (prop_id)
+    {
+    case PROP_MODEL:
+      ide_tweaks_factory_set_model (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_tweaks_factory_class_init (IdeTweaksFactoryClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  IdeTweaksItemClass *item_class = IDE_TWEAKS_ITEM_CLASS (klass);
+
+  object_class->dispose = ide_tweaks_factory_dispose;
+  object_class->get_property = ide_tweaks_factory_get_property;
+  object_class->set_property = ide_tweaks_factory_set_property;
+
+  item_class->accepts = ide_tweaks_factory_accepts;
+
+  properties[PROP_ITEM] =
+    g_param_spec_object ("item", NULL, NULL,
+                         G_TYPE_OBJECT,
+                         (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_MODEL] =
+    g_param_spec_object ("model", NULL, NULL,
+                         G_TYPE_LIST_MODEL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+ide_tweaks_factory_init (IdeTweaksFactory *self)
+{
+}
+
+/**
+ * ide_tweaks_factory_get_model:
+ * @self: a #IdeTweaksFactory
+ *
+ * Returns: (transfer none) (nullable): a #GListModel or %NULL
+ */
+GListModel *
+ide_tweaks_factory_get_model (IdeTweaksFactory *self)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_FACTORY (self), NULL);
+
+  return self->model;
+}
+
+void
+ide_tweaks_factory_set_model (IdeTweaksFactory *self,
+                              GListModel       *model)
+{
+  g_return_if_fail (IDE_IS_TWEAKS_FACTORY (self));
+  g_return_if_fail (!model || G_IS_LIST_MODEL (model));
+
+  if (g_set_object (&self->model, model))
+    g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MODEL]);
+}
+
+gboolean
+_ide_tweaks_factory_is_one_of (IdeTweaksFactory *self,
+                               const GType      *allowed_types,
+                               guint             n_allowed_types)
+{
+  IdeTweaksItem *child;
+  GType child_type;
+
+  g_return_val_if_fail (IDE_IS_TWEAKS_FACTORY (self), FALSE);
+  g_return_val_if_fail (allowed_types || n_allowed_types == 0, FALSE);
+
+  if (!(child = ide_tweaks_item_get_first_child (IDE_TWEAKS_ITEM (self))))
+    return FALSE;
+
+  child_type = G_OBJECT_TYPE (child);
+
+  for (guint i = 0; i < n_allowed_types; i++)
+    {
+      if (g_type_is_a (child_type, allowed_types[i]))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+GPtrArray *
+_ide_tweaks_factory_inflate (IdeTweaksFactory *self)
+{
+  g_autoptr(GListModel) model = NULL;
+  IdeTweaksItem *child;
+  GPtrArray *ar;
+  guint n_items;
+
+  g_return_val_if_fail (IDE_IS_TWEAKS_FACTORY (self), NULL);
+
+  ar = g_ptr_array_new_with_free_func (g_object_unref);
+
+  if (!g_set_object (&model, self->model))
+    return ar;
+
+  if (!(child = ide_tweaks_item_get_first_child (IDE_TWEAKS_ITEM (self))))
+    return ar;
+
+  n_items = g_list_model_get_n_items (model);
+
+  for (guint i = 0; i < n_items; i++)
+    {
+      g_autoptr(GObject) object = g_list_model_get_item (model, i);
+
+      /* Allow bindings on/descendant-to @child to update */
+      if (g_set_object (&self->item, object))
+        g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ITEM]);
+
+      /* Now deep copy child to snapshot state */
+      g_ptr_array_add (ar, _ide_tweaks_item_deep_copy (child));
+    }
+
+  return ar;
+}
diff --git a/src/libide/tweaks/ide-tweaks-subpage-factory.h b/src/libide/tweaks/ide-tweaks-factory.h
similarity index 61%
rename from src/libide/tweaks/ide-tweaks-subpage-factory.h
rename to src/libide/tweaks/ide-tweaks-factory.h
index ffe0509ed..fbadef114 100644
--- a/src/libide/tweaks/ide-tweaks-subpage-factory.h
+++ b/src/libide/tweaks/ide-tweaks-factory.h
@@ -1,4 +1,4 @@
-/* ide-tweaks-subpage-factory.h
+/* ide-tweaks-factory.h
  *
  * Copyright 2022 Christian Hergert <chergert redhat com>
  *
@@ -24,17 +24,17 @@
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_TWEAKS_SUBPAGE_FACTORY (ide_tweaks_subpage_factory_get_type())
+#define IDE_TYPE_TWEAKS_FACTORY (ide_tweaks_factory_get_type())
 
 IDE_AVAILABLE_IN_ALL
-G_DECLARE_FINAL_TYPE (IdeTweaksSubpageFactory, ide_tweaks_subpage_factory, IDE, TWEAKS_SUBPAGE_FACTORY, 
IdeTweaksItem)
+G_DECLARE_FINAL_TYPE (IdeTweaksFactory, ide_tweaks_factory, IDE, TWEAKS_FACTORY, IdeTweaksItem)
 
 IDE_AVAILABLE_IN_ALL
-IdeTweaksSubpageFactory *ide_tweaks_subpage_factory_new       (void);
+IdeTweaksFactory *ide_tweaks_factory_new       (void);
 IDE_AVAILABLE_IN_ALL
-GListModel              *ide_tweaks_subpage_factory_get_model (IdeTweaksSubpageFactory *self);
+GListModel       *ide_tweaks_factory_get_model (IdeTweaksFactory *self);
 IDE_AVAILABLE_IN_ALL
-void                     ide_tweaks_subpage_factory_set_model (IdeTweaksSubpageFactory *self,
-                                                               GListModel              *model);
+void              ide_tweaks_factory_set_model (IdeTweaksFactory *self,
+                                                GListModel       *model);
 
 G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-init.c b/src/libide/tweaks/ide-tweaks-init.c
index cd4839afa..86a8e4685 100644
--- a/src/libide/tweaks/ide-tweaks-init.c
+++ b/src/libide/tweaks/ide-tweaks-init.c
@@ -34,12 +34,12 @@ _ide_tweaks_init (void)
 
   g_type_ensure (IDE_TYPE_TWEAKS);
   g_type_ensure (IDE_TYPE_TWEAKS_CUSTOM);
+  g_type_ensure (IDE_TYPE_TWEAKS_FACTORY);
   g_type_ensure (IDE_TYPE_TWEAKS_GROUP);
   g_type_ensure (IDE_TYPE_TWEAKS_ITEM);
   g_type_ensure (IDE_TYPE_TWEAKS_PAGE);
   g_type_ensure (IDE_TYPE_TWEAKS_SECTION);
   g_type_ensure (IDE_TYPE_TWEAKS_SUBPAGE);
-  g_type_ensure (IDE_TYPE_TWEAKS_SUBPAGE_FACTORY);
   g_type_ensure (IDE_TYPE_TWEAKS_VARIABLE);
   g_type_ensure (IDE_TYPE_TWEAKS_WINDOW);
 }
diff --git a/src/libide/tweaks/ide-tweaks-item-private.h b/src/libide/tweaks/ide-tweaks-item-private.h
index 4b34f67eb..dcee8c417 100644
--- a/src/libide/tweaks/ide-tweaks-item-private.h
+++ b/src/libide/tweaks/ide-tweaks-item-private.h
@@ -24,8 +24,9 @@
 
 G_BEGIN_DECLS
 
-void _ide_tweaks_item_printf (IdeTweaksItem *self,
-                              GString       *string,
-                              guint          level);
+IdeTweaksItem *_ide_tweaks_item_deep_copy (IdeTweaksItem *self);
+void           _ide_tweaks_item_printf    (IdeTweaksItem *self,
+                                           GString       *string,
+                                           guint          level);
 
 G_END_DECLS
diff --git a/src/libide/tweaks/ide-tweaks-item.c b/src/libide/tweaks/ide-tweaks-item.c
index adb27f302..891e252d0 100644
--- a/src/libide/tweaks/ide-tweaks-item.c
+++ b/src/libide/tweaks/ide-tweaks-item.c
@@ -603,3 +603,11 @@ _ide_tweaks_item_printf (IdeTweaksItem *self,
     g_string_append (string, "  ");
   g_string_append_printf (string, "</%s>\n", G_OBJECT_TYPE_NAME (self));
 }
+
+IdeTweaksItem *
+_ide_tweaks_item_deep_copy (IdeTweaksItem *self)
+{
+  /* TODO: actually implement deep copy */
+
+  return g_object_new (G_OBJECT_TYPE (self), NULL);
+}
diff --git a/src/libide/tweaks/ide-tweaks-page.c b/src/libide/tweaks/ide-tweaks-page.c
index f0353e2da..8ee4802f1 100644
--- a/src/libide/tweaks/ide-tweaks-page.c
+++ b/src/libide/tweaks/ide-tweaks-page.c
@@ -23,10 +23,10 @@
 
 #include "config.h"
 
+#include "ide-tweaks-factory.h"
 #include "ide-tweaks-group.h"
 #include "ide-tweaks-page.h"
 #include "ide-tweaks-subpage.h"
-#include "ide-tweaks-subpage-factory.h"
 
 struct _IdeTweaksPage
 {
@@ -57,7 +57,7 @@ ide_tweaks_page_accepts (IdeTweaksItem *item,
                          IdeTweaksItem *child)
 {
   return IDE_IS_TWEAKS_SUBPAGE (child) ||
-         IDE_IS_TWEAKS_SUBPAGE_FACTORY (child) ||
+         IDE_IS_TWEAKS_FACTORY (child) ||
          IDE_IS_TWEAKS_GROUP (child);
 }
 
diff --git a/src/libide/tweaks/libide-tweaks.h b/src/libide/tweaks/libide-tweaks.h
index 7958831f9..23d3bcd72 100644
--- a/src/libide/tweaks/libide-tweaks.h
+++ b/src/libide/tweaks/libide-tweaks.h
@@ -23,12 +23,12 @@
 #define IDE_TWEAKS_INSIDE
 # include "ide-tweaks.h"
 # include "ide-tweaks-custom.h"
+# include "ide-tweaks-factory.h"
 # include "ide-tweaks-group.h"
 # include "ide-tweaks-item.h"
 # include "ide-tweaks-page.h"
 # include "ide-tweaks-section.h"
 # include "ide-tweaks-subpage.h"
-# include "ide-tweaks-subpage-factory.h"
 # include "ide-tweaks-variable.h"
 # include "ide-tweaks-window.h"
 #undef IDE_TWEAKS_INSIDE
diff --git a/src/libide/tweaks/meson.build b/src/libide/tweaks/meson.build
index a6a5762fa..d6809bfe2 100644
--- a/src/libide/tweaks/meson.build
+++ b/src/libide/tweaks/meson.build
@@ -10,12 +10,12 @@ libide_tweaks_public_headers = [
   'libide-tweaks.h',
   'ide-tweaks.h',
   'ide-tweaks-custom.h',
+  'ide-tweaks-factory.h',
   'ide-tweaks-group.h',
   'ide-tweaks-item.h',
   'ide-tweaks-page.h',
   'ide-tweaks-section.h',
   'ide-tweaks-subpage.h',
-  'ide-tweaks-subpage-factory.h',
   'ide-tweaks-variable.h',
   'ide-tweaks-window.h',
 ]
@@ -30,11 +30,11 @@ libide_tweaks_public_sources = [
   'ide-tweaks.c',
   'ide-tweaks-custom.c',
   'ide-tweaks-item.c',
+  'ide-tweaks-factory.c',
   'ide-tweaks-group.c',
   'ide-tweaks-page.c',
   'ide-tweaks-section.c',
   'ide-tweaks-subpage.c',
-  'ide-tweaks-subpage-factory.c',
   'ide-tweaks-variable.c',
   'ide-tweaks-window.c',
 ]
diff --git a/src/libide/tweaks/tests/test2/0.ui b/src/libide/tweaks/tests/test2/0.ui
index 516a9b69f..3411ef4e6 100644
--- a/src/libide/tweaks/tests/test2/0.ui
+++ b/src/libide/tweaks/tests/test2/0.ui
@@ -5,7 +5,7 @@
         <child>
           <object class="IdeTweaksPage" id="languages_page">
             <child>
-              <object class="IdeTweaksSubpageFactory" id="language_subpage_factory">
+              <object class="IdeTweaksFactory" id="language_subpage_factory">
                 <property name="model">GtkSourceLanguages</property>
                 <child>
                   <object class="IdeTweaksSubpage" id="language_subpage">
diff --git a/src/libide/tweaks/tests/test2/1.ui b/src/libide/tweaks/tests/test2/1.ui
index 046f3f6f0..699c83e8d 100644
--- a/src/libide/tweaks/tests/test2/1.ui
+++ b/src/libide/tweaks/tests/test2/1.ui
@@ -5,9 +5,14 @@
         <child internal-child="languages_page">
           <object class="IdeTweaksPage">
             <child internal-child="language_subpage_factory">
-              <object class="IdeTweaksSubpageFactory">
+              <object class="IdeTweaksFactory">
                 <child internal-child="language_subpage">
                   <object class="IdeTweaksSubpage">
+                    <binding name="title">
+                      <lookup name="title" type="IdeTweaksPage">
+                        <lookup name="item">language_subpage_factory</lookup>
+                      </lookup>
+                    </binding>
                     <child internal-child="language_general_group">
                       <object class="IdeTweaksGroup">
                         <property name="sort-key">test-key</property>
diff --git a/src/libide/tweaks/tests/test2/expected.xml b/src/libide/tweaks/tests/test2/expected.xml
index e9a950440..2fa220e37 100644
--- a/src/libide/tweaks/tests/test2/expected.xml
+++ b/src/libide/tweaks/tests/test2/expected.xml
@@ -1,11 +1,11 @@
 <IdeTweaks id="IdeTweaks" sort-key="">
   <IdeTweaksSection id="programming_section" sort-key="">
     <IdeTweaksPage id="languages_page" icon-name="" sort-key="" title="">
-      <IdeTweaksSubpageFactory id="language_subpage_factory" model="GListStore<GtkSourceLanguage>" 
sort-key="">
+      <IdeTweaksFactory id="language_subpage_factory" item="" model="GListStore<GtkSourceLanguage>" 
sort-key="">
         <IdeTweaksSubpage id="language_subpage" icon-name="" sort-key="" title="">
           <IdeTweaksGroup id="language_general_group" sort-key="test-key" title="General"/>
         </IdeTweaksSubpage>
-      </IdeTweaksSubpageFactory>
+      </IdeTweaksFactory>
     </IdeTweaksPage>
   </IdeTweaksSection>
 </IdeTweaks>


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