[gnome-builder/wip/chergert/configview] config: add new IdeConfigViewAddin and associated plumbing



commit 381e93aae656bab1b295f6c4ef8b40167510694a
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jun 22 14:53:09 2018 -0700

    config: add new IdeConfigViewAddin and associated plumbing

 src/libide/buildui/ide-build-perspective.c  |  27 ++-
 src/libide/buildui/ide-build-perspective.ui |  12 +-
 src/libide/buildui/meson.build              |   9 -
 src/libide/config/ide-config-view-addin.c   | 143 +++++++++++++
 src/libide/config/ide-config-view-addin.h   |  71 +++++++
 src/libide/config/ide-config-view.c         | 307 ++++++++++++++++++++++++++++
 src/libide/config/ide-config-view.h         |  44 ++++
 src/libide/config/ide-config-view.ui        |  17 ++
 src/libide/config/meson.build               |   4 +
 src/libide/ide.h                            |   2 +
 src/libide/libide.gresource.xml             |   1 +
 11 files changed, 614 insertions(+), 23 deletions(-)
---
diff --git a/src/libide/buildui/ide-build-perspective.c b/src/libide/buildui/ide-build-perspective.c
index 73bc712cc..fec78c829 100644
--- a/src/libide/buildui/ide-build-perspective.c
+++ b/src/libide/buildui/ide-build-perspective.c
@@ -23,8 +23,8 @@
 #include <glib/gi18n.h>
 
 #include "buildui/ide-build-configuration-row.h"
-#include "buildui/ide-build-configuration-view.h"
 #include "buildui/ide-build-perspective.h"
+#include "config/ide-config-view.h"
 
 struct _IdeBuildPerspective
 {
@@ -34,7 +34,7 @@ struct _IdeBuildPerspective
   IdeConfigurationManager   *configuration_manager;
 
   GtkListBox                *list_box;
-  IdeBuildConfigurationView *view;
+  IdeConfigView             *view;
 };
 
 enum {
@@ -172,7 +172,7 @@ ide_build_perspective_row_selected (IdeBuildPerspective      *self,
 
       configuration = ide_build_configuration_row_get_configuration (row);
       g_set_object (&self->configuration, configuration);
-      ide_build_configuration_view_set_configuration (self->view, configuration);
+      ide_config_view_set_config (self->view, configuration);
 
       gtk_container_foreach (GTK_CONTAINER (list_box),
                              update_selected_state,
@@ -268,6 +268,23 @@ ide_build_perspective_grab_focus (GtkWidget *widget)
   gtk_widget_child_focus (GTK_WIDGET (self->list_box), GTK_DIR_TAB_FORWARD);
 }
 
+static void
+header_cb (GtkListBoxRow *row,
+           GtkListBoxRow *before,
+           gpointer       user_data)
+{
+  if (before == NULL)
+    gtk_list_box_row_set_header (row,
+                                 g_object_new (GTK_TYPE_LABEL,
+                                               "label", _("<b>Configurations</b>"),
+                                               "opacity", 0.55,
+                                               "margin", 6,
+                                               "use-markup", TRUE,
+                                               "xalign", 0.0f,
+                                               "visible", TRUE,
+                                               NULL));
+}
+
 static void
 ide_build_perspective_finalize (GObject *object)
 {
@@ -357,7 +374,7 @@ ide_build_perspective_class_init (IdeBuildPerspectiveClass *klass)
   gtk_widget_class_bind_template_child (widget_class, IdeBuildPerspective, list_box);
   gtk_widget_class_bind_template_child (widget_class, IdeBuildPerspective, view);
 
-  g_type_ensure (IDE_TYPE_BUILD_CONFIGURATION_VIEW);
+  g_type_ensure (IDE_TYPE_CONFIG_VIEW);
 }
 
 static const GActionEntry actions[] = {
@@ -384,6 +401,8 @@ ide_build_perspective_init (IdeBuildPerspective *self)
                            self,
                            G_CONNECT_SWAPPED);
 
+  gtk_list_box_set_header_func (self->list_box, header_cb, NULL, NULL);
+
   group = g_simple_action_group_new ();
   g_action_map_add_action_entries (G_ACTION_MAP (group), actions, G_N_ELEMENTS (actions), self);
   gtk_widget_insert_action_group (GTK_WIDGET (self), "build-preferences", G_ACTION_GROUP (group));
diff --git a/src/libide/buildui/ide-build-perspective.ui b/src/libide/buildui/ide-build-perspective.ui
index 9075f6561..b577ed121 100644
--- a/src/libide/buildui/ide-build-perspective.ui
+++ b/src/libide/buildui/ide-build-perspective.ui
@@ -27,17 +27,9 @@
           </object>
         </child>
         <child>
-          <object class="GtkScrolledWindow">
-            <property name="hscrollbar-policy">never</property>
+          <object class="IdeConfigView" id="view">
+            <property name="expand">true</property>
             <property name="visible">true</property>
-            <property name="propagate-natural-height">true</property>
-            <property name="propagate-natural-width">true</property>
-            <child>
-              <object class="IdeBuildConfigurationView" id="view">
-                <property name="expand">true</property>
-                <property name="visible">true</property>
-              </object>
-            </child>
           </object>
         </child>
       </object>
diff --git a/src/libide/buildui/meson.build b/src/libide/buildui/meson.build
index 3cbfd9cff..23a9e036a 100644
--- a/src/libide/buildui/meson.build
+++ b/src/libide/buildui/meson.build
@@ -1,24 +1,15 @@
 buildui_private_sources = [
   'ide-build-configuration-row.c',
-  'ide-build-configuration-row.h',
   'ide-build-configuration-view.c',
-  'ide-build-configuration-view.h',
   'ide-build-log-panel.c',
-  'ide-build-log-panel.h',
   'ide-build-panel.c',
-  'ide-build-panel.h',
   'ide-build-perspective.c',
-  'ide-build-perspective.h',
   'ide-build-plugin.c',
   'ide-build-stage-row.c',
-  'ide-build-stage-row.h',
   'ide-build-tool.h',
   'ide-build-workbench-addin.c',
-  'ide-build-workbench-addin.h',
   'ide-environment-editor-row.c',
-  'ide-environment-editor-row.h',
   'ide-environment-editor.c',
-  'ide-environment-editor.h',
 ]
 
 libide_private_sources += files(buildui_private_sources)
diff --git a/src/libide/config/ide-config-view-addin.c b/src/libide/config/ide-config-view-addin.c
new file mode 100644
index 000000000..fa1ecd645
--- /dev/null
+++ b/src/libide/config/ide-config-view-addin.c
@@ -0,0 +1,143 @@
+/* ide-config-view-addin.c
+ *
+ * Copyright 2018 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
+ */
+
+#include "config.h"
+
+#define G_LOG_DOMAIN "ide-config-view-addin"
+
+#include "config/ide-config-view-addin.h"
+
+/**
+ * SECTION:ide-config-view-addin
+ * @title: IdeConfigViewAddin
+ * @short_description: addins for extending the configuration view
+ *
+ * The #IdeConfigViewAddin allows plugins to add widgets for configuring
+ * a build configuration.
+ *
+ * Since: 3.32
+ */
+
+G_DEFINE_INTERFACE (IdeConfigViewAddin, ide_config_view_addin, IDE_TYPE_OBJECT)
+
+static void
+ide_config_view_addin_real_load_async (IdeConfigViewAddin  *self,
+                                       DzlPreferences      *preferences,
+                                       IdeConfiguration    *configuration,
+                                       GCancellable        *cancellable,
+                                       GAsyncReadyCallback  callback,
+                                       gpointer             user_data)
+{
+  g_task_report_new_error (self, callback, user_data,
+                           ide_config_view_addin_real_load_async,
+                           G_IO_ERROR,
+                           G_IO_ERROR_NOT_SUPPORTED,
+                           "Load async not implemented");
+}
+
+static gboolean
+ide_config_view_addin_real_load_finish (IdeConfigViewAddin  *self,
+                                        GAsyncResult        *result,
+                                        GError             **error)
+{
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+ide_config_view_addin_default_init (IdeConfigViewAddinInterface *iface)
+{
+  iface->load_async = ide_config_view_addin_real_load_async;
+  iface->load_finish = ide_config_view_addin_real_load_finish;
+}
+
+/**
+ * ide_config_view_addin_load_async:
+ * @self: an #IdeConfigViewAddin
+ * @preferences: a #DzlPreferences
+ * @config: an #IdeConfiguration
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: a #GAsyncReadyCallback to execute upon completion
+ * @user_data: closure data for @callback
+ *
+ * Asynchronously loads any preferences that are part of the plugin
+ * in relation to @config.
+ *
+ * Since: 3.32
+ */
+void
+ide_config_view_addin_load_async (IdeConfigViewAddin  *self,
+                                  DzlPreferences      *preferences,
+                                  IdeConfiguration    *config,
+                                  GCancellable        *cancellable,
+                                  GAsyncReadyCallback  callback,
+                                  gpointer             user_data)
+{
+  g_return_if_fail (IDE_IS_CONFIG_VIEW_ADDIN (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  IDE_CONFIG_VIEW_ADDIN_GET_IFACE (self)->load_async (self, preferences, config,
+                                                      cancellable, callback, user_data);
+}
+
+/**
+ * ide_config_view_addin_load_finish:
+ * @self: an #IdeConfigViewAddin
+ * @result: a #GAsyncResult provided to callback
+ * @error: a location for a #GError, or %NULL
+ *
+ * Returns: %TRUE if successful; otherwise %FALSE and @error is set.
+ *
+ * Since: 3.32
+ */
+gboolean
+ide_config_view_addin_load_finish (IdeConfigViewAddin  *self,
+                                   GAsyncResult        *result,
+                                   GError             **error)
+{
+  g_return_val_if_fail (IDE_IS_CONFIG_VIEW_ADDIN (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+  return IDE_CONFIG_VIEW_ADDIN_GET_IFACE (self)->load_finish (self, result, error);
+}
+
+/**
+ * ide_config_view_addin_unload:
+ * @self: an #IdeConfigViewAddin
+ * @preferences: a #DzlPreferences
+ * @config: an #IdeConfiguration
+ *
+ * This is called when the plugin should release any of it's previously
+ * registered settings in ide_config_view_addin_load_async(). This can happen
+ * when the plugin is unloaded or @preferences is being destroyed.
+ *
+ * Since: 3.32
+ */
+void
+ide_config_view_addin_unload (IdeConfigViewAddin *self,
+                              DzlPreferences     *preferences,
+                              IdeConfiguration   *config)
+{
+  g_return_if_fail (IDE_IS_CONFIG_VIEW_ADDIN (self));
+  g_return_if_fail (DZL_IS_PREFERENCES (preferences));
+  g_return_if_fail (IDE_IS_CONFIGURATION (config));
+
+  if (IDE_CONFIG_VIEW_ADDIN_GET_IFACE (self)->unload)
+    IDE_CONFIG_VIEW_ADDIN_GET_IFACE (self)->unload (self, preferences, config);
+}
diff --git a/src/libide/config/ide-config-view-addin.h b/src/libide/config/ide-config-view-addin.h
new file mode 100644
index 000000000..6d471cbed
--- /dev/null
+++ b/src/libide/config/ide-config-view-addin.h
@@ -0,0 +1,71 @@
+/* ide-config-view-addin.h
+ *
+ * Copyright 2018 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 <dazzle.h>
+
+#include "ide-object.h"
+#include "ide-version-macros.h"
+
+#include "config/ide-configuration.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_CONFIG_VIEW_ADDIN (ide_config_view_addin_get_type ())
+
+IDE_AVAILABLE_IN_3_32
+G_DECLARE_INTERFACE (IdeConfigViewAddin, ide_config_view_addin, IDE, CONFIG_VIEW_ADDIN, IdeObject)
+
+struct _IdeConfigViewAddinInterface
+{
+  GTypeInterface parent;
+
+  void     (*load_async)  (IdeConfigViewAddin   *self,
+                           DzlPreferences       *preferences,
+                           IdeConfiguration     *config,
+                           GCancellable         *cancellable,
+                           GAsyncReadyCallback   callback,
+                           gpointer              user_data);
+  gboolean (*load_finish) (IdeConfigViewAddin   *self,
+                           GAsyncResult         *result,
+                           GError              **error);
+  void     (*unload)      (IdeConfigViewAddin   *self,
+                           DzlPreferences       *preferences,
+                           IdeConfiguration     *config);
+};
+
+IDE_AVAILABLE_IN_3_32
+void     ide_config_view_addin_load_async  (IdeConfigViewAddin   *self,
+                                            DzlPreferences       *preferences,
+                                            IdeConfiguration     *config,
+                                            GCancellable         *cancellable,
+                                            GAsyncReadyCallback   callback,
+                                            gpointer              user_data);
+IDE_AVAILABLE_IN_3_32
+gboolean ide_config_view_addin_load_finish (IdeConfigViewAddin   *self,
+                                            GAsyncResult         *result,
+                                            GError              **error);
+IDE_AVAILABLE_IN_3_32
+void     ide_config_view_addin_unload      (IdeConfigViewAddin   *self,
+                                            DzlPreferences       *preferences,
+                                            IdeConfiguration     *config);
+
+G_END_DECLS
diff --git a/src/libide/config/ide-config-view.c b/src/libide/config/ide-config-view.c
new file mode 100644
index 000000000..c5f70408c
--- /dev/null
+++ b/src/libide/config/ide-config-view.c
@@ -0,0 +1,307 @@
+/* ide-config-view.c
+ *
+ * Copyright 2018 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
+ */
+
+#include "config.h"
+
+#define G_LOG_DOMAIN "ide-config-view"
+
+#include <glib/gi18n.h>
+#include <libpeas/peas.h>
+
+#include "config/ide-config-view.h"
+#include "config/ide-config-view-addin.h"
+#include "util/ide-gtk.h"
+
+struct _IdeConfigView
+{
+  GtkBin            parent_instance;
+
+  /* Owned references */
+  IdeConfiguration *config;
+  PeasExtensionSet *addins;
+  GCancellable     *cancellable;
+
+  /* Template widgets */
+  DzlPreferences   *preferences;
+};
+
+static void ide_config_view_connect    (IdeConfigView    *self,
+                                        IdeConfiguration *config);
+static void ide_config_view_disconnect (IdeConfigView    *self);
+
+G_DEFINE_TYPE (IdeConfigView, ide_config_view, GTK_TYPE_BIN)
+
+enum {
+  PROP_0,
+  PROP_CONFIG,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+/**
+ * ide_config_view_new:
+ *
+ * Create a new #IdeConfigView.
+ *
+ * Returns: (transfer full): a newly created #IdeConfigView
+ */
+GtkWidget *
+ide_config_view_new (void)
+{
+  return g_object_new (IDE_TYPE_CONFIG_VIEW, NULL);
+}
+
+static void
+ide_config_view_destroy (GtkWidget *widget)
+{
+  IdeConfigView *self = (IdeConfigView *)widget;
+
+  g_assert (IDE_IS_CONFIG_VIEW (self));
+
+  if (self->config)
+    ide_config_view_disconnect (self);
+
+  GTK_WIDGET_CLASS (ide_config_view_parent_class)->destroy (widget);
+}
+
+static void
+ide_config_view_finalize (GObject *object)
+{
+  IdeConfigView *self = (IdeConfigView *)object;
+
+  g_assert (self->addins == NULL);
+  g_assert (self->config == NULL);
+  g_assert (self->cancellable == NULL);
+
+  G_OBJECT_CLASS (ide_config_view_parent_class)->finalize (object);
+}
+
+static void
+ide_config_view_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  IdeConfigView *self = IDE_CONFIG_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONFIG:
+      g_value_set_object (value, ide_config_view_get_config (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_config_view_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  IdeConfigView *self = IDE_CONFIG_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONFIG:
+      ide_config_view_set_config (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_config_view_class_init (IdeConfigViewClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = ide_config_view_finalize;
+  object_class->get_property = ide_config_view_get_property;
+  object_class->set_property = ide_config_view_set_property;
+
+  widget_class->destroy = ide_config_view_destroy;
+
+  properties [PROP_CONFIG] =
+    g_param_spec_object ("config",
+                         "Configuration",
+                         "The configuration to be displayed",
+                         IDE_TYPE_CONFIGURATION,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/builder/ui/ide-config-view.ui");
+  gtk_widget_class_bind_template_child (widget_class, IdeConfigView, preferences);
+}
+
+static void
+ide_config_view_init (IdeConfigView *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  dzl_preferences_add_page (self->preferences, "general", _("General"), 0);
+  dzl_preferences_add_list_group (self->preferences, "general", "general", _("General"), GTK_SELECTION_NONE, 
0);
+  dzl_preferences_add_custom (self->preferences, "general", "general", g_object_new (GTK_TYPE_LABEL, 
"visible", TRUE, NULL), NULL, 0);
+  dzl_preferences_add_custom (self->preferences, "general", "general", g_object_new (GTK_TYPE_LABEL, 
"visible", TRUE, NULL), NULL, 0);
+}
+
+static void
+ide_config_view_load_cb (GObject      *object,
+                         GAsyncResult *result,
+                         gpointer      user_data)
+{
+  IdeConfigViewAddin *addin = (IdeConfigViewAddin *)object;
+  g_autoptr(IdeConfigView) self = user_data;
+  g_autoptr(GError) error = NULL;
+  IdeContext *context;
+
+  g_assert (IDE_IS_CONFIG_VIEW_ADDIN (addin));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_CONFIG_VIEW (self));
+
+  context = ide_widget_get_context (GTK_WIDGET (self));
+
+  if (!ide_config_view_addin_load_finish (addin, result, &error))
+    ide_context_warning (context, "%s: %s", G_OBJECT_TYPE_NAME (addin), error->message);
+}
+
+static void
+ide_config_view_addin_added_cb (PeasExtensionSet *set,
+                                PeasPluginInfo   *plugin_info,
+                                PeasExtension    *exten,
+                                gpointer          user_data)
+{
+  IdeConfigViewAddin *addin = (IdeConfigViewAddin *)exten;
+  IdeConfigView *self = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_CONFIG_VIEW_ADDIN (addin));
+  g_assert (IDE_IS_CONFIG_VIEW (self));
+
+  ide_config_view_addin_load_async (addin,
+                                    self->preferences,
+                                    self->config,
+                                    self->cancellable,
+                                    ide_config_view_load_cb,
+                                    g_object_ref (self));
+}
+
+static void
+ide_config_view_addin_removed_cb (PeasExtensionSet *set,
+                                  PeasPluginInfo   *plugin_info,
+                                  PeasExtension    *exten,
+                                  gpointer          user_data)
+{
+  IdeConfigViewAddin *addin = (IdeConfigViewAddin *)exten;
+  IdeConfigView *self = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_CONFIG_VIEW_ADDIN (addin));
+  g_assert (IDE_IS_CONFIG_VIEW (self));
+
+  ide_config_view_addin_unload (addin, self->preferences, self->config);
+}
+
+static void
+ide_config_view_disconnect (IdeConfigView *self)
+{
+  g_assert (IDE_IS_CONFIG_VIEW (self));
+  g_assert (IDE_IS_CONFIGURATION (self->config));
+
+  g_cancellable_cancel (self->cancellable);
+  g_clear_object (&self->cancellable);
+  g_clear_object (&self->addins);
+  g_clear_object (&self->config);
+}
+
+static void
+ide_config_view_connect (IdeConfigView    *self,
+                         IdeConfiguration *config)
+{
+  IdeContext *context;
+
+  g_assert (IDE_IS_CONFIG_VIEW (self));
+  g_assert (IDE_IS_CONFIGURATION (config));
+  g_assert (self->cancellable == NULL);
+  g_assert (self->config == NULL);
+
+  self->cancellable = g_cancellable_new ();
+  self->config = g_object_ref (config);
+  context = ide_widget_get_context (GTK_WIDGET (self));
+  self->addins = peas_extension_set_new (peas_engine_get_default (),
+                                         IDE_TYPE_CONFIG_VIEW_ADDIN,
+                                         "context", context,
+                                         NULL);
+  g_signal_connect (self->addins,
+                    "extension-added",
+                    G_CALLBACK (ide_config_view_addin_added_cb),
+                    self);
+  g_signal_connect (self->addins,
+                    "extension-removed",
+                    G_CALLBACK (ide_config_view_addin_removed_cb),
+                    self);
+  peas_extension_set_foreach (self->addins,
+                              ide_config_view_addin_added_cb,
+                              self);
+}
+
+/**
+ * ide_config_view_get_config:
+ *
+ * Gets the #IdeConfigView:config property.
+ *
+ * Returns: (nullable) (transfer none): an #IdeConfiguration.
+ *
+ * Since: 3.32
+ */
+IdeConfiguration *
+ide_config_view_get_config (IdeConfigView *self)
+{
+  g_return_val_if_fail (IDE_IS_CONFIG_VIEW (self), NULL);
+
+  return self->config;
+}
+
+void
+ide_config_view_set_config (IdeConfigView    *self,
+                            IdeConfiguration *config)
+{
+  g_return_if_fail (IDE_IS_CONFIG_VIEW (self));
+  g_return_if_fail (!config || IDE_IS_CONFIGURATION (config));
+
+  if (self->config != config)
+    {
+      if (self->config)
+        ide_config_view_disconnect (self);
+
+      if (config)
+        ide_config_view_connect (self, config);
+
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CONFIG]);
+    }
+}
diff --git a/src/libide/config/ide-config-view.h b/src/libide/config/ide-config-view.h
new file mode 100644
index 000000000..be3a7680b
--- /dev/null
+++ b/src/libide/config/ide-config-view.h
@@ -0,0 +1,44 @@
+/* ide-config-view.h
+ *
+ * Copyright 2018 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 <dazzle.h>
+
+#include "ide-version-macros.h"
+
+#include "config/ide-configuration.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_CONFIG_VIEW (ide_config_view_get_type())
+
+IDE_AVAILABLE_IN_3_32
+G_DECLARE_FINAL_TYPE (IdeConfigView, ide_config_view, IDE, CONFIG_VIEW, GtkBin)
+
+IDE_AVAILABLE_IN_3_32
+GtkWidget        *ide_config_view_new        (void);
+IDE_AVAILABLE_IN_3_32
+void              ide_config_view_set_config (IdeConfigView    *self,
+                                              IdeConfiguration *configuration);
+IDE_AVAILABLE_IN_3_32
+IdeConfiguration *ide_config_view_get_config (IdeConfigView    *self);
+
+G_END_DECLS
diff --git a/src/libide/config/ide-config-view.ui b/src/libide/config/ide-config-view.ui
new file mode 100644
index 000000000..a33429cb6
--- /dev/null
+++ b/src/libide/config/ide-config-view.ui
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="IdeConfigView" parent="GtkBin">
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">horizontal</property>
+        <property name="visible">true</property>
+        <child>
+          <object class="DzlPreferencesView" id="preferences">
+            <property name="use-sidebar">false</property>
+            <property name="visible">true</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
\ No newline at end of file
diff --git a/src/libide/config/meson.build b/src/libide/config/meson.build
index 85a3a9e71..0d1229c5e 100644
--- a/src/libide/config/meson.build
+++ b/src/libide/config/meson.build
@@ -2,12 +2,16 @@ config_headers = [
   'ide-configuration-manager.h',
   'ide-configuration-provider.h',
   'ide-configuration.h',
+  'ide-config-view.h',
+  'ide-config-view-addin.h',
 ]
 
 config_sources = [
   'ide-configuration-manager.c',
   'ide-configuration-provider.c',
   'ide-configuration.c',
+  'ide-config-view.c',
+  'ide-config-view-addin.c',
 ]
 
 config_enums = [
diff --git a/src/libide/ide.h b/src/libide/ide.h
index 31f0f677c..6f97c816c 100644
--- a/src/libide/ide.h
+++ b/src/libide/ide.h
@@ -73,6 +73,8 @@ G_BEGIN_DECLS
 #include "config/ide-configuration.h"
 #include "config/ide-configuration-manager.h"
 #include "config/ide-configuration-provider.h"
+#include "config/ide-config-view.h"
+#include "config/ide-config-view-addin.h"
 #include "debugger/ide-debug-manager.h"
 #include "debugger/ide-debugger-breakpoint.h"
 #include "debugger/ide-debugger-breakpoints.h"
diff --git a/src/libide/libide.gresource.xml b/src/libide/libide.gresource.xml
index 72bb47c9a..f3f48190d 100644
--- a/src/libide/libide.gresource.xml
+++ b/src/libide/libide.gresource.xml
@@ -69,6 +69,7 @@
     <file preprocess="xml-stripblanks" 
alias="ide-completion-overlay.ui">completion/ide-completion-overlay.ui</file>
     <file preprocess="xml-stripblanks" 
alias="ide-completion-view.ui">completion/ide-completion-view.ui</file>
     <file preprocess="xml-stripblanks" 
alias="ide-completion-window.ui">completion/ide-completion-window.ui</file>
+    <file preprocess="xml-stripblanks" alias="ide-config-view.ui">config/ide-config-view.ui</file>
     <file preprocess="xml-stripblanks" 
alias="ide-debugger-breakpoints-view.ui">debugger/ide-debugger-breakpoints-view.ui</file>
     <file preprocess="xml-stripblanks" 
alias="ide-debugger-controls.ui">debugger/ide-debugger-controls.ui</file>
     <file preprocess="xml-stripblanks" 
alias="ide-debugger-disassembly-view.ui">debugger/ide-debugger-disassembly-view.ui</file>


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