[gnome-builder] plugins/buildui: add environment variable editor for config



commit d86a51461e4d7d7c750a8d4a02173d76903f912f
Author: Christian Hergert <chergert redhat com>
Date:   Sat Aug 27 21:03:06 2022 -0700

    plugins/buildui: add environment variable editor for config
    
    This is one of the last pieces missing from project configuration that
    would prevent us from shipping the gtk4 port. There is plenty more we
    can do here (like sysroot/toolchain stuff) but I don't think that is
    really used enought (at all?) because I can't even tell you if it works
    in the stable release.

 src/plugins/buildui/buildui.gresource.xml          |   2 +
 .../buildui/gbp-buildui-environment-editor.c       | 304 +++++++++++++++++++++
 .../buildui/gbp-buildui-environment-editor.h       |  35 +++
 .../buildui/gbp-buildui-environment-editor.ui      |  40 +++
 src/plugins/buildui/gbp-buildui-environment-row.c  | 164 +++++++++++
 src/plugins/buildui/gbp-buildui-environment-row.h  |  34 +++
 src/plugins/buildui/gbp-buildui-environment-row.ui |  53 ++++
 src/plugins/buildui/gbp-buildui-tweaks-addin.c     |  17 ++
 src/plugins/buildui/meson.build                    |   2 +
 src/plugins/buildui/tweaks.ui                      |  17 ++
 10 files changed, 668 insertions(+)
---
diff --git a/src/plugins/buildui/buildui.gresource.xml b/src/plugins/buildui/buildui.gresource.xml
index 9de612586..7e11f9a01 100644
--- a/src/plugins/buildui/buildui.gresource.xml
+++ b/src/plugins/buildui/buildui.gresource.xml
@@ -3,6 +3,8 @@
   <gresource prefix="/plugins/buildui">
     <file>buildui.plugin</file>
     <file>gtk/keybindings.json</file>
+    <file preprocess="xml-stripblanks">gbp-buildui-environment-editor.ui</file>
+    <file preprocess="xml-stripblanks">gbp-buildui-environment-row.ui</file>
     <file preprocess="xml-stripblanks">gbp-buildui-log-pane.ui</file>
     <file preprocess="xml-stripblanks">gbp-buildui-omni-bar-section.ui</file>
     <file preprocess="xml-stripblanks">gbp-buildui-pane.ui</file>
diff --git a/src/plugins/buildui/gbp-buildui-environment-editor.c 
b/src/plugins/buildui/gbp-buildui-environment-editor.c
new file mode 100644
index 000000000..6996ad7f9
--- /dev/null
+++ b/src/plugins/buildui/gbp-buildui-environment-editor.c
@@ -0,0 +1,304 @@
+/* gbp-buildui-environment-editor.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 "gbp-buildui-environment-editor"
+
+#include "config.h"
+
+#include <libide-gtk.h>
+
+#include "gbp-buildui-environment-editor.h"
+#include "gbp-buildui-environment-row.h"
+
+struct _GbpBuilduiEnvironmentEditor
+{
+  GtkWidget         parent_instance;
+
+  IdeTweaksBinding *binding;
+
+  GtkBox           *box;
+  GtkListBox       *list_box;
+};
+
+enum {
+  PROP_0,
+  PROP_BINDING,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (GbpBuilduiEnvironmentEditor, gbp_buildui_environment_editor, GTK_TYPE_WIDGET)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+on_row_remove_cb (GbpBuilduiEnvironmentEditor *self,
+                  GbpBuilduiEnvironmentRow    *row)
+{
+  g_auto(GStrv) value = NULL;
+  const char *variable;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_EDITOR (self));
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_ROW (row));
+
+  if (self->binding == NULL)
+    return;
+
+  if (!(variable = gbp_buildui_environment_row_get_variable (row)))
+    return;
+
+  value = ide_tweaks_binding_dup_strv (self->binding);
+  if (ide_strv_remove_from_set (value, variable))
+    ide_tweaks_binding_set_strv (self->binding, (const char * const *)value);
+}
+
+static GtkWidget *
+gbp_buildui_environment_editor_create_row_cb (gpointer item,
+                                              gpointer user_data)
+{
+  GbpBuilduiEnvironmentEditor *self = user_data;
+  GtkStringObject *object = item;
+  const char *str = gtk_string_object_get_string (object);
+  GtkWidget *row = gbp_buildui_environment_row_new (str);
+
+  g_signal_connect_object (row,
+                           "remove",
+                           G_CALLBACK (on_row_remove_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  return row;
+}
+
+static void
+on_binding_changed_cb (GbpBuilduiEnvironmentEditor *self,
+                       IdeTweaksBinding            *binding)
+{
+  g_auto(GStrv) strv = NULL;
+  g_autoptr(GtkStringList) model = NULL;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_EDITOR (self));
+  g_assert (IDE_IS_TWEAKS_BINDING (binding));
+
+  strv = ide_tweaks_binding_dup_strv (binding);
+  model = gtk_string_list_new ((const char * const *)strv);
+
+  gtk_list_box_bind_model (self->list_box,
+                           G_LIST_MODEL (model),
+                           gbp_buildui_environment_editor_create_row_cb,
+                           self, NULL);
+
+  gtk_widget_set_visible (GTK_WIDGET (self->list_box),
+                          g_list_model_get_n_items (G_LIST_MODEL (model)) > 0);
+}
+
+static void
+on_entry_activate_cb (GbpBuilduiEnvironmentEditor *self,
+                      const char                  *text,
+                      IdeEntryPopover             *popover)
+{
+  g_autofree char *copy = NULL;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_EDITOR (self));
+  g_assert (IDE_IS_ENTRY_POPOVER (popover));
+
+  /* First copy the text so we can clear it */
+  copy = g_strdup (ide_entry_popover_get_text (popover));
+
+  /* Clear and dismiss popover */
+  ide_entry_popover_set_text (popover, "");
+  gtk_popover_popdown (GTK_POPOVER (popover));
+
+  /* Now request that the variable be added */
+  if (!ide_str_empty0 (copy))
+    gtk_widget_activate_action (GTK_WIDGET (self), "variable.add", "s", text);
+}
+
+static void
+on_entry_changed_cb (GbpBuilduiEnvironmentEditor *self,
+                     IdeEntryPopover             *popover)
+{
+  gboolean valid = FALSE;
+  const char *text;
+  const char *eq;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_EDITOR (self));
+  g_assert (IDE_IS_ENTRY_POPOVER (popover));
+
+  text = ide_entry_popover_get_text (popover);
+  eq = strchr (text, '=');
+
+  if (eq != NULL && eq != text)
+    {
+      for (const char *iter = text; iter < eq; iter = g_utf8_next_char (iter))
+        {
+          gunichar ch = g_utf8_get_char (iter);
+
+          if (!g_unichar_isalnum (ch) && ch != '_')
+            goto failure;
+        }
+
+      if (g_ascii_isalpha (*text))
+        valid = TRUE;
+    }
+
+failure:
+  ide_entry_popover_set_ready (popover, valid);
+}
+
+static void
+variable_add_action (GtkWidget  *widget,
+                     const char *action_name,
+                     GVariant   *param)
+{
+  GbpBuilduiEnvironmentEditor *self = (GbpBuilduiEnvironmentEditor *)widget;
+  g_auto(GStrv) value = NULL;
+  const char *text;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_EDITOR (self));
+  g_assert (param != NULL);
+  g_assert (g_variant_is_of_type (param, G_VARIANT_TYPE_STRING));
+
+  if (self->binding == NULL)
+    return;
+
+  text = g_variant_get_string (param, NULL);
+  value = ide_tweaks_binding_dup_strv (self->binding);
+
+  if (ide_strv_add_to_set (&value, g_strdup (text)))
+    ide_tweaks_binding_set_strv (self->binding, (const char * const *)value);
+}
+
+static void
+gbp_buildui_environment_editor_constructed (GObject *object)
+{
+  GbpBuilduiEnvironmentEditor *self = (GbpBuilduiEnvironmentEditor *)object;
+  GType type;
+
+  G_OBJECT_CLASS (gbp_buildui_environment_editor_parent_class)->constructed (object);
+
+  if (self->binding == NULL)
+    return;
+
+  if (!ide_tweaks_binding_get_expected_type (self->binding, &type) || type != G_TYPE_STRV)
+    return;
+
+  g_signal_connect_object (self->binding,
+                           "changed",
+                           G_CALLBACK (on_binding_changed_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  on_binding_changed_cb (self, self->binding);
+}
+
+static void
+gbp_buildui_environment_editor_dispose (GObject *object)
+{
+  GbpBuilduiEnvironmentEditor *self = (GbpBuilduiEnvironmentEditor *)object;
+
+  g_clear_pointer ((GtkWidget **)&self->box, gtk_widget_unparent);
+  g_clear_object (&self->binding);
+
+  G_OBJECT_CLASS (gbp_buildui_environment_editor_parent_class)->dispose (object);
+}
+
+static void
+gbp_buildui_environment_editor_get_property (GObject    *object,
+                                             guint       prop_id,
+                                             GValue     *value,
+                                             GParamSpec *pspec)
+{
+  GbpBuilduiEnvironmentEditor *self = GBP_BUILDUI_ENVIRONMENT_EDITOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_BINDING:
+      g_value_set_object (value, self->binding);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_buildui_environment_editor_set_property (GObject      *object,
+                                             guint         prop_id,
+                                             const GValue *value,
+                                             GParamSpec   *pspec)
+{
+  GbpBuilduiEnvironmentEditor *self = GBP_BUILDUI_ENVIRONMENT_EDITOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_BINDING:
+      self->binding = g_value_dup_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_buildui_environment_editor_class_init (GbpBuilduiEnvironmentEditorClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->constructed = gbp_buildui_environment_editor_constructed;
+  object_class->dispose = gbp_buildui_environment_editor_dispose;
+  object_class->get_property = gbp_buildui_environment_editor_get_property;
+  object_class->set_property = gbp_buildui_environment_editor_set_property;
+
+  properties[PROP_BINDING] =
+    g_param_spec_object ("binding", NULL, NULL,
+                         IDE_TYPE_TWEAKS_BINDING,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/plugins/buildui/gbp-buildui-environment-editor.ui");
+  gtk_widget_class_bind_template_child (widget_class, GbpBuilduiEnvironmentEditor, box);
+  gtk_widget_class_bind_template_child (widget_class, GbpBuilduiEnvironmentEditor, list_box);
+  gtk_widget_class_bind_template_callback (widget_class, on_entry_activate_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_entry_changed_cb);
+
+  gtk_widget_class_install_action (widget_class, "variable.add", "s", variable_add_action);
+
+  g_type_ensure (IDE_TYPE_ENTRY_POPOVER);
+}
+
+static void
+gbp_buildui_environment_editor_init (GbpBuilduiEnvironmentEditor *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GtkWidget *
+gbp_buildui_environment_editor_new (IdeTweaksBinding *binding)
+{
+  g_return_val_if_fail (IDE_IS_TWEAKS_BINDING (binding), NULL);
+
+  return g_object_new (GBP_TYPE_BUILDUI_ENVIRONMENT_EDITOR,
+                       "binding", binding,
+                       NULL);
+}
diff --git a/src/plugins/buildui/gbp-buildui-environment-editor.h 
b/src/plugins/buildui/gbp-buildui-environment-editor.h
new file mode 100644
index 000000000..dc1d46e22
--- /dev/null
+++ b/src/plugins/buildui/gbp-buildui-environment-editor.h
@@ -0,0 +1,35 @@
+/* gbp-buildui-environment-editor.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 <gtk/gtk.h>
+
+#include <libide-tweaks.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_BUILDUI_ENVIRONMENT_EDITOR (gbp_buildui_environment_editor_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpBuilduiEnvironmentEditor, gbp_buildui_environment_editor, GBP, 
BUILDUI_ENVIRONMENT_EDITOR, GtkWidget)
+
+GtkWidget *gbp_buildui_environment_editor_new (IdeTweaksBinding *binding);
+
+G_END_DECLS
diff --git a/src/plugins/buildui/gbp-buildui-environment-editor.ui 
b/src/plugins/buildui/gbp-buildui-environment-editor.ui
new file mode 100644
index 000000000..b29aa9e08
--- /dev/null
+++ b/src/plugins/buildui/gbp-buildui-environment-editor.ui
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GbpBuilduiEnvironmentEditor">
+    <child>
+      <object class="GtkBox" id="box">
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkListBox" id="list_box">
+            <property name="selection-mode">none</property>
+            <property name="visible">false</property>
+            <style>
+              <class name="boxed-list"/>
+            </style>
+          </object>
+        </child>
+        <child>
+          <object class="GtkMenuButton">
+            <property name="direction">left</property>
+            <property name="halign">end</property>
+            <property name="child">
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">Add _Variable</property>
+                <property name="use-underline">true</property>
+              </object>
+            </property>
+            <property name="popover">
+              <object class="IdeEntryPopover">
+                <property name="title" translatable="yes">Add Variable</property>
+                <property name="button-text" translatable="yes">_Add</property>
+                <signal name="activate" handler="on_entry_activate_cb" swapped="true" 
object="GbpBuilduiEnvironmentEditor"/>
+                <signal name="changed" handler="on_entry_changed_cb" swapped="true" 
object="GbpBuilduiEnvironmentEditor"/>
+              </object>
+            </property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/plugins/buildui/gbp-buildui-environment-row.c 
b/src/plugins/buildui/gbp-buildui-environment-row.c
new file mode 100644
index 000000000..8f75b43e6
--- /dev/null
+++ b/src/plugins/buildui/gbp-buildui-environment-row.c
@@ -0,0 +1,164 @@
+/* gbp-buildui-environment-row.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 "gbp-buildui-environment-row"
+
+#include "config.h"
+
+#include "gbp-buildui-environment-row.h"
+
+struct _GbpBuilduiEnvironmentRow
+{
+  GtkListBoxRow parent_instance;
+  GtkLabel *variable;
+};
+
+enum {
+  PROP_0,
+  PROP_VARIABLE,
+  N_PROPS
+};
+
+enum {
+  REMOVE,
+  N_SIGNALS
+};
+
+G_DEFINE_FINAL_TYPE (GbpBuilduiEnvironmentRow, gbp_buildui_environment_row, GTK_TYPE_LIST_BOX_ROW)
+
+static GParamSpec *properties [N_PROPS];
+static guint signals [N_SIGNALS];
+
+static void
+variable_copy_action (GtkWidget  *widget,
+                      const char *action_name,
+                      GVariant   *param)
+{
+  GbpBuilduiEnvironmentRow *self = (GbpBuilduiEnvironmentRow *)widget;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_ROW (self));
+
+  gdk_clipboard_set_text (gtk_widget_get_clipboard (widget),
+                          gbp_buildui_environment_row_get_variable (self));
+}
+
+static void
+variable_remove_action (GtkWidget  *widget,
+                        const char *action_name,
+                        GVariant   *param)
+{
+  GbpBuilduiEnvironmentRow *self = (GbpBuilduiEnvironmentRow *)widget;
+
+  g_assert (GBP_IS_BUILDUI_ENVIRONMENT_ROW (self));
+
+  g_signal_emit (self, signals [REMOVE], 0);
+}
+
+static void
+gbp_buildui_environment_row_get_property (GObject    *object,
+                                          guint       prop_id,
+                                          GValue     *value,
+                                          GParamSpec *pspec)
+{
+  GbpBuilduiEnvironmentRow *self = GBP_BUILDUI_ENVIRONMENT_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_VARIABLE:
+      g_value_set_string (value, gbp_buildui_environment_row_get_variable (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_buildui_environment_row_set_property (GObject      *object,
+                                          guint         prop_id,
+                                          const GValue *value,
+                                          GParamSpec   *pspec)
+{
+  GbpBuilduiEnvironmentRow *self = GBP_BUILDUI_ENVIRONMENT_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_VARIABLE:
+      gtk_label_set_label (self->variable, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_buildui_environment_row_class_init (GbpBuilduiEnvironmentRowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->get_property = gbp_buildui_environment_row_get_property;
+  object_class->set_property = gbp_buildui_environment_row_set_property;
+
+  properties[PROP_VARIABLE] =
+    g_param_spec_string ("variable", NULL, NULL,
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  signals [REMOVE] =
+    g_signal_new ("remove",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE, 0);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/plugins/buildui/gbp-buildui-environment-row.ui");
+  gtk_widget_class_bind_template_child (widget_class, GbpBuilduiEnvironmentRow, variable);
+
+  gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL, variable_copy_action);
+  gtk_widget_class_install_action (widget_class, "variable.remove", NULL, variable_remove_action);
+}
+
+static void
+gbp_buildui_environment_row_init (GbpBuilduiEnvironmentRow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GtkWidget *
+gbp_buildui_environment_row_new (const char *variable)
+{
+  return g_object_new (GBP_TYPE_BUILDUI_ENVIRONMENT_ROW,
+                       "variable", variable,
+                       NULL);
+}
+
+const char *
+gbp_buildui_environment_row_get_variable (GbpBuilduiEnvironmentRow *self)
+{
+  g_return_val_if_fail (GBP_IS_BUILDUI_ENVIRONMENT_ROW (self), NULL);
+
+  return gtk_label_get_label (self->variable);
+}
diff --git a/src/plugins/buildui/gbp-buildui-environment-row.h 
b/src/plugins/buildui/gbp-buildui-environment-row.h
new file mode 100644
index 000000000..332f1e725
--- /dev/null
+++ b/src/plugins/buildui/gbp-buildui-environment-row.h
@@ -0,0 +1,34 @@
+/* gbp-buildui-environment-row.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 <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_BUILDUI_ENVIRONMENT_ROW (gbp_buildui_environment_row_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpBuilduiEnvironmentRow, gbp_buildui_environment_row, GBP, BUILDUI_ENVIRONMENT_ROW, 
GtkListBoxRow)
+
+GtkWidget  *gbp_buildui_environment_row_new          (const char               *variable);
+const char *gbp_buildui_environment_row_get_variable (GbpBuilduiEnvironmentRow *self);
+
+G_END_DECLS
diff --git a/src/plugins/buildui/gbp-buildui-environment-row.ui 
b/src/plugins/buildui/gbp-buildui-environment-row.ui
new file mode 100644
index 000000000..3d1605257
--- /dev/null
+++ b/src/plugins/buildui/gbp-buildui-environment-row.ui
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GbpBuilduiEnvironmentRow" parent="GtkListBoxRow">
+    <property name="activatable">false</property>
+    <child>
+      <object class="GtkBox">
+        <property name="margin-end">12</property>
+        <property name="margin-start">12</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkLabel" id="variable">
+            <property name="ellipsize">end</property>
+            <property name="hexpand">true</property>
+            <property name="margin-bottom">12</property>
+            <property name="margin-top">12</property>
+            <property name="selectable">true</property>
+            <property name="xalign">.0</property>
+            <attributes>
+              <attribute name="family" value="monospace"/>
+              <attribute name="scale" value=".9"/>
+            </attributes>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton">
+            <property name="icon-name">edit-copy-symbolic</property>
+            <property name="action-name">clipboard.copy</property>
+            <property name="valign">center</property>
+            <property name="tooltip-text" translatable="yes">Copy</property>
+            <style>
+              <class name="image-button"/>
+              <class name="circular"/>
+              <class name="flat"/>
+            </style>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton">
+            <property name="icon-name">list-remove-symbolic</property>
+            <property name="action-name">variable.remove</property>
+            <property name="valign">center</property>
+            <property name="tooltip-text" translatable="yes">Remove</property>
+            <style>
+              <class name="image-button"/>
+              <class name="circular"/>
+              <class name="flat"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/plugins/buildui/gbp-buildui-tweaks-addin.c b/src/plugins/buildui/gbp-buildui-tweaks-addin.c
index 350501f8c..e6c2eefdb 100644
--- a/src/plugins/buildui/gbp-buildui-tweaks-addin.c
+++ b/src/plugins/buildui/gbp-buildui-tweaks-addin.c
@@ -26,6 +26,7 @@
 
 #include <libide-foundry.h>
 
+#include "gbp-buildui-environment-editor.h"
 #include "gbp-buildui-tweaks-addin.h"
 
 struct _GbpBuilduiTweaksAddin
@@ -102,6 +103,21 @@ create_runtime_list_cb (GbpBuilduiTweaksAddin *self,
   return GTK_WIDGET (row);
 }
 
+static GtkWidget *
+create_environ_editor_cb (GbpBuilduiTweaksAddin *self,
+                          IdeTweaksWidget       *widget,
+                          IdeTweaksWidget       *instance)
+{
+  IdeTweaksBinding *binding;
+
+  g_assert (GBP_IS_BUILDUI_TWEAKS_ADDIN (self));
+
+  if (!(binding = ide_tweaks_widget_get_binding (widget)))
+    return NULL;
+
+  return gbp_buildui_environment_editor_new (binding);
+}
+
 static void
 gbp_buildui_tweaks_addin_load (IdeTweaksAddin *addin,
                                IdeTweaks      *tweaks)
@@ -128,6 +144,7 @@ gbp_buildui_tweaks_addin_load (IdeTweaksAddin *addin,
     }
 
   ide_tweaks_addin_bind_callback (IDE_TWEAKS_ADDIN (self), create_runtime_list_cb);
+  ide_tweaks_addin_bind_callback (IDE_TWEAKS_ADDIN (self), create_environ_editor_cb);
   ide_tweaks_addin_set_resource_paths (IDE_TWEAKS_ADDIN (self),
                                        IDE_STRV_INIT ("/plugins/buildui/tweaks.ui"));
 
diff --git a/src/plugins/buildui/meson.build b/src/plugins/buildui/meson.build
index a59ac0cc8..96de9a81b 100644
--- a/src/plugins/buildui/meson.build
+++ b/src/plugins/buildui/meson.build
@@ -1,6 +1,8 @@
 plugins_sources += files([
   'buildui-plugin.c',
   'gbp-buildui-editor-page-addin.c',
+  'gbp-buildui-environment-editor.c',
+  'gbp-buildui-environment-row.c',
   'gbp-buildui-log-pane.c',
   'gbp-buildui-omni-bar-section.c',
   'gbp-buildui-pane.c',
diff --git a/src/plugins/buildui/tweaks.ui b/src/plugins/buildui/tweaks.ui
index 2b5f0d581..925a417a8 100644
--- a/src/plugins/buildui/tweaks.ui
+++ b/src/plugins/buildui/tweaks.ui
@@ -389,6 +389,23 @@
                     </child>
                   </object>
                 </child>
+                <child>
+                  <object class="IdeTweaksGroup">
+                    <child>
+                      <object class="IdeTweaksWidget">
+                        <signal name="create-for-item" handler="create_environ_editor_cb" swapped="true" 
object="GbpBuilduiTweaksAddin"/>
+                        <property name="binding">
+                          <object class="IdeTweaksProperty">
+                            <property name="name">environ</property>
+                            <binding name="object">
+                              <lookup name="item">config_factory</lookup>
+                            </binding>
+                          </object>
+                        </property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
               </object>
             </child>
           </object>


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