gplugin/gplugin

Rename gplugin-gtk to gplugin-gtk3

2021-09-30, Gary Kramlich
130949050a8a
Parents 72edc8323368
Children 82687b8b1f97
Rename gplugin-gtk to gplugin-gtk3

Testing Done:
Built and ran the unit tests and gplugin-gtk3-viewer on my dev machine.
Built the debian packages, installed them in a container and ran gplugin-gtk3-viewer via broadway.
Built the fedora packages, installed them in a container and ran gplugin-gtk3-viewer via broadway.

Bugs closed: GPLUGIN-98

Reviewed at https://reviews.imfreedom.org/r/961/
  • +2 -2
    convey.yml
  • +0 -6
    gplugin-gtk-viewer/data/gplugin-gtk-viewer.gresource.xml
  • +0 -65
    gplugin-gtk-viewer/data/window.ui
  • +0 -54
    gplugin-gtk-viewer/gplugin-gtk-viewer-window.c
  • +0 -40
    gplugin-gtk-viewer/gplugin-gtk-viewer-window.h
  • +0 -237
    gplugin-gtk-viewer/gplugin-gtk-viewer.c
  • +0 -36
    gplugin-gtk-viewer/meson.build
  • +0 -6
    gplugin-gtk/data/gplugin-gtk.gresource.xml
  • +0 -582
    gplugin-gtk/data/plugin-info.ui
  • +0 -494
    gplugin-gtk/gplugin-gtk-plugin-info.c
  • +0 -52
    gplugin-gtk/gplugin-gtk-plugin-info.h
  • +0 -325
    gplugin-gtk/gplugin-gtk-store.c
  • +0 -57
    gplugin-gtk/gplugin-gtk-store.h
  • +0 -317
    gplugin-gtk/gplugin-gtk-view.c
  • +0 -50
    gplugin-gtk/gplugin-gtk-view.h
  • +0 -34
    gplugin-gtk/gplugin-gtk.h.in
  • +0 -36
    gplugin-gtk/gplugin-gtk.xml.in
  • +0 -154
    gplugin-gtk/meson.build
  • +0 -48
    gplugin-gtk/reference/gplugin-gtk.toml.in
  • +0 -31
    gplugin-gtk/reference/meson.build
  • +0 -11
    gplugin-gtk/reference/urlmap.js
  • +6 -0
    gplugin-gtk3-viewer/data/gplugin-gtk-viewer.gresource.xml
  • +65 -0
    gplugin-gtk3-viewer/data/window.ui
  • +54 -0
    gplugin-gtk3-viewer/gplugin-gtk-viewer-window.c
  • +40 -0
    gplugin-gtk3-viewer/gplugin-gtk-viewer-window.h
  • +237 -0
    gplugin-gtk3-viewer/gplugin-gtk-viewer.c
  • +36 -0
    gplugin-gtk3-viewer/meson.build
  • +6 -0
    gplugin-gtk3/data/gplugin-gtk.gresource.xml
  • +582 -0
    gplugin-gtk3/data/plugin-info.ui
  • +496 -0
    gplugin-gtk3/gplugin-gtk-plugin-info.c
  • +52 -0
    gplugin-gtk3/gplugin-gtk-plugin-info.h
  • +326 -0
    gplugin-gtk3/gplugin-gtk-store.c
  • +57 -0
    gplugin-gtk3/gplugin-gtk-store.h
  • +318 -0
    gplugin-gtk3/gplugin-gtk-view.c
  • +50 -0
    gplugin-gtk3/gplugin-gtk-view.h
  • +34 -0
    gplugin-gtk3/gplugin-gtk.h.in
  • +36 -0
    gplugin-gtk3/gplugin-gtk3.xml.in
  • +153 -0
    gplugin-gtk3/meson.build
  • +48 -0
    gplugin-gtk3/reference/gplugin-gtk3.toml.in
  • +31 -0
    gplugin-gtk3/reference/meson.build
  • +11 -0
    gplugin-gtk3/reference/urlmap.js
  • +3 -3
    meson.build
  • +2 -2
    meson_options.txt
  • +9 -0
    packaging/debian/changelog
  • +26 -18
    packaging/debian/control
  • +0 -1
    packaging/debian/gir1.2-gplugin-gtk-1.0.install
  • +1 -0
    packaging/debian/gir1.2-gplugin-gtk3-1.0.install
  • +0 -2
    packaging/debian/libgplugin-gtk-bin.install
  • +0 -7
    packaging/debian/libgplugin-gtk-dev.install
  • +0 -1
    packaging/debian/libgplugin-gtk0.install
  • +0 -1
    packaging/debian/libgplugin-gtk0.triggers
  • +1 -0
    packaging/debian/libgplugin-gtk3-0.install
  • +1 -0
    packaging/debian/libgplugin-gtk3-0.triggers
  • +2 -0
    packaging/debian/libgplugin-gtk3-bin.install
  • +7 -0
    packaging/debian/libgplugin-gtk3-dev.install
  • +19 -13
    packaging/gplugin.spec.in
  • +2 -3
    vala/meson.build
  • --- a/convey.yml Thu Sep 30 00:56:21 2021 -0500
    +++ b/convey.yml Thu Sep 30 01:07:52 2021 -0500
    @@ -26,7 +26,7 @@
    - valgrind
    # docs
    - gplugin-docs
    - - gplugin-gtk-docs
    + - gplugin-gtk3-docs
    import:
    type: docker/import
    @@ -71,7 +71,7 @@
    type: docker/export
    files:
    - build-docs/gplugin/reference/gplugin:gplugin-docs
    - - build-docs/gplugin-gtk/reference/gplugin-gtk:gplugin-gtk-docs
    + - build-docs/gplugin-gtk3/reference/gplugin-gtk3:gplugin-gtk3-docs
    plans:
    clean:
    --- a/gplugin-gtk-viewer/data/gplugin-gtk-viewer.gresource.xml Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,6 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<gresources>
    - <gresource prefix="/org/imfreedom/keep/gplugin/gplugin/viewer/">
    - <file compressed="true">window.ui</file>
    - </gresource>
    -</gresources>
    --- a/gplugin-gtk-viewer/data/window.ui Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,65 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<!-- Generated with glade 3.22.1 -->
    -<interface>
    - <requires lib="gtk+" version="3.20"/>
    - <requires lib="gplugin-gtk" version="0.28"/>
    - <template class="viewer" parent="GtkWindow">
    - <property name="can_focus">False</property>
    - <property name="border_width">12</property>
    - <property name="title" translatable="yes">GPlugin Viewer</property>
    - <child>
    - <placeholder/>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">12</property>
    - <child>
    - <object class="GtkScrolledWindow">
    - <property name="visible">True</property>
    - <property name="can_focus">True</property>
    - <property name="hscrollbar_policy">never</property>
    - <property name="shadow_type">in</property>
    - <child>
    - <object class="GPluginGtkView" id="view">
    - <property name="visible">True</property>
    - <property name="can_focus">True</property>
    - <property name="headers_visible">False</property>
    - <property name="headers_clickable">False</property>
    - <child internal-child="selection">
    - <object class="GtkTreeSelection"/>
    - </child>
    - </object>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">True</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GPluginGtkPluginInfo" id="info">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label_xalign">0</property>
    - <property name="shadow_type">none</property>
    - <child type="label">
    - <object class="GtkLabel">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">__glade_unnamed_5</property>
    - </object>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">True</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - </child>
    - </template>
    -</interface>
    --- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.c Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,54 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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-gtk-viewer-window.h"
    -
    -#include <gtk/gtk.h>
    -
    -struct _GPluginGtkViewerWindow {
    - GtkWindow parent;
    -};
    -
    -G_DEFINE_TYPE(
    - GPluginGtkViewerWindow,
    - gplugin_gtk_viewer_window,
    - GTK_TYPE_WINDOW)
    -
    -/******************************************************************************
    - * GObject Stuff
    - *****************************************************************************/
    -static void
    -gplugin_gtk_viewer_window_init(GPluginGtkViewerWindow *window)
    -{
    - gtk_widget_init_template(GTK_WIDGET(window));
    -}
    -
    -static void
    -gplugin_gtk_viewer_window_class_init(GPluginGtkViewerWindowClass *klass)
    -{
    - gtk_widget_class_set_template_from_resource(
    - GTK_WIDGET_CLASS(klass),
    - "/org/imfreedom/keep/gplugin/gplugin/viewer/window.ui");
    -}
    -
    -/******************************************************************************
    - * Public API
    - *****************************************************************************/
    -GtkWidget *
    -gplugin_gtk_viewer_window_new(void)
    -{
    - return GTK_WIDGET(g_object_new(GPLUGIN_GTK_VIEWER_TYPE_WINDOW, NULL));
    -}
    --- a/gplugin-gtk-viewer/gplugin-gtk-viewer-window.h Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,40 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/>.
    - */
    -
    -#ifndef GPLUGIN_GTK_VIEWER_WINDOW_H
    -#define GPLUGIN_GTK_VIEWER_WINDOW_H
    -
    -#include <glib.h>
    -#include <glib-object.h>
    -
    -#include <gtk/gtk.h>
    -
    -#define GPLUGIN_GTK_VIEWER_TYPE_WINDOW (gplugin_gtk_viewer_window_get_type())
    -G_DECLARE_FINAL_TYPE(
    - GPluginGtkViewerWindow,
    - gplugin_gtk_viewer_window,
    - GPLUGIN_GTK_VIEWER,
    - WINDOW,
    - GtkWindow)
    -
    -G_BEGIN_DECLS
    -
    -GtkWidget *gplugin_gtk_viewer_window_new(void);
    -
    -G_END_DECLS
    -
    -#endif /* GPLUGIN_GTK_VIEWER_WINDOW_H */
    --- a/gplugin-gtk-viewer/gplugin-gtk-viewer.c Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,237 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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 <stdio.h>
    -#include <stdlib.h>
    -
    -#include <gtk/gtk.h>
    -
    -#include <gplugin.h>
    -#include <gplugin-gtk.h>
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static gboolean show_internal = FALSE;
    -static gboolean add_default_paths = TRUE, version_only = FALSE;
    -static gchar **paths = NULL;
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static gboolean
    -window_closed_cb(
    - G_GNUC_UNUSED GtkWidget *w,
    - G_GNUC_UNUSED GdkEvent *e,
    - G_GNUC_UNUSED gpointer d)
    -{
    - gtk_main_quit();
    -
    - return FALSE;
    -}
    -
    -static void
    -selection_changed_cb(GtkTreeSelection *sel, gpointer data)
    -{
    - GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(data);
    - GPluginPlugin *plugin = NULL;
    - GtkTreeModel *model = NULL;
    - GtkTreeIter iter;
    -
    - if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
    - gtk_tree_model_get(
    - model,
    - &iter,
    - GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    - &plugin,
    - -1);
    - }
    -
    - gplugin_gtk_plugin_info_set_plugin(info, plugin);
    -}
    -
    -/******************************************************************************
    - * Helpers
    - *****************************************************************************/
    -static gboolean
    -internal_cb(
    - G_GNUC_UNUSED const gchar *n,
    - G_GNUC_UNUSED const gchar *v,
    - G_GNUC_UNUSED gpointer d,
    - G_GNUC_UNUSED GError **e)
    -{
    - show_internal = TRUE;
    -
    - return TRUE;
    -}
    -
    -static gboolean
    -no_default_cb(
    - G_GNUC_UNUSED const gchar *n,
    - G_GNUC_UNUSED const gchar *v,
    - G_GNUC_UNUSED gpointer d,
    - G_GNUC_UNUSED GError **e)
    -{
    - add_default_paths = FALSE;
    -
    - return TRUE;
    -}
    -
    -static gboolean
    -version_cb(
    - G_GNUC_UNUSED const gchar *n,
    - G_GNUC_UNUSED const gchar *v,
    - G_GNUC_UNUSED gpointer d,
    - G_GNUC_UNUSED GError **e)
    -{
    - version_only = TRUE;
    -
    - printf("gplugin-gtk-viewer %s\n", GPLUGIN_VERSION);
    -
    - return TRUE;
    -}
    -
    -static GtkWidget *
    -create_window(void)
    -{
    - GtkWidget *window = NULL, *grid = NULL, *sw = NULL;
    - GtkWidget *view = NULL, *info = NULL;
    - GtkTreeSelection *sel = NULL;
    -
    - window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    - gtk_window_set_title(GTK_WINDOW(window), "GPlugin Viewer");
    - gtk_container_set_border_width(GTK_CONTAINER(window), 12);
    - g_signal_connect(
    - G_OBJECT(window),
    - "delete-event",
    - G_CALLBACK(window_closed_cb),
    - NULL);
    -
    - grid = gtk_grid_new();
    - gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    - gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
    - gtk_container_add(GTK_CONTAINER(window), grid);
    -
    - sw = gtk_scrolled_window_new(NULL, NULL);
    - gtk_scrolled_window_set_policy(
    - GTK_SCROLLED_WINDOW(sw),
    - GTK_POLICY_NEVER,
    - GTK_POLICY_AUTOMATIC);
    - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
    - gtk_grid_attach(GTK_GRID(grid), sw, 0, 0, 1, 1);
    -
    - view = gplugin_gtk_view_new();
    - gplugin_gtk_view_set_show_internal(GPLUGIN_GTK_VIEW(view), show_internal);
    - gtk_container_add(GTK_CONTAINER(sw), view);
    -
    - info = gplugin_gtk_plugin_info_new();
    - gtk_grid_attach(GTK_GRID(grid), info, 1, 0, 1, 1);
    -
    - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
    - g_signal_connect(
    - G_OBJECT(sel),
    - "changed",
    - G_CALLBACK(selection_changed_cb),
    - info);
    -
    - return window;
    -}
    -
    -/******************************************************************************
    - * Main Stuff
    - *****************************************************************************/
    -/* clang-format off */
    -static GOptionEntry entries[] = {
    - {
    - "internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    - internal_cb, "Show internal plugins",
    - NULL,
    - }, {
    - "no-default-paths", 'D', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    - no_default_cb, "Do not search the default plugin paths",
    - NULL,
    - }, {
    - "path", 'p', 0, G_OPTION_ARG_STRING_ARRAY,
    - &paths, "Additional paths to look for plugins",
    - "PATH",
    - }, {
    - "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    - version_cb, "Display the version and exit",
    - NULL,
    - }, {
    - NULL, 0, 0, 0, NULL, NULL, NULL,
    - },
    -};
    -/* clang-format on */
    -
    -gint
    -main(gint argc, gchar **argv)
    -{
    - GPluginManager *manager = NULL;
    - GError *error = NULL;
    - GOptionContext *ctx = NULL;
    - GtkWidget *window = NULL;
    -
    - ctx = g_option_context_new("");
    - g_option_context_add_main_entries(ctx, entries, NULL);
    - g_option_context_add_group(ctx, gtk_get_option_group(TRUE));
    - g_option_context_parse(ctx, &argc, &argv, &error);
    - g_option_context_free(ctx);
    -
    - if(error) {
    - fprintf(stderr, "%s\n", error->message);
    -
    - g_error_free(error);
    -
    - gplugin_uninit();
    -
    - return EXIT_FAILURE;
    - }
    -
    - if(version_only) {
    - return 0;
    - }
    -
    - gtk_init(&argc, &argv);
    -
    - gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
    -
    - manager = gplugin_manager_get_default();
    -
    - if(add_default_paths)
    - gplugin_manager_add_default_paths(manager);
    -
    - if(paths) {
    - gint i;
    -
    - for(i = 0; paths[i]; i++) {
    - gplugin_manager_prepend_path(manager, paths[i]);
    - }
    - }
    -
    - gplugin_manager_refresh(manager);
    -
    - /* now create and show the window */
    - window = create_window();
    - gtk_widget_show_all(window);
    -
    - gtk_main();
    -
    - gplugin_uninit();
    -
    - return 0;
    -}
    --- a/gplugin-gtk-viewer/meson.build Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,36 +0,0 @@
    -if get_option('gtk3')
    -
    -if not get_option('install-gplugin-gtk-viewer')
    -summary('gplugin-gtk-viewer',
    - 'You have disabled installation of gplugin-gtk-viewer which is a ' +
    - 'very useful diagnostics tool.',
    - section : 'Warnings')
    -endif
    -
    -gplugin_gtk_viewer_resources = gnome.compile_resources(
    - 'gplugin-gtk-viewer-resources',
    - 'data/gplugin-gtk-viewer.gresource.xml',
    - c_name: 'gplugin_gtk_viewer',
    - source_dir: 'data')
    -
    -gplugin_gtk_viewer = executable('gplugin-gtk-viewer',
    - 'gplugin-gtk-viewer.c',
    - 'gplugin-gtk-viewer-window.c',
    - 'gplugin-gtk-viewer-window.h',
    - dependencies : [gplugin_dep, gplugin_gtk_dep],
    - install : get_option('install-gplugin-gtk-viewer')
    -)
    -
    -if get_option('help2man')
    - gplugin_gtk_viewer_man = custom_target('gplugin-gtk-viewer.1',
    - command : [help2man,
    - '--name=View installed plugins', '--section=1',
    - '--help-option=--help-all', '--no-info',
    - '--output', '@OUTPUT@',
    - gplugin_gtk_viewer],
    - output : 'gplugin-gtk-viewer.1',
    - install : get_option('install-gplugin-gtk-viewer'),
    - install_dir : get_option('mandir') / 'man1')
    -endif
    -
    -endif
    --- a/gplugin-gtk/data/gplugin-gtk.gresource.xml Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,6 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<gresources>
    - <gresource prefix="/org/imfreedom/keep/gplugin/gplugin-gtk/">
    - <file compressed="true">plugin-info.ui</file>
    - </gresource>
    -</gresources>
    --- a/gplugin-gtk/data/plugin-info.ui Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,582 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<!-- Generated with glade 3.22.2 -->
    -<interface>
    - <requires lib="gtk+" version="3.10"/>
    - <template class="GPluginGtkPluginInfo" parent="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="orientation">vertical</property>
    - <child>
    - <object class="GtkLabel" id="name">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - <attributes>
    - <attribute name="weight" value="bold"/>
    - <attribute name="scale" value="2"/>
    - </attributes>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="version_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Version</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="version">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="authors_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Authors</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox" id="authors_box">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="orientation">vertical</property>
    - <child>
    - <placeholder/>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">2</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="website_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Website</property>
    - <property name="use_underline">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="website">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="use_markup">True</property>
    - <property name="track_visited_links">False</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">3</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="summary_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Summary</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="summary">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">4</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="description_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Description</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="description">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="wrap">True</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">5</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="dependencies_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Dependencies</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox" id="dependencies_box">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="orientation">vertical</property>
    - <child>
    - <placeholder/>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">6</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="error_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Error</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="error">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">7</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkExpander">
    - <property name="visible">True</property>
    - <property name="can_focus">True</property>
    - <property name="label_fill">True</property>
    - <signal name="activate" handler="gplugin_gtk_plugin_info_expander_activate" object="GPluginGtkPluginInfo" swapped="no"/>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="orientation">vertical</property>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="id_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">ID</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="id">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="filename_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Filename</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="filename">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="abi_version_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">ABI Version</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="abi_version">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">2</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="loader_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Loader</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="loader">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">3</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="internal_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Internal</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="internal">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">4</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkBox">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="spacing">6</property>
    - <child>
    - <object class="GtkLabel" id="load_on_query_label">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">Load on Query</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">0</property>
    - </packing>
    - </child>
    - <child>
    - <object class="GtkLabel" id="load_on_query">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="xalign">0</property>
    - <property name="yalign">0</property>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">1</property>
    - </packing>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">False</property>
    - <property name="fill">True</property>
    - <property name="position">5</property>
    - </packing>
    - </child>
    - </object>
    - </child>
    - <child type="label">
    - <object class="GtkLabel" id="expander">
    - <property name="visible">True</property>
    - <property name="can_focus">False</property>
    - <property name="label" translatable="yes">More</property>
    - </object>
    - </child>
    - </object>
    - <packing>
    - <property name="expand">True</property>
    - <property name="fill">True</property>
    - <property name="position">8</property>
    - </packing>
    - </child>
    - </template>
    - <object class="GtkSizeGroup" id="size_group">
    - <widgets>
    - <widget name="version_label"/>
    - <widget name="authors_label"/>
    - <widget name="website_label"/>
    - <widget name="summary_label"/>
    - <widget name="description_label"/>
    - <widget name="dependencies_label"/>
    - <widget name="id_label"/>
    - <widget name="filename_label"/>
    - <widget name="abi_version_label"/>
    - <widget name="loader_label"/>
    - <widget name="internal_label"/>
    - <widget name="load_on_query_label"/>
    - <widget name="error_label"/>
    - </widgets>
    - </object>
    -</interface>
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.c Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,494 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/gplugin-gtk-plugin-info.h>
    -
    -#include <glib/gi18n-lib.h>
    -
    -/**
    - * SECTION:gplugin-gtk-plugin-info
    - * @title: Plugin Info Gtk Widgets
    - * @short_description: Gtk Widgets for plugins
    - *
    - * #GPluginGtkPluginInfo is a Gtk widget that shows information about plugins.
    - */
    -
    -/**
    - * GPLUGIN_GTK_TYPE_PLUGIN_INFO:
    - *
    - * The standard _get_type macro for #GPluginGtkPluginInfo.
    - */
    -
    -/**
    - * GPluginGtkPluginInfo:
    - *
    - * A widget that displays a #GPluginPluginInfo in a user friendly way.
    - */
    -
    -/******************************************************************************
    - * Structs
    - *****************************************************************************/
    -struct _GPluginGtkPluginInfo {
    - GtkBox parent;
    -
    - GPluginPlugin *plugin;
    - gulong signal_id;
    -
    - GtkWidget *name;
    - GtkWidget *version;
    - GtkWidget *authors_box;
    - GtkWidget *website;
    - GtkWidget *summary;
    - GtkWidget *description;
    - GtkWidget *dependencies_box;
    - GtkWidget *error;
    - GtkWidget *expander;
    - GtkWidget *id;
    - GtkWidget *filename;
    - GtkWidget *abi_version;
    - GtkWidget *loader;
    - GtkWidget *internal;
    - GtkWidget *load_on_query;
    -};
    -
    -/*****************************************************************************s
    - * Enums
    - *****************************************************************************/
    -enum {
    - PROP_ZERO,
    - PROP_PLUGIN,
    - N_PROPERTIES,
    -};
    -static GParamSpec *properties[N_PROPERTIES] = {
    - NULL,
    -};
    -
    -G_DEFINE_TYPE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_BOX);
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static void
    -gplugin_gtk_plugin_info_expander_activate(
    - GtkExpander *expander,
    - G_GNUC_UNUSED gpointer data)
    -{
    - if(gtk_expander_get_expanded(expander))
    - gtk_expander_set_label(expander, "More");
    - else
    - gtk_expander_set_label(expander, "Less");
    -}
    -
    -/******************************************************************************
    - * Helpers
    - *****************************************************************************/
    -static void
    -_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfo *info)
    -{
    - GtkWidget *widget = NULL;
    - GError *error = NULL;
    - GList *children = NULL, *iter = NULL;
    - gchar *markup = NULL;
    - gchar *name = NULL, *version = NULL, *website = NULL;
    - gchar *summary = NULL, *description = NULL, *id = NULL, *abi_version = NULL;
    - gchar *loader = NULL;
    - gchar **authors = NULL;
    - gchar **dependencies = NULL;
    - guint32 abi_version_uint;
    - gboolean loq = FALSE, internal = FALSE;
    - const gchar *filename = NULL;
    -
    - /* remove all the children from the authors box */
    - children = gtk_container_get_children(GTK_CONTAINER(info->authors_box));
    - for(iter = children; iter; iter = iter->next)
    - gtk_widget_destroy(GTK_WIDGET(iter->data));
    - g_list_free(children);
    -
    - /* remove all the children from the dependencies box */
    - children =
    - gtk_container_get_children(GTK_CONTAINER(info->dependencies_box));
    - for(iter = children; iter; iter = iter->next)
    - gtk_widget_destroy(GTK_WIDGET(iter->data));
    - g_list_free(children);
    -
    - /* now get the info if we can */
    - if(GPLUGIN_IS_PLUGIN(info->plugin)) {
    - GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(info->plugin);
    - GPluginLoader *plugin_loader = gplugin_plugin_get_loader(info->plugin);
    -
    - filename = gplugin_plugin_get_filename(info->plugin);
    - error = gplugin_plugin_get_error(info->plugin);
    -
    - if(plugin_loader && GPLUGIN_IS_LOADER(plugin_loader)) {
    - const char *loader_name = G_OBJECT_TYPE_NAME(plugin_loader);
    - loader = g_strdup(loader_name);
    - g_object_unref(G_OBJECT(plugin_loader));
    - }
    -
    - /* clang-format off */
    - g_object_get(
    - G_OBJECT(plugin_info),
    - "abi_version", &abi_version_uint,
    - "authors", &authors,
    - "summary", &summary,
    - "description", &description,
    - "dependencies", &dependencies,
    - "id", &id,
    - "internal", &internal,
    - "load-on-query", &loq,
    - "name", &name,
    - "version", &version,
    - "website", &website,
    - NULL);
    - /* clang-format on */
    -
    - /* fanagle the plugin name */
    - markup = g_markup_printf_escaped(
    - "<span font_size=\"large\" "
    - "font_weight=\"bold\">%s</span>",
    - (name) ? name : "Unnamed");
    - g_free(name);
    - name = markup;
    -
    - /* fanagle the website */
    - if(website) {
    - markup = g_markup_printf_escaped(
    - "<a href=\"%s\">%s</a>",
    - website,
    - website);
    - g_free(website);
    - website = markup;
    - }
    -
    - /* fanagle the abi_version */
    - abi_version = g_strdup_printf("%08x", abi_version_uint);
    -
    - g_object_unref(G_OBJECT(plugin_info));
    - }
    -
    - gtk_label_set_markup(GTK_LABEL(info->name), (name) ? name : "Unnamed");
    - gtk_label_set_text(GTK_LABEL(info->version), (version) ? version : "");
    - gtk_label_set_markup(GTK_LABEL(info->website), (website) ? website : "");
    - gtk_label_set_text(GTK_LABEL(info->summary), (summary) ? summary : "");
    - gtk_label_set_text(
    - GTK_LABEL(info->description),
    - (description) ? description : "");
    - gtk_label_set_text(GTK_LABEL(info->id), (id) ? id : "");
    - gtk_label_set_text(
    - GTK_LABEL(info->error),
    - (error) ? error->message : "(none)");
    - gtk_label_set_text(GTK_LABEL(info->filename), (filename) ? filename : "");
    - gtk_label_set_text(
    - GTK_LABEL(info->abi_version),
    - (abi_version) ? abi_version : "");
    - gtk_label_set_text(GTK_LABEL(info->loader), (loader) ? loader : "Unknown");
    - gtk_label_set_text(GTK_LABEL(info->internal), (internal) ? "Yes" : "No");
    - gtk_label_set_text(GTK_LABEL(info->load_on_query), (loq) ? "Yes" : "No");
    -
    - g_free(description);
    - g_free(id);
    - g_free(name);
    - g_free(version);
    - g_free(website);
    - g_free(loader);
    - g_clear_error(&error);
    -
    - /* set the authors */
    - if(authors) {
    - gint i = 0;
    -
    - for(i = 0; authors[i]; i++) {
    - widget = gtk_label_new(authors[i]);
    - gtk_widget_set_halign(widget, GTK_ALIGN_START);
    - gtk_widget_set_valign(widget, GTK_ALIGN_START);
    - gtk_box_pack_start(
    - GTK_BOX(info->authors_box),
    - widget,
    - TRUE,
    - TRUE,
    - 0);
    - gtk_widget_show(widget);
    - }
    - }
    - g_strfreev(authors);
    -
    - /* set the dependencies */
    - if(dependencies) {
    - gint i = 0;
    -
    - for(i = 0; dependencies[i]; i++) {
    - widget = gtk_label_new(dependencies[i]);
    - gtk_widget_set_halign(widget, GTK_ALIGN_START);
    - gtk_widget_set_valign(widget, GTK_ALIGN_START);
    - gtk_box_pack_start(
    - GTK_BOX(info->dependencies_box),
    - widget,
    - TRUE,
    - TRUE,
    - 0);
    - gtk_widget_show(widget);
    - }
    - } else {
    - widget = gtk_label_new(_("(none)"));
    - gtk_box_pack_start(
    - GTK_BOX(info->dependencies_box),
    - widget,
    - TRUE,
    - TRUE,
    - 0);
    - gtk_widget_show(widget);
    - }
    - g_strfreev(dependencies);
    -}
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static void
    -gplugin_gtk_plugin_info_state_cb(GObject *obj, GParamSpec *pspec, gpointer data)
    -{
    - _gplugin_gtk_plugin_info_refresh(GPLUGIN_GTK_PLUGIN_INFO(data));
    -}
    -
    -/******************************************************************************
    - * GObject Stuff
    - *****************************************************************************/
    -static void
    -gplugin_gtk_plugin_info_set_property(
    - GObject *obj,
    - guint prop_id,
    - const GValue *value,
    - GParamSpec *pspec)
    -{
    - GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    -
    - switch(prop_id) {
    - case PROP_PLUGIN:
    - gplugin_gtk_plugin_info_set_plugin(info, g_value_get_object(value));
    - break;
    - default:
    - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    - break;
    - }
    -}
    -
    -static void
    -gplugin_gtk_plugin_info_get_property(
    - GObject *obj,
    - guint prop_id,
    - GValue *value,
    - GParamSpec *pspec)
    -{
    - GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    -
    - switch(prop_id) {
    - case PROP_PLUGIN:
    - g_value_set_object(value, gplugin_gtk_plugin_info_get_plugin(info));
    - break;
    - default:
    - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    - break;
    - }
    -}
    -
    -static void
    -gplugin_gtk_plugin_info_finalize(GObject *obj)
    -{
    - GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    -
    - if(info->signal_id != 0 && GPLUGIN_IS_PLUGIN(info->plugin)) {
    - g_signal_handler_disconnect(G_OBJECT(info->plugin), info->signal_id);
    - }
    -
    - g_clear_object(&info->plugin);
    -
    - G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->finalize(obj);
    -}
    -
    -static void
    -gplugin_gtk_plugin_info_init(GPluginGtkPluginInfo *info)
    -{
    - gtk_widget_init_template(GTK_WIDGET(info));
    -
    - info->signal_id = 0;
    -}
    -
    -static void
    -gplugin_gtk_plugin_info_class_init(GPluginGtkPluginInfoClass *klass)
    -{
    - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
    - GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    -
    - obj_class->get_property = gplugin_gtk_plugin_info_get_property;
    - obj_class->set_property = gplugin_gtk_plugin_info_set_property;
    - obj_class->finalize = gplugin_gtk_plugin_info_finalize;
    -
    - /* properties */
    - properties[PROP_PLUGIN] = g_param_spec_object(
    - "plugin",
    - "plugin",
    - "The GPluginPlugin who's info should be displayed",
    - G_TYPE_OBJECT,
    - G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
    -
    - /* template stuff */
    - gtk_widget_class_set_template_from_resource(
    - widget_class,
    - "/org/imfreedom/keep/gplugin/gplugin-gtk/plugin-info.ui");
    -
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - name);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - version);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - authors_box);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - website);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - summary);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - description);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - dependencies_box);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - error);
    -
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - expander);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - id);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - filename);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - abi_version);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - loader);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - internal);
    - gtk_widget_class_bind_template_child(
    - widget_class,
    - GPluginGtkPluginInfo,
    - load_on_query);
    -
    - gtk_widget_class_bind_template_callback(
    - widget_class,
    - gplugin_gtk_plugin_info_expander_activate);
    -}
    -
    -/******************************************************************************
    - * API
    - *****************************************************************************/
    -
    -/**
    - * gplugin_gtk_plugin_info_new:
    - *
    - * Create a new GPluginGtkView which can be used to display info about a
    - * #GPluginPlugin.
    - *
    - * Returns: (transfer full): The new #GPluginGtkView widget.
    - */
    -GtkWidget *
    -gplugin_gtk_plugin_info_new(void)
    -{
    - return GTK_WIDGET(g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_INFO, NULL));
    -}
    -
    -/**
    - * gplugin_gtk_plugin_info_set_plugin:
    - * @info: The #GPluginGtkPluginInfo instance.
    - * @plugin: The #GPluginPlugin instance.
    - *
    - * Sets the #GPluginPlugin that should be displayed.
    - *
    - * A @plugin value of %NULL will clear the widget.
    - */
    -void
    -gplugin_gtk_plugin_info_set_plugin(
    - GPluginGtkPluginInfo *info,
    - GPluginPlugin *plugin)
    -{
    - g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info));
    -
    - if(info->signal_id != 0 && GPLUGIN_IS_PLUGIN(info->plugin)) {
    - g_signal_handler_disconnect(info->plugin, info->signal_id);
    - info->signal_id = 0;
    - }
    -
    - if(g_set_object(&info->plugin, plugin) && GPLUGIN_IS_PLUGIN(plugin)) {
    - _gplugin_gtk_plugin_info_refresh(info);
    -
    - /* Connect a signal to refresh when the plugin's state changes. We
    - * can't use g_signal_connect_object because the plugin object never
    - * gets destroyed, as the manager and the loader both keep a reference
    - * to it and the GPluginGtkPluginInfo widget is reused for all plugins
    - * so that all means that we just have to manage the callback
    - * ourselves.
    - */
    - info->signal_id = g_signal_connect(
    - G_OBJECT(plugin),
    - "notify::state",
    - G_CALLBACK(gplugin_gtk_plugin_info_state_cb),
    - info);
    - }
    -}
    -
    -/**
    - * gplugin_gtk_plugin_info_get_plugin:
    - * @info: The #GPluginGtkPluginInfo instance.
    - *
    - * Returns the #GPluginPlugin that's being displayed.
    - *
    - * Return Value: (transfer full): The #GPluginPlugin that's being
    - * displayed.
    - */
    -GPluginPlugin *
    -gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info)
    -{
    - g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info), NULL);
    -
    - return (info->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(info->plugin)))
    - : NULL;
    -}
    --- a/gplugin-gtk/gplugin-gtk-plugin-info.h Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,52 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/gplugin-gtk.h> may be included directly"
    -#endif
    -
    -#ifndef GPLUGIN_GTK_PLUGIN_INFO_H
    -#define GPLUGIN_GTK_PLUGIN_INFO_H
    -
    -#include <glib.h>
    -#include <glib-object.h>
    -
    -#include <gtk/gtk.h>
    -
    -#include <gplugin.h>
    -
    -G_BEGIN_DECLS
    -
    -#define GPLUGIN_GTK_TYPE_PLUGIN_INFO (gplugin_gtk_plugin_info_get_type())
    -G_DECLARE_FINAL_TYPE(
    - GPluginGtkPluginInfo,
    - gplugin_gtk_plugin_info,
    - GPLUGIN_GTK,
    - PLUGIN_INFO,
    - GtkBox)
    -
    -GtkWidget *gplugin_gtk_plugin_info_new(void);
    -
    -void gplugin_gtk_plugin_info_set_plugin(
    - GPluginGtkPluginInfo *info,
    - GPluginPlugin *plugin);
    -GPluginPlugin *gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info);
    -
    -G_END_DECLS
    -
    -#endif /* GPLUGIN_GTK_PLUGIN_INFO_H */
    --- a/gplugin-gtk/gplugin-gtk-store.c Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,325 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/gplugin-gtk-store.h>
    -
    -/**
    - * SECTION:gplugin-gtk-store
    - * @title: GtkTreeModelStore for plugins
    - * @short_description: A store for plugins
    - *
    - * #GPluginGtkStore is a GtkTreeModel populated with plugins.
    - */
    -
    -/**
    - * GPLUGIN_GTK_TYPE_STORE:
    - *
    - * The standard _get_type macro for #GPluginGtkStore.
    - */
    -
    -/**
    - * GPluginGtkStoreColumns:
    - * @GPLUGIN_GTK_STORE_ENABLED_COLUMN: The disabled column. This is used when a
    - * plugin is in a state that can't be
    - * changed. So the row should be disabled.
    - * @GPLUGIN_GTK_STORE_LOADED_COLUMN: The loaded column.
    - * @GPLUGIN_GTK_STORE_PLUGIN_COLUMN: The plugin column.
    - * @GPLUGIN_GTK_STORE_MARKUP_COLUMN: The markup column.
    - *
    - * An enum declaring the columns in a #GPluginGtkStore.
    - */
    -
    -/**
    - * GPluginGtkStore:
    - *
    - * A #GtkListStore that contains all of the known plugins in GPlugin.
    - */
    -
    -struct _GPluginGtkStore {
    - GtkListStore parent;
    -};
    -
    -G_DEFINE_TYPE(GPluginGtkStore, gplugin_gtk_store, GTK_TYPE_LIST_STORE);
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -static const GType column_types[] = {
    - G_TYPE_BOOLEAN,
    - G_TYPE_BOOLEAN,
    - G_TYPE_OBJECT,
    - G_TYPE_STRING,
    -};
    -
    -G_STATIC_ASSERT(G_N_ELEMENTS(column_types) == GPLUGIN_GTK_STORE_N_COLUMNS);
    -
    -/******************************************************************************
    - * Helpers
    - *****************************************************************************/
    -static void
    -gplugin_gtk_store_add_plugin(GPluginGtkStore *store, GPluginPlugin *plugin)
    -{
    - GtkTreeIter iter;
    - GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
    - GPluginPluginState state = gplugin_plugin_get_state(plugin);
    - GString *str = g_string_new("");
    - gchar *name = NULL, *summary = NULL;
    - gboolean loaded = FALSE, enabled = TRUE;
    -
    - /* clang-format off */
    - g_object_get(
    - G_OBJECT(info),
    - "name", &name,
    - "summary", &summary,
    - NULL);
    - /* clang-format on */
    -
    - g_string_append_printf(
    - str,
    - "<b>%s</b>\n",
    - (name) ? name : "<i>Unnamed</i>");
    - g_string_append_printf(
    - str,
    - "%s",
    - (summary) ? summary : "<i>No Summary</i>");
    -
    - g_free(name);
    - g_free(summary);
    -
    - loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED);
    - if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) {
    - loaded = TRUE;
    - enabled = FALSE;
    - }
    -
    - gtk_list_store_append(GTK_LIST_STORE(store), &iter);
    - gtk_list_store_set(
    - GTK_LIST_STORE(store),
    - &iter,
    - GPLUGIN_GTK_STORE_LOADED_COLUMN,
    - loaded,
    - GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    - enabled,
    - GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    - g_object_ref(plugin),
    - GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    - str->str,
    - -1);
    -
    - g_string_free(str, TRUE);
    - g_object_unref(G_OBJECT(info));
    -}
    -
    -static void
    -gplugin_gtk_store_add_plugin_by_id(GPluginGtkStore *store, const gchar *id)
    -{
    - GPluginManager *manager = NULL;
    - GSList *plugins = NULL, *l = NULL;
    -
    - manager = gplugin_manager_get_default();
    -
    - plugins = gplugin_manager_find_plugins(manager, id);
    - for(l = plugins; l; l = l->next)
    - gplugin_gtk_store_add_plugin(store, GPLUGIN_PLUGIN(l->data));
    - g_slist_free_full(plugins, g_object_unref);
    -}
    -
    -static gboolean
    -gplugin_gtk_store_update_plugin_state_cb(
    - GtkTreeModel *model,
    - GtkTreePath *path,
    - GtkTreeIter *iter,
    - gpointer data)
    -{
    - GPluginPlugin *plugin_a = GPLUGIN_PLUGIN(data);
    - GPluginPlugin *plugin_b = NULL;
    - gboolean ret = FALSE;
    -
    - gtk_tree_model_get(
    - model,
    - iter,
    - GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    - &plugin_b,
    - -1);
    -
    - if(plugin_a == plugin_b) {
    - GPluginPluginState state = gplugin_plugin_get_state(plugin_a);
    - gboolean loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED);
    - gboolean enabled = TRUE;
    -
    - if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) {
    - loaded = TRUE;
    - enabled = FALSE;
    - }
    -
    - gtk_list_store_set(
    - GTK_LIST_STORE(model),
    - iter,
    - GPLUGIN_GTK_STORE_LOADED_COLUMN,
    - loaded,
    - GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    - enabled,
    - -1);
    -
    - /* tell gplugin_gtk_store_update_plugin_state that we're done */
    - ret = TRUE;
    - }
    -
    - g_object_unref(G_OBJECT(plugin_b));
    -
    - return ret;
    -}
    -
    -static void
    -gplugin_gtk_store_update_plugin_state(
    - GPluginGtkStore *store,
    - GPluginPlugin *plugin)
    -{
    - gtk_tree_model_foreach(
    - GTK_TREE_MODEL(store),
    - gplugin_gtk_store_update_plugin_state_cb,
    - plugin);
    -}
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static void
    -gplugin_gtk_store_plugin_loaded_cb(
    - GObject *manager,
    - GPluginPlugin *plugin,
    - gpointer data)
    -{
    - gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
    -}
    -
    -static void
    -gplugin_gtk_store_plugin_unloaded_cb(
    - GObject *manager,
    - GPluginPlugin *plugin,
    - gpointer data)
    -{
    - gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
    -}
    -
    -static void
    -gplugin_gtk_store_plugin_unload_failed_cb(
    - G_GNUC_UNUSED GObject *manager,
    - GPluginPlugin *plugin,
    - gpointer data)
    -{
    - gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
    -}
    -
    -/******************************************************************************
    - * GObject Implementation
    - *****************************************************************************/
    -static void
    -gplugin_gtk_store_constructed(GObject *obj)
    -{
    - GPluginManager *manager = NULL;
    - GList *l, *ids = NULL;
    -
    - G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->constructed(obj);
    -
    - manager = gplugin_manager_get_default();
    -
    - ids = gplugin_manager_list_plugins(manager);
    - for(l = ids; l; l = l->next)
    - gplugin_gtk_store_add_plugin_by_id(
    - GPLUGIN_GTK_STORE(obj),
    - (const gchar *)l->data);
    - g_list_free(ids);
    -
    - g_signal_connect_object(
    - manager,
    - "loaded-plugin",
    - G_CALLBACK(gplugin_gtk_store_plugin_loaded_cb),
    - obj,
    - 0);
    - g_signal_connect_object(
    - manager,
    - "unloaded-plugin",
    - G_CALLBACK(gplugin_gtk_store_plugin_unloaded_cb),
    - obj,
    - 0);
    - g_signal_connect_object(
    - manager,
    - "unload-plugin-failed",
    - G_CALLBACK(gplugin_gtk_store_plugin_unload_failed_cb),
    - obj,
    - 0);
    -}
    -
    -static void
    -gplugin_gtk_store_dispose(GObject *obj)
    -{
    - G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->dispose(obj);
    -}
    -
    -static void
    -gplugin_gtk_store_init(GPluginGtkStore *store)
    -{
    - GType *types = (GType *)gplugin_gtk_store_get_column_types();
    -
    - gtk_list_store_set_column_types(
    - GTK_LIST_STORE(store),
    - GPLUGIN_GTK_STORE_N_COLUMNS,
    - types);
    -}
    -
    -static void
    -gplugin_gtk_store_class_init(GPluginGtkStoreClass *klass)
    -{
    - GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    -
    - obj_class->constructed = gplugin_gtk_store_constructed;
    - obj_class->dispose = gplugin_gtk_store_dispose;
    -}
    -
    -/******************************************************************************
    - * API
    - *****************************************************************************/
    -
    -/**
    - * gplugin_gtk_store_new:
    - *
    - * Create a new #GPluginGtkStore which is a prepopulated #GtkTreeStore.
    - *
    - * Returns: (transfer full): A new #GtkTreeModel prepopulated with all of the
    - * plugins.
    - */
    -GPluginGtkStore *
    -gplugin_gtk_store_new(void)
    -{
    - return GPLUGIN_GTK_STORE(g_object_new(GPLUGIN_GTK_TYPE_STORE, NULL));
    -}
    -
    -/**
    - * gplugin_gtk_store_get_column_types:
    - *
    - * Returns the columns that #GPluginGtkStore's will use.
    - *
    - * Returns: (transfer none): A list of #GType's for the columns that the store
    - * will use.
    - */
    -const GType *
    -gplugin_gtk_store_get_column_types(void)
    -{
    - return column_types;
    -}
    --- a/gplugin-gtk/gplugin-gtk-store.h Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,57 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/gplugin-gtk.h> may be included directly"
    -#endif
    -
    -#ifndef GPLUGIN_GTK_STORE_H
    -#define GPLUGIN_GTK_STORE_H
    -
    -#include <glib.h>
    -#include <glib-object.h>
    -
    -#include <gtk/gtk.h>
    -
    -G_BEGIN_DECLS
    -
    -#define GPLUGIN_GTK_TYPE_STORE (gplugin_gtk_store_get_type())
    -G_DECLARE_FINAL_TYPE(
    - GPluginGtkStore,
    - gplugin_gtk_store,
    - GPLUGIN_GTK,
    - STORE,
    - GtkListStore)
    -
    -typedef enum {
    - GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    - GPLUGIN_GTK_STORE_LOADED_COLUMN,
    - GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    - GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    -
    - /*< private >*/
    - GPLUGIN_GTK_STORE_N_COLUMNS,
    -} GPluginGtkStoreColumns;
    -
    -GPluginGtkStore *gplugin_gtk_store_new(void);
    -
    -const GType *gplugin_gtk_store_get_column_types(void);
    -
    -G_END_DECLS
    -
    -#endif /* GPLUGIN_GTK_STORE_H */
    --- a/gplugin-gtk/gplugin-gtk-view.c Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,317 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/gplugin-gtk-store.h>
    -#include <gplugin-gtk/gplugin-gtk-view.h>
    -
    -/**
    - * SECTION:gplugin-gtk-view
    - * @title: GtkTreeView for plugins
    - * @short_description: A view for plugins
    - *
    - * #GPluginGtkView is a display widget for a list of plugins.
    - */
    -
    -/**
    - * GPLUGIN_GTK_TYPE_VIEW:
    - *
    - * The standard _get_type macro for #GPluginGtkView.
    - */
    -
    -/**
    - * GPluginGtkView:
    - *
    - * A #GtkTreeView widget that displays all the plugins and some basic
    - * information about them.
    - */
    -
    -/******************************************************************************
    - * Structs
    - *****************************************************************************/
    -struct _GPluginGtkView {
    - GtkTreeView parent;
    -
    - gboolean show_internal;
    -};
    -
    -/******************************************************************************
    - * Enums
    - *****************************************************************************/
    -enum {
    - PROP_ZERO,
    - PROP_SHOW_INTERNAL,
    - N_PROPERTIES,
    -};
    -static GParamSpec *properties[N_PROPERTIES] = {
    - NULL,
    -};
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static void
    -gplugin_gtk_view_plugin_toggled_cb(
    - GtkCellRendererToggle *rend,
    - gchar *path,
    - gpointer data)
    -{
    - GPluginGtkView *view = GPLUGIN_GTK_VIEW(data);
    - GPluginManager *manager = NULL;
    - GPluginPlugin *plugin = NULL;
    - GPluginPluginState state;
    - GtkTreeModel *model = NULL;
    - GtkTreeIter iter;
    - GtkTreePath *tree_path = NULL;
    -
    - manager = gplugin_manager_get_default();
    -
    - tree_path = gtk_tree_path_new_from_string(path);
    -
    - model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
    - gtk_tree_model_get_iter(model, &iter, tree_path);
    - gtk_tree_path_free(tree_path);
    -
    - gtk_tree_model_get(
    - model,
    - &iter,
    - GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    - &plugin,
    - -1);
    -
    - if(!GPLUGIN_IS_PLUGIN(plugin)) {
    - return;
    - }
    -
    - state = gplugin_plugin_get_state(plugin);
    - if(state == GPLUGIN_PLUGIN_STATE_LOADED) {
    - GError *error = NULL;
    -
    - gplugin_manager_unload_plugin(manager, plugin, &error);
    -
    - if(error != NULL) {
    - g_warning("Failed to unload plugin: %s", error->message);
    -
    - g_error_free(error);
    - }
    - } else {
    - GError *error = NULL;
    -
    - gplugin_manager_load_plugin(manager, plugin, &error);
    -
    - if(error != NULL) {
    - g_warning("Failed to load plugin: %s", error->message);
    -
    - g_error_free(error);
    - }
    - }
    -
    - g_object_unref(G_OBJECT(plugin));
    -}
    -
    -/******************************************************************************
    - * GObject Implementation
    - *****************************************************************************/
    -G_DEFINE_TYPE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
    -
    -static void
    -gplugin_gtk_view_set_property(
    - GObject *obj,
    - guint prop_id,
    - const GValue *value,
    - GParamSpec *pspec)
    -{
    - GPluginGtkView *view = GPLUGIN_GTK_VIEW(obj);
    -
    - switch(prop_id) {
    - case PROP_SHOW_INTERNAL:
    - gplugin_gtk_view_set_show_internal(
    - view,
    - g_value_get_boolean(value));
    - break;
    - default:
    - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    - break;
    - }
    -}
    -
    -static void
    -gplugin_gtk_view_get_property(
    - GObject *obj,
    - guint prop_id,
    - GValue *value,
    - GParamSpec *pspec)
    -{
    - GPluginGtkView *view = GPLUGIN_GTK_VIEW(obj);
    -
    - switch(prop_id) {
    - case PROP_SHOW_INTERNAL:
    - g_value_set_boolean(
    - value,
    - gplugin_gtk_view_get_show_internal(view));
    - break;
    - default:
    - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    - break;
    - }
    -}
    -
    -static void
    -gplugin_gtk_view_constructed(GObject *obj)
    -{
    - G_OBJECT_CLASS(gplugin_gtk_view_parent_class)->constructed(obj);
    -}
    -
    -static void
    -gplugin_gtk_view_dispose(GObject *obj)
    -{
    - G_OBJECT_CLASS(gplugin_gtk_view_parent_class)->dispose(obj);
    -}
    -
    -static void
    -gplugin_gtk_view_init(GPluginGtkView *view)
    -{
    - GtkTreeViewColumn *col = NULL;
    - GtkCellRenderer *rend = NULL;
    -
    - /* create the first column */
    - col = gtk_tree_view_column_new();
    - gtk_tree_view_column_set_title(col, "Enabled");
    - gtk_tree_view_column_set_resizable(col, FALSE);
    -
    - rend = gtk_cell_renderer_toggle_new();
    - gtk_tree_view_column_pack_start(col, rend, FALSE);
    - g_signal_connect(
    - G_OBJECT(rend),
    - "toggled",
    - G_CALLBACK(gplugin_gtk_view_plugin_toggled_cb),
    - view);
    -
    - gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
    - gtk_tree_view_column_set_attributes(
    - col,
    - rend,
    - "active",
    - GPLUGIN_GTK_STORE_LOADED_COLUMN,
    - "sensitive",
    - GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    - NULL);
    -
    - /* create the markup column */
    - col = gtk_tree_view_column_new();
    - gtk_tree_view_column_set_title(col, "Name");
    - gtk_tree_view_column_set_resizable(col, FALSE);
    -
    - rend = gtk_cell_renderer_text_new();
    - gtk_tree_view_column_pack_start(col, rend, TRUE);
    -
    - gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
    - gtk_tree_view_column_set_attributes(
    - col,
    - rend,
    - "markup",
    - GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    - "sensitive",
    - GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    - NULL);
    -}
    -
    -static void
    -gplugin_gtk_view_class_init(GPluginGtkViewClass *klass)
    -{
    - GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    -
    - obj_class->get_property = gplugin_gtk_view_get_property;
    - obj_class->set_property = gplugin_gtk_view_set_property;
    - obj_class->constructed = gplugin_gtk_view_constructed;
    - obj_class->dispose = gplugin_gtk_view_dispose;
    -
    - /* properties */
    -
    - /**
    - * GPluginGtkView:show-internal:
    - *
    - * Whether or not to show internal plugins.
    - */
    - properties[PROP_SHOW_INTERNAL] = g_param_spec_boolean(
    - "show-internal",
    - "show-internal",
    - "Whether or not to show internal plugins",
    - FALSE,
    - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
    -
    - g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    -}
    -
    -/******************************************************************************
    - * API
    - *****************************************************************************/
    -
    -/**
    - * gplugin_gtk_view_new:
    - *
    - * Creates a new #GPluginGtkView.
    - *
    - * Returns: (transfer full): The new view.
    - */
    -GtkWidget *
    -gplugin_gtk_view_new(void)
    -{
    - GObject *ret = NULL;
    - GPluginGtkStore *store = gplugin_gtk_store_new();
    -
    - /* clang-format off */
    - ret = g_object_new(
    - GPLUGIN_GTK_TYPE_VIEW,
    - "model", GTK_TREE_MODEL(store),
    - NULL);
    - /* clang-format on */
    -
    - return GTK_WIDGET(ret);
    -}
    -
    -/**
    - * gplugin_gtk_view_set_show_internal:
    - * @view: The #GPluginGtkView instance.
    - * @show_internal: Whether or not to show internal plugins.
    - *
    - * This function will toggle whether or not the widget will show internal
    - * plugins.
    - */
    -void
    -gplugin_gtk_view_set_show_internal(GPluginGtkView *view, gboolean show_internal)
    -{
    - g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view));
    -
    - view->show_internal = show_internal;
    -
    - g_object_notify(G_OBJECT(view), "show-internal");
    -}
    -
    -/**
    - * gplugin_gtk_view_get_show_internal:
    - * @view: The #GPluginGtkView instance.
    - *
    - * Returns whether or not @view is showing internal plugins.
    - */
    -gboolean
    -gplugin_gtk_view_get_show_internal(GPluginGtkView *view)
    -{
    - g_return_val_if_fail(GPLUGIN_GTK_IS_VIEW(view), FALSE);
    -
    - return view->show_internal;
    -}
    --- a/gplugin-gtk/gplugin-gtk-view.h Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,50 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/gplugin-gtk.h> may be included directly"
    -#endif
    -
    -#ifndef GPLUGIN_GTK_VIEW_H
    -#define GPLUGIN_GTK_VIEW_H
    -
    -#include <glib.h>
    -#include <glib-object.h>
    -
    -#include <gtk/gtk.h>
    -
    -G_BEGIN_DECLS
    -
    -#define GPLUGIN_GTK_TYPE_VIEW (gplugin_gtk_view_get_type())
    -G_DECLARE_FINAL_TYPE(
    - GPluginGtkView,
    - gplugin_gtk_view,
    - GPLUGIN_GTK,
    - VIEW,
    - GtkTreeView)
    -
    -GtkWidget *gplugin_gtk_view_new(void);
    -
    -void gplugin_gtk_view_set_show_internal(
    - GPluginGtkView *view,
    - gboolean show_internal);
    -gboolean gplugin_gtk_view_get_show_internal(GPluginGtkView *view);
    -
    -G_END_DECLS
    -
    -#endif /* GPLUGIN_GTK_VIEW_H */
    --- a/gplugin-gtk/gplugin-gtk.h.in Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,34 +0,0 @@
    -/*
    - * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/>.
    - */
    -#ifndef GPLUGIN_GTK_H
    -#define GPLUGIN_GTK_H
    -
    -#ifndef __GI_SCANNER__
    -# ifdef GPLUGIN_GTK_COMPILATION
    -# error "gplugin-gtk source files should not include gplugin-gtk.h"
    -# endif /* GPLUGIN_GTK_COMPILATION */
    -#endif /* __GI_SCANNER__ */
    -
    -#ifndef GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
    -# define GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
    -#endif /* GPLUGIN_GTK_GLOBAL_HEADER_INSIDE */
    -
    -@GPLUGIN_GTK_H_INCLUDES@
    -
    -#undef GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
    -
    -#endif /* GPLUGIN_GTK_H */
    --- a/gplugin-gtk/gplugin-gtk.xml.in Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,36 +0,0 @@
    -<?xml version="1.0" encoding="UTF-8"?>
    -<glade-catalog name="gplugin-gtk"
    - version="@GPLUGIN_VERSION@"
    - library="gplugin-gtk"
    - domain="gplugin"
    - depends="gtk+"
    - book="GPlugin">
    - <glade-widget-classes>
    - <!-- the get-type-function's are needed due to gplugin's weirdo namespace.
    - Without them, Glade is going to look for g_plugin_*_get_type and not
    - gplugin_*_get_type.
    - -->
    - <glade-widget-class
    - name="GPluginGtkPluginInfo"
    - generic-name="plugininfo"
    - title="Plugin Info"
    - get-type-function="gplugin_gtk_plugin_info_get_type"/>
    - <glade-widget-class
    - name="GPluginGtkView"
    - generic-name="pluginview"
    - title="Plugin View"
    - get-type-function="gplugin_gtk_view_get_type"/>
    - <glade-widget-class
    - name="GPluginGtkStore"
    - generic-name="pluginstore"
    - title="Plugin Store"
    - get-type-function="gplugin_gtk_store_get_type"
    - toplevel="True"/>
    - </glade-widget-classes>
    -
    - <glade-widget-group name="gplugin-gtk" title="GPlugin Gtk Widgets">
    - <glade-widget-class-ref name="GPluginGtkPluginInfo"/>
    - <glade-widget-class-ref name="GPluginGtkView"/>
    - <glade-widget-class-ref name="GPluginGtkStore"/>
    - </glade-widget-group>
    -</glade-catalog>
    --- a/gplugin-gtk/meson.build Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,154 +0,0 @@
    -if get_option('gtk3')
    -
    -###############################################################################
    -# Build Info
    -###############################################################################
    -GTK3 = dependency('gtk+-3.0', version : '>=3.0.0')
    -
    -GPLUGIN_GTK_LIBRARY_VERSION = '0.1.0'
    -
    -GPLUGIN_GTK_SOURCES = [
    - 'gplugin-gtk-plugin-info.c',
    - 'gplugin-gtk-store.c',
    - 'gplugin-gtk-view.c',
    -]
    -
    -GPLUGIN_GTK_HEADERS = [
    - 'gplugin-gtk-plugin-info.h',
    - 'gplugin-gtk-store.h',
    - 'gplugin-gtk-view.h',
    -]
    -
    -GPLUGIN_GTK_PRIVATE_SOURCES = [
    -]
    -
    -GPLUGIN_GTK_PRIVATE_HEADERS = [
    -]
    -
    -GPLUGIN_GTK_PUBLIC_BUILT_SOURCES = [
    -]
    -
    -GPLUGIN_GTK_PUBLIC_BUILT_HEADERS = [
    -]
    -
    -GPLUGIN_GTK_GENERATED_TARGETS = [
    -]
    -
    -###############################################################################
    -# Configure Files
    -###############################################################################
    -GPLUGIN_GTK_H_INCLUDES = ''
    -foreach header : GPLUGIN_GTK_HEADERS
    - GPLUGIN_GTK_H_INCLUDES = '@0@\n#include <gplugin-gtk/@1@>'.format(
    - GPLUGIN_GTK_H_INCLUDES,
    - header)
    -endforeach
    -
    -conf = configuration_data()
    -conf.set('GPLUGIN_GTK_H_INCLUDES', GPLUGIN_GTK_H_INCLUDES)
    -gplugin_gtk_h = configure_file(
    - input : 'gplugin-gtk.h.in',
    - output : 'gplugin-gtk.h',
    - configuration : conf,
    - install : true,
    - install_dir : get_option('includedir') / 'gplugin-1.0')
    -
    -gplugin_gtk_xml = configure_file(
    - input : 'gplugin-gtk.xml.in',
    - output: 'gplugin-gtk.xml',
    - configuration : version_conf,
    - install: true,
    - install_dir : get_option('datadir') / 'glade' / 'catalogs',
    -)
    -
    -###############################################################################
    -# Resource Target
    -###############################################################################
    -gplugin_gtk_resources = gnome.compile_resources(
    - 'gplugin-gtk-resources',
    - 'data/gplugin-gtk.gresource.xml',
    - c_name: 'gplugin_gtk',
    - source_dir: 'data')
    -
    -###############################################################################
    -# Library Target
    -###############################################################################
    -gplugin_gtk = shared_library('gplugin-gtk',
    - GPLUGIN_GTK_SOURCES,
    - GPLUGIN_GTK_HEADERS,
    - GPLUGIN_GTK_PRIVATE_SOURCES,
    - GPLUGIN_GTK_PRIVATE_HEADERS,
    - GPLUGIN_GTK_PUBLIC_BUILT_SOURCES,
    - GPLUGIN_GTK_PUBLIC_BUILT_HEADERS,
    - gplugin_gtk_resources,
    - c_args : ['-DGPLUGIN_GTK_COMPILATION', '-DG_LOG_DOMAIN="GPluginGtk"'],
    - include_directories : toplevel_inc,
    - dependencies : [gplugin_dep, GTK3],
    - version : GPLUGIN_GTK_LIBRARY_VERSION,
    - install : true
    -)
    -
    -gplugin_gtk_inc = include_directories('.')
    -
    -pkgconfig.generate(
    - gplugin_gtk,
    - name : 'gplugin-gtk',
    - description : 'Gtk widgets for GPlugin',
    - filebase : 'gplugin-gtk',
    - subdirs : 'gplugin-1.0',
    - libraries : [gplugin],
    - requires : [GLIB, GOBJECT, GMODULE],
    - variables : [
    - 'plugindir=${libdir}',
    - ],
    -)
    -
    -###############################################################################
    -# GObject Introspection
    -###############################################################################
    -if get_option('introspection')
    - gplugin_gtk_gir = gnome.generate_gir(
    - gplugin_gtk,
    - sources : GPLUGIN_GTK_SOURCES + GPLUGIN_GTK_HEADERS +
    - GPLUGIN_GTK_PUBLIC_BUILT_SOURCES +
    - GPLUGIN_GTK_PUBLIC_BUILT_HEADERS,
    - includes : [gplugin_gir[0], 'Gtk-3.0'],
    - namespace : 'GPluginGtk',
    - symbol_prefix : 'gplugin_gtk',
    - nsversion : '1.0',
    - install : true,
    - export_packages: ['gplugin-gtk'],
    - dependencies : [gplugin_dep],
    - extra_args : ['--quiet', '-DGPLUGIN_GTK_COMPILATION'])
    - GPLUGIN_GTK_GENERATED_TARGETS += gplugin_gtk_gir
    -endif
    -
    -###############################################################################
    -# Library Dependency Object
    -###############################################################################
    -gplugin_gtk_dep = declare_dependency(
    - include_directories: [toplevel_inc, gplugin_gtk_inc],
    - link_with : [gplugin, gplugin_gtk],
    - sources : GPLUGIN_GTK_PUBLIC_BUILT_HEADERS + GPLUGIN_GTK_GENERATED_TARGETS,
    - dependencies : [GLIB, GOBJECT, GTK3],
    -)
    -
    -if meson.version().version_compare('>=0.54.0')
    - meson.override_dependency('gplugin-gtk', gplugin_gtk_dep)
    -endif
    -
    -###############################################################################
    -# Install Stuff
    -###############################################################################
    -# install the normal includes into the gplugin-gtk subdirectory
    -install_headers(
    - GPLUGIN_GTK_HEADERS,
    - subdir : 'gplugin-1.0/gplugin-gtk'
    -)
    -
    -###############################################################################
    -# subdirectories
    -###############################################################################
    -subdir('reference')
    -
    -endif # gtk3
    --- a/gplugin-gtk/reference/gplugin-gtk.toml.in Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,48 +0,0 @@
    -[library]
    -version = "@GPLUGIN_VERSION@"
    -browse_url = "https://keep.imfreedom.org/gplugin/gplugin/"
    -repository_url = "https://keep.imfreedom.org/gplugin/gplugin/"
    -website_url = "https://keep.imfreedom.org/gplugin/gplugin/"
    -authors = "GPlugin Developers"
    -logo_url = ""
    -license = "LGPL-2.1-or-later"
    -description = "GPlugin Gtk Library"
    -dependencies = [ "GLib-2.0", "GObject-2.0", "GPlugin-1.0", "Gtk-3.0" ]
    -devhelp = true
    -search_index = true
    -
    - [dependencies."GLib-2.0"]
    - name = "GLib"
    - description = "General-purpose, portable utility library."
    - docs_url = "https://docs.gtk.org/glib/"
    -
    - [dependencies."GObject-2.0"]
    - name = "GObject"
    - description = "The base type system library"
    - docs_url = "https://docs.gtk.org/gobject/"
    -
    - [dependencies."GPlugin-1.0"]
    - name = "GPlugin"
    - description = "Plugin library"
    - docs_url = "https://docs.imfreedom.org/gplugin/"
    -
    - [dependencies."Gtk-3.0"]
    - name = "Gtk3"
    - description = "Gtk Widget Toolkit"
    - docs_url = "https://docs.gtk.org/gtk3/"
    -
    -[theme]
    -name = "basic"
    -show_index_summary = true
    -show_class_hierarchy = true
    -
    -[source-location]
    -base_url = "https://keep.imfreedom.org/gplugin/gplugin/file/default/"
    -
    -[extra]
    -# The same order will be used when generating the index
    -content_files = [
    -]
    -content_images = [
    -]
    -urlmap_file = "urlmap.js"
    --- a/gplugin-gtk/reference/meson.build Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,31 +0,0 @@
    -if get_option('doc')
    - gplugin_gtk_toml = configure_file(
    - input : 'gplugin-gtk.toml.in',
    - output : 'gplugin-gtk.toml',
    - configuration : version_conf,
    - install : true,
    - install_dir : docs_dir / 'gplugin-gtk',
    - )
    -
    - gplugin_gtk_doc = custom_target('gplugin-gtk-doc',
    - input : [ gplugin_gtk_toml, gplugin_gtk_gir[0] ],
    - output : 'gplugin-gtk',
    - command : [
    - gidocgen,
    - 'generate',
    - '--quiet',
    - '--fatal-warnings',
    - '--add-include-path=@0@'.format(meson.project_build_root() / 'gplugin'),
    - '--config=@INPUT0@',
    - '--output-dir=@OUTPUT@',
    - '--no-namespace-dir',
    - '--content-dir=@0@'.format(meson.current_source_dir()),
    - '@INPUT1@'
    - ],
    - depends : [ gplugin_gir[0] ],
    - build_by_default : true,
    - install : true,
    - install_dir : docs_dir,
    - )
    -endif
    -
    --- a/gplugin-gtk/reference/urlmap.js Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,11 +0,0 @@
    -// SPDX-FileCopyrightText: 2021 GNOME Foundation
    -// SPDX-License-Identifier: LGPL-2.1-or-later
    -
    -// A map between namespaces and base URLs for their online documentation
    -baseURLs = [
    - [ 'GLib', 'https://docs.gtk.org/glib/' ],
    - [ 'GObject', 'https://docs.gtk.org/gobject/' ],
    - [ 'GPlugin', 'https://docs.imfreedom.org/gplugin/' ],
    - [ 'GModule', 'https://docs.gtk.org/gmodule/' ],
    - [ 'Gtk3', 'https://docs.gtk.org/gtk3/' ],
    -]
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3-viewer/data/gplugin-gtk-viewer.gresource.xml Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,6 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<gresources>
    + <gresource prefix="/org/imfreedom/keep/gplugin/gplugin/viewer/">
    + <file compressed="true">window.ui</file>
    + </gresource>
    +</gresources>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3-viewer/data/window.ui Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,65 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Generated with glade 3.22.1 -->
    +<interface>
    + <requires lib="gtk+" version="3.20"/>
    + <requires lib="gplugin-gtk" version="0.28"/>
    + <template class="viewer" parent="GtkWindow">
    + <property name="can_focus">False</property>
    + <property name="border_width">12</property>
    + <property name="title" translatable="yes">GPlugin Viewer</property>
    + <child>
    + <placeholder/>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">12</property>
    + <child>
    + <object class="GtkScrolledWindow">
    + <property name="visible">True</property>
    + <property name="can_focus">True</property>
    + <property name="hscrollbar_policy">never</property>
    + <property name="shadow_type">in</property>
    + <child>
    + <object class="GPluginGtkView" id="view">
    + <property name="visible">True</property>
    + <property name="can_focus">True</property>
    + <property name="headers_visible">False</property>
    + <property name="headers_clickable">False</property>
    + <child internal-child="selection">
    + <object class="GtkTreeSelection"/>
    + </child>
    + </object>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GPluginGtkPluginInfo" id="info">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label_xalign">0</property>
    + <property name="shadow_type">none</property>
    + <child type="label">
    + <object class="GtkLabel">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">__glade_unnamed_5</property>
    + </object>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + </child>
    + </template>
    +</interface>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3-viewer/gplugin-gtk-viewer-window.c Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,54 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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-gtk-viewer-window.h"
    +
    +#include <gtk/gtk.h>
    +
    +struct _GPluginGtkViewerWindow {
    + GtkWindow parent;
    +};
    +
    +G_DEFINE_TYPE(
    + GPluginGtkViewerWindow,
    + gplugin_gtk_viewer_window,
    + GTK_TYPE_WINDOW)
    +
    +/******************************************************************************
    + * GObject Stuff
    + *****************************************************************************/
    +static void
    +gplugin_gtk_viewer_window_init(GPluginGtkViewerWindow *window)
    +{
    + gtk_widget_init_template(GTK_WIDGET(window));
    +}
    +
    +static void
    +gplugin_gtk_viewer_window_class_init(GPluginGtkViewerWindowClass *klass)
    +{
    + gtk_widget_class_set_template_from_resource(
    + GTK_WIDGET_CLASS(klass),
    + "/org/imfreedom/keep/gplugin/gplugin/viewer/window.ui");
    +}
    +
    +/******************************************************************************
    + * Public API
    + *****************************************************************************/
    +GtkWidget *
    +gplugin_gtk_viewer_window_new(void)
    +{
    + return GTK_WIDGET(g_object_new(GPLUGIN_GTK_VIEWER_TYPE_WINDOW, NULL));
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3-viewer/gplugin-gtk-viewer-window.h Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,40 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/>.
    + */
    +
    +#ifndef GPLUGIN_GTK_VIEWER_WINDOW_H
    +#define GPLUGIN_GTK_VIEWER_WINDOW_H
    +
    +#include <glib.h>
    +#include <glib-object.h>
    +
    +#include <gtk/gtk.h>
    +
    +#define GPLUGIN_GTK_VIEWER_TYPE_WINDOW (gplugin_gtk_viewer_window_get_type())
    +G_DECLARE_FINAL_TYPE(
    + GPluginGtkViewerWindow,
    + gplugin_gtk_viewer_window,
    + GPLUGIN_GTK_VIEWER,
    + WINDOW,
    + GtkWindow)
    +
    +G_BEGIN_DECLS
    +
    +GtkWidget *gplugin_gtk_viewer_window_new(void);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_GTK_VIEWER_WINDOW_H */
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3-viewer/gplugin-gtk-viewer.c Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,237 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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 <stdio.h>
    +#include <stdlib.h>
    +
    +#include <gtk/gtk.h>
    +
    +#include <gplugin.h>
    +#include <gplugin-gtk.h>
    +
    +/******************************************************************************
    + * Globals
    + *****************************************************************************/
    +static gboolean show_internal = FALSE;
    +static gboolean add_default_paths = TRUE, version_only = FALSE;
    +static gchar **paths = NULL;
    +
    +/******************************************************************************
    + * Callbacks
    + *****************************************************************************/
    +static gboolean
    +window_closed_cb(
    + G_GNUC_UNUSED GtkWidget *w,
    + G_GNUC_UNUSED GdkEvent *e,
    + G_GNUC_UNUSED gpointer d)
    +{
    + gtk_main_quit();
    +
    + return FALSE;
    +}
    +
    +static void
    +selection_changed_cb(GtkTreeSelection *sel, gpointer data)
    +{
    + GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(data);
    + GPluginPlugin *plugin = NULL;
    + GtkTreeModel *model = NULL;
    + GtkTreeIter iter;
    +
    + if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
    + gtk_tree_model_get(
    + model,
    + &iter,
    + GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    + &plugin,
    + -1);
    + }
    +
    + gplugin_gtk_plugin_info_set_plugin(info, plugin);
    +}
    +
    +/******************************************************************************
    + * Helpers
    + *****************************************************************************/
    +static gboolean
    +internal_cb(
    + G_GNUC_UNUSED const gchar *n,
    + G_GNUC_UNUSED const gchar *v,
    + G_GNUC_UNUSED gpointer d,
    + G_GNUC_UNUSED GError **e)
    +{
    + show_internal = TRUE;
    +
    + return TRUE;
    +}
    +
    +static gboolean
    +no_default_cb(
    + G_GNUC_UNUSED const gchar *n,
    + G_GNUC_UNUSED const gchar *v,
    + G_GNUC_UNUSED gpointer d,
    + G_GNUC_UNUSED GError **e)
    +{
    + add_default_paths = FALSE;
    +
    + return TRUE;
    +}
    +
    +static gboolean
    +version_cb(
    + G_GNUC_UNUSED const gchar *n,
    + G_GNUC_UNUSED const gchar *v,
    + G_GNUC_UNUSED gpointer d,
    + G_GNUC_UNUSED GError **e)
    +{
    + version_only = TRUE;
    +
    + printf("gplugin-gtk-viewer %s\n", GPLUGIN_VERSION);
    +
    + return TRUE;
    +}
    +
    +static GtkWidget *
    +create_window(void)
    +{
    + GtkWidget *window = NULL, *grid = NULL, *sw = NULL;
    + GtkWidget *view = NULL, *info = NULL;
    + GtkTreeSelection *sel = NULL;
    +
    + window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    + gtk_window_set_title(GTK_WINDOW(window), "GPlugin Viewer");
    + gtk_container_set_border_width(GTK_CONTAINER(window), 12);
    + g_signal_connect(
    + G_OBJECT(window),
    + "delete-event",
    + G_CALLBACK(window_closed_cb),
    + NULL);
    +
    + grid = gtk_grid_new();
    + gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    + gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
    + gtk_container_add(GTK_CONTAINER(window), grid);
    +
    + sw = gtk_scrolled_window_new(NULL, NULL);
    + gtk_scrolled_window_set_policy(
    + GTK_SCROLLED_WINDOW(sw),
    + GTK_POLICY_NEVER,
    + GTK_POLICY_AUTOMATIC);
    + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
    + gtk_grid_attach(GTK_GRID(grid), sw, 0, 0, 1, 1);
    +
    + view = gplugin_gtk_view_new();
    + gplugin_gtk_view_set_show_internal(GPLUGIN_GTK_VIEW(view), show_internal);
    + gtk_container_add(GTK_CONTAINER(sw), view);
    +
    + info = gplugin_gtk_plugin_info_new();
    + gtk_grid_attach(GTK_GRID(grid), info, 1, 0, 1, 1);
    +
    + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
    + g_signal_connect(
    + G_OBJECT(sel),
    + "changed",
    + G_CALLBACK(selection_changed_cb),
    + info);
    +
    + return window;
    +}
    +
    +/******************************************************************************
    + * Main Stuff
    + *****************************************************************************/
    +/* clang-format off */
    +static GOptionEntry entries[] = {
    + {
    + "internal", 'i', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    + internal_cb, "Show internal plugins",
    + NULL,
    + }, {
    + "no-default-paths", 'D', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    + no_default_cb, "Do not search the default plugin paths",
    + NULL,
    + }, {
    + "path", 'p', 0, G_OPTION_ARG_STRING_ARRAY,
    + &paths, "Additional paths to look for plugins",
    + "PATH",
    + }, {
    + "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
    + version_cb, "Display the version and exit",
    + NULL,
    + }, {
    + NULL, 0, 0, 0, NULL, NULL, NULL,
    + },
    +};
    +/* clang-format on */
    +
    +gint
    +main(gint argc, gchar **argv)
    +{
    + GPluginManager *manager = NULL;
    + GError *error = NULL;
    + GOptionContext *ctx = NULL;
    + GtkWidget *window = NULL;
    +
    + ctx = g_option_context_new("");
    + g_option_context_add_main_entries(ctx, entries, NULL);
    + g_option_context_add_group(ctx, gtk_get_option_group(TRUE));
    + g_option_context_parse(ctx, &argc, &argv, &error);
    + g_option_context_free(ctx);
    +
    + if(error) {
    + fprintf(stderr, "%s\n", error->message);
    +
    + g_error_free(error);
    +
    + gplugin_uninit();
    +
    + return EXIT_FAILURE;
    + }
    +
    + if(version_only) {
    + return 0;
    + }
    +
    + gtk_init(&argc, &argv);
    +
    + gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
    +
    + manager = gplugin_manager_get_default();
    +
    + if(add_default_paths)
    + gplugin_manager_add_default_paths(manager);
    +
    + if(paths) {
    + gint i;
    +
    + for(i = 0; paths[i]; i++) {
    + gplugin_manager_prepend_path(manager, paths[i]);
    + }
    + }
    +
    + gplugin_manager_refresh(manager);
    +
    + /* now create and show the window */
    + window = create_window();
    + gtk_widget_show_all(window);
    +
    + gtk_main();
    +
    + gplugin_uninit();
    +
    + return 0;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3-viewer/meson.build Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,36 @@
    +if get_option('gtk3')
    +
    +if not get_option('install-gplugin-gtk3-viewer')
    +summary('gplugin-gtk3-viewer',
    + 'You have disabled installation of gplugin-gtk-viewer which is a ' +
    + 'very useful diagnostics tool.',
    + section : 'Warnings')
    +endif
    +
    +gplugin_gtk3_viewer_resources = gnome.compile_resources(
    + 'gplugin-gtk-viewer-resources',
    + 'data/gplugin-gtk-viewer.gresource.xml',
    + c_name: 'gplugin_gtk_viewer',
    + source_dir: 'data')
    +
    +gplugin_gtk3_viewer = executable('gplugin-gtk3-viewer',
    + 'gplugin-gtk-viewer.c',
    + 'gplugin-gtk-viewer-window.c',
    + 'gplugin-gtk-viewer-window.h',
    + dependencies : [gplugin_dep, gplugin_gtk3_dep],
    + install : get_option('install-gplugin-gtk3-viewer')
    +)
    +
    +if get_option('help2man')
    + gplugin_gtk_viewer_man = custom_target('gplugin-gtk3-viewer.1',
    + command : [help2man,
    + '--name=View installed plugins', '--section=1',
    + '--help-option=--help-all', '--no-info',
    + '--output', '@OUTPUT@',
    + gplugin_gtk3_viewer],
    + output : 'gplugin-gtk3-viewer.1',
    + install : get_option('install-gplugin-gtk3-viewer'),
    + install_dir : get_option('mandir') / 'man1')
    +endif
    +
    +endif
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/data/gplugin-gtk.gresource.xml Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,6 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<gresources>
    + <gresource prefix="/org/imfreedom/keep/gplugin/gplugin-gtk/">
    + <file compressed="true">plugin-info.ui</file>
    + </gresource>
    +</gresources>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/data/plugin-info.ui Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,582 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Generated with glade 3.22.2 -->
    +<interface>
    + <requires lib="gtk+" version="3.10"/>
    + <template class="GPluginGtkPluginInfo" parent="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <object class="GtkLabel" id="name">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + <attributes>
    + <attribute name="weight" value="bold"/>
    + <attribute name="scale" value="2"/>
    + </attributes>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="version_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Version</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="version">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="authors_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Authors</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox" id="authors_box">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <placeholder/>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">2</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="website_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Website</property>
    + <property name="use_underline">True</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="website">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="use_markup">True</property>
    + <property name="track_visited_links">False</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">3</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="summary_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Summary</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="summary">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">4</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="description_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Description</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="description">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="wrap">True</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">5</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="dependencies_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Dependencies</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox" id="dependencies_box">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <placeholder/>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">6</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="error_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Error</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="error">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">7</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkExpander">
    + <property name="visible">True</property>
    + <property name="can_focus">True</property>
    + <property name="label_fill">True</property>
    + <signal name="activate" handler="gplugin_gtk_plugin_info_expander_activate" object="GPluginGtkPluginInfo" swapped="no"/>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="orientation">vertical</property>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="id_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">ID</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="id">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="filename_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Filename</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="filename">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="abi_version_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">ABI Version</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="abi_version">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">2</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="loader_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Loader</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="loader">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">3</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="internal_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Internal</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="internal">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">4</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkBox">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="spacing">6</property>
    + <child>
    + <object class="GtkLabel" id="load_on_query_label">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">Load on Query</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">0</property>
    + </packing>
    + </child>
    + <child>
    + <object class="GtkLabel" id="load_on_query">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="xalign">0</property>
    + <property name="yalign">0</property>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">1</property>
    + </packing>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">False</property>
    + <property name="fill">True</property>
    + <property name="position">5</property>
    + </packing>
    + </child>
    + </object>
    + </child>
    + <child type="label">
    + <object class="GtkLabel" id="expander">
    + <property name="visible">True</property>
    + <property name="can_focus">False</property>
    + <property name="label" translatable="yes">More</property>
    + </object>
    + </child>
    + </object>
    + <packing>
    + <property name="expand">True</property>
    + <property name="fill">True</property>
    + <property name="position">8</property>
    + </packing>
    + </child>
    + </template>
    + <object class="GtkSizeGroup" id="size_group">
    + <widgets>
    + <widget name="version_label"/>
    + <widget name="authors_label"/>
    + <widget name="website_label"/>
    + <widget name="summary_label"/>
    + <widget name="description_label"/>
    + <widget name="dependencies_label"/>
    + <widget name="id_label"/>
    + <widget name="filename_label"/>
    + <widget name="abi_version_label"/>
    + <widget name="loader_label"/>
    + <widget name="internal_label"/>
    + <widget name="load_on_query_label"/>
    + <widget name="error_label"/>
    + </widgets>
    + </object>
    +</interface>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk-plugin-info.c Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,496 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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 <glib/gi18n-lib.h>
    +
    +#include <gplugin.h>
    +
    +#include <gplugin-gtk-plugin-info.h>
    +
    +
    +/**
    + * SECTION:gplugin-gtk-plugin-info
    + * @title: Plugin Info Gtk Widgets
    + * @short_description: Gtk Widgets for plugins
    + *
    + * #GPluginGtkPluginInfo is a Gtk widget that shows information about plugins.
    + */
    +
    +/**
    + * GPLUGIN_GTK_TYPE_PLUGIN_INFO:
    + *
    + * The standard _get_type macro for #GPluginGtkPluginInfo.
    + */
    +
    +/**
    + * GPluginGtkPluginInfo:
    + *
    + * A widget that displays a #GPluginPluginInfo in a user friendly way.
    + */
    +
    +/******************************************************************************
    + * Structs
    + *****************************************************************************/
    +struct _GPluginGtkPluginInfo {
    + GtkBox parent;
    +
    + GPluginPlugin *plugin;
    + gulong signal_id;
    +
    + GtkWidget *name;
    + GtkWidget *version;
    + GtkWidget *authors_box;
    + GtkWidget *website;
    + GtkWidget *summary;
    + GtkWidget *description;
    + GtkWidget *dependencies_box;
    + GtkWidget *error;
    + GtkWidget *expander;
    + GtkWidget *id;
    + GtkWidget *filename;
    + GtkWidget *abi_version;
    + GtkWidget *loader;
    + GtkWidget *internal;
    + GtkWidget *load_on_query;
    +};
    +
    +/*****************************************************************************s
    + * Enums
    + *****************************************************************************/
    +enum {
    + PROP_ZERO,
    + PROP_PLUGIN,
    + N_PROPERTIES,
    +};
    +static GParamSpec *properties[N_PROPERTIES] = {
    + NULL,
    +};
    +
    +G_DEFINE_TYPE(GPluginGtkPluginInfo, gplugin_gtk_plugin_info, GTK_TYPE_BOX);
    +
    +/******************************************************************************
    + * Callbacks
    + *****************************************************************************/
    +static void
    +gplugin_gtk_plugin_info_expander_activate(
    + GtkExpander *expander,
    + G_GNUC_UNUSED gpointer data)
    +{
    + if(gtk_expander_get_expanded(expander))
    + gtk_expander_set_label(expander, "More");
    + else
    + gtk_expander_set_label(expander, "Less");
    +}
    +
    +/******************************************************************************
    + * Helpers
    + *****************************************************************************/
    +static void
    +_gplugin_gtk_plugin_info_refresh(GPluginGtkPluginInfo *info)
    +{
    + GtkWidget *widget = NULL;
    + GError *error = NULL;
    + GList *children = NULL, *iter = NULL;
    + gchar *markup = NULL;
    + gchar *name = NULL, *version = NULL, *website = NULL;
    + gchar *summary = NULL, *description = NULL, *id = NULL, *abi_version = NULL;
    + gchar *loader = NULL;
    + gchar **authors = NULL;
    + gchar **dependencies = NULL;
    + guint32 abi_version_uint;
    + gboolean loq = FALSE, internal = FALSE;
    + const gchar *filename = NULL;
    +
    + /* remove all the children from the authors box */
    + children = gtk_container_get_children(GTK_CONTAINER(info->authors_box));
    + for(iter = children; iter; iter = iter->next)
    + gtk_widget_destroy(GTK_WIDGET(iter->data));
    + g_list_free(children);
    +
    + /* remove all the children from the dependencies box */
    + children =
    + gtk_container_get_children(GTK_CONTAINER(info->dependencies_box));
    + for(iter = children; iter; iter = iter->next)
    + gtk_widget_destroy(GTK_WIDGET(iter->data));
    + g_list_free(children);
    +
    + /* now get the info if we can */
    + if(GPLUGIN_IS_PLUGIN(info->plugin)) {
    + GPluginPluginInfo *plugin_info = gplugin_plugin_get_info(info->plugin);
    + GPluginLoader *plugin_loader = gplugin_plugin_get_loader(info->plugin);
    +
    + filename = gplugin_plugin_get_filename(info->plugin);
    + error = gplugin_plugin_get_error(info->plugin);
    +
    + if(plugin_loader && GPLUGIN_IS_LOADER(plugin_loader)) {
    + const char *loader_name = G_OBJECT_TYPE_NAME(plugin_loader);
    + loader = g_strdup(loader_name);
    + g_object_unref(G_OBJECT(plugin_loader));
    + }
    +
    + /* clang-format off */
    + g_object_get(
    + G_OBJECT(plugin_info),
    + "abi_version", &abi_version_uint,
    + "authors", &authors,
    + "summary", &summary,
    + "description", &description,
    + "dependencies", &dependencies,
    + "id", &id,
    + "internal", &internal,
    + "load-on-query", &loq,
    + "name", &name,
    + "version", &version,
    + "website", &website,
    + NULL);
    + /* clang-format on */
    +
    + /* fanagle the plugin name */
    + markup = g_markup_printf_escaped(
    + "<span font_size=\"large\" "
    + "font_weight=\"bold\">%s</span>",
    + (name) ? name : "Unnamed");
    + g_free(name);
    + name = markup;
    +
    + /* fanagle the website */
    + if(website) {
    + markup = g_markup_printf_escaped(
    + "<a href=\"%s\">%s</a>",
    + website,
    + website);
    + g_free(website);
    + website = markup;
    + }
    +
    + /* fanagle the abi_version */
    + abi_version = g_strdup_printf("%08x", abi_version_uint);
    +
    + g_object_unref(G_OBJECT(plugin_info));
    + }
    +
    + gtk_label_set_markup(GTK_LABEL(info->name), (name) ? name : "Unnamed");
    + gtk_label_set_text(GTK_LABEL(info->version), (version) ? version : "");
    + gtk_label_set_markup(GTK_LABEL(info->website), (website) ? website : "");
    + gtk_label_set_text(GTK_LABEL(info->summary), (summary) ? summary : "");
    + gtk_label_set_text(
    + GTK_LABEL(info->description),
    + (description) ? description : "");
    + gtk_label_set_text(GTK_LABEL(info->id), (id) ? id : "");
    + gtk_label_set_text(
    + GTK_LABEL(info->error),
    + (error) ? error->message : "(none)");
    + gtk_label_set_text(GTK_LABEL(info->filename), (filename) ? filename : "");
    + gtk_label_set_text(
    + GTK_LABEL(info->abi_version),
    + (abi_version) ? abi_version : "");
    + gtk_label_set_text(GTK_LABEL(info->loader), (loader) ? loader : "Unknown");
    + gtk_label_set_text(GTK_LABEL(info->internal), (internal) ? "Yes" : "No");
    + gtk_label_set_text(GTK_LABEL(info->load_on_query), (loq) ? "Yes" : "No");
    +
    + g_free(description);
    + g_free(id);
    + g_free(name);
    + g_free(version);
    + g_free(website);
    + g_free(loader);
    + g_clear_error(&error);
    +
    + /* set the authors */
    + if(authors) {
    + gint i = 0;
    +
    + for(i = 0; authors[i]; i++) {
    + widget = gtk_label_new(authors[i]);
    + gtk_widget_set_halign(widget, GTK_ALIGN_START);
    + gtk_widget_set_valign(widget, GTK_ALIGN_START);
    + gtk_box_pack_start(
    + GTK_BOX(info->authors_box),
    + widget,
    + TRUE,
    + TRUE,
    + 0);
    + gtk_widget_show(widget);
    + }
    + }
    + g_strfreev(authors);
    +
    + /* set the dependencies */
    + if(dependencies) {
    + gint i = 0;
    +
    + for(i = 0; dependencies[i]; i++) {
    + widget = gtk_label_new(dependencies[i]);
    + gtk_widget_set_halign(widget, GTK_ALIGN_START);
    + gtk_widget_set_valign(widget, GTK_ALIGN_START);
    + gtk_box_pack_start(
    + GTK_BOX(info->dependencies_box),
    + widget,
    + TRUE,
    + TRUE,
    + 0);
    + gtk_widget_show(widget);
    + }
    + } else {
    + widget = gtk_label_new(_("(none)"));
    + gtk_box_pack_start(
    + GTK_BOX(info->dependencies_box),
    + widget,
    + TRUE,
    + TRUE,
    + 0);
    + gtk_widget_show(widget);
    + }
    + g_strfreev(dependencies);
    +}
    +
    +/******************************************************************************
    + * Callbacks
    + *****************************************************************************/
    +static void
    +gplugin_gtk_plugin_info_state_cb(GObject *obj, GParamSpec *pspec, gpointer data)
    +{
    + _gplugin_gtk_plugin_info_refresh(GPLUGIN_GTK_PLUGIN_INFO(data));
    +}
    +
    +/******************************************************************************
    + * GObject Stuff
    + *****************************************************************************/
    +static void
    +gplugin_gtk_plugin_info_set_property(
    + GObject *obj,
    + guint prop_id,
    + const GValue *value,
    + GParamSpec *pspec)
    +{
    + GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    +
    + switch(prop_id) {
    + case PROP_PLUGIN:
    + gplugin_gtk_plugin_info_set_plugin(info, g_value_get_object(value));
    + break;
    + default:
    + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    + break;
    + }
    +}
    +
    +static void
    +gplugin_gtk_plugin_info_get_property(
    + GObject *obj,
    + guint prop_id,
    + GValue *value,
    + GParamSpec *pspec)
    +{
    + GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    +
    + switch(prop_id) {
    + case PROP_PLUGIN:
    + g_value_set_object(value, gplugin_gtk_plugin_info_get_plugin(info));
    + break;
    + default:
    + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    + break;
    + }
    +}
    +
    +static void
    +gplugin_gtk_plugin_info_finalize(GObject *obj)
    +{
    + GPluginGtkPluginInfo *info = GPLUGIN_GTK_PLUGIN_INFO(obj);
    +
    + if(info->signal_id != 0 && GPLUGIN_IS_PLUGIN(info->plugin)) {
    + g_signal_handler_disconnect(G_OBJECT(info->plugin), info->signal_id);
    + }
    +
    + g_clear_object(&info->plugin);
    +
    + G_OBJECT_CLASS(gplugin_gtk_plugin_info_parent_class)->finalize(obj);
    +}
    +
    +static void
    +gplugin_gtk_plugin_info_init(GPluginGtkPluginInfo *info)
    +{
    + gtk_widget_init_template(GTK_WIDGET(info));
    +
    + info->signal_id = 0;
    +}
    +
    +static void
    +gplugin_gtk_plugin_info_class_init(GPluginGtkPluginInfoClass *klass)
    +{
    + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
    + GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    +
    + obj_class->get_property = gplugin_gtk_plugin_info_get_property;
    + obj_class->set_property = gplugin_gtk_plugin_info_set_property;
    + obj_class->finalize = gplugin_gtk_plugin_info_finalize;
    +
    + /* properties */
    + properties[PROP_PLUGIN] = g_param_spec_object(
    + "plugin",
    + "plugin",
    + "The GPluginPlugin who's info should be displayed",
    + G_TYPE_OBJECT,
    + G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
    +
    + /* template stuff */
    + gtk_widget_class_set_template_from_resource(
    + widget_class,
    + "/org/imfreedom/keep/gplugin/gplugin-gtk/plugin-info.ui");
    +
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + name);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + version);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + authors_box);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + website);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + summary);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + description);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + dependencies_box);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + error);
    +
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + expander);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + id);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + filename);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + abi_version);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + loader);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + internal);
    + gtk_widget_class_bind_template_child(
    + widget_class,
    + GPluginGtkPluginInfo,
    + load_on_query);
    +
    + gtk_widget_class_bind_template_callback(
    + widget_class,
    + gplugin_gtk_plugin_info_expander_activate);
    +}
    +
    +/******************************************************************************
    + * API
    + *****************************************************************************/
    +
    +/**
    + * gplugin_gtk_plugin_info_new:
    + *
    + * Create a new GPluginGtkView which can be used to display info about a
    + * #GPluginPlugin.
    + *
    + * Returns: (transfer full): The new #GPluginGtkView widget.
    + */
    +GtkWidget *
    +gplugin_gtk_plugin_info_new(void)
    +{
    + return GTK_WIDGET(g_object_new(GPLUGIN_GTK_TYPE_PLUGIN_INFO, NULL));
    +}
    +
    +/**
    + * gplugin_gtk_plugin_info_set_plugin:
    + * @info: The #GPluginGtkPluginInfo instance.
    + * @plugin: The #GPluginPlugin instance.
    + *
    + * Sets the #GPluginPlugin that should be displayed.
    + *
    + * A @plugin value of %NULL will clear the widget.
    + */
    +void
    +gplugin_gtk_plugin_info_set_plugin(
    + GPluginGtkPluginInfo *info,
    + GPluginPlugin *plugin)
    +{
    + g_return_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info));
    +
    + if(info->signal_id != 0 && GPLUGIN_IS_PLUGIN(info->plugin)) {
    + g_signal_handler_disconnect(info->plugin, info->signal_id);
    + info->signal_id = 0;
    + }
    +
    + if(g_set_object(&info->plugin, plugin) && GPLUGIN_IS_PLUGIN(plugin)) {
    + _gplugin_gtk_plugin_info_refresh(info);
    +
    + /* Connect a signal to refresh when the plugin's state changes. We
    + * can't use g_signal_connect_object because the plugin object never
    + * gets destroyed, as the manager and the loader both keep a reference
    + * to it and the GPluginGtkPluginInfo widget is reused for all plugins
    + * so that all means that we just have to manage the callback
    + * ourselves.
    + */
    + info->signal_id = g_signal_connect(
    + G_OBJECT(plugin),
    + "notify::state",
    + G_CALLBACK(gplugin_gtk_plugin_info_state_cb),
    + info);
    + }
    +}
    +
    +/**
    + * gplugin_gtk_plugin_info_get_plugin:
    + * @info: The #GPluginGtkPluginInfo instance.
    + *
    + * Returns the #GPluginPlugin that's being displayed.
    + *
    + * Return Value: (transfer full): The #GPluginPlugin that's being
    + * displayed.
    + */
    +GPluginPlugin *
    +gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info)
    +{
    + g_return_val_if_fail(GPLUGIN_GTK_IS_PLUGIN_INFO(info), NULL);
    +
    + return (info->plugin) ? GPLUGIN_PLUGIN(g_object_ref(G_OBJECT(info->plugin)))
    + : NULL;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk-plugin-info.h Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,52 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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_INFO_H
    +#define GPLUGIN_GTK_PLUGIN_INFO_H
    +
    +#include <glib.h>
    +#include <glib-object.h>
    +
    +#include <gtk/gtk.h>
    +
    +#include <gplugin.h>
    +
    +G_BEGIN_DECLS
    +
    +#define GPLUGIN_GTK_TYPE_PLUGIN_INFO (gplugin_gtk_plugin_info_get_type())
    +G_DECLARE_FINAL_TYPE(
    + GPluginGtkPluginInfo,
    + gplugin_gtk_plugin_info,
    + GPLUGIN_GTK,
    + PLUGIN_INFO,
    + GtkBox)
    +
    +GtkWidget *gplugin_gtk_plugin_info_new(void);
    +
    +void gplugin_gtk_plugin_info_set_plugin(
    + GPluginGtkPluginInfo *info,
    + GPluginPlugin *plugin);
    +GPluginPlugin *gplugin_gtk_plugin_info_get_plugin(GPluginGtkPluginInfo *info);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_GTK_PLUGIN_INFO_H */
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk-store.c Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,326 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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-store.h>
    +
    +/**
    + * SECTION:gplugin-gtk-store
    + * @title: GtkTreeModelStore for plugins
    + * @short_description: A store for plugins
    + *
    + * #GPluginGtkStore is a GtkTreeModel populated with plugins.
    + */
    +
    +/**
    + * GPLUGIN_GTK_TYPE_STORE:
    + *
    + * The standard _get_type macro for #GPluginGtkStore.
    + */
    +
    +/**
    + * GPluginGtkStoreColumns:
    + * @GPLUGIN_GTK_STORE_ENABLED_COLUMN: The disabled column. This is used when a
    + * plugin is in a state that can't be
    + * changed. So the row should be disabled.
    + * @GPLUGIN_GTK_STORE_LOADED_COLUMN: The loaded column.
    + * @GPLUGIN_GTK_STORE_PLUGIN_COLUMN: The plugin column.
    + * @GPLUGIN_GTK_STORE_MARKUP_COLUMN: The markup column.
    + *
    + * An enum declaring the columns in a #GPluginGtkStore.
    + */
    +
    +/**
    + * GPluginGtkStore:
    + *
    + * A #GtkListStore that contains all of the known plugins in GPlugin.
    + */
    +
    +struct _GPluginGtkStore {
    + GtkListStore parent;
    +};
    +
    +G_DEFINE_TYPE(GPluginGtkStore, gplugin_gtk_store, GTK_TYPE_LIST_STORE);
    +
    +/******************************************************************************
    + * Globals
    + *****************************************************************************/
    +static const GType column_types[] = {
    + G_TYPE_BOOLEAN,
    + G_TYPE_BOOLEAN,
    + G_TYPE_OBJECT,
    + G_TYPE_STRING,
    +};
    +
    +G_STATIC_ASSERT(G_N_ELEMENTS(column_types) == GPLUGIN_GTK_STORE_N_COLUMNS);
    +
    +/******************************************************************************
    + * Helpers
    + *****************************************************************************/
    +static void
    +gplugin_gtk_store_add_plugin(GPluginGtkStore *store, GPluginPlugin *plugin)
    +{
    + GtkTreeIter iter;
    + GPluginPluginInfo *info = gplugin_plugin_get_info(plugin);
    + GPluginPluginState state = gplugin_plugin_get_state(plugin);
    + GString *str = g_string_new("");
    + gchar *name = NULL, *summary = NULL;
    + gboolean loaded = FALSE, enabled = TRUE;
    +
    + /* clang-format off */
    + g_object_get(
    + G_OBJECT(info),
    + "name", &name,
    + "summary", &summary,
    + NULL);
    + /* clang-format on */
    +
    + g_string_append_printf(
    + str,
    + "<b>%s</b>\n",
    + (name) ? name : "<i>Unnamed</i>");
    + g_string_append_printf(
    + str,
    + "%s",
    + (summary) ? summary : "<i>No Summary</i>");
    +
    + g_free(name);
    + g_free(summary);
    +
    + loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED);
    + if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) {
    + loaded = TRUE;
    + enabled = FALSE;
    + }
    +
    + gtk_list_store_append(GTK_LIST_STORE(store), &iter);
    + gtk_list_store_set(
    + GTK_LIST_STORE(store),
    + &iter,
    + GPLUGIN_GTK_STORE_LOADED_COLUMN,
    + loaded,
    + GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    + enabled,
    + GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    + g_object_ref(plugin),
    + GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    + str->str,
    + -1);
    +
    + g_string_free(str, TRUE);
    + g_object_unref(G_OBJECT(info));
    +}
    +
    +static void
    +gplugin_gtk_store_add_plugin_by_id(GPluginGtkStore *store, const gchar *id)
    +{
    + GPluginManager *manager = NULL;
    + GSList *plugins = NULL, *l = NULL;
    +
    + manager = gplugin_manager_get_default();
    +
    + plugins = gplugin_manager_find_plugins(manager, id);
    + for(l = plugins; l; l = l->next)
    + gplugin_gtk_store_add_plugin(store, GPLUGIN_PLUGIN(l->data));
    + g_slist_free_full(plugins, g_object_unref);
    +}
    +
    +static gboolean
    +gplugin_gtk_store_update_plugin_state_cb(
    + GtkTreeModel *model,
    + GtkTreePath *path,
    + GtkTreeIter *iter,
    + gpointer data)
    +{
    + GPluginPlugin *plugin_a = GPLUGIN_PLUGIN(data);
    + GPluginPlugin *plugin_b = NULL;
    + gboolean ret = FALSE;
    +
    + gtk_tree_model_get(
    + model,
    + iter,
    + GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    + &plugin_b,
    + -1);
    +
    + if(plugin_a == plugin_b) {
    + GPluginPluginState state = gplugin_plugin_get_state(plugin_a);
    + gboolean loaded = (state == GPLUGIN_PLUGIN_STATE_LOADED);
    + gboolean enabled = TRUE;
    +
    + if(state == GPLUGIN_PLUGIN_STATE_UNLOAD_FAILED) {
    + loaded = TRUE;
    + enabled = FALSE;
    + }
    +
    + gtk_list_store_set(
    + GTK_LIST_STORE(model),
    + iter,
    + GPLUGIN_GTK_STORE_LOADED_COLUMN,
    + loaded,
    + GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    + enabled,
    + -1);
    +
    + /* tell gplugin_gtk_store_update_plugin_state that we're done */
    + ret = TRUE;
    + }
    +
    + g_object_unref(G_OBJECT(plugin_b));
    +
    + return ret;
    +}
    +
    +static void
    +gplugin_gtk_store_update_plugin_state(
    + GPluginGtkStore *store,
    + GPluginPlugin *plugin)
    +{
    + gtk_tree_model_foreach(
    + GTK_TREE_MODEL(store),
    + gplugin_gtk_store_update_plugin_state_cb,
    + plugin);
    +}
    +
    +/******************************************************************************
    + * Callbacks
    + *****************************************************************************/
    +static void
    +gplugin_gtk_store_plugin_loaded_cb(
    + GObject *manager,
    + GPluginPlugin *plugin,
    + gpointer data)
    +{
    + gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
    +}
    +
    +static void
    +gplugin_gtk_store_plugin_unloaded_cb(
    + GObject *manager,
    + GPluginPlugin *plugin,
    + gpointer data)
    +{
    + gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
    +}
    +
    +static void
    +gplugin_gtk_store_plugin_unload_failed_cb(
    + G_GNUC_UNUSED GObject *manager,
    + GPluginPlugin *plugin,
    + gpointer data)
    +{
    + gplugin_gtk_store_update_plugin_state(GPLUGIN_GTK_STORE(data), plugin);
    +}
    +
    +/******************************************************************************
    + * GObject Implementation
    + *****************************************************************************/
    +static void
    +gplugin_gtk_store_constructed(GObject *obj)
    +{
    + GPluginManager *manager = NULL;
    + GList *l, *ids = NULL;
    +
    + G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->constructed(obj);
    +
    + manager = gplugin_manager_get_default();
    +
    + ids = gplugin_manager_list_plugins(manager);
    + for(l = ids; l; l = l->next)
    + gplugin_gtk_store_add_plugin_by_id(
    + GPLUGIN_GTK_STORE(obj),
    + (const gchar *)l->data);
    + g_list_free(ids);
    +
    + g_signal_connect_object(
    + manager,
    + "loaded-plugin",
    + G_CALLBACK(gplugin_gtk_store_plugin_loaded_cb),
    + obj,
    + 0);
    + g_signal_connect_object(
    + manager,
    + "unloaded-plugin",
    + G_CALLBACK(gplugin_gtk_store_plugin_unloaded_cb),
    + obj,
    + 0);
    + g_signal_connect_object(
    + manager,
    + "unload-plugin-failed",
    + G_CALLBACK(gplugin_gtk_store_plugin_unload_failed_cb),
    + obj,
    + 0);
    +}
    +
    +static void
    +gplugin_gtk_store_dispose(GObject *obj)
    +{
    + G_OBJECT_CLASS(gplugin_gtk_store_parent_class)->dispose(obj);
    +}
    +
    +static void
    +gplugin_gtk_store_init(GPluginGtkStore *store)
    +{
    + GType *types = (GType *)gplugin_gtk_store_get_column_types();
    +
    + gtk_list_store_set_column_types(
    + GTK_LIST_STORE(store),
    + GPLUGIN_GTK_STORE_N_COLUMNS,
    + types);
    +}
    +
    +static void
    +gplugin_gtk_store_class_init(GPluginGtkStoreClass *klass)
    +{
    + GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    +
    + obj_class->constructed = gplugin_gtk_store_constructed;
    + obj_class->dispose = gplugin_gtk_store_dispose;
    +}
    +
    +/******************************************************************************
    + * API
    + *****************************************************************************/
    +
    +/**
    + * gplugin_gtk_store_new:
    + *
    + * Create a new #GPluginGtkStore which is a prepopulated #GtkTreeStore.
    + *
    + * Returns: (transfer full): A new #GtkTreeModel prepopulated with all of the
    + * plugins.
    + */
    +GPluginGtkStore *
    +gplugin_gtk_store_new(void)
    +{
    + return GPLUGIN_GTK_STORE(g_object_new(GPLUGIN_GTK_TYPE_STORE, NULL));
    +}
    +
    +/**
    + * gplugin_gtk_store_get_column_types:
    + *
    + * Returns the columns that #GPluginGtkStore's will use.
    + *
    + * Returns: (transfer none): A list of #GType's for the columns that the store
    + * will use.
    + */
    +const GType *
    +gplugin_gtk_store_get_column_types(void)
    +{
    + return column_types;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk-store.h Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,57 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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_STORE_H
    +#define GPLUGIN_GTK_STORE_H
    +
    +#include <glib.h>
    +#include <glib-object.h>
    +
    +#include <gtk/gtk.h>
    +
    +G_BEGIN_DECLS
    +
    +#define GPLUGIN_GTK_TYPE_STORE (gplugin_gtk_store_get_type())
    +G_DECLARE_FINAL_TYPE(
    + GPluginGtkStore,
    + gplugin_gtk_store,
    + GPLUGIN_GTK,
    + STORE,
    + GtkListStore)
    +
    +typedef enum {
    + GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    + GPLUGIN_GTK_STORE_LOADED_COLUMN,
    + GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    + GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    +
    + /*< private >*/
    + GPLUGIN_GTK_STORE_N_COLUMNS,
    +} GPluginGtkStoreColumns;
    +
    +GPluginGtkStore *gplugin_gtk_store_new(void);
    +
    +const GType *gplugin_gtk_store_get_column_types(void);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_GTK_STORE_H */
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk-view.c Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,318 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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-store.h>
    +#include <gplugin-gtk-view.h>
    +
    +/**
    + * SECTION:gplugin-gtk-view
    + * @title: GtkTreeView for plugins
    + * @short_description: A view for plugins
    + *
    + * #GPluginGtkView is a display widget for a list of plugins.
    + */
    +
    +/**
    + * GPLUGIN_GTK_TYPE_VIEW:
    + *
    + * The standard _get_type macro for #GPluginGtkView.
    + */
    +
    +/**
    + * GPluginGtkView:
    + *
    + * A #GtkTreeView widget that displays all the plugins and some basic
    + * information about them.
    + */
    +
    +/******************************************************************************
    + * Structs
    + *****************************************************************************/
    +struct _GPluginGtkView {
    + GtkTreeView parent;
    +
    + gboolean show_internal;
    +};
    +
    +/******************************************************************************
    + * Enums
    + *****************************************************************************/
    +enum {
    + PROP_ZERO,
    + PROP_SHOW_INTERNAL,
    + N_PROPERTIES,
    +};
    +static GParamSpec *properties[N_PROPERTIES] = {
    + NULL,
    +};
    +
    +/******************************************************************************
    + * Callbacks
    + *****************************************************************************/
    +static void
    +gplugin_gtk_view_plugin_toggled_cb(
    + GtkCellRendererToggle *rend,
    + gchar *path,
    + gpointer data)
    +{
    + GPluginGtkView *view = GPLUGIN_GTK_VIEW(data);
    + GPluginManager *manager = NULL;
    + GPluginPlugin *plugin = NULL;
    + GPluginPluginState state;
    + GtkTreeModel *model = NULL;
    + GtkTreeIter iter;
    + GtkTreePath *tree_path = NULL;
    +
    + manager = gplugin_manager_get_default();
    +
    + tree_path = gtk_tree_path_new_from_string(path);
    +
    + model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
    + gtk_tree_model_get_iter(model, &iter, tree_path);
    + gtk_tree_path_free(tree_path);
    +
    + gtk_tree_model_get(
    + model,
    + &iter,
    + GPLUGIN_GTK_STORE_PLUGIN_COLUMN,
    + &plugin,
    + -1);
    +
    + if(!GPLUGIN_IS_PLUGIN(plugin)) {
    + return;
    + }
    +
    + state = gplugin_plugin_get_state(plugin);
    + if(state == GPLUGIN_PLUGIN_STATE_LOADED) {
    + GError *error = NULL;
    +
    + gplugin_manager_unload_plugin(manager, plugin, &error);
    +
    + if(error != NULL) {
    + g_warning("Failed to unload plugin: %s", error->message);
    +
    + g_error_free(error);
    + }
    + } else {
    + GError *error = NULL;
    +
    + gplugin_manager_load_plugin(manager, plugin, &error);
    +
    + if(error != NULL) {
    + g_warning("Failed to load plugin: %s", error->message);
    +
    + g_error_free(error);
    + }
    + }
    +
    + g_object_unref(G_OBJECT(plugin));
    +}
    +
    +/******************************************************************************
    + * GObject Implementation
    + *****************************************************************************/
    +G_DEFINE_TYPE(GPluginGtkView, gplugin_gtk_view, GTK_TYPE_TREE_VIEW);
    +
    +static void
    +gplugin_gtk_view_set_property(
    + GObject *obj,
    + guint prop_id,
    + const GValue *value,
    + GParamSpec *pspec)
    +{
    + GPluginGtkView *view = GPLUGIN_GTK_VIEW(obj);
    +
    + switch(prop_id) {
    + case PROP_SHOW_INTERNAL:
    + gplugin_gtk_view_set_show_internal(
    + view,
    + g_value_get_boolean(value));
    + break;
    + default:
    + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    + break;
    + }
    +}
    +
    +static void
    +gplugin_gtk_view_get_property(
    + GObject *obj,
    + guint prop_id,
    + GValue *value,
    + GParamSpec *pspec)
    +{
    + GPluginGtkView *view = GPLUGIN_GTK_VIEW(obj);
    +
    + switch(prop_id) {
    + case PROP_SHOW_INTERNAL:
    + g_value_set_boolean(
    + value,
    + gplugin_gtk_view_get_show_internal(view));
    + break;
    + default:
    + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
    + break;
    + }
    +}
    +
    +static void
    +gplugin_gtk_view_constructed(GObject *obj)
    +{
    + G_OBJECT_CLASS(gplugin_gtk_view_parent_class)->constructed(obj);
    +}
    +
    +static void
    +gplugin_gtk_view_dispose(GObject *obj)
    +{
    + G_OBJECT_CLASS(gplugin_gtk_view_parent_class)->dispose(obj);
    +}
    +
    +static void
    +gplugin_gtk_view_init(GPluginGtkView *view)
    +{
    + GtkTreeViewColumn *col = NULL;
    + GtkCellRenderer *rend = NULL;
    +
    + /* create the first column */
    + col = gtk_tree_view_column_new();
    + gtk_tree_view_column_set_title(col, "Enabled");
    + gtk_tree_view_column_set_resizable(col, FALSE);
    +
    + rend = gtk_cell_renderer_toggle_new();
    + gtk_tree_view_column_pack_start(col, rend, FALSE);
    + g_signal_connect(
    + G_OBJECT(rend),
    + "toggled",
    + G_CALLBACK(gplugin_gtk_view_plugin_toggled_cb),
    + view);
    +
    + gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
    + gtk_tree_view_column_set_attributes(
    + col,
    + rend,
    + "active",
    + GPLUGIN_GTK_STORE_LOADED_COLUMN,
    + "sensitive",
    + GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    + NULL);
    +
    + /* create the markup column */
    + col = gtk_tree_view_column_new();
    + gtk_tree_view_column_set_title(col, "Name");
    + gtk_tree_view_column_set_resizable(col, FALSE);
    +
    + rend = gtk_cell_renderer_text_new();
    + gtk_tree_view_column_pack_start(col, rend, TRUE);
    +
    + gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
    + gtk_tree_view_column_set_attributes(
    + col,
    + rend,
    + "markup",
    + GPLUGIN_GTK_STORE_MARKUP_COLUMN,
    + "sensitive",
    + GPLUGIN_GTK_STORE_ENABLED_COLUMN,
    + NULL);
    +}
    +
    +static void
    +gplugin_gtk_view_class_init(GPluginGtkViewClass *klass)
    +{
    + GObjectClass *obj_class = G_OBJECT_CLASS(klass);
    +
    + obj_class->get_property = gplugin_gtk_view_get_property;
    + obj_class->set_property = gplugin_gtk_view_set_property;
    + obj_class->constructed = gplugin_gtk_view_constructed;
    + obj_class->dispose = gplugin_gtk_view_dispose;
    +
    + /* properties */
    +
    + /**
    + * GPluginGtkView:show-internal:
    + *
    + * Whether or not to show internal plugins.
    + */
    + properties[PROP_SHOW_INTERNAL] = g_param_spec_boolean(
    + "show-internal",
    + "show-internal",
    + "Whether or not to show internal plugins",
    + FALSE,
    + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
    +
    + g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
    +}
    +
    +/******************************************************************************
    + * API
    + *****************************************************************************/
    +
    +/**
    + * gplugin_gtk_view_new:
    + *
    + * Creates a new #GPluginGtkView.
    + *
    + * Returns: (transfer full): The new view.
    + */
    +GtkWidget *
    +gplugin_gtk_view_new(void)
    +{
    + GObject *ret = NULL;
    + GPluginGtkStore *store = gplugin_gtk_store_new();
    +
    + /* clang-format off */
    + ret = g_object_new(
    + GPLUGIN_GTK_TYPE_VIEW,
    + "model", GTK_TREE_MODEL(store),
    + NULL);
    + /* clang-format on */
    +
    + return GTK_WIDGET(ret);
    +}
    +
    +/**
    + * gplugin_gtk_view_set_show_internal:
    + * @view: The #GPluginGtkView instance.
    + * @show_internal: Whether or not to show internal plugins.
    + *
    + * This function will toggle whether or not the widget will show internal
    + * plugins.
    + */
    +void
    +gplugin_gtk_view_set_show_internal(GPluginGtkView *view, gboolean show_internal)
    +{
    + g_return_if_fail(GPLUGIN_GTK_IS_VIEW(view));
    +
    + view->show_internal = show_internal;
    +
    + g_object_notify(G_OBJECT(view), "show-internal");
    +}
    +
    +/**
    + * gplugin_gtk_view_get_show_internal:
    + * @view: The #GPluginGtkView instance.
    + *
    + * Returns whether or not @view is showing internal plugins.
    + */
    +gboolean
    +gplugin_gtk_view_get_show_internal(GPluginGtkView *view)
    +{
    + g_return_val_if_fail(GPLUGIN_GTK_IS_VIEW(view), FALSE);
    +
    + return view->show_internal;
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk-view.h Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,50 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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_VIEW_H
    +#define GPLUGIN_GTK_VIEW_H
    +
    +#include <glib.h>
    +#include <glib-object.h>
    +
    +#include <gtk/gtk.h>
    +
    +G_BEGIN_DECLS
    +
    +#define GPLUGIN_GTK_TYPE_VIEW (gplugin_gtk_view_get_type())
    +G_DECLARE_FINAL_TYPE(
    + GPluginGtkView,
    + gplugin_gtk_view,
    + GPLUGIN_GTK,
    + VIEW,
    + GtkTreeView)
    +
    +GtkWidget *gplugin_gtk_view_new(void);
    +
    +void gplugin_gtk_view_set_show_internal(
    + GPluginGtkView *view,
    + gboolean show_internal);
    +gboolean gplugin_gtk_view_get_show_internal(GPluginGtkView *view);
    +
    +G_END_DECLS
    +
    +#endif /* GPLUGIN_GTK_VIEW_H */
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk.h.in Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,34 @@
    +/*
    + * Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.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/>.
    + */
    +#ifndef GPLUGIN_GTK_H
    +#define GPLUGIN_GTK_H
    +
    +#ifndef __GI_SCANNER__
    +# ifdef GPLUGIN_GTK_COMPILATION
    +# error "gplugin-gtk source files should not include gplugin-gtk.h"
    +# endif /* GPLUGIN_GTK_COMPILATION */
    +#endif /* __GI_SCANNER__ */
    +
    +#ifndef GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
    +# define GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
    +#endif /* GPLUGIN_GTK_GLOBAL_HEADER_INSIDE */
    +
    +@GPLUGIN_GTK_H_INCLUDES@
    +
    +#undef GPLUGIN_GTK_GLOBAL_HEADER_INSIDE
    +
    +#endif /* GPLUGIN_GTK_H */
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/gplugin-gtk3.xml.in Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,36 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<glade-catalog name="gplugin-gtk"
    + version="@GPLUGIN_VERSION@"
    + library="gplugin-gtk"
    + domain="gplugin"
    + depends="gtk+"
    + book="GPlugin">
    + <glade-widget-classes>
    + <!-- the get-type-function's are needed due to gplugin's weirdo namespace.
    + Without them, Glade is going to look for g_plugin_*_get_type and not
    + gplugin_*_get_type.
    + -->
    + <glade-widget-class
    + name="GPluginGtkPluginInfo"
    + generic-name="plugininfo"
    + title="Plugin Info"
    + get-type-function="gplugin_gtk_plugin_info_get_type"/>
    + <glade-widget-class
    + name="GPluginGtkView"
    + generic-name="pluginview"
    + title="Plugin View"
    + get-type-function="gplugin_gtk_view_get_type"/>
    + <glade-widget-class
    + name="GPluginGtkStore"
    + generic-name="pluginstore"
    + title="Plugin Store"
    + get-type-function="gplugin_gtk_store_get_type"
    + toplevel="True"/>
    + </glade-widget-classes>
    +
    + <glade-widget-group name="gplugin-gtk" title="GPlugin Gtk Widgets">
    + <glade-widget-class-ref name="GPluginGtkPluginInfo"/>
    + <glade-widget-class-ref name="GPluginGtkView"/>
    + <glade-widget-class-ref name="GPluginGtkStore"/>
    + </glade-widget-group>
    +</glade-catalog>
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/meson.build Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,153 @@
    +if get_option('gtk3')
    +
    +###############################################################################
    +# Build Info
    +###############################################################################
    +GTK3 = dependency('gtk+-3.0', version : '>=3.0.0')
    +
    +GPLUGIN_GTK3_LIBRARY_VERSION = '0.1.0'
    +
    +GPLUGIN_GTK3_SOURCES = [
    + 'gplugin-gtk-plugin-info.c',
    + 'gplugin-gtk-store.c',
    + 'gplugin-gtk-view.c',
    +]
    +
    +GPLUGIN_GTK3_HEADERS = [
    + 'gplugin-gtk-plugin-info.h',
    + 'gplugin-gtk-store.h',
    + 'gplugin-gtk-view.h',
    +]
    +
    +GPLUGIN_GTK3_PRIVATE_SOURCES = [
    +]
    +
    +GPLUGIN_GTK3_PRIVATE_HEADERS = [
    +]
    +
    +GPLUGIN_GTK3_PUBLIC_BUILT_SOURCES = [
    +]
    +
    +GPLUGIN_GTK3_PUBLIC_BUILT_HEADERS = [
    +]
    +
    +GPLUGIN_GTK3_GENERATED_TARGETS = [
    +]
    +
    +###############################################################################
    +# Configure Files
    +###############################################################################
    +GPLUGIN_GTK3_H_INCLUDES = ''
    +foreach header : GPLUGIN_GTK3_HEADERS
    + GPLUGIN_GTK3_H_INCLUDES = '@0@\n#include <@1@>'.format(
    + GPLUGIN_GTK3_H_INCLUDES,
    + header)
    +endforeach
    +
    +conf = configuration_data()
    +conf.set('GPLUGIN_GTK_H_INCLUDES', GPLUGIN_GTK3_H_INCLUDES)
    +gplugin_gtk3_h = configure_file(
    + input : 'gplugin-gtk.h.in',
    + output : 'gplugin-gtk.h',
    + configuration : conf,
    + install : true,
    + install_dir : get_option('includedir') / 'gplugin-gtk3-1.0')
    +
    +gplugin_gtk3_xml = configure_file(
    + input : 'gplugin-gtk3.xml.in',
    + output: 'gplugin-gtk3.xml',
    + configuration : version_conf,
    + install: true,
    + install_dir : get_option('datadir') / 'glade' / 'catalogs',
    +)
    +
    +###############################################################################
    +# Resource Target
    +###############################################################################
    +gplugin_gtk3_resources = gnome.compile_resources(
    + 'gplugin-gtk3-resources',
    + 'data/gplugin-gtk.gresource.xml',
    + c_name: 'gplugin_gtk',
    + source_dir: 'data')
    +
    +###############################################################################
    +# Library Target
    +###############################################################################
    +gplugin_gtk3 = shared_library('gplugin-gtk3',
    + GPLUGIN_GTK3_SOURCES,
    + GPLUGIN_GTK3_HEADERS,
    + GPLUGIN_GTK3_PRIVATE_SOURCES,
    + GPLUGIN_GTK3_PRIVATE_HEADERS,
    + GPLUGIN_GTK3_PUBLIC_BUILT_SOURCES,
    + GPLUGIN_GTK3_PUBLIC_BUILT_HEADERS,
    + gplugin_gtk3_resources,
    + c_args : ['-DGPLUGIN_GTK_COMPILATION', '-DG_LOG_DOMAIN="GPluginGtk"'],
    + include_directories : toplevel_inc,
    + dependencies : [gplugin_dep, GTK3],
    + version : GPLUGIN_GTK3_LIBRARY_VERSION,
    + install : true
    +)
    +
    +gplugin_gtk3_inc = include_directories('.')
    +
    +pkgconfig.generate(
    + gplugin_gtk3,
    + name : 'gplugin-gtk3',
    + description : 'Gtk3 widgets for GPlugin',
    + filebase : 'gplugin-gtk3',
    + subdirs : 'gplugin-gtk3-1.0',
    + libraries : [gplugin],
    + requires : [GLIB, GOBJECT, GMODULE, GTK3],
    +)
    +
    +###############################################################################
    +# GObject Introspection
    +###############################################################################
    +if get_option('introspection')
    + gplugin_gtk3_gir = gnome.generate_gir(
    + gplugin_gtk3,
    + sources : GPLUGIN_GTK3_SOURCES + GPLUGIN_GTK3_HEADERS +
    + GPLUGIN_GTK3_PUBLIC_BUILT_SOURCES +
    + GPLUGIN_GTK3_PUBLIC_BUILT_HEADERS,
    + includes : [gplugin_gir[0], 'Gtk-3.0'],
    + namespace : 'GPluginGtk3',
    + nsversion : '1.0',
    + symbol_prefix : 'gplugin_gtk',
    + identifier_prefix : 'GPluginGtk',
    + install : true,
    + header : 'gplugin-gtk.h',
    + export_packages: ['gplugin-gtk3'],
    + dependencies : [gplugin_dep],
    + extra_args : ['--quiet', '-DGPLUGIN_GTK_COMPILATION'])
    + GPLUGIN_GTK3_GENERATED_TARGETS += gplugin_gtk3_gir
    +endif
    +
    +###############################################################################
    +# Library Dependency Object
    +###############################################################################
    +gplugin_gtk3_dep = declare_dependency(
    + include_directories: [toplevel_inc, gplugin_gtk3_inc],
    + link_with : [gplugin, gplugin_gtk3],
    + sources : GPLUGIN_GTK3_PUBLIC_BUILT_HEADERS + GPLUGIN_GTK3_GENERATED_TARGETS,
    + dependencies : [GLIB, GOBJECT, GTK3],
    +)
    +
    +if meson.version().version_compare('>=0.54.0')
    + meson.override_dependency('gplugin-gtk3', gplugin_gtk3_dep)
    +endif
    +
    +###############################################################################
    +# Install Stuff
    +###############################################################################
    +# install the normal includes into the gplugin-gtk subdirectory
    +install_headers(
    + GPLUGIN_GTK3_HEADERS,
    + subdir : 'gplugin-gtk3-1.0/gplugin-gtk'
    +)
    +
    +###############################################################################
    +# subdirectories
    +###############################################################################
    +subdir('reference')
    +
    +endif # gtk3
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/reference/gplugin-gtk3.toml.in Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,48 @@
    +[library]
    +version = "@GPLUGIN_VERSION@"
    +browse_url = "https://keep.imfreedom.org/gplugin/gplugin/"
    +repository_url = "https://keep.imfreedom.org/gplugin/gplugin/"
    +website_url = "https://keep.imfreedom.org/gplugin/gplugin/"
    +authors = "GPlugin Developers"
    +logo_url = ""
    +license = "LGPL-2.1-or-later"
    +description = "GPlugin Gtk Library"
    +dependencies = [ "GLib-2.0", "GObject-2.0", "GPlugin-1.0", "Gtk-3.0" ]
    +devhelp = true
    +search_index = true
    +
    + [dependencies."GLib-2.0"]
    + name = "GLib"
    + description = "General-purpose, portable utility library."
    + docs_url = "https://docs.gtk.org/glib/"
    +
    + [dependencies."GObject-2.0"]
    + name = "GObject"
    + description = "The base type system library"
    + docs_url = "https://docs.gtk.org/gobject/"
    +
    + [dependencies."GPlugin-1.0"]
    + name = "GPlugin"
    + description = "Plugin library"
    + docs_url = "https://docs.imfreedom.org/gplugin/"
    +
    + [dependencies."Gtk-3.0"]
    + name = "Gtk3"
    + description = "Gtk Widget Toolkit"
    + docs_url = "https://docs.gtk.org/gtk3/"
    +
    +[theme]
    +name = "basic"
    +show_index_summary = true
    +show_class_hierarchy = true
    +
    +[source-location]
    +base_url = "https://keep.imfreedom.org/gplugin/gplugin/file/default/"
    +
    +[extra]
    +# The same order will be used when generating the index
    +content_files = [
    +]
    +content_images = [
    +]
    +urlmap_file = "urlmap.js"
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/reference/meson.build Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,31 @@
    +if get_option('doc')
    + gplugin_gtk_toml = configure_file(
    + input : 'gplugin-gtk3.toml.in',
    + output : 'gplugin-gtk3.toml',
    + configuration : version_conf,
    + install : true,
    + install_dir : docs_dir / 'gplugin-gtk3',
    + )
    +
    + gplugin_gtk3_doc = custom_target('gplugin-gtk3-doc',
    + input : [ gplugin_gtk_toml, gplugin_gtk3_gir[0] ],
    + output : 'gplugin-gtk3',
    + command : [
    + gidocgen,
    + 'generate',
    + '--quiet',
    + '--fatal-warnings',
    + '--add-include-path=@0@'.format(meson.project_build_root() / 'gplugin'),
    + '--config=@INPUT0@',
    + '--output-dir=@OUTPUT@',
    + '--no-namespace-dir',
    + '--content-dir=@0@'.format(meson.current_source_dir()),
    + '@INPUT1@'
    + ],
    + depends : [ gplugin_gir[0] ],
    + build_by_default : true,
    + install : true,
    + install_dir : docs_dir,
    + )
    +endif
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/gplugin-gtk3/reference/urlmap.js Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,11 @@
    +// SPDX-FileCopyrightText: 2021 GNOME Foundation
    +// SPDX-License-Identifier: LGPL-2.1-or-later
    +
    +// A map between namespaces and base URLs for their online documentation
    +baseURLs = [
    + [ 'GLib', 'https://docs.gtk.org/glib/' ],
    + [ 'GObject', 'https://docs.gtk.org/gobject/' ],
    + [ 'GPlugin', 'https://docs.imfreedom.org/gplugin/' ],
    + [ 'GModule', 'https://docs.gtk.org/gmodule/' ],
    + [ 'Gtk3', 'https://docs.gtk.org/gtk3/' ],
    +]
    --- a/meson.build Thu Sep 30 00:56:21 2021 -0500
    +++ b/meson.build Thu Sep 30 01:07:52 2021 -0500
    @@ -101,8 +101,8 @@
    # Subdirectories
    ###############################################################################
    subdir('gplugin')
    -subdir('gplugin-gtk')
    -subdir('gplugin-gtk-viewer')
    +subdir('gplugin-gtk3')
    +subdir('gplugin-gtk3-viewer')
    subdir('gplugin-query')
    subdir('packaging')
    subdir('po')
    @@ -117,7 +117,7 @@
    if get_option('doc')
    doc_targets = [gplugin_doc]
    if get_option('gtk3')
    - doc_targets += gplugin_gtk_doc
    + doc_targets += gplugin_gtk3_doc
    endif
    alias_target('doc', doc_targets)
    --- a/meson_options.txt Thu Sep 30 00:56:21 2021 -0500
    +++ b/meson_options.txt Thu Sep 30 01:07:52 2021 -0500
    @@ -23,9 +23,9 @@
    )
    option(
    - 'install-gplugin-gtk-viewer',
    + 'install-gplugin-gtk3-viewer',
    type : 'boolean', value : true,
    - description : 'Whether or not to install the gtk viewer application'
    + description : 'Whether or not to install the gtk3 viewer application'
    )
    option(
    --- a/packaging/debian/changelog Thu Sep 30 00:56:21 2021 -0500
    +++ b/packaging/debian/changelog Thu Sep 30 01:07:52 2021 -0500
    @@ -1,3 +1,12 @@
    +gplugin (0.35.0) UNRELEASED; urgency=medium
    +
    + * Renamed gir1.2-gplugin-gtk-1.0 to gir1.2-gplugin-gtk3-1.0
    + * Renamed libgplugin-gtk-bin to libgplugin-gtk3-bin
    + * Renamed libgplugin-gtk-dev to libgplugin-gtk3-dev
    + * Renamed libgplugin-gtk0 to libgplugin-gtk3-0
    +
    + -- Gary Kramlich <grim@reaperworld.com> Wed, 29 Sep 2021 23:35:01 -0500
    +
    gplugin (0.28.3) unstable; urgency=medium
    * New upstream release, see official changelog
    --- a/packaging/debian/control Thu Sep 30 00:56:21 2021 -0500
    +++ b/packaging/debian/control Thu Sep 30 01:07:52 2021 -0500
    @@ -3,7 +3,7 @@
    Priority: optional
    Maintainer: Gary Kramlich <grim@reaperworld.com>
    Build-Depends: debhelper (>=9),
    - meson (>=0.37.0), libglib2.0-dev, libgtk-3-dev,
    + meson (>=0.56.0), libglib2.0-dev, libgtk-3-dev,
    gettext, help2man,
    gobject-introspection, libgirepository1.0-dev,
    liblua5.3-dev, lua-lgi,
    @@ -60,37 +60,43 @@
    .
    This package will install all of the gplugin loaders.
    -Package: libgplugin-gtk0
    +Package: libgplugin-gtk3-0
    Architecture: any
    Depends: ${misc:Depends}, ${shlibs:Depends}, libgtk-3-0, libgplugin0
    -Description: GTK+3 bindings for GPlugin
    +Conflicts: libgplugin-gtk0
    +Replaces: libgplugin-gtk0
    +Provides: libgplugin-gtk0
    +Description: GTK3 bindings for GPlugin
    GPlugin is a GObject based library that implements a reusable plugin system
    which supports loading plugins in other languages via loaders. It relies
    heavily on GObjectIntrospection to expose its API to the other languages.
    .
    - This library provides some default GTK+-3 widgets for GPlugin.
    + This library provides some default GTK3 widgets for GPlugin.
    -Package: libgplugin-gtk-dev
    +Package: libgplugin-gtk3-dev
    Architecture: any
    Section: libdevel
    -Depends: ${misc:Depends}, libgtk-3-dev, libgplugin-gtk0 (= ${binary:Version})
    -Description: Development file for libgplugin-gtk
    +Depends: ${misc:Depends}, libgtk-3-dev, libgplugin-gtk3-0 (= ${binary:Version})
    +Conflicts: libgplugin-gtk-dev
    +Replaces: libgplugin-gtk-dev
    +Description: Development file for libgplugin-gtk3-0
    GPlugin is a GObject based library that implements a reusable plugin system
    which supports loading plugins in other languages via loaders. It relies
    heavily on GObjectIntrospection to expose its API to the other languages.
    .
    - This library provides the developmental headers for the GPlugin GTK+-3
    - bindings.
    + This library provides the developmental headers for the GPlugin GTK3 bindings.
    -Package: libgplugin-gtk-bin
    +Package: libgplugin-gtk3-bin
    Architecture: any
    Depends: ${misc:Depends}, ${shlibs:Depends}, libgplugin-gtk0
    -Description: Programs for the GTK+ interface to GPlugin
    +Conflicts: libgplugin-gtk-bin
    +Replaces: libgplugin-gtk-bin
    +Description: Programs for the GTK3 interface to GPlugin
    GPlugin is a GObject based library that implements a reusable plugin system
    which supports loading plugins in other languages via loaders. It relies
    heavily on GObjectIntrospection to expose its API to the other languages.
    .
    - This package contains the gplugin-gtk-viewer application for viewing plugins.
    + This package contains the gplugin-gtk3-viewer application for viewing plugins.
    Package: gir1.2-gplugin-1.0
    Architecture: any
    @@ -104,9 +110,11 @@
    This package can be used by other packages using the GIRepository format to
    generate dynamic bindings for libgplugin.
    -Package: gir1.2-gplugin-gtk-1.0
    +Package: gir1.2-gplugin-gtk3-1.0
    Architecture: any
    -Depends: ${gir:Depends}, ${misc:Depends}, libgplugin0
    +Depends: ${gir:Depends}, ${misc:Depends}, libgplugin0, libgplugin-gtk3-0
    +Conflicts: gir1.2-gplugin-gtk-1.0
    +Replaces: gir1.2-gplugin-gtk-1.0
    Section: introspection
    Description: typelibe for libgplugin
    GPlugin is a GObject based library that implements a reusable plugin system
    @@ -114,12 +122,12 @@
    heavily on GObjectIntrospection to expose its API to the other languages.
    .
    This package can be used by other packages using the GIRepository format to
    - generate dynamic bindings for libgplugin-gtk.
    + generate dynamic bindings for libgplugin-gtk3.
    Package: libgplugin-lua
    Architecture: any
    Depends: ${misc:Depends}, ${shlibs:Depends}, liblua5.1-0,
    - libgplugin0, gir1.2-gplugin-0.0
    + libgplugin0, gir1.2-gplugin-1.0
    Description: GPlugin Lua Loader
    GPlugin is a GObject based library that implements a reusable plugin system
    which supports loading plugins in other languages via loaders. It relies
    @@ -131,7 +139,7 @@
    Package: libgplugin-python3
    Architecture: any
    Depends: ${misc:Depends}, ${shlibs:Depends}, python3, python3-gi,
    - libgplugin0, gir1.2-gplugin-0.0
    + libgplugin0, gir1.2-gplugin-1.0
    Description: GPlugin Python3 Loader
    GPlugin is a GObject based library that implements a reusable plugin system
    which supports loading plugins in other languages via loaders. It relies
    @@ -143,7 +151,7 @@
    Package: libgplugin-perl5
    Architecture: any
    Depends: ${misc:Depends}, ${shlibs:Depends}, perl, libglib-perl,
    - libglib-object-introspection-perl, libgplugin0, gir1.2-gplugin-0.0
    + libglib-object-introspection-perl, libgplugin0, gir1.2-gplugin-1.0
    Description: GPlugin Perl5 Loader
    GPlugin is a GObject based library that implements a reusable plugin system
    which supports loading plugins in other languages via loaders. It relies
    --- a/packaging/debian/gir1.2-gplugin-gtk-1.0.install Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -debian/tmp/usr/lib/*/girepository-1.0/GPluginGtk-1.0.typelib
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/gir1.2-gplugin-gtk3-1.0.install Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,1 @@
    +debian/tmp/usr/lib/*/girepository-1.0/GPluginGtk3-1.0.typelib
    --- a/packaging/debian/libgplugin-gtk-bin.install Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -debian/tmp/usr/bin/gplugin-gtk-viewer
    -debian/tmp/usr/share/man/man1/gplugin-gtk-viewer.1
    --- a/packaging/debian/libgplugin-gtk-dev.install Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,7 +0,0 @@
    -usr/include/gplugin-1.0/gplugin-gtk
    -usr/include/gplugin-1.0/gplugin-gtk.h
    -debian/tmp/usr/lib/*/libgplugin-gtk.so
    -debian/tmp/usr/lib/*/pkgconfig/gplugin-gtk.pc
    -debian/tmp/usr/share/gir-1.0/GPluginGtk-1.0.gir
    -debian/tmp/usr/share/vala/vapi/gplugin-gtk.deps
    -debian/tmp/usr/share/vala/vapi/gplugin-gtk.vapi
    \ No newline at end of file
    --- a/packaging/debian/libgplugin-gtk0.install Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -debian/tmp/usr/lib/*/libgplugin-gtk.so.*
    --- a/packaging/debian/libgplugin-gtk0.triggers Thu Sep 30 00:56:21 2021 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,1 +0,0 @@
    -activate-noawait ldconfig
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin-gtk3-0.install Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,1 @@
    +debian/tmp/usr/lib/*/libgplugin-gtk3.so.*
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin-gtk3-0.triggers Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,1 @@
    +activate-noawait ldconfig
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin-gtk3-bin.install Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,2 @@
    +debian/tmp/usr/bin/gplugin-gtk3-viewer
    +debian/tmp/usr/share/man/man1/gplugin-gtk3-viewer.1
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/packaging/debian/libgplugin-gtk3-dev.install Thu Sep 30 01:07:52 2021 -0500
    @@ -0,0 +1,7 @@
    +usr/include/gplugin-gtk3-1.0/gplugin-gtk
    +usr/include/gplugin-gtk3-1.0/gplugin-gtk.h
    +debian/tmp/usr/lib/*/libgplugin-gtk3.so
    +debian/tmp/usr/lib/*/pkgconfig/gplugin-gtk3.pc
    +debian/tmp/usr/share/gir-1.0/GPluginGtk3-1.0.gir
    +debian/tmp/usr/share/vala/vapi/gplugin-gtk3.deps
    +debian/tmp/usr/share/vala/vapi/gplugin-gtk3.vapi
    --- a/packaging/gplugin.spec.in Thu Sep 30 00:56:21 2021 -0500
    +++ b/packaging/gplugin.spec.in Thu Sep 30 01:07:52 2021 -0500
    @@ -10,7 +10,7 @@
    Url: https://keep.imfreedom.org/rw_grim/gplugin/overview
    Group: Development/Libraries
    -BuildRequires: meson >= 0.37.0
    +BuildRequires: meson >= 0.56.0
    BuildRequires: glib2-devel >= 2.44.0
    BuildRequires: gobject-introspection-devel
    BuildRequires: gettext
    @@ -188,35 +188,36 @@
    %{_libdir}/girepository-1.0/GPlugin-1.0.typelib
    %{_libdir}/libgplugin.so
    %{_libdir}/libgplugin.so.0
    -%{_libdir}/pkgconfig/gplugin-gtk.pc
    %{_libdir}/pkgconfig/gplugin.pc
    %files gtk3
    %defattr(-,root,root)
    %doc README.md
    %license COPYING
    -%{_bindir}/gplugin-gtk-viewer
    -%{_libdir}/libgplugin-gtk.so.0.1.0
    -%{_mandir}/man1/gplugin-gtk-viewer.1*
    +%{_bindir}/gplugin-gtk3-viewer
    +%{_libdir}/libgplugin-gtk3.so.0.1.0
    +%{_mandir}/man1/gplugin-gtk3-viewer.1*
    %files gtk3-devel
    %defattr(-,root,root)
    %dir %{_datadir}/glade/catalogs/
    %doc README.md
    %license COPYING
    -%{_datadir}/gir-1.0/GPluginGtk-1.0.gir
    -%{_datadir}/glade/catalogs/gplugin-gtk.xml
    -%{_datadir}/doc/gplugin-gtk/
    -%{_libdir}/girepository-1.0/GPluginGtk-1.0.typelib
    -%{_libdir}/libgplugin-gtk.so
    -%{_libdir}/libgplugin-gtk.so.0
    +%{_datadir}/gir-1.0/GPluginGtk3-1.0.gir
    +%{_datadir}/glade/catalogs/gplugin-gtk3.xml
    +%{_datadir}/doc/gplugin-gtk3/
    +%{_includedir}/gplugin-gtk3-1.0/
    +%{_libdir}/girepository-1.0/GPluginGtk3-1.0.typelib
    +%{_libdir}/libgplugin-gtk3.so
    +%{_libdir}/libgplugin-gtk3.so.0
    +%{_libdir}/pkgconfig/gplugin-gtk3.pc
    %files gtk3-vala
    %defattr(-,root,root)
    %doc README.md
    %license COPYING
    -%{_datadir}/vala/vapi/gplugin-gtk.vapi
    -%{_datadir}/vala/vapi/gplugin-gtk.deps
    +%{_datadir}/vala/vapi/gplugin-gtk3.vapi
    +%{_datadir}/vala/vapi/gplugin-gtk3.deps
    %files lua
    %defattr(-,root,root)
    @@ -244,6 +245,11 @@
    %{_datadir}/vala/vapi/gplugin.deps
    %changelog
    +* Wed Sep 29 2021 Gary Kramlich <grim@reaperworld.com>
    +- Renamed gplugin-gtk to gplugin-gtk3
    +- Renamed gplugin-gtk-devel to gplugin-gtk3-devel
    +- Renamed gplugin-gtk-vala to gplugin-gtk3-vala
    +
    * Thu Sep 02 2021 Gary Kramlich <grim@reaperworld.com>
    - Update the devel packages for gi-docgen
    --- a/vala/meson.build Thu Sep 30 00:56:21 2021 -0500
    +++ b/vala/meson.build Thu Sep 30 01:07:52 2021 -0500
    @@ -8,12 +8,11 @@
    gplugin_vapi = gnome.generate_vapi('gplugin',
    sources : gplugin_gir[0],
    install : true,
    - gir_dirs : meson.current_build_dir() / '..' / 'gplugin',
    )
    if get_option('gtk3')
    - gplugin_gtk_vapi = gnome.generate_vapi('gplugin-gtk',
    - sources : gplugin_gtk_gir[0],
    + gplugin_gtk_vapi = gnome.generate_vapi('gplugin-gtk3',
    + sources : gplugin_gtk3_gir[0],
    packages : [ 'gtk+-3.0' ],
    install : true,
    gir_dirs : meson.current_build_dir() / '..' / 'gplugin',