pidgin/pidgin

Modernize XMPP discovery plugin

21 months ago, Elliott Sales de Andrade
a80a41434f44
Parents ea40c778bf9d
Children 9a1ad10a0940
Modernize XMPP discovery plugin

By porting common triggers to actions, dialog buttons to action widgets, `GtkMenu` to `GtkPopoverMenu`, using the `g_rc_box` API, and add braces everywhere. These will mostly make porting to GTK4 easier.

Also, added a default Service name of the JID. Otherwise, looking at `xmpp.org`, you previously got a big list of empty-looking rows (which also warn when the tooltip is shown).

Testing Done:
Opened plugin window, Browsed to `xmpp.org` and `pidgin.im`, checked that the Add button opened the Add-to-chat dialog, checked that double-click did the same, checked that the menu item did the same. I did not check Register in any of its forms as I don't know what server to query that returns something which could be registered on.

Reviewed at https://reviews.imfreedom.org/r/1596/
--- a/pidgin/plugins/disco/gtkdisco.c Mon Aug 15 21:30:26 2022 -0500
+++ b/pidgin/plugins/disco/gtkdisco.c Mon Aug 15 22:19:19 2022 -0500
@@ -1,4 +1,6 @@
-/* pidgin
+/*
+ * Pidgin - Internet Messenger
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
*
* Pidgin is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
@@ -15,8 +17,7 @@
* 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 02111-1301 USA
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@@ -42,61 +43,62 @@
NUM_OF_COLUMNS
};
+static PidginDiscoList *
+pidgin_disco_list_new(void) {
+ return g_rc_box_new0(PidginDiscoList);
+}
+
static void
pidgin_disco_list_destroy(PidginDiscoList *list)
{
g_hash_table_destroy(list->services);
- if (list->dialog && list->dialog->discolist == list)
+ if (list->dialog && list->dialog->discolist == list) {
list->dialog->discolist = NULL;
+ }
g_free((gchar*)list->server);
- g_free(list);
}
PidginDiscoList *pidgin_disco_list_ref(PidginDiscoList *list)
{
g_return_val_if_fail(list != NULL, NULL);
- ++list->ref;
- purple_debug_misc("xmppdisco", "reffing list, ref count now %d\n", list->ref);
-
- return list;
+ purple_debug_misc("xmppdisco", "reffing list");
+ return g_rc_box_acquire(list);
}
void pidgin_disco_list_unref(PidginDiscoList *list)
{
g_return_if_fail(list != NULL);
- --list->ref;
-
- purple_debug_misc("xmppdisco", "unreffing list, ref count now %d\n", list->ref);
- if (list->ref == 0)
- pidgin_disco_list_destroy(list);
+ purple_debug_misc("xmppdisco", "unreffing list");
+ g_rc_box_release_full(list, (GDestroyNotify)pidgin_disco_list_destroy);
}
void pidgin_disco_list_set_in_progress(PidginDiscoList *list, gboolean in_progress)
{
PidginDiscoDialog *dialog = list->dialog;
- if (!dialog)
+ if (!dialog) {
return;
+ }
list->in_progress = in_progress;
if (in_progress) {
gtk_widget_set_sensitive(dialog->account_chooser, FALSE);
- gtk_widget_set_sensitive(dialog->stop_button, TRUE);
- gtk_widget_set_sensitive(dialog->browse_button, FALSE);
+ g_simple_action_set_enabled(dialog->stop_action, TRUE);
+ g_simple_action_set_enabled(dialog->browse_action, FALSE);
} else {
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->progress), 0.0);
gtk_widget_set_sensitive(dialog->account_chooser, TRUE);
- gtk_widget_set_sensitive(dialog->stop_button, FALSE);
- gtk_widget_set_sensitive(dialog->browse_button, TRUE);
+ g_simple_action_set_enabled(dialog->stop_action, FALSE);
+ g_simple_action_set_enabled(dialog->browse_action, TRUE);
/*
- gtk_widget_set_sensitive(dialog->register_button, FALSE);
- gtk_widget_set_sensitive(dialog->add_button, FALSE);
+ g_simple_action_set_enabled(dialog->register_action, FALSE);
+ g_simple_action_set_enabled(dialog->add_action, FALSE);
*/
}
}
@@ -148,16 +150,24 @@
PurpleAccount *account = pidgin_account_chooser_get_selected(PIDGIN_ACCOUNT_CHOOSER(chooser));
gboolean change = (account != dialog->account);
dialog->account = account;
- gtk_widget_set_sensitive(dialog->browse_button, account != NULL);
+ g_simple_action_set_enabled(dialog->browse_action, account != NULL);
if (change) {
g_clear_pointer(&dialog->discolist, pidgin_disco_list_unref);
}
}
-static void register_button_cb(GtkWidget *unused, PidginDiscoDialog *dialog)
+static void
+activate_register(G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer data)
{
- xmpp_disco_service_register(dialog->selected);
+ PidginDiscoDialog *dialog = data;
+ XmppDiscoService *service = dialog->selected;
+
+ g_return_if_fail(service != NULL);
+
+ xmpp_disco_service_register(service);
}
static void discolist_cancel_cb(PidginDiscoList *pdl, const char *server)
@@ -171,7 +181,7 @@
static void discolist_ok_cb(PidginDiscoList *pdl, const char *server)
{
pdl->dialog->prompt_handle = NULL;
- gtk_widget_set_sensitive(pdl->dialog->browse_button, TRUE);
+ g_simple_action_set_enabled(pdl->dialog->browse_action, TRUE);
if (!server || !*server) {
purple_notify_error(my_plugin, _("Invalid Server"), _("Invalid Server"),
@@ -187,8 +197,12 @@
xmpp_disco_start(pdl);
}
-static void browse_button_cb(GtkWidget *button, PidginDiscoDialog *dialog)
+static void
+activate_browse(G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer data)
{
+ PidginDiscoDialog *dialog = data;
PurpleConnection *pc;
PidginDiscoList *pdl;
const char *username;
@@ -196,17 +210,18 @@
char *server = NULL;
pc = purple_account_get_connection(dialog->account);
- if (!pc)
+ if (!pc) {
return;
+ }
- gtk_widget_set_sensitive(dialog->browse_button, FALSE);
- gtk_widget_set_sensitive(dialog->add_button, FALSE);
- gtk_widget_set_sensitive(dialog->register_button, FALSE);
+ g_simple_action_set_enabled(dialog->browse_action, FALSE);
+ g_simple_action_set_enabled(dialog->add_action, FALSE);
+ g_simple_action_set_enabled(dialog->register_action, FALSE);
g_clear_pointer(&dialog->discolist, pidgin_disco_list_unref);
gtk_tree_store_clear(dialog->model);
- pdl = dialog->discolist = g_new0(PidginDiscoList, 1);
+ pdl = dialog->discolist = pidgin_disco_list_new();
pdl->services = g_hash_table_new_full(NULL, NULL, NULL,
(GDestroyNotify)gtk_tree_row_reference_free);
pdl->pc = pc;
@@ -226,9 +241,10 @@
server = g_strdup_printf("%.*s", (int)(slash - (at + 1)), at + 1);
}
- if (server == NULL)
+ if (server == NULL) {
/* This shouldn't ever happen since the account is connected */
server = g_strdup("jabber.org");
+ }
/* Translators: The string "Enter an XMPP Server" is asking the user to
type the name of an XMPP server which will then be queried */
@@ -242,8 +258,12 @@
g_free(server);
}
-static void add_to_blist_cb(GtkWidget *unused, PidginDiscoDialog *dialog)
+static void
+activate_add_to_blist(G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer data)
{
+ PidginDiscoDialog *dialog = data;
XmppDiscoService *service = dialog->selected;
PurpleAccount *account;
const char *jid;
@@ -253,10 +273,11 @@
account = purple_connection_get_account(service->list->pc);
jid = service->jid;
- if (service->type == XMPP_DISCO_SERVICE_TYPE_CHAT)
+ if (service->type == XMPP_DISCO_SERVICE_TYPE_CHAT) {
purple_blist_request_add_chat(account, NULL, NULL, jid);
- else
+ } else {
purple_blist_request_add_buddy(account, jid, NULL, NULL);
+ }
}
static gboolean
@@ -264,20 +285,23 @@
{
PidginDiscoDialog *dialog = user_data;
XmppDiscoService *service;
- GtkWidget *menu;
- GtkWidget *menuitem = NULL;
GtkTreePath *path;
GtkTreeIter iter;
GValue val;
- if (!gdk_event_triggers_context_menu((GdkEvent *)event))
+ GdkRectangle rect;
+
+ if (!gdk_event_triggers_context_menu((GdkEvent *)event)) {
return FALSE;
+ }
/* Figure out what was clicked */
if (!gtk_tree_view_get_path_at_pos(tree, event->x, event->y, &path,
NULL, NULL, NULL))
+ {
return FALSE;
+ }
gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path);
gtk_tree_path_free(path);
val.g_type = 0;
@@ -285,27 +309,19 @@
SERVICE_COLUMN, &val);
service = g_value_get_pointer(&val);
- if (!service)
+ if (!service) {
return FALSE;
-
- menu = gtk_menu_new();
-
- if (service->flags & XMPP_DISCO_ADD) {
- menuitem = gtk_menu_item_new_with_label(_("Add to Buddy List"));
- g_signal_connect(G_OBJECT(menuitem), "activate",
- G_CALLBACK(add_to_blist_cb), dialog);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
}
- if (service->flags & XMPP_DISCO_REGISTER) {
- menuitem = gtk_menu_item_new_with_label(_("Register"));
- g_signal_connect(G_OBJECT(menuitem), "activate",
- G_CALLBACK(register_button_cb), dialog);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- }
+ gtk_tree_view_convert_bin_window_to_widget_coords(dialog->tree,
+ (gint)event->x,
+ (gint)event->y,
+ &rect.x, &rect.y);
+ rect.width = rect.height = 1;
- gtk_widget_show_all(menu);
- gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
+ gtk_popover_set_pointing_to(GTK_POPOVER(dialog->popover), &rect);
+ gtk_popover_popup(GTK_POPOVER(dialog->popover));
+
return FALSE;
}
@@ -314,24 +330,21 @@
{
GtkTreeIter iter;
GValue val;
+ gboolean allow_add = FALSE, allow_register = FALSE;
if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
val.g_type = 0;
gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter,
SERVICE_COLUMN, &val);
dialog->selected = g_value_get_pointer(&val);
- if (!dialog->selected) {
- gtk_widget_set_sensitive(dialog->add_button, FALSE);
- gtk_widget_set_sensitive(dialog->register_button, FALSE);
- return;
+ if (dialog->selected != NULL) {
+ allow_add = (dialog->selected->flags & XMPP_DISCO_ADD);
+ allow_register = (dialog->selected->flags & XMPP_DISCO_REGISTER);
}
+ }
- gtk_widget_set_sensitive(dialog->add_button, dialog->selected->flags & XMPP_DISCO_ADD);
- gtk_widget_set_sensitive(dialog->register_button, dialog->selected->flags & XMPP_DISCO_REGISTER);
- } else {
- gtk_widget_set_sensitive(dialog->add_button, FALSE);
- gtk_widget_set_sensitive(dialog->register_button, FALSE);
- }
+ g_simple_action_set_enabled(dialog->add_action, allow_add);
+ g_simple_action_set_enabled(dialog->register_action, allow_register);
}
static void
@@ -360,8 +373,7 @@
XmppDiscoService *service;
GValue val;
- if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter,
- path)) {
+ if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path)) {
return;
}
@@ -371,18 +383,15 @@
service = g_value_get_pointer(&val);
if (service->flags & XMPP_DISCO_BROWSE) {
- if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(dialog->tree),
- path)) {
- gtk_tree_view_collapse_row(GTK_TREE_VIEW(dialog->tree),
- path);
+ if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(dialog->tree), path)) {
+ gtk_tree_view_collapse_row(GTK_TREE_VIEW(dialog->tree), path);
} else {
- gtk_tree_view_expand_row(GTK_TREE_VIEW(dialog->tree),
- path, FALSE);
+ gtk_tree_view_expand_row(GTK_TREE_VIEW(dialog->tree), path, FALSE);
}
} else if (service->flags & XMPP_DISCO_REGISTER) {
- register_button_cb(NULL, dialog);
+ g_action_activate(G_ACTION(dialog->register_action), NULL);
} else if (service->flags & XMPP_DISCO_ADD) {
- add_to_blist_cb(NULL, dialog);
+ g_action_activate(G_ACTION(dialog->add_action), NULL);
}
}
@@ -392,14 +401,16 @@
PidginDiscoDialog *dialog = PIDGIN_DISCO_DIALOG(window);
PidginDiscoList *list = dialog->discolist;
- if (dialog->prompt_handle)
+ if (dialog->prompt_handle) {
purple_request_close(PURPLE_REQUEST_INPUT, dialog->prompt_handle);
+ }
if (list) {
list->dialog = NULL;
- if (list->in_progress)
+ if (list->in_progress) {
list->in_progress = FALSE;
+ }
pidgin_disco_list_unref(list);
}
@@ -407,8 +418,13 @@
dialogs = g_list_remove(dialogs, dialog);
}
-static void stop_button_cb(GtkButton *button, PidginDiscoDialog *dialog)
+static void
+activate_stop(G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer data)
{
+ PidginDiscoDialog *dialog = data;
+
pidgin_disco_list_set_in_progress(dialog->discolist, FALSE);
}
@@ -491,12 +507,16 @@
break;
}
+ name = g_markup_escape_text(service->name, -1);
+ jid = g_markup_escape_text(service->jid, -1);
+ if (service->description != NULL) {
+ desc = g_markup_escape_text(service->description, -1);
+ }
+
markup = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>\n<b>%s:</b> %s%s%s",
- name = g_markup_escape_text(service->name, -1),
- type,
- jid = g_markup_escape_text(service->jid, -1),
+ name, type, jid,
service->description ? _("\n<b>Description:</b> ") : "",
- service->description ? desc = g_markup_escape_text(service->description, -1) : "");
+ service->description ? desc : "");
gtk_tooltip_set_markup(tooltip, markup);
gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, path);
@@ -521,8 +541,9 @@
if (list && list->pc == pc) {
PurpleAccount *account = NULL;
- if (list->in_progress)
+ if (list->in_progress) {
pidgin_disco_list_set_in_progress(list, FALSE);
+ }
gtk_tree_store_clear(dialog->model);
@@ -532,12 +553,9 @@
account = pidgin_account_chooser_get_selected(
PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser));
- gtk_widget_set_sensitive(
- dialog->browse_button,
- account != NULL);
-
- gtk_widget_set_sensitive(dialog->register_button, FALSE);
- gtk_widget_set_sensitive(dialog->add_button, FALSE);
+ g_simple_action_set_enabled(dialog->browse_action, account != NULL);
+ g_simple_action_set_enabled(dialog->add_action, FALSE);
+ g_simple_action_set_enabled(dialog->register_action, FALSE);
}
}
}
@@ -571,24 +589,15 @@
gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
progress);
gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
- stop_button);
- gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
- browse_button);
- gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
- register_button);
- gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
- add_button);
- gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
tree);
gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
model);
+ gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
+ popover);
+ gtk_widget_class_bind_template_child(widget_class, PidginDiscoDialog,
+ popover_menu);
gtk_widget_class_bind_template_callback(widget_class, destroy_win_cb);
- gtk_widget_class_bind_template_callback(widget_class, stop_button_cb);
- gtk_widget_class_bind_template_callback(widget_class, browse_button_cb);
- gtk_widget_class_bind_template_callback(widget_class,
- register_button_cb);
- gtk_widget_class_bind_template_callback(widget_class, add_to_blist_cb);
gtk_widget_class_bind_template_callback(widget_class, close_button_cb);
gtk_widget_class_bind_template_callback(widget_class,
dialog_select_account_cb);
@@ -607,6 +616,15 @@
static void
pidgin_disco_dialog_init(PidginDiscoDialog *dialog)
{
+ GActionEntry entries[] = {
+ { .name = "stop", .activate = activate_stop },
+ { .name = "browse", .activate = activate_browse },
+ { .name = "register", .activate = activate_register },
+ { .name = "add", .activate = activate_add_to_blist },
+ };
+ GSimpleActionGroup *action_group = NULL;
+ GActionMap *action_map = NULL;
+
dialogs = g_list_prepend(dialogs, dialog);
gtk_widget_init_template(GTK_WIDGET(dialog));
@@ -615,12 +633,36 @@
dialog->account = pidgin_account_chooser_get_selected(
PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser));
- /* browse button */
- gtk_widget_set_sensitive(dialog->browse_button, dialog->account != NULL);
-
gtk_widget_set_has_tooltip(GTK_WIDGET(dialog->tree), TRUE);
g_signal_connect(G_OBJECT(dialog->tree), "query-tooltip",
G_CALLBACK(disco_query_tooltip), dialog);
+
+ action_group = g_simple_action_group_new();
+ action_map = G_ACTION_MAP(action_group);
+ g_action_map_add_action_entries(action_map, entries, G_N_ELEMENTS(entries),
+ dialog);
+
+ dialog->stop_action = G_SIMPLE_ACTION(
+ g_action_map_lookup_action(action_map, "stop"));
+ g_simple_action_set_enabled(dialog->stop_action, FALSE);
+
+ dialog->browse_action = G_SIMPLE_ACTION(
+ g_action_map_lookup_action(action_map, "browse"));
+ g_simple_action_set_enabled(dialog->browse_action, dialog->account != NULL);
+
+ dialog->register_action = G_SIMPLE_ACTION(
+ g_action_map_lookup_action(action_map, "register"));
+ g_simple_action_set_enabled(dialog->register_action, FALSE);
+
+ dialog->add_action = G_SIMPLE_ACTION(
+ g_action_map_lookup_action(action_map, "add"));
+ g_simple_action_set_enabled(dialog->add_action, FALSE);
+
+ gtk_widget_insert_action_group(GTK_WIDGET(dialog), "disco",
+ G_ACTION_GROUP(action_group));
+
+ gtk_popover_bind_model(GTK_POPOVER(dialog->popover), dialog->popover_menu,
+ NULL);
}
/******************************************************************************
@@ -636,8 +678,7 @@
PidginDiscoDialog *
pidgin_disco_dialog_new(void)
{
- PidginDiscoDialog *dialog =
- g_object_new(PIDGIN_TYPE_DISCO_DIALOG, NULL);
+ PidginDiscoDialog *dialog = g_object_new(PIDGIN_TYPE_DISCO_DIALOG, NULL);
gtk_widget_show_all(GTK_WIDGET(dialog));
return dialog;
}
@@ -652,10 +693,12 @@
dialog = pdl->dialog;
g_return_if_fail(dialog != NULL);
- if (service != NULL)
- purple_debug_info("xmppdisco", "Adding service \"%s\"\n", service->name);
- else
- purple_debug_info("xmppdisco", "Service \"%s\" has no childrens\n", parent->name);
+ if (service != NULL) {
+ purple_debug_info("xmppdisco", "Adding service \"%s\"", service->name);
+ } else {
+ purple_debug_info("xmppdisco", "Service \"%s\" has no children",
+ parent->name);
+ }
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(dialog->progress));
@@ -677,15 +720,17 @@
gtk_tree_model_get(
GTK_TREE_MODEL(dialog->model), &child,
SERVICE_COLUMN, &tmp, -1);
- if (!tmp)
+ if (!tmp) {
append = FALSE;
+ }
}
}
}
if (service == NULL) {
- if (parent != NULL && !append)
+ if (parent != NULL && !append) {
gtk_tree_store_remove(dialog->model, &child);
+ }
return;
}
@@ -716,7 +761,8 @@
NAME_COLUMN, service->name, DESCRIPTION_COLUMN,
service->description, SERVICE_COLUMN, service, -1);
- if (pixbuf)
+ if (pixbuf) {
g_object_unref(pixbuf);
+ }
}
--- a/pidgin/plugins/disco/gtkdisco.h Mon Aug 15 21:30:26 2022 -0500
+++ b/pidgin/plugins/disco/gtkdisco.h Mon Aug 15 22:19:19 2022 -0500
@@ -37,10 +37,10 @@
GtkWidget *progress;
- GtkWidget *stop_button;
- GtkWidget *browse_button;
- GtkWidget *register_button;
- GtkWidget *add_button;
+ GSimpleAction *stop_action;
+ GSimpleAction *browse_action;
+ GSimpleAction *register_action;
+ GSimpleAction *add_action;
XmppDiscoService *selected;
GtkTreeView *tree;
@@ -48,7 +48,10 @@
PurpleAccount *account;
PidginDiscoList *discolist;
- gpointer *prompt_handle;
+ GtkPopoverMenu *popover;
+ GMenuModel *popover_menu;
+
+ gpointer prompt_handle;
};
#define PIDGIN_TYPE_DISCO_DIALOG (pidgin_disco_dialog_get_type())
@@ -60,7 +63,6 @@
gboolean in_progress;
const gchar *server;
- gint ref;
guint fetch_count;
PidginDiscoDialog *dialog;
--- a/pidgin/plugins/disco/resources/disco.ui Mon Aug 15 21:30:26 2022 -0500
+++ b/pidgin/plugins/disco/resources/disco.ui Mon Aug 15 22:19:19 2022 -0500
@@ -26,6 +26,23 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+ <menu id="popover_menu">
+ <section>
+ <item>
+ <attribute name="action">disco.add</attribute>
+ <attribute name="label" translatable="yes">Add to Buddy List</attribute>
+ </item>
+ <item>
+ <attribute name="action">disco.register</attribute>
+ <attribute name="label" translatable="yes">Register</attribute>
+ </item>
+ </section>
+ </menu>
+ <object class="GtkPopoverMenu" id="popover">
+ <property name="can_focus">False</property>
+ <property name="relative-to">tree</property>
+ <property name="position">bottom</property>
+ </object>
<object class="PidginAccountStore" id="accounts"/>
<object class="PidginAccountFilterConnected" id="accounts_connected">
<property name="child_model">accounts</property>
@@ -52,102 +69,11 @@
<property name="role">service discovery</property>
<property name="type_hint">dialog</property>
<signal name="destroy" handler="destroy_win_cb" swapped="no"/>
- <child>
- <placeholder/>
- </child>
<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="stop_button">
- <property name="label" translatable="yes">_Stop</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="stop_button_cb" object="PidginDiscoDialog" 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" id="browse_button">
- <property name="label" translatable="yes">_Browse</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="browse_button_cb" object="PidginDiscoDialog" swapped="no"/>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="register_button">
- <property name="label" translatable="yes">Register</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="register_button_cb" object="PidginDiscoDialog" swapped="no"/>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="add_button">
- <property name="label" translatable="yes">_Add</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="add_to_blist_cb" object="PidginDiscoDialog" swapped="no"/>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="close_button">
- <property name="label" translatable="yes">_Close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="close_button_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">4</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>
@@ -277,5 +203,61 @@
</child>
</object>
</child>
+ <child type="action">
+ <object class="GtkButton" id="stop_button">
+ <property name="label" translatable="yes">_Stop</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="action-name">disco.stop</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="browse_button">
+ <property name="label" translatable="yes">_Browse</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="action-name">disco.browse</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="register_button">
+ <property name="label" translatable="yes">Register</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action-name">disco.register</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="add_button">
+ <property name="label" translatable="yes">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="action-name">disco.add</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="close_button">
+ <property name="label" translatable="yes">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="close_button_cb" swapped="no"/>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">stop_button</action-widget>
+ <action-widget response="1">browse_button</action-widget>
+ <action-widget response="2">register_button</action-widget>
+ <action-widget response="3">add_button</action-widget>
+ <action-widget response="close">close_button</action-widget>
+ </action-widgets>
</template>
</interface>
--- a/pidgin/plugins/disco/xmppdisco.c Mon Aug 15 21:30:26 2022 -0500
+++ b/pidgin/plugins/disco/xmppdisco.c Mon Aug 15 22:19:19 2022 -0500
@@ -1,5 +1,10 @@
/*
* Purple - XMPP Service Disco Browser
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
*
* 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
@@ -12,9 +17,7 @@
* 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 02111-1301 USA
- *
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/* TODO list (a little bit of a brain dump):
@@ -116,8 +119,9 @@
struct xmpp_iq_cb_data *cb_data;
cb_data = g_hash_table_lookup(iq_callbacks, id);
- if (!cb_data)
+ if (!cb_data) {
return FALSE;
+ }
cb_data->cb(cb_data->pc, type, id, from, iq, cb_data->context);
@@ -170,16 +174,18 @@
query = purple_xmlnode_new_child(iq, "query");
purple_xmlnode_set_namespace(query, NS_DISCO_INFO);
- if (node)
+ if (node) {
purple_xmlnode_set_attrib(query, "node", node);
+ }
/* Steals id */
xmpp_iq_register_callback(pc, id, cbdata, cb);
purple_signal_emit(purple_connection_get_protocol(pc), "jabber-sending-xmlnode",
pc, &iq);
- if (iq != NULL)
+ if (iq != NULL) {
purple_xmlnode_free(iq);
+ }
}
static void
@@ -196,16 +202,18 @@
query = purple_xmlnode_new_child(iq, "query");
purple_xmlnode_set_namespace(query, NS_DISCO_ITEMS);
- if (node)
+ if (node) {
purple_xmlnode_set_attrib(query, "node", node);
+ }
/* Steals id */
xmpp_iq_register_callback(pc, id, cbdata, cb);
purple_signal_emit(purple_connection_get_protocol(pc), "jabber-sending-xmlnode",
pc, &iq);
- if (iq != NULL)
+ if (iq != NULL) {
purple_xmlnode_free(iq);
+ }
}
static XmppDiscoServiceType
@@ -213,29 +221,31 @@
{
const char *category, *type;
- if (!identity)
+ if (!identity) {
return XMPP_DISCO_SERVICE_TYPE_OTHER;
+ }
category = purple_xmlnode_get_attrib(identity, "category");
type = purple_xmlnode_get_attrib(identity, "type");
- if (!category)
+ if (!category) {
return XMPP_DISCO_SERVICE_TYPE_OTHER;
+ }
- if (purple_strequal(category, "conference"))
+ if (purple_strequal(category, "conference")) {
return XMPP_DISCO_SERVICE_TYPE_CHAT;
- else if (purple_strequal(category, "directory"))
+ } else if (purple_strequal(category, "directory")) {
return XMPP_DISCO_SERVICE_TYPE_DIRECTORY;
- else if (purple_strequal(category, "gateway"))
+ } else if (purple_strequal(category, "gateway")) {
return XMPP_DISCO_SERVICE_TYPE_GATEWAY;
- else if (purple_strequal(category, "pubsub")) {
- if (!type || purple_strequal(type, "collection"))
+ } else if (purple_strequal(category, "pubsub")) {
+ if (!type || purple_strequal(type, "collection")) {
return XMPP_DISCO_SERVICE_TYPE_PUBSUB_COLLECTION;
- else if (purple_strequal(type, "leaf"))
+ } else if (purple_strequal(type, "leaf")) {
return XMPP_DISCO_SERVICE_TYPE_PUBSUB_LEAF;
- else if (purple_strequal(type, "service"))
+ } else if (purple_strequal(type, "service")) {
return XMPP_DISCO_SERVICE_TYPE_OTHER;
- else {
+ } else {
purple_debug_warning("xmppdisco", "Unknown pubsub type '%s'\n", type);
return XMPP_DISCO_SERVICE_TYPE_OTHER;
}
@@ -262,8 +272,9 @@
g_return_val_if_fail(str != NULL, "");
for ( ; disco_type_mappings[i].from; ++i) {
- if (!g_ascii_strcasecmp(str, disco_type_mappings[i].from))
+ if (!g_ascii_strcasecmp(str, disco_type_mappings[i].from)) {
return disco_type_mappings[i].to;
+ }
}
/* fallback to the string itself */
@@ -280,8 +291,9 @@
--list->fetch_count;
- if (!list->in_progress)
+ if (!list->in_progress) {
goto out;
+ }
if (purple_strequal(type, "result") &&
(query = purple_xmlnode_get_child(iq, "query"))) {
@@ -300,26 +312,31 @@
if (item_data->name) {
service->name = item_data->name;
item_data->name = NULL;
- } else
+ } else {
service->name = g_strdup(item_data->node);
+ }
service->node = item_data->node;
item_data->node = NULL;
- if (service->type == XMPP_DISCO_SERVICE_TYPE_PUBSUB_COLLECTION)
+ if (service->type == XMPP_DISCO_SERVICE_TYPE_PUBSUB_COLLECTION) {
service->flags |= XMPP_DISCO_BROWSE;
- } else
+ }
+ } else {
service->name = g_strdup(from);
+ }
- if (!service->node)
+ if (!service->node) {
/* Only support adding JIDs, not JID+node combos */
service->flags |= XMPP_DISCO_ADD;
+ }
if (item_data->name) {
service->description = item_data->name;
item_data->name = NULL;
- } else if (identity)
+ } else if (identity) {
service->description = g_strdup(purple_xmlnode_get_attrib(identity, "name"));
+ }
/* TODO: Overlap with service->name a bit */
service->jid = g_strdup(from);
@@ -327,29 +344,32 @@
for (feature = purple_xmlnode_get_child(query, "feature"); feature;
feature = purple_xmlnode_get_next_twin(feature)) {
const char *var;
- if (!(var = purple_xmlnode_get_attrib(feature, "var")))
+ if (!(var = purple_xmlnode_get_attrib(feature, "var"))) {
continue;
+ }
- if (purple_strequal(var, NS_REGISTER))
+ if (purple_strequal(var, NS_REGISTER)) {
service->flags |= XMPP_DISCO_REGISTER;
- else if (purple_strequal(var, NS_DISCO_ITEMS))
+ } else if (purple_strequal(var, NS_DISCO_ITEMS)) {
service->flags |= XMPP_DISCO_BROWSE;
- else if (purple_strequal(var, NS_MUC)) {
+ } else if (purple_strequal(var, NS_MUC)) {
service->flags |= XMPP_DISCO_BROWSE;
service->type = XMPP_DISCO_SERVICE_TYPE_CHAT;
}
}
- if (service->type == XMPP_DISCO_SERVICE_TYPE_GATEWAY)
+ if (service->type == XMPP_DISCO_SERVICE_TYPE_GATEWAY) {
service->gateway_type = g_strdup(disco_type_from_string(
purple_xmlnode_get_attrib(identity, "type")));
+ }
pidgin_disco_add_service(list, service, service->parent);
}
out:
- if (list->fetch_count == 0)
+ if (list->fetch_count == 0) {
pidgin_disco_list_set_in_progress(list, FALSE);
+ }
g_free(item_data->name);
g_free(item_data->node);
@@ -368,8 +388,9 @@
--list->fetch_count;
- if (!list->in_progress)
+ if (!list->in_progress) {
goto out;
+ }
if (purple_strequal(type, "result") &&
(query = purple_xmlnode_get_child(iq, "query"))) {
@@ -400,6 +421,9 @@
service->name = g_strdup(name);
service->jid = g_strdup(jid);
service->node = g_strdup(node);
+ if (service->name == NULL) {
+ service->name = g_strdup(jid);
+ }
pidgin_disco_add_service(list, service, item_data->parent);
} else {
struct item_data *item_data2 = g_new0(struct item_data, 1);
@@ -416,12 +440,14 @@
}
}
- if (!has_items)
+ if (!has_items) {
pidgin_disco_add_service(list, NULL, item_data->parent);
+ }
out:
- if (list->fetch_count == 0)
+ if (list->fetch_count == 0) {
pidgin_disco_list_set_in_progress(list, FALSE);
+ }
g_free(item_data);
pidgin_disco_list_unref(list);
@@ -449,8 +475,9 @@
const char *node = purple_xmlnode_get_attrib(item, "node");
struct item_data *item_data;
- if (!jid)
+ if (!jid) {
continue;
+ }
item_data = g_new0(struct item_data, 1);
item_data->list = list;
@@ -463,8 +490,9 @@
}
}
- if (list->fetch_count == 0)
+ if (list->fetch_count == 0) {
pidgin_disco_list_set_in_progress(list, FALSE);
+ }
pidgin_disco_list_unref(list);
}
@@ -511,8 +539,7 @@
purple_notify_error(my_plugin, _("Error"),
_("Server does not exist"),
NULL, NULL);
- }
- else {
+ } else {
purple_notify_error(my_plugin, _("Error"),
_("Server does not support service discovery"),
NULL, NULL);
@@ -545,8 +572,9 @@
g_return_if_fail(service != NULL);
- if (service->expanded)
+ if (service->expanded) {
return;
+ }
item_data = g_new0(struct item_data, 1);
item_data->list = service->list;
@@ -577,8 +605,9 @@
purple_signal_emit(purple_connection_get_protocol(service->list->pc),
"jabber-sending-xmlnode", service->list->pc, &iq);
- if (iq != NULL)
+ if (iq != NULL) {
purple_xmlnode_free(iq);
+ }
g_free(id);
}