gplugin/gplugin

Add a settings list to plugins page

16 months ago, Elliott Sales de Andrade
bc5f36d168a5
Parents 63c86ee51e6a
Children a4ee5a7bbbe9
Add a settings list to plugins page

This currently creates a **placeholder** widget that simply displays the setting value. I do have a local copy with proper widgets for most cases, but I need to go through and confirm that everything useful is covered (`GVariant` is very flexible, but I think settings are less so.)

Additionally, because of the way that settings are loaded from the devenv, we don't get the summary/description, so those won't load just yet. I've left those out of here for now so this only displays the key name. Once https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2893 is complete, then we can put everything into a resource and the summary/description will work properly.

Testing Done:
Compiled only.

Reviewed at https://reviews.imfreedom.org/r/2129/
--- a/gplugin-gtk4/data/gplugin-gtk.gresource.xml Tue Dec 13 00:44:10 2022 -0600
+++ b/gplugin-gtk4/data/gplugin-gtk.gresource.xml Tue Dec 13 01:55:01 2022 -0600
@@ -3,6 +3,7 @@
<gresource prefix="/org/imfreedom/keep/gplugin/gplugin-gtk/">
<file compressed="true" preprocess="xml-stripblanks">plugin-page.ui</file>
<file compressed="true" preprocess="xml-stripblanks">plugin-row.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">plugin-settings-list.ui</file>
<file compressed="true" preprocess="xml-stripblanks">view.ui</file>
</gresource>
</gresources>
--- a/gplugin-gtk4/data/plugin-page.ui Tue Dec 13 00:44:10 2022 -0600
+++ b/gplugin-gtk4/data/plugin-page.ui Tue Dec 13 01:55:01 2022 -0600
@@ -432,6 +432,10 @@
</property>
</object>
</child>
+ <child>
+ <object class="GPluginGtkPluginSettingsList" id="settings">
+ </object>
+ </child>
</template>
<object class="GtkSizeGroup">
<property name="mode">horizontal</property>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-gtk4/data/plugin-settings-list.ui Tue Dec 13 01:55:01 2022 -0600
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk" version="4.0"/>
+ <template class="GPluginGtkPluginSettingsList" parent="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="css-classes">title-2</property>
+ <property name="label" translatable="1">Settings</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <child>
+ <object class="GtkListBox" id="list_box">
+ <property name="css-classes">rich-list</property>
+ <property name="selection-mode">none</property>
+ <property name="show-separators">1</property>
+ <child type="placeholder">
+ <object class="GtkLabel">
+ <property name="css-classes">large-title</property>
+ <property name="label" translatable="1">No settings available</property>
+ <property name="margin-bottom">24</property>
+ <property name="margin-end">24</property>
+ <property name="margin-start">24</property>
+ <property name="margin-top">24</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
--- a/gplugin-gtk4/gplugin-gtk-plugin-page.c Tue Dec 13 00:44:10 2022 -0600
+++ b/gplugin-gtk4/gplugin-gtk-plugin-page.c Tue Dec 13 01:55:01 2022 -0600
@@ -21,6 +21,7 @@
#include <gplugin-gtk-plugin-closures.h>
#include <gplugin-gtk-plugin-page.h>
+#include <gplugin-gtk-plugin-settings-list.h>
#define G_SETTINGS_ENABLE_BACKEND
#include <gio/gsettingsbackend.h>
@@ -42,6 +43,8 @@
GPluginPlugin *plugin;
GSettingsBackend *backend;
+
+ GPluginGtkPluginSettingsList *settings;
};
/******************************************************************************
@@ -66,6 +69,36 @@
};
/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+gplugin_gtk_plugin_page_update_settings_list(GPluginGtkPluginPage *page)
+{
+ GSettings *settings = NULL;
+
+ if(GPLUGIN_IS_PLUGIN(page->plugin)) {
+ GPluginPluginInfo *info = NULL;
+
+ info = gplugin_plugin_get_info(page->plugin);
+ if(GPLUGIN_IS_PLUGIN_INFO(info)) {
+ const gchar *schema = NULL;
+
+ schema = gplugin_plugin_info_get_settings_schema(info);
+ if(schema != NULL) {
+ if(page->backend != NULL) {
+ settings =
+ g_settings_new_with_backend(schema, page->backend);
+ } else {
+ settings = g_settings_new(schema);
+ }
+ }
+ }
+ }
+
+ gplugin_gtk_plugin_settings_list_set_settings(page->settings, settings);
+}
+
+/******************************************************************************
* Callbacks
*****************************************************************************/
static gboolean
@@ -285,6 +318,11 @@
widget_class,
"/org/imfreedom/keep/gplugin/gplugin-gtk/plugin-page.ui");
+ gtk_widget_class_bind_template_child(
+ widget_class,
+ GPluginGtkPluginPage,
+ settings);
+
gtk_widget_class_bind_template_callback(
widget_class,
gplugin_gtk_lookup_plugin_name);
@@ -353,6 +391,8 @@
g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_PAGE(page));
if(g_set_object(&page->plugin, plugin)) {
+ gplugin_gtk_plugin_page_update_settings_list(page);
+
g_object_notify_by_pspec(G_OBJECT(page), properties[PROP_PLUGIN]);
}
}
@@ -399,6 +439,8 @@
g_return_if_fail(G_IS_SETTINGS_BACKEND(backend) || backend == NULL);
if(g_set_object(&page->backend, backend)) {
+ gplugin_gtk_plugin_page_update_settings_list(page);
+
g_object_notify_by_pspec(
G_OBJECT(page),
properties[PROP_SETTINGS_BACKEND]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-gtk4/gplugin-gtk-plugin-settings-list.c Tue Dec 13 01:55:01 2022 -0600
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2022 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <gplugin.h>
+
+#include <gplugin-gtk-plugin-settings-list.h>
+
+/**
+ * GPluginGtkPluginSettingslist:
+ *
+ * A [class@Gtk.ListBox] widget that displays all the settings from a plugin.
+ *
+ * Since: 0.40.0
+ */
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+struct _GPluginGtkPluginSettingsList {
+ GtkBox parent;
+
+ GSettings *settings;
+ GtkListBox *list_box;
+ GList *rows;
+};
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_ZERO,
+ PROP_SETTINGS,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {
+ NULL,
+};
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static GtkWidget *
+gplugin_gtk_plugin_settings_row_new_for_key(
+ GSettings *settings,
+ const gchar *name,
+ GSettingsSchemaKey *key)
+{
+ /* TODO: Make real widgets. */
+ GtkWidget *widget = NULL;
+ GtkWidget *label = NULL;
+ GtkWidget *entry = NULL;
+ GVariant *value = NULL;
+ char *value_str = NULL;
+
+ widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
+
+ label = gtk_label_new(g_settings_schema_key_get_name(key));
+ gtk_label_set_xalign(GTK_LABEL(label), 0);
+ gtk_box_append(GTK_BOX(widget), label);
+
+ value = g_settings_get_value(settings, name);
+ value_str = g_variant_print(value, TRUE);
+ g_variant_unref(value);
+
+ entry = gtk_entry_new();
+ gtk_editable_set_text(GTK_EDITABLE(entry), value_str);
+ gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
+ gtk_widget_set_hexpand(entry, TRUE);
+ gtk_box_append(GTK_BOX(widget), entry);
+
+ g_free(value_str);
+
+ return widget;
+}
+
+static void
+gplugin_gtk_plugin_settings_list_refresh(
+ GPluginGtkPluginSettingsList *list,
+ GSettings *settings)
+{
+ GSettingsSchema *schema = NULL;
+ gchar **names = NULL;
+
+ while(list->rows) {
+ gtk_list_box_remove(list->list_box, list->rows->data);
+ list->rows = g_list_delete_link(list->rows, list->rows);
+ }
+
+ if(settings == NULL) {
+ return;
+ }
+
+ g_object_get(G_OBJECT(settings), "settings-schema", &schema, NULL);
+ names = g_settings_schema_list_keys(schema);
+
+ for(gint i = 0; names[i] != NULL; i++) {
+ GSettingsSchemaKey *key = NULL;
+ GtkWidget *row = NULL;
+ GtkWidget *widget = NULL;
+
+ key = g_settings_schema_get_key(schema, names[i]);
+ widget = gplugin_gtk_plugin_settings_row_new_for_key(
+ settings,
+ names[i],
+ key);
+
+ row = gtk_list_box_row_new();
+ gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(row), widget);
+ gtk_widget_set_focusable(row, FALSE);
+ gtk_list_box_append(list->list_box, row);
+
+ list->rows = g_list_append(list->rows, row);
+
+ g_settings_schema_key_unref(key);
+ }
+
+ g_strfreev(names);
+ g_settings_schema_unref(schema);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(
+ GPluginGtkPluginSettingsList,
+ gplugin_gtk_plugin_settings_list,
+ GTK_TYPE_BOX)
+
+static void
+gplugin_gtk_plugin_settings_list_set_property(
+ GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GPluginGtkPluginSettingsList *list = GPLUGIN_GTK_PLUGIN_SETTINGS_LIST(obj);
+
+ switch(prop_id) {
+ case PROP_SETTINGS:
+ gplugin_gtk_plugin_settings_list_set_settings(
+ list,
+ g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gplugin_gtk_plugin_settings_list_get_property(
+ GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GPluginGtkPluginSettingsList *list = GPLUGIN_GTK_PLUGIN_SETTINGS_LIST(obj);
+
+ switch(prop_id) {
+ case PROP_SETTINGS:
+ g_value_set_object(
+ value,
+ gplugin_gtk_plugin_settings_list_get_settings(list));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gplugin_gtk_plugin_settings_list_finalize(GObject *obj)
+{
+ GPluginGtkPluginSettingsList *list = GPLUGIN_GTK_PLUGIN_SETTINGS_LIST(obj);
+
+ g_clear_object(&list->settings);
+ g_clear_pointer(&list->rows, g_list_free);
+
+ G_OBJECT_CLASS(gplugin_gtk_plugin_settings_list_parent_class)
+ ->finalize(obj);
+}
+
+static void
+gplugin_gtk_plugin_settings_list_class_init(
+ GPluginGtkPluginSettingsListClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+ obj_class->get_property = gplugin_gtk_plugin_settings_list_get_property;
+ obj_class->set_property = gplugin_gtk_plugin_settings_list_set_property;
+ obj_class->finalize = gplugin_gtk_plugin_settings_list_finalize;
+
+ gtk_widget_class_set_template_from_resource(
+ widget_class,
+ "/org/imfreedom/keep/gplugin/gplugin-gtk/plugin-settings-list.ui");
+
+ gtk_widget_class_bind_template_child(
+ widget_class,
+ GPluginGtkPluginSettingsList,
+ list_box);
+
+ /* properties */
+
+ /**
+ * GPluginGtkPluginSettingsList:settings:
+ *
+ * The [class@Gio.Settings] to display.
+ */
+ properties[PROP_SETTINGS] = g_param_spec_object(
+ "settings",
+ "settings",
+ "The settings to display",
+ G_TYPE_SETTINGS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+static void
+gplugin_gtk_plugin_settings_list_init(GPluginGtkPluginSettingsList *self)
+{
+ gtk_widget_init_template(GTK_WIDGET(self));
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+
+/**
+ * gplugin_gtk_plugin_settings_list_new:
+ *
+ * Creates a new [class@GPluginGtk4.PluginSettingsList].
+ *
+ * Returns: (transfer full): The new list.
+ *
+ * Since: 0.40.0
+ */
+GtkWidget *
+gplugin_gtk_plugin_settings_list_new(void)
+{
+ return g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_SETTINGS_LIST, NULL);
+}
+
+/**
+ * gplugin_gtk_plugin_settings_list_set_settings:
+ * @list: The instance.
+ * @settings: (transfer none) (nullable): The plugin settings to display.
+ *
+ * This function will set which plugin settings to display.
+ *
+ * Since: 0.40.0
+ */
+void
+gplugin_gtk_plugin_settings_list_set_settings(
+ GPluginGtkPluginSettingsList *list,
+ GSettings *settings)
+{
+ g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_SETTINGS_LIST(list));
+ g_return_if_fail(G_IS_SETTINGS(settings) || settings == NULL);
+
+ if(g_set_object(&list->settings, settings)) {
+ gplugin_gtk_plugin_settings_list_refresh(list, settings);
+
+ g_object_notify(G_OBJECT(list), "settings");
+ }
+}
+
+/**
+ * gplugin_gtk_plugin_settings_list_get_settings:
+ * @list: The instance.
+ *
+ * Returns the plugin settings that are being displayed.
+ *
+ * Returns: (transfer none): The settings being displayed.
+ *
+ * Since: 0.40.0
+ */
+GSettings *
+gplugin_gtk_plugin_settings_list_get_settings(
+ GPluginGtkPluginSettingsList *list)
+{
+ g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_SETTINGS_LIST(list), NULL);
+
+ return list->settings;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gplugin-gtk4/gplugin-gtk-plugin-settings-list.h Tue Dec 13 01:55:01 2022 -0600
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(GPLUGIN_GTK_GLOBAL_HEADER_INSIDE) && \
+ !defined(GPLUGIN_GTK_COMPILATION)
+#error "only <gplugin-gtk.h> may be included directly"
+#endif
+
+#ifndef GPLUGIN_GTK_PLUGIN_SETTINGS_LIST_H
+#define GPLUGIN_GTK_PLUGIN_SETTINGS_LIST_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+
+#include <gplugin.h>
+
+G_BEGIN_DECLS
+
+#define GPLUGIN_GTK_TYPE_PLUGIN_SETTINGS_LIST \
+ (gplugin_gtk_plugin_settings_list_get_type())
+G_DECLARE_FINAL_TYPE(
+ GPluginGtkPluginSettingsList,
+ gplugin_gtk_plugin_settings_list,
+ GPLUGIN_GTK,
+ PLUGIN_SETTINGS_LIST,
+ GtkBox)
+
+GtkWidget *gplugin_gtk_plugin_settings_list_new(void);
+
+void gplugin_gtk_plugin_settings_list_set_settings(
+ GPluginGtkPluginSettingsList *list,
+ GSettings *settings);
+GSettings *gplugin_gtk_plugin_settings_list_get_settings(
+ GPluginGtkPluginSettingsList *list);
+
+G_END_DECLS
+
+#endif /* GPLUGIN_GTK_PLUGIN_SETTINGS_LIST_H */
--- a/gplugin-gtk4/meson.build Tue Dec 13 00:44:10 2022 -0600
+++ b/gplugin-gtk4/meson.build Tue Dec 13 01:55:01 2022 -0600
@@ -12,12 +12,14 @@
GPLUGIN_GTK4_SOURCES = [
'gplugin-gtk-plugin-page.c',
'gplugin-gtk-plugin-row.c',
+ 'gplugin-gtk-plugin-settings-list.c',
'gplugin-gtk-view.c',
]
GPLUGIN_GTK4_HEADERS = [
'gplugin-gtk-plugin-page.h',
'gplugin-gtk-plugin-row.h',
+ 'gplugin-gtk-plugin-settings-list.h',
'gplugin-gtk-view.h',
]
--- a/po/POTFILES Tue Dec 13 00:44:10 2022 -0600
+++ b/po/POTFILES Tue Dec 13 01:55:01 2022 -0600
@@ -1,8 +1,10 @@
gplugin-gtk4/data/plugin-page.ui
gplugin-gtk4/data/plugin-row.ui
+gplugin-gtk4/data/plugin-settings-list.ui
gplugin-gtk4/data/view.ui
gplugin-gtk4/gplugin-gtk-plugin-page.c
gplugin-gtk4/gplugin-gtk-plugin-row.c
+gplugin-gtk4/gplugin-gtk-plugin-settings-list.c
gplugin-gtk4/gplugin-gtk-view.c
gplugin-gtk4-viewer/data/window.ui
gplugin-gtk4-viewer/gplugin-gtk-viewer-window.c