Fri, 06 May 2022 00:39:20 -0500
Update the plugins dialog to use the GPluginGtkView from gplugin-gtk4
I also removed all of the configuration stuff for now as we need to solve that
in GPlugin first and then we can map the pidgin stuff into it.
Testing Done:
Compiled
Reviewed at https://reviews.imfreedom.org/r/1415/
| pidgin/pidginpluginsdialog.c | file | annotate | diff | comparison | revisions | |
| pidgin/resources/Plugins/dialog.ui | file | annotate | diff | comparison | revisions |
--- a/pidgin/pidginpluginsdialog.c Thu May 05 23:18:27 2022 -0500 +++ b/pidgin/pidginpluginsdialog.c Fri May 06 00:39:20 2022 -0500 @@ -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)); } -
--- a/pidgin/resources/Plugins/dialog.ui Thu May 05 23:18:27 2022 -0500 +++ b/pidgin/resources/Plugins/dialog.ui Fri May 06 00:39:20 2022 -0500 @@ -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,22 @@ 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"/> + <requires lib="gtk" version="4.0"/> + <requires lib="gplugin-gtk4" version="0.35"/> <!-- 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> <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>