# HG changeset patch
# Node ID f7549672efec
# Parent  d9bf1d3a62f1
diff --git a/pidgin/pidginpluginsdialog.c b/pidgin/pidginpluginsdialog.c
--- a/pidgin/pidginpluginsdialog.c
+++ b/pidgin/pidginpluginsdialog.c
@@ -35,261 +35,8 @@
 
 struct _PidginPluginsDialog {
 	GtkDialog parent;
-
-	GtkWidget *tree_view;
-	GtkWidget *configure_plugin_button;
-	GtkWidget *plugin_info;
-
-	GtkListStore *plugin_store;
 };
 
-/* this has a short life left to it... */
-typedef struct
-{
-	enum
-	{
-		PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME,
-		PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST
-	} type;
-
-	union
-	{
-		struct
-		{
-			GtkWidget *dialog;
-			PurplePluginPrefFrame *pref_frame;
-		} frame;
-
-		gpointer request_handle;
-	} u;
-} PidginPluginUiData;
-
-/******************************************************************************
- * Helpers
- *****************************************************************************/
-static gboolean
-pidgin_plugins_dialog_plugin_has_config(GPluginPlugin *plugin) {
-	GPluginPluginInfo *ginfo = gplugin_plugin_get_info(plugin);
-	PurplePluginInfo *info = PURPLE_PLUGIN_INFO(ginfo);
-	GPluginPluginState state;
-
-	g_return_val_if_fail(GPLUGIN_IS_PLUGIN(plugin), FALSE);
-
-	state = gplugin_plugin_get_state(plugin);
-
-	if (state != GPLUGIN_PLUGIN_STATE_LOADED) {
-		return FALSE;
-	}
-
-	return (purple_plugin_info_get_pref_frame_cb(info) ||
-	       purple_plugin_info_get_pref_request_cb(info));
-}
-
-static GPluginPlugin *
-pidgin_plugins_dialog_get_selected(PidginPluginsDialog *dialog) {
-	GPluginPlugin *plugin = NULL;
-	GtkTreeSelection *selection = NULL;
-	GtkTreeModel *model = NULL;
-	GtkTreeIter iter;
-
-	g_return_val_if_fail(PIDGIN_IS_PLUGINS_DIALOG(dialog), NULL);
-
-	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->tree_view));
-	/* not sure if this is necessary, but playing defense. - grim 20191112 */
-	if(selection == NULL) {
-		return NULL;
-	}
-
-	if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
-		gtk_tree_model_get(model, &iter,
-		                   GPLUGIN_GTK_STORE_PLUGIN_COLUMN, &plugin,
-		                   -1);
-	}
-
-	return plugin;
-}
-
-static void
-pidgin_plugins_dialog_pref_dialog_close(GPluginPlugin *plugin) {
-	GPluginPluginInfo *ginfo = gplugin_plugin_get_info(plugin);
-	PurplePluginInfo *info = PURPLE_PLUGIN_INFO(ginfo);
-	PidginPluginUiData *ui_data;
-
-	ui_data = g_object_get_data(G_OBJECT(info), "pidgin-ui-data");
-	if (ui_data == NULL) {
-		purple_debug_info("PidginPluginsDialog", "failed to find uidata\n");
-		return;
-	}
-
-	if (ui_data->type == PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST) {
-		purple_request_close(PURPLE_REQUEST_FIELDS,
-			ui_data->u.request_handle);
-		return;
-	}
-
-	g_return_if_fail(ui_data->type == PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME);
-
-	gtk_widget_destroy(ui_data->u.frame.dialog);
-
-	if (ui_data->u.frame.pref_frame) {
-		purple_plugin_pref_frame_destroy(ui_data->u.frame.pref_frame);
-	}
-
-	g_object_set_data(G_OBJECT(info), "pidgin-ui-data", NULL);
-}
-
-/******************************************************************************
- * Callbacks
- *****************************************************************************/
-static void
-pidgin_plugins_dialog_selection_cb(GtkTreeSelection *sel, gpointer data) {
-	PidginPluginsDialog *dialog = PIDGIN_PLUGINS_DIALOG(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(
-		GPLUGIN_GTK_PLUGIN_INFO(dialog->plugin_info),
-		plugin
-	);
-
-	if(GPLUGIN_IS_PLUGIN(plugin)) {
-		gtk_widget_set_sensitive(
-			GTK_WIDGET(dialog->configure_plugin_button),
-			pidgin_plugins_dialog_plugin_has_config(plugin)
-		);
-
-		g_object_unref(G_OBJECT(plugin));
-	}
-}
-
-static void
-pidgin_plugins_dialog_pref_dialog_response_cb(GtkWidget *dialog, int response,
-                                              gpointer data)
-{
-	if (response == GTK_RESPONSE_CLOSE ||
-		response == GTK_RESPONSE_DELETE_EVENT)
-	{
-		pidgin_plugins_dialog_pref_dialog_close(GPLUGIN_PLUGIN(data));
-	}
-}
-
-static void
-pidgin_plugins_dialog_request_close_cb(PurplePluginInfo *info)
-{
-	g_object_set_data(G_OBJECT(info), "pidgin-ui-data", NULL);
-}
-
-static void
-pidgin_plugins_dialog_config_plugin_cb(GtkWidget *button, gpointer data) {
-	PidginPluginsDialog *dialog = PIDGIN_PLUGINS_DIALOG(data);
-	PidginPluginUiData *ui_data;
-	PurplePluginInfo *info;
-	PurplePluginPrefFrameCb pref_frame_cb;
-	PurplePluginPrefRequestCb pref_request_cb;
-	GPluginPlugin *plugin = NULL;
-	GPluginPluginInfo *ginfo = NULL;
-	gint prefs_count;
-
-	plugin = pidgin_plugins_dialog_get_selected(dialog);
-	if(!GPLUGIN_IS_PLUGIN(plugin)) {
-		return;
-	}
-
-	ginfo = gplugin_plugin_get_info(plugin);
-	info = PURPLE_PLUGIN_INFO(ginfo);
-
-	if (g_object_get_data(G_OBJECT(info), "pidgin-ui-data")) {
-		g_object_unref(G_OBJECT(plugin));
-		return;
-	}
-
-	pref_frame_cb = purple_plugin_info_get_pref_frame_cb(info);
-	pref_request_cb = purple_plugin_info_get_pref_request_cb(info);
-
-	ui_data = g_new0(PidginPluginUiData, 1);
-	g_object_set_data_full(G_OBJECT(info), "pidgin-ui-data", ui_data, g_free);
-
-	prefs_count = 0;
-	if (pref_frame_cb) {
-		prefs_count++;
-
-		ui_data->u.frame.pref_frame = pref_frame_cb(plugin);
-	}
-
-	if (pref_request_cb) {
-		prefs_count++;
-	}
-
-	if (prefs_count > 1) {
-		purple_debug_warning("gtkplugin",
-		                     "Plugin %s contains more than one prefs "
-		                     "callback, some will be ignored.",
-		                     gplugin_plugin_info_get_name(ginfo));
-	}
-	g_return_if_fail(prefs_count > 0);
-
-
-	/* Priority: pidgin frame > purple request > purple frame
-	 * Purple frame could be replaced with purple request some day.
-	 */
-	if (pref_request_cb) {
-		ui_data->type = PIDGIN_PLUGIN_UI_DATA_TYPE_REQUEST;
-		ui_data->u.request_handle = pref_request_cb(plugin);
-		purple_request_add_close_notify(
-		        ui_data->u.request_handle,
-		        (GDestroyNotify)pidgin_plugins_dialog_request_close_cb, info);
-	} else {
-		GtkWidget *box, *pdialog, *content, *sw;
-
-		ui_data->type = PIDGIN_PLUGIN_UI_DATA_TYPE_FRAME;
-
-		box = pidgin_plugin_pref_create_frame(ui_data->u.frame.pref_frame);
-		if (box == NULL) {
-			purple_debug_error("gtkplugin",
-				"Failed to display prefs frame");
-			g_object_set_data(G_OBJECT(info), "pidgin-ui-data", NULL);
-			g_object_unref(G_OBJECT(plugin));
-			return;
-		}
-		gtk_widget_set_vexpand(box, TRUE);
-
-		ui_data->u.frame.dialog = pdialog = gtk_dialog_new_with_buttons(
-			PIDGIN_ALERT_TITLE, GTK_WINDOW(dialog),
-			GTK_DIALOG_DESTROY_WITH_PARENT,
-			_("Close"), GTK_RESPONSE_CLOSE,
-			NULL);
-
-		g_signal_connect(G_OBJECT(pdialog), "response",
-			G_CALLBACK(pidgin_plugins_dialog_pref_dialog_response_cb), plugin);
-
-		content = gtk_dialog_get_content_area(GTK_DIALOG(pdialog));
-
-		sw = gtk_scrolled_window_new(NULL, NULL);
-		gtk_container_add(GTK_CONTAINER(content), sw);
-		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_widget_set_size_request(sw, 400, 400);
-
-		gtk_container_add(GTK_CONTAINER(sw), box);
-
-		gtk_window_set_role(GTK_WINDOW(pdialog), "plugin_config");
-		gtk_window_set_title(GTK_WINDOW(pdialog),
-		                     _(gplugin_plugin_info_get_name(
-		                             GPLUGIN_PLUGIN_INFO(info))));
-		gtk_widget_show_all(pdialog);
-	}
-	g_object_unref(G_OBJECT(plugin));
-}
-
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
@@ -303,26 +50,11 @@
 		widget_class,
 		"/im/pidgin/Pidgin3/Plugins/dialog.ui"
 	);
-
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, tree_view);
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, configure_plugin_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, plugin_info);
-	gtk_widget_class_bind_template_child(widget_class, PidginPluginsDialog, plugin_store);
-
-	gtk_widget_class_bind_template_callback(widget_class, pidgin_plugins_dialog_selection_cb);
-	gtk_widget_class_bind_template_callback(widget_class, pidgin_plugins_dialog_config_plugin_cb);
 }
 
 static void
 pidgin_plugins_dialog_init(PidginPluginsDialog *dialog) {
 	gtk_widget_init_template(GTK_WIDGET(dialog));
-
-	/* set the sort column for the plugin_store */
-	gtk_tree_sortable_set_sort_column_id(
-		GTK_TREE_SORTABLE(dialog->plugin_store),
-		GPLUGIN_GTK_STORE_MARKUP_COLUMN,
-		GTK_SORT_ASCENDING
-	);
 }
 
 /******************************************************************************
@@ -332,4 +64,3 @@
 pidgin_plugins_dialog_new(void) {
 	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_PLUGINS_DIALOG, NULL));
 }
-
diff --git a/pidgin/resources/Plugins/dialog.ui b/pidgin/resources/Plugins/dialog.ui
--- a/pidgin/resources/Plugins/dialog.ui
+++ b/pidgin/resources/Plugins/dialog.ui
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 
-
+<!--
 Pidgin - Internet Messenger
 Copyright (C) Pidgin Developers <devel@pidgin.im>
 
@@ -15,121 +14,18 @@
 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, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
+along with this library; if not, see <https://www.gnu.org/licenses/>.
 -->
 <interface>
-  <requires lib="gtk+" version="3.22"/>
-  <requires lib="gplugin-gtk" version="0.28"/>
-  <!-- interface-license-type gplv2 -->
-  <!-- interface-name Pidgin -->
-  <!-- interface-description Internet Messenger -->
-  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="GPluginGtkStore" type-func="gplugin_gtk_store_get_type" id="raw_plugin_store"/>
-  <object class="GtkTreeModelSort" id="plugin_store">
-    <property name="model">raw_plugin_store</property>
-  </object>
+  <requires lib="gtk" version="4.0"/>
+  <requires lib="gplugin-gtk4" version="0.35"/>
   <template class="PidginPluginsDialog" parent="GtkDialog">
-    <property name="can-focus">False</property>
-    <property name="title" translatable="yes">Plugins</property>
+    <property name="title" translatable="1">Plugins</property>
     <property name="type-hint">dialog</property>
     <signal name="delete-event" handler="gtk_widget_destroy" swapped="no"/>
-    <child internal-child="vbox">
-      <object class="GtkBox">
-        <property name="can-focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox">
-            <property name="can-focus">False</property>
-            <property name="layout-style">end</property>
-            <child>
-              <object class="GtkButton" id="configure_plugin_button">
-                <property name="label" translatable="yes">Configure Plugin</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <signal name="clicked" handler="pidgin_plugins_dialog_config_plugin_cb" object="PidginPluginsDialog" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton">
-                <property name="label" translatable="yes">Close</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="receives-default">True</property>
-                <signal name="clicked" handler="gtk_widget_destroy" object="PidginPluginsDialog" swapped="yes"/>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</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="homogeneous">True</property>
-            <child>
-              <object class="GtkScrolledWindow">
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="shadow-type">in</property>
-                <child>
-                  <object class="GPluginGtkView" type-func="gplugin_gtk_view_get_type" id="tree_view">
-                    <property name="visible">True</property>
-                    <property name="can-focus">True</property>
-                    <property name="model">plugin_store</property>
-                    <property name="headers-clickable">False</property>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection">
-                        <signal name="changed" handler="pidgin_plugins_dialog_selection_cb" object="PidginPluginsDialog" swapped="no"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GPluginGtkPluginInfo" type-func="gplugin_gtk_plugin_info_get_type" id="plugin_info">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="orientation">vertical</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">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-      </object>
+    <child internal-child="content_area">
+      <object class="GPluginGtkView" id="view"/>
     </child>
+    <child internal-child="action_area"/>
   </template>
 </interface>
