# HG changeset patch
# Node ID 35a9e828a7b1
# Parent  c24d77cbf268
diff --git a/gplugin-gtk3-viewer/data/gplugin-gtk-viewer.gresource.xml b/gplugin-gtk4-viewer/data/gplugin-gtk-viewer.gresource.xml
copy from gplugin-gtk3-viewer/data/gplugin-gtk-viewer.gresource.xml
copy to gplugin-gtk4-viewer/data/gplugin-gtk-viewer.gresource.xml
diff --git a/gplugin-gtk3-viewer/meson.build b/gplugin-gtk4-viewer/meson.build
copy from gplugin-gtk3-viewer/meson.build
copy to gplugin-gtk4-viewer/meson.build
--- a/gplugin-gtk3-viewer/meson.build
+++ b/gplugin-gtk4-viewer/meson.build
@@ -1,35 +1,35 @@
-if get_option('gtk3')
+if get_option('gtk4')
 
-if not get_option('install-gplugin-gtk3-viewer')
-summary('gplugin-gtk3-viewer',
-        'You have disabled installation of gplugin-gtk-viewer which is a ' +
+if not get_option('install-gplugin-gtk4-viewer')
+summary('gplugin-gtk4-viewer',
+        'You have disabled installation of gplugin-gtk4-viewer which is a ' +
         'very useful diagnostics tool.',
         section : 'Warnings')
 endif
 
-gplugin_gtk3_viewer_resources = gnome.compile_resources(
+gplugin_gtk4_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_gtk4_viewer = executable('gplugin-gtk4-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')
+	gplugin_gtk4_viewer_resources,
+	dependencies : [gplugin_dep, gplugin_gtk4_dep],
+	install : get_option('install-gplugin-gtk4-viewer')
 )
 
 if get_option('help2man')
-	gplugin_gtk_viewer_man = custom_target('gplugin-gtk3-viewer.1',
+	gplugin_gtk_viewer_man = custom_target('gplugin-gtk4-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'),
+		           gplugin_gtk4_viewer],
+		output : 'gplugin-gtk4-viewer.1',
+		install : get_option('install-gplugin-gtk4-viewer'),
 		install_dir : get_option('mandir') / 'man1')
 endif
 
diff --git a/gplugin-gtk4-viewer/data/window.ui b/gplugin-gtk4-viewer/data/window.ui
new file mode 100644
--- /dev/null
+++ b/gplugin-gtk4-viewer/data/window.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="gplugin-gtk" version="0.35"/>
+  <template class="GPluginGtkViewerWindow" parent="GtkApplicationWindow">
+    <property name="title" translatable="yes">GPlugin Viewer</property>
+    <property name="default-width">600</property>
+    <property name="default-height">400</property>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="hscrollbar_policy">never</property>
+        <child>
+          <object class="GtkListBox">
+            <child type="placeholder">
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">No plugins found</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/gplugin-gtk4-viewer/gplugin-gtk-viewer-window.h b/gplugin-gtk4-viewer/gplugin-gtk-viewer-window.h
new file mode 100644
--- /dev/null
+++ b/gplugin-gtk4-viewer/gplugin-gtk-viewer-window.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GPLUGIN_GTK_VIEWER_WINDOW_H
+#define GPLUGIN_GTK_VIEWER_WINDOW_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#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,
+	GtkApplicationWindow)
+
+G_END_DECLS
+
+#endif /* GPLUGIN_GTK_VIEWER_WINDOW_H */
diff --git a/gplugin-gtk4-viewer/gplugin-gtk-viewer-window.c b/gplugin-gtk4-viewer/gplugin-gtk-viewer-window.c
new file mode 100644
--- /dev/null
+++ b/gplugin-gtk4-viewer/gplugin-gtk-viewer-window.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gplugin-gtk-viewer-window.h"
+
+struct _GPluginGtkViewerWindow {
+	GtkApplicationWindow parent;
+};
+
+G_DEFINE_TYPE(
+	GPluginGtkViewerWindow,
+	gplugin_gtk_viewer_window,
+	GTK_TYPE_APPLICATION_WINDOW)
+
+/******************************************************************************
+ * GObject Stuff
+ *****************************************************************************/
+
+static void
+gplugin_gtk_viewer_window_class_init(GPluginGtkViewerWindowClass *klass)
+{
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+	gtk_widget_class_set_template_from_resource(
+		widget_class,
+		"/org/imfreedom/keep/gplugin/gplugin/viewer/window.ui");
+
+	gtk_widget_class_add_binding_action(
+		widget_class,
+		GDK_KEY_w,
+		GDK_CONTROL_MASK,
+		"window.close",
+		NULL);
+}
+
+static void
+gplugin_gtk_viewer_window_init(GPluginGtkViewerWindow *self)
+{
+	gtk_widget_init_template(GTK_WIDGET(self));
+}
diff --git a/gplugin-gtk4-viewer/gplugin-gtk-viewer.c b/gplugin-gtk4-viewer/gplugin-gtk-viewer.c
new file mode 100644
--- /dev/null
+++ b/gplugin-gtk4-viewer/gplugin-gtk-viewer.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2021 Elliott Sales de Andrade <quantum.analyst@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gplugin.h>
+#include <gplugin-gtk.h>
+
+#include "gplugin-gtk-viewer-window.h"
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static gboolean show_internal = FALSE;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+
+static gint
+handle_local_options_cb(
+	G_GNUC_UNUSED GApplication *app,
+	GVariantDict *options,
+	G_GNUC_UNUSED gpointer data)
+{
+	gboolean option = FALSE;
+
+	if(g_variant_dict_lookup(options, "version", "b", &option, NULL)) {
+		/* Handle --version and exit with success. */
+		printf("gplugin-gtk-viewer %s\n", GPLUGIN_VERSION);
+
+		return 0;
+	}
+
+	return -1;
+}
+
+static void
+startup_cb(G_GNUC_UNUSED GApplication *app, G_GNUC_UNUSED gpointer data)
+{
+	GPluginManager *manager = NULL;
+	const gchar *env_paths = NULL;
+
+	gplugin_init(GPLUGIN_CORE_FLAGS_NONE);
+	manager = gplugin_manager_get_default();
+
+	env_paths = g_getenv("GPLUGIN_PLUGIN_PATH");
+	if(env_paths != NULL) {
+		gchar **paths = g_strsplit(env_paths, G_SEARCHPATH_SEPARATOR_S, 0);
+		gint i;
+
+		for(i = 0; paths[i] != NULL; i++) {
+			gplugin_manager_prepend_path(manager, paths[i]);
+		}
+
+		g_strfreev(paths);
+	}
+
+	gplugin_manager_refresh(manager);
+}
+
+static void
+shutdown_cb(G_GNUC_UNUSED GApplication *app, G_GNUC_UNUSED gpointer data)
+{
+	gplugin_uninit();
+}
+
+static void
+activate_cb(GApplication *app)
+{
+	GtkWindow *window = NULL;
+
+	g_return_if_fail(GTK_IS_APPLICATION(app));
+
+	window = gtk_application_get_active_window(GTK_APPLICATION(app));
+	if(window == NULL) {
+		/* clang-format off */
+		window = g_object_new(
+			GPLUGIN_GTK_VIEWER_TYPE_WINDOW,
+			"application", app,
+			NULL);
+		/* clang-format on */
+	}
+
+	gtk_window_present(window);
+}
+
+/******************************************************************************
+ * Main Stuff
+ *****************************************************************************/
+/* clang-format off */
+static GOptionEntry entries[] = {
+	{
+		"internal", 'i', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+		&show_internal, "Show internal plugins", NULL,
+	}, {
+		"version", 'V', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+		NULL, "Display the version and exit", NULL,
+	}, {
+		NULL, 0, 0, 0, NULL, NULL, NULL,
+	},
+};
+/* clang-format on */
+
+gint
+main(gint argc, gchar **argv)
+{
+	GtkApplication *app = NULL;
+	gint ret;
+
+	/* Set up gettext translations. */
+	bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+	textdomain(GETTEXT_PACKAGE);
+
+	/* Prepare application and options. */
+	app = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
+	g_application_add_main_option_entries(G_APPLICATION(app), entries);
+	g_application_add_option_group(
+		G_APPLICATION(app),
+		gplugin_get_option_group());
+
+	g_signal_connect(app, "activate", G_CALLBACK(activate_cb), NULL);
+	g_signal_connect(
+		app,
+		"handle-local-options",
+		G_CALLBACK(handle_local_options_cb),
+		NULL);
+	g_signal_connect(app, "startup", G_CALLBACK(startup_cb), NULL);
+	g_signal_connect(app, "shutdown", G_CALLBACK(shutdown_cb), NULL);
+
+	/* Run and get exit code. */
+	ret = g_application_run(G_APPLICATION(app), argc, argv);
+
+	g_object_unref(app);
+
+	return ret;
+}
diff --git a/meson.build b/meson.build
--- a/meson.build
+++ b/meson.build
@@ -124,6 +124,7 @@ subdir('gplugin')
 subdir('gplugin-gtk3')
 subdir('gplugin-gtk3-viewer')
 subdir('gplugin-gtk4')
+subdir('gplugin-gtk4-viewer')
 subdir('gplugin-query')
 subdir('packaging')
 subdir('po')
diff --git a/meson_options.txt b/meson_options.txt
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -37,7 +37,13 @@ option(
 option(
 	'install-gplugin-gtk3-viewer',
 	type : 'boolean', value : true,
-	description : 'Whether or not to install the gtk3 viewer application'
+	description : 'Whether or not to install the GTK3 viewer application'
+)
+
+option(
+	'install-gplugin-gtk4-viewer',
+	type : 'boolean', value : true,
+	description : 'Whether or not to install the GTK4 viewer application'
 )
 
 option(
diff --git a/po/POTFILES b/po/POTFILES
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -5,6 +5,9 @@ gplugin-gtk3/data/plugin-info.ui
 gplugin-gtk3/gplugin-gtk-plugin-info.c
 gplugin-gtk3/gplugin-gtk-store.c
 gplugin-gtk3/gplugin-gtk-view.c
+gplugin-gtk4-viewer/data/window.ui
+gplugin-gtk4-viewer/gplugin-gtk-viewer-window.c
+gplugin-gtk4-viewer/gplugin-gtk-viewer.c
 gplugin-query/gplugin-query.c
 gplugin/gplugin-core.c
 gplugin/gplugin-file-tree.c
