Separate the AccountChooser from its model and move options to filters
Create a store for accounts and a filter to only show connected accounts
Update everything to use the new PidginAccountStore and PidginAccountFilterConnected filter
Add a GtkTreeModelFilter for protocols by id
Testing Done:
Compiled and opened most of the dialogs to make sure they're still working the same. Was unable to test gevolution.
Reviewed at https://reviews.imfreedom.org/r/95/
--- a/doc/reference/pidgin/pidgin-docs.xml Tue Sep 15 20:26:57 2020 -0500
+++ b/doc/reference/pidgin/pidgin-docs.xml Tue Sep 15 21:54:10 2020 -0500
@@ -1,5 +1,5 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
@@ -54,9 +54,12 @@
<xi:include href="xml/minidialog.xml" />
<xi:include href="xml/pidgin.xml" />
<xi:include href="xml/pidginabout.xml" />
+ <xi:include href="xml/pidginaccountactionsmenu.xml" /> <xi:include href="xml/pidginaccountchooser.xml" />
- <xi:include href="xml/pidginaccountactionsmenu.xml" />
+ <xi:include href="xml/pidginaccountfilterconnected.xml" /> + <xi:include href="xml/pidginaccountfilterprotocol.xml" /> <xi:include href="xml/pidginaccountsmenu.xml" />
+ <xi:include href="xml/pidginaccountstore.xml" /> <xi:include href="xml/pidginactiongroup.xml" />
<xi:include href="xml/pidginattachment.xml" />
<xi:include href="xml/pidginbuddylistmenu.xml" />
--- a/pidgin/glade/pidgin3.xml.in Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/glade/pidgin3.xml.in Tue Sep 15 21:54:10 2020 -0500
@@ -3,6 +3,9 @@
<glade-widget-class name="PidginAccountChooser" generic-name="account_chooser" title="AccountChooser"/>
<glade-widget-class name="PidginAccountsMenu" generic-name="accounts_menu" title="AccountsMenu"/>
+ <glade-widget-class name="PidginAccountStore" generic-name="account_store" title="AccountStore"/> + <glade-widget-class name="PidginAccountFilterConnected" generic-name="account_filter_connected" title="FilterConnected"/> + <glade-widget-class name="PidginAccountFilterProtocol" generic-name="account_filter_protocol" title="FilterProtocol"/> <glade-widget-class name="PidginCloseButton" generic-name="close-button" title="CloseButton"/>
<glade-widget-class name="PidginDialog" generic-name="dialog" title="Dialog"/>
<glade-widget-class name="PidginInviteDialog" generic-name="invite_dialog" title="InviteDialog"/>
@@ -14,6 +17,9 @@
<glade-widget-group name="pidgin" title="Pidgin">
<glade-widget-class-ref name="PidginAccountChooser"/>
<glade-widget-class-ref name="PidginAccountsMenu"/>
+ <glade-widget-class-ref name="PidginAccountStore"/> + <glade-widget-class-ref name="PidginAccountFilterConnected"/> + <glade-widget-class-ref name="PidginAccountFilterProtocol"/> <glade-widget-class-ref name="PidginCloseButton"/>
<glade-widget-class-ref name="PidginDialog"/>
<glade-widget-class-ref name="PidginInviteDialog"/>
--- a/pidgin/gtkblist.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/gtkblist.c Tue Sep 15 21:54:10 2020 -0500
@@ -44,6 +44,8 @@
#include "pidgin/minidialog.h"
#include "pidgin/pidginaccountchooser.h"
+#include "pidgin/pidginaccountfilterconnected.h" +#include "pidgin/pidginaccountstore.h" #include "pidgin/pidginactiongroup.h"
#include "pidgin/pidginbuddylistmenu.h"
#include "pidgin/pidginclosebutton.h"
@@ -967,6 +969,7 @@
+ GtkTreeModel *model = NULL, *filter = NULL; PidginBuddyList *gtkblist;
@@ -1009,7 +1012,19 @@
data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
- data->account_menu = pidgin_account_chooser_new(account, FALSE);
+ model = GTK_TREE_MODEL(pidgin_account_store_new()); + filter = pidgin_account_filter_connected_new(model, NULL); + g_object_unref(G_OBJECT(model)); + data->account_menu = pidgin_account_chooser_new(); + gtk_combo_box_set_model(GTK_COMBO_BOX(data->account_menu), filter); + g_object_unref(G_OBJECT(filter)); + if(PURPLE_IS_ACCOUNT(account)) { + pidgin_account_chooser_set_selected(PIDGIN_ACCOUNT_CHOOSER( + data->account_menu), account); + gtk_combo_box_set_active(GTK_COMBO_BOX(data->account_menu), 0); pidgin_account_chooser_set_filter_func(
PIDGIN_ACCOUNT_CHOOSER(data->account_menu), filter_func);
pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("A_ccount"), data->sg, data->account_menu, TRUE, NULL);
@@ -1109,8 +1124,8 @@
chat_select_account_cb(GObject *w, PidginChatData *data)
- PurpleAccount *account =
- pidgin_account_chooser_get_selected(GTK_WIDGET(w));
+ PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w); + PurpleAccount *account = pidgin_account_chooser_get_selected(chooser); g_return_if_fail(data != NULL);
g_return_if_fail(account != NULL);
@@ -1131,6 +1146,7 @@
pidgin_blist_joinchat_show(void)
PidginChatData *data = NULL;
+ PidginAccountChooser *chooser = NULL; data = g_new0(PidginChatData, 1);
@@ -1147,8 +1163,9 @@
gtk_dialog_set_default_response(GTK_DIALOG(data->rq_data.window),
data->default_chat_name = NULL;
- data->rq_data.account =
- pidgin_account_chooser_get_selected(data->rq_data.account_menu);
+ chooser = PIDGIN_ACCOUNT_CHOOSER(data->rq_data.account_menu); + data->rq_data.account = pidgin_account_chooser_get_selected(chooser); rebuild_chat_entries(data, NULL);
@@ -6263,8 +6280,8 @@
add_buddy_select_account_cb(GObject *w, PidginAddBuddyData *data)
- PurpleAccount *account =
- pidgin_account_chooser_get_selected(GTK_WIDGET(w));
+ PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w); + PurpleAccount *account = pidgin_account_chooser_get_selected(chooser); PurpleConnection *pc = NULL;
PurpleProtocol *protocol = NULL;
gboolean invite_enabled = TRUE;
@@ -6371,6 +6388,7 @@
const char *username, const char *group,
+ PidginAccountChooser *chooser = NULL; PidginAddBuddyData *data = g_new0(PidginAddBuddyData, 1);
PidginBlistRequestData *blist_req_data = &data->rq_data;
@@ -6434,8 +6452,8 @@
gtk_widget_show_all(data->rq_data.window);
/* Force update of invite message entry sensitivity */
- pidgin_account_chooser_set_selected(blist_req_data->account_menu,
+ chooser = PIDGIN_ACCOUNT_CHOOSER(blist_req_data->account_menu); + pidgin_account_chooser_set_selected(chooser, account); --- a/pidgin/gtkpounce.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/gtkpounce.c Tue Sep 15 21:54:10 2020 -0500
@@ -33,6 +33,7 @@
#include "pidginaccountchooser.h"
+#include "pidginaccountstore.h" #include "pidgindialog.h"
#include "pidgintalkatu.h"
@@ -347,8 +348,9 @@
-pounce_choose_cb(GtkWidget *chooser, PidginPounceDialog *dialog)
+pounce_choose_cb(GtkWidget *w, PidginPounceDialog *dialog) + PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w); dialog->account = pidgin_account_chooser_get_selected(chooser);
@@ -399,7 +401,8 @@
gtk_entry_set_text(GTK_ENTRY(dialog->buddy_entry), purple_buddy_get_name(buddy));
dialog->account = purple_buddy_get_account(buddy);
pidgin_account_chooser_set_selected(
- dialog->account_menu, purple_buddy_get_account(buddy));
+ PIDGIN_ACCOUNT_CHOOSER(dialog->account_menu), + purple_buddy_get_account(buddy)); gtk_drag_finish(dc, TRUE, (gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE), t);
@@ -425,7 +428,7 @@
gtk_entry_set_text(GTK_ENTRY(dialog->buddy_entry), username);
dialog->account = account;
pidgin_account_chooser_set_selected(
- dialog->account_menu, account);
+ PIDGIN_ACCOUNT_CHOOSER(dialog->account_menu), account); @@ -445,8 +448,8 @@
reset_send_msg_entry(PidginPounceDialog *dialog, GtkWidget *dontcare)
- PurpleAccount *account =
- pidgin_account_chooser_get_selected(dialog->account_menu);
+ PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(dialog->account_menu); + PurpleAccount *account = pidgin_account_chooser_get_selected(chooser); if(GTK_IS_TEXT_BUFFER(dialog->send_msg_buffer)) {
g_object_unref(dialog->send_msg_buffer);
@@ -483,6 +486,7 @@
g_return_if_fail((cur_pounce != NULL) ||
@@ -547,8 +551,12 @@
gtk_size_group_add_widget(sg, label);
- pidgin_account_chooser_new(dialog->account, TRUE);
+ dialog->account_menu = pidgin_account_chooser_new(); + model = GTK_TREE_MODEL(pidgin_account_store_new()); + gtk_combo_box_set_model(GTK_COMBO_BOX(dialog->account_menu), model); + g_object_unref(G_OBJECT(model)); + pidgin_account_chooser_set_selected( + PIDGIN_ACCOUNT_CHOOSER(dialog->account_menu), dialog->account); g_signal_connect(dialog->account_menu, "changed",
G_CALLBACK(pounce_choose_cb), dialog);
--- a/pidgin/gtkprivacy.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/gtkprivacy.c Tue Sep 15 21:54:10 2020 -0500
@@ -28,6 +28,7 @@
#include "pidginaccountchooser.h"
+#include "pidginaccountstore.h" #define PIDGIN_TYPE_PRIVACY_DIALOG (pidgin_privacy_dialog_get_type())
G_DECLARE_FINAL_TYPE(PidginPrivacyDialog, pidgin_privacy_dialog, PIDGIN,
@@ -119,8 +120,8 @@
-select_account_cb(GtkWidget *chooser, PidginPrivacyDialog *dialog)
+select_account_cb(GtkWidget *w, PidginPrivacyDialog *dialog) { + PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w); PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
@@ -300,15 +301,15 @@
-pidgin_privacy_dialog_init(PidginPrivacyDialog *dialog)
+pidgin_privacy_dialog_init(PidginPrivacyDialog *dialog) { + PidginAccountChooser *chooser = NULL; gtk_widget_init_template(GTK_WIDGET(dialog));
- pidgin_account_chooser_get_selected(dialog->account_chooser);
+ chooser = PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser); + dialog->account = pidgin_account_chooser_get_selected(chooser); /* Add the drop-down list with the allow/block types. */
for (i = 0; i < menu_entry_count; i++) {
--- a/pidgin/gtkrequest.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/gtkrequest.c Tue Sep 15 21:54:10 2020 -0500
@@ -26,9 +26,11 @@
#include "pidginaccountchooser.h"
+#include "pidginaccountfilterconnected.h" +#include "pidginaccountstore.h" #include "pidgindialog.h"
@@ -262,8 +264,10 @@
field_account_cb(GObject *w, PurpleRequestField *field)
+ PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w); purple_request_field_account_set_value(
- field, pidgin_account_chooser_get_selected(GTK_WIDGET(w)));
+ field, pidgin_account_chooser_get_selected(chooser)); @@ -1325,10 +1329,32 @@
create_account_field(PurpleRequestField *field)
- widget = pidgin_account_chooser_new(
- purple_request_field_account_get_default_value(field),
- purple_request_field_account_get_show_all(field));
+ PurpleAccount *account; + widget = pidgin_account_chooser_new(); + account = purple_request_field_account_get_default_value(field); + if(purple_request_field_account_get_show_all(field)) { + GtkListStore *store = pidgin_account_store_new(); + gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + GtkListStore *store = NULL; + GtkTreeModel *filter = NULL; + store = pidgin_account_store_new(); + filter = pidgin_account_filter_connected_new(GTK_TREE_MODEL(store), + g_object_unref(G_OBJECT(store)); + gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(filter)); + g_object_unref(G_OBJECT(filter)); + pidgin_account_chooser_set_selected(PIDGIN_ACCOUNT_CHOOSER(widget), pidgin_account_chooser_set_filter_func(
PIDGIN_ACCOUNT_CHOOSER(widget),
purple_request_field_account_get_filter(field));
@@ -1338,6 +1364,7 @@
gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
g_signal_connect(widget, "changed",
G_CALLBACK(req_field_changed_cb), field);
+ gtk_widget_show(widget); --- a/pidgin/gtkroomlist.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/gtkroomlist.c Tue Sep 15 21:54:10 2020 -0500
@@ -110,8 +110,8 @@
-dialog_select_account_cb(GtkWidget *chooser, PidginRoomlistDialog *dialog)
+dialog_select_account_cb(GtkWidget *w, PidginRoomlistDialog *dialog) { + PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(w); PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
gboolean change = (account != dialog->account);
dialog->account = account;
@@ -566,19 +566,20 @@
static PidginRoomlistDialog *
pidgin_roomlist_dialog_new_with_account(PurpleAccount *account)
- PidginRoomlistDialog *dialog;
+ PidginRoomlistDialog *dialog = NULL; + PidginAccountChooser *chooser = NULL; dialog = g_object_new(PIDGIN_TYPE_ROOMLIST_DIALOG, NULL);
dialog->account = account;
+ chooser = PIDGIN_ACCOUNT_CHOOSER(dialog->account_widget); /* This is normally NULL, and we normally don't care what the
* first selected item is */
- dialog->account = pidgin_account_chooser_get_selected(
- dialog->account_widget);
+ dialog->account = pidgin_account_chooser_get_selected(chooser); - pidgin_account_chooser_set_selected(dialog->account_widget,
+ pidgin_account_chooser_set_selected(chooser, account); /* show the dialog window and return the dialog */
--- a/pidgin/meson.build Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/meson.build Tue Sep 15 21:54:10 2020 -0500
@@ -35,7 +35,10 @@
'pidginaccountactionsmenu.c',
'pidginaccountchooser.c',
+ 'pidginaccountfilterconnected.c', + 'pidginaccountfilterprotocol.c', + 'pidginaccountstore.c', @@ -97,7 +100,10 @@
'pidginaccountactionsmenu.h',
'pidginaccountchooser.h',
+ 'pidginaccountfilterconnected.h', + 'pidginaccountfilterprotocol.h', + 'pidginaccountstore.h', --- a/pidgin/pidginaccountchooser.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/pidginaccountchooser.c Tue Sep 15 21:54:10 2020 -0500
@@ -1,4 +1,6 @@
+ * 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
@@ -20,196 +22,38 @@
#include "pidginaccountchooser.h"
-/******************************************************************************
- *****************************************************************************/
+#include "pidginaccountstore.h"
+struct _PidginAccountChooser { + PurpleFilterAccountFunc filter_func;
-/******************************************************************************
- *****************************************************************************/
-struct _PidginAccountChooser {
- PurpleFilterAccountFunc filter_func;
-/******************************************************************************
- *****************************************************************************/
static GParamSpec *properties[PROP_LAST] = {NULL};
-G_DEFINE_TYPE(PidginAccountChooser, pidgin_account_chooser, GTK_TYPE_COMBO_BOX)
-account_chooser_get_selected(PidginAccountChooser *chooser)
- if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(chooser), &iter)) {
- gtk_combo_box_get_model(GTK_COMBO_BOX(chooser)), &iter,
- AOP_DATA_COLUMN, &data, -1);
-account_chooser_select_by_data(GtkWidget *chooser, gpointer data)
- model = gtk_combo_box_get_model(GTK_COMBO_BOX(chooser));
- if (gtk_tree_model_get_iter_first(model, &iter)) {
- gtk_tree_model_get(model, &iter, AOP_DATA_COLUMN,
- if (iter_data == data) {
- gtk_combo_box_set_active_iter(
- GTK_COMBO_BOX(chooser), &iter);
- } while (gtk_tree_model_iter_next(model, &iter));
+/****************************************************************************** + *****************************************************************************/ -set_account_menu(PidginAccountChooser *chooser, PurpleAccount *default_account)
- PurpleAccount *account;
- GdkPixbuf *pixbuf = NULL;
- if (chooser->show_all) {
- list = purple_accounts_get_all();
- list = purple_connections_get_all();
- gtk_list_store_clear(chooser->model);
- for (p = list, i = 0; p != NULL; p = p->next, i++) {
- if (chooser->show_all) {
- account = (PurpleAccount *)p->data;
- PurpleConnection *gc = (PurpleConnection *)p->data;
- account = purple_connection_get_account(gc);
- if (chooser->filter_func && !chooser->filter_func(account)) {
- pixbuf = pidgin_create_protocol_icon(
- account, PIDGIN_PROTOCOL_ICON_SMALL);
- if (purple_account_is_disconnected(account) &&
- chooser->show_all && purple_connections_get_all()) {
- gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf,
- if (purple_account_get_private_alias(account)) {
- g_snprintf(buf, sizeof(buf), "%s (%s) (%s)",
- purple_account_get_username(account),
- purple_account_get_private_alias(account),
- purple_account_get_protocol_name(account));
- g_snprintf(buf, sizeof(buf), "%s (%s)",
- purple_account_get_username(account),
- purple_account_get_protocol_name(account));
- gtk_list_store_append(chooser->model, &iter);
- gtk_list_store_set(chooser->model, &iter, AOP_ICON_COLUMN,
- pixbuf, AOP_NAME_COLUMN, buf,
- AOP_DATA_COLUMN, account, -1);
- g_object_unref(pixbuf);
- if (default_account && account == default_account) {
- gtk_combo_box_set_active(GTK_COMBO_BOX(chooser), default_item);
-regenerate_account_menu(PidginAccountChooser *chooser)
- PurpleAccount *account;
- account = (PurpleAccount *)account_chooser_get_selected(chooser);
- set_account_menu(chooser, account);
-account_menu_sign_on_off_cb(PurpleConnection *gc, PidginAccountChooser *chooser)
- regenerate_account_menu(chooser);
-account_menu_added_removed_cb(PurpleAccount *account,
- PidginAccountChooser *chooser)
- regenerate_account_menu(chooser);
-account_menu_destroyed_cb(GtkWidget *chooser, GdkEvent *event, void *user_data)
- purple_signals_disconnect_by_handle(chooser);
-pidgin_account_chooser_changed_cb(GtkComboBox *widget, gpointer user_data)
+pidgin_account_chooser_changed_cb(GtkComboBox *widget, gpointer user_data) { g_object_notify_by_pspec(G_OBJECT(widget), properties[PROP_ACCOUNT]);
/******************************************************************************
*****************************************************************************/
+G_DEFINE_TYPE(PidginAccountChooser, pidgin_account_chooser, GTK_TYPE_COMBO_BOX) pidgin_account_chooser_get_property(GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -218,10 +62,7 @@
- g_value_set_object(value, account_chooser_get_selected(chooser));
- g_value_set_boolean(value, chooser->show_all);
+ g_value_set_object(value, pidgin_account_chooser_get_selected(chooser)); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -237,11 +78,8 @@
- account_chooser_select_by_data(GTK_WIDGET(chooser),
- g_value_get_object(value));
- chooser->show_all = g_value_get_boolean(value);
+ pidgin_account_chooser_set_selected(chooser, + g_value_get_object(value)); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -263,61 +101,30 @@
"account", "Account", "The account that is currently selected.",
PURPLE_TYPE_ACCOUNT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_SHOW_ALL] = g_param_spec_boolean(
- "show-all", "Show all",
- "Whether to show all accounts, or just online ones.", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(obj_class, PROP_LAST, properties);
gtk_widget_class_set_template_from_resource(
widget_class, "/im/pidgin/Pidgin/Accounts/chooser.ui");
- gtk_widget_class_bind_template_child(widget_class, PidginAccountChooser,
- gtk_widget_class_bind_template_callback(widget_class,
- account_menu_destroyed_cb);
-pidgin_account_chooser_init(PidginAccountChooser *chooser)
+pidgin_account_chooser_init(PidginAccountChooser *chooser) { gtk_widget_init_template(GTK_WIDGET(chooser));
- set_account_menu(chooser, NULL);
+ /* this callback emits the notify for the account property */ g_signal_connect(chooser, "changed",
G_CALLBACK(pidgin_account_chooser_changed_cb), NULL);
- /* Register the purple sign on/off event callbacks. */
- purple_connections_get_handle(), "signed-on", chooser,
- PURPLE_CALLBACK(account_menu_sign_on_off_cb), chooser);
- purple_connections_get_handle(), "signed-off", chooser,
- PURPLE_CALLBACK(account_menu_sign_on_off_cb), chooser);
- purple_accounts_get_handle(), "account-added", chooser,
- PURPLE_CALLBACK(account_menu_added_removed_cb), chooser);
- purple_accounts_get_handle(), "account-removed", chooser,
- PURPLE_CALLBACK(account_menu_added_removed_cb), chooser);
/******************************************************************************
*****************************************************************************/
-pidgin_account_chooser_new(PurpleAccount *default_account, gboolean show_all)
+pidgin_account_chooser_new(void) { PidginAccountChooser *chooser = NULL;
- chooser = g_object_new(PIDGIN_TYPE_ACCOUNT_CHOOSER, "account",
- default_account, "show-all", show_all, NULL);
+ chooser = g_object_new(PIDGIN_TYPE_ACCOUNT_CHOOSER, NULL); return GTK_WIDGET(chooser);
@@ -329,32 +136,53 @@
g_return_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser));
chooser->filter_func = filter_func;
- regenerate_account_menu(chooser);
-pidgin_account_chooser_get_selected(GtkWidget *chooser)
+pidgin_account_chooser_get_selected(PidginAccountChooser *chooser) { + gpointer account = NULL; g_return_val_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser), NULL);
- return (PurpleAccount *)account_chooser_get_selected(
- PIDGIN_ACCOUNT_CHOOSER(chooser));
+ if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(chooser), &iter)) { + GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(chooser)); + gtk_tree_model_get(model, &iter, + PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, &account, -1); -pidgin_account_chooser_set_selected(GtkWidget *chooser, PurpleAccount *account)
+pidgin_account_chooser_set_selected(PidginAccountChooser *chooser, + PurpleAccount *account) + GtkTreeModel *model = NULL; + PurpleAccount *acc = NULL; g_return_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser));
- account_chooser_select_by_data(chooser, account);
+ model = gtk_combo_box_get_model(GTK_COMBO_BOX(chooser)); + g_return_if_fail(GTK_IS_TREE_MODEL(model)); - /* NOTE: Property notification occurs in 'changed' signal callback. */
+ if(gtk_tree_model_get_iter_first(model, &iter)) { + gtk_tree_model_get(model, &iter, + PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, &acc, -1); + /* NOTE: Property notification occurs in 'changed' signal + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(chooser), &iter); + g_object_unref(G_OBJECT(acc)); + g_object_unref(G_OBJECT(acc)); + } while(gtk_tree_model_iter_next(model, &iter));
-pidgin_account_chooser_get_show_all(GtkWidget *chooser)
- g_return_val_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser), FALSE);
- return PIDGIN_ACCOUNT_CHOOSER(chooser)->show_all;
--- a/pidgin/pidginaccountchooser.h Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/pidginaccountchooser.h Tue Sep 15 21:54:10 2020 -0500
@@ -45,8 +45,6 @@
* pidgin_account_chooser_new:
- * @default_account: The account to select by default.
- * @show_all: Whether or not to show all accounts, or just active accounts.
* Creates a combo box filled with accounts.
@@ -54,8 +52,7 @@
-GtkWidget *pidgin_account_chooser_new(PurpleAccount *default_account,
+GtkWidget *pidgin_account_chooser_new(void); * pidgin_account_chooser_set_filter_func:
@@ -76,12 +73,12 @@
* Gets the currently selected account from an account combo box.
- * Returns: (transfer none): Returns the #PurpleAccount that is currently
+ * Returns: (transfer full): Returns the #PurpleAccount that is currently -PurpleAccount *pidgin_account_chooser_get_selected(GtkWidget *chooser);
+PurpleAccount *pidgin_account_chooser_get_selected(PidginAccountChooser *chooser); * pidgin_account_chooser_set_selected:
@@ -92,21 +89,9 @@
-void pidgin_account_chooser_set_selected(GtkWidget *chooser,
+void pidgin_account_chooser_set_selected(PidginAccountChooser *chooser,
- * pidgin_account_chooser_get_show_all:
- * @chooser: The chooser created by pidgin_account_chooser_new().
- * Returns whether to show all accounts.
- * Returns: Whether or not to show all accounts, or just active accounts.
-gboolean pidgin_account_chooser_get_show_all(GtkWidget *chooser);
#endif /* PIDGIN_ACCOUNT_CHOOSER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountfilterconnected.c Tue Sep 15 21:54:10 2020 -0500
@@ -0,0 +1,123 @@
+ * 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 + * 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 2 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 "pidgin/pidginaccountfilterconnected.h" +#include "pidgin/pidginaccountstore.h" +struct _PidginAccountFilterConnected { + GtkTreeModelFilter parent; +/****************************************************************************** + *****************************************************************************/ +pidgin_account_filter_connected_changed(PurpleConnection *connection, + PidginAccountFilterConnected *filter = NULL; + filter = PIDGIN_ACCOUNT_FILTER_CONNECTED(data); + gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter)); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +pidgin_account_filter_connected_func(GtkTreeModel *model, GtkTreeIter *iter, + PurpleAccount *account = NULL; + g_return_val_if_fail(GTK_IS_TREE_MODEL(model), FALSE); + g_return_val_if_fail(iter != NULL, FALSE); + gtk_tree_model_get(model, iter, PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, + if(!PURPLE_IS_ACCOUNT(account)) { + ret = purple_account_is_connected(account); + g_object_unref(G_OBJECT(account)); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_TYPE(PidginAccountFilterConnected, pidgin_account_filter_connected, + GTK_TYPE_TREE_MODEL_FILTER) +pidgin_account_filter_connected_init(PidginAccountFilterConnected *filter) { + gpointer connections_handle = NULL; + gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter), + pidgin_account_filter_connected_func, + /* we connect to the connections signals to force a refresh of the filter */ + connections_handle = purple_connections_get_handle(); + purple_signal_connect(connections_handle, "signed-on", filter, + G_CALLBACK(pidgin_account_filter_connected_changed), + purple_signal_connect(connections_handle, "signed-off", filter, + G_CALLBACK(pidgin_account_filter_connected_changed), +pidgin_account_filter_connected_finalize(GObject *obj) { + purple_signals_disconnect_by_handle(obj); + G_OBJECT_CLASS(pidgin_account_filter_connected_parent_class)->finalize(obj); +pidgin_account_filter_connected_class_init(PidginAccountFilterConnectedClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->finalize = pidgin_account_filter_connected_finalize; +/****************************************************************************** + *****************************************************************************/ +pidgin_account_filter_connected_new(GtkTreeModel *child_model, + g_return_val_if_fail(GTK_IS_TREE_MODEL(child_model), NULL); + return g_object_new(PIDGIN_TYPE_ACCOUNT_FILTER_CONNECTED, "child-model", + child_model, "virtual-root", root, NULL); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountfilterconnected.h Tue Sep 15 21:54:10 2020 -0500
@@ -0,0 +1,60 @@
+ * 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 + * 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 2 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 PIDGIN_ACCOUNT_FILTER_CONNECTED_H +#define PIDGIN_ACCOUNT_FILTER_CONNECTED_H + * SECTION:pidginaccountfilterconnected + * @section_id: pidgin-account-filter-connected + * @short_description: A GtkTreeModelFilter that displays connected accounts. + * @title: Account Connected Filter + * #PidginAccountFilterConnected is a #GtkTreeModelFilter that will only show + * accounts that are connected. It's intended to be used with +#define PIDGIN_TYPE_ACCOUNT_FILTER_CONNECTED pidgin_account_filter_connected_get_type() +G_DECLARE_FINAL_TYPE(PidginAccountFilterConnected, + pidgin_account_filter_connected, PIDGIN, + ACCOUNT_FILTER_CONNECTED, GtkTreeModelFilter) + * pidgin_account_filter_connected_new: + * Creates a new #PidginAccountFilterConnected that should be used to filter + * only online accounts in a #PidginAccountStore. + * Returns: (transfer full): The new #PidginAccountFilterConnected instance. +GtkTreeModel *pidgin_account_filter_connected_new(GtkTreeModel *child_model, GtkTreePath *root); +#endif /* PIDGIN_ACCOUNT_FILTER_CONNECTED_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountfilterprotocol.c Tue Sep 15 21:54:10 2020 -0500
@@ -0,0 +1,183 @@
+ * 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 + * 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 2 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 "pidgin/pidginaccountfilterprotocol.h" +#include "pidgin/pidginaccountstore.h" +struct _PidginAccountFilterProtocol { + GtkTreeModelFilter parent; +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; +/****************************************************************************** + *****************************************************************************/ +pidgin_account_filter_protocol_set_protocol_id(PidginAccountFilterProtocol *filter, + const gchar *protocol_id) + g_free(filter->protocol_id); + filter->protocol_id = g_strdup(protocol_id); +pidgin_account_filter_protocol_func(GtkTreeModel *model, GtkTreeIter *iter, + PidginAccountFilterProtocol *filter = NULL; + PurpleAccount *account = NULL; + g_return_val_if_fail(PIDGIN_IS_ACCOUNT_FILTER_PROTOCOL(data), FALSE); + g_return_val_if_fail(GTK_IS_TREE_MODEL(model), FALSE); + g_return_val_if_fail(iter != NULL, FALSE); + filter = PIDGIN_ACCOUNT_FILTER_PROTOCOL(data); + gtk_tree_model_get(model, iter, PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, + if(!PURPLE_IS_ACCOUNT(account)) { + ret = purple_strequal(purple_account_get_protocol_id(account), + g_object_unref(G_OBJECT(account)); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_TYPE(PidginAccountFilterProtocol, pidgin_account_filter_protocol, + GTK_TYPE_TREE_MODEL_FILTER) +pidgin_account_filter_protocol_get_property(GObject *obj, guint param_id, + GValue *value, GParamSpec *pspec) + PidginAccountFilterProtocol *filter = PIDGIN_ACCOUNT_FILTER_PROTOCOL(obj); + value, pidgin_account_filter_protocol_get_protocol_id(filter)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +pidgin_account_filter_protocol_set_property(GObject *obj, guint param_id, + PidginAccountFilterProtocol *filter = PIDGIN_ACCOUNT_FILTER_PROTOCOL(obj); + pidgin_account_filter_protocol_set_protocol_id( + filter, g_value_get_string(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +pidgin_account_filter_protocol_finalize(GObject *obj) { + PidginAccountFilterProtocol *filter = PIDGIN_ACCOUNT_FILTER_PROTOCOL(obj); + g_free(filter->protocol_id); + G_OBJECT_CLASS(pidgin_account_filter_protocol_parent_class)->finalize(obj); +pidgin_account_filter_protocol_init(PidginAccountFilterProtocol *filter) { + gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter), + pidgin_account_filter_protocol_func, +pidgin_account_filter_protocol_class_init(PidginAccountFilterProtocolClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = pidgin_account_filter_protocol_get_property; + obj_class->set_property = pidgin_account_filter_protocol_set_property; + obj_class->finalize = pidgin_account_filter_protocol_finalize; + * PidginAccountFilterProtocol::protocol-id: + * The protocol id that will be filtered for. + properties[PROP_PROTOCOL_ID] = g_param_spec_string( + "protocol-id", "protocol-id", "The id of the protocol to filter", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +/****************************************************************************** + *****************************************************************************/ +pidgin_account_filter_protocol_new(const gchar *protocol_id, + GtkTreeModel *child_model, + g_return_val_if_fail(GTK_IS_TREE_MODEL(child_model), NULL); + PIDGIN_TYPE_ACCOUNT_FILTER_PROTOCOL, + "protocol-id", protocol_id, + "child-model", child_model, +pidgin_account_filter_protocol_get_protocol_id(PidginAccountFilterProtocol *filter) { + g_return_val_if_fail(PIDGIN_IS_ACCOUNT_FILTER_PROTOCOL(filter), NULL); + return filter->protocol_id; --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountfilterprotocol.h Tue Sep 15 21:54:10 2020 -0500
@@ -0,0 +1,75 @@
+ * 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 + * 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 2 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 PIDGIN_ACCOUNT_FILTER_PROTOCOL_H +#define PIDGIN_ACCOUNT_FILTER_PROTOCOL_H + * SECTION:pidginaccountfilterprotocol + * @section_id: pidgin-account-filter-protocol + * @short_description: A GtkTreeModelFilter that displays the given protocol. + * @title: Account Protocol Filter + * #PidginAccountFilterProtocol is a #GtkTreeModelFilter that will only show + * accounts for the given protocol. It's intended to be used with +#define PIDGIN_TYPE_ACCOUNT_FILTER_PROTOCOL pidgin_account_filter_protocol_get_type() +G_DECLARE_FINAL_TYPE(PidginAccountFilterProtocol, + pidgin_account_filter_protocol, PIDGIN, + ACCOUNT_FILTER_PROTOCOL, GtkTreeModelFilter) + * pidgin_account_filter_protocol_new: + * @protocol_id: The ID of the protocol to filter for. + * @child_model: The #GtkTreeModel that should be filtered. + * @root: The root path that should be filtered. + * Creates a new #PidginAccountFilterProtocol that should be used to filter + * only online accounts in a #PidginAccountStore. + * See gtk_tree_model_filter_new() for more information. + * Returns: (transfer full): The new #PidginAccountFilterProtocol instance. +GtkTreeModel *pidgin_account_filter_protocol_new(const gchar *protocol_id, GtkTreeModel *child_model, GtkTreePath *root); + * pidgin_account_filter_protocol_get_protocol_id: + * @filter: The #PidginAccountFilterProtocol instance. + * Gets the ID of the protocol that @filter is filtering for. + * Returns: The Protocol ID that @filter is filtering for. +const gchar *pidgin_account_filter_protocol_get_protocol_id(PidginAccountFilterProtocol *filter); +#endif /* PIDGIN_ACCOUNT_FILTER_PROTOCOL_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountstore.c Tue Sep 15 21:54:10 2020 -0500
@@ -0,0 +1,191 @@
+ * 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 + * 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 2 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-lib.h> +#include "pidgin/pidginaccountstore.h" +struct _PidginAccountStore { +/****************************************************************************** + *****************************************************************************/ +pidgin_account_store_add_account(PidginAccountStore *store, + PurpleAccount *account) + GdkPixbuf *pixbuf = NULL; + const gchar *alias = NULL; + pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL); + alias = purple_account_get_private_alias(account); + markup = g_strdup_printf(_("%s (%s) (%s)"), + purple_account_get_username(account), + purple_account_get_protocol_name(account)); + markup = g_strdup_printf(_("%s (%s)"), + purple_account_get_username(account), + purple_account_get_protocol_name(account)); + gtk_list_store_append(GTK_LIST_STORE(store), &iter); + PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, account, + PIDGIN_ACCOUNT_STORE_COLUMN_MARKUP, markup, + PIDGIN_ACCOUNT_STORE_COLUMN_ICON, pixbuf, + g_clear_object(&pixbuf); +pidgin_account_store_add_account_helper(gpointer data, gpointer user_data) { + if(PURPLE_IS_ACCOUNT(data)) { + pidgin_account_store_add_account(PIDGIN_ACCOUNT_STORE(user_data), +pidgin_account_store_add_accounts(PidginAccountStore *store) { + g_list_foreach(purple_accounts_get_all(), + pidgin_account_store_add_account_helper, store); +pidgin_account_store_remove_account(PidginAccountStore *store, + PurpleAccount *account) + if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter) == FALSE) { + purple_debug_warning("account-store", + "account %s was removed but not in the store", + purple_account_get_username(account)); + /* walk through the store and look for the account to remove */ + PurpleAccount *found = NULL; + PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, &found, + g_object_unref(G_OBJECT(found)); + gtk_list_store_remove(GTK_LIST_STORE(store), &iter); + } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); +/****************************************************************************** + *****************************************************************************/ +pidgin_account_store_account_added_cb(PurpleAccount *account, + pidgin_account_store_add_account(PIDGIN_ACCOUNT_STORE(data), account); +pidgin_account_store_account_removed_cb(PurpleAccount *account, + pidgin_account_store_remove_account(PIDGIN_ACCOUNT_STORE(data), account); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_TYPE(PidginAccountStore, pidgin_account_store, GTK_TYPE_LIST_STORE) +pidgin_account_store_init(PidginAccountStore *store) { + gpointer accounts_handle = NULL; + GType types[PIDGIN_ACCOUNT_STORE_N_COLUMNS] = { + gtk_list_store_set_column_types( + PIDGIN_ACCOUNT_STORE_N_COLUMNS, + /* add the known accounts */ + pidgin_account_store_add_accounts(store); + /* add the signal handlers to dynamically add/remove accounts */ + accounts_handle = purple_accounts_get_handle(); + purple_signal_connect(accounts_handle, "account-added", store, + G_CALLBACK(pidgin_account_store_account_added_cb), + purple_signal_connect(accounts_handle, "account-removed", store, + G_CALLBACK(pidgin_account_store_account_removed_cb), +pidgin_account_store_finalize(GObject *obj) { + purple_signals_disconnect_by_handle(obj); + G_OBJECT_CLASS(pidgin_account_store_parent_class)->finalize(obj); +pidgin_account_store_class_init(PidginAccountStoreClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->finalize = pidgin_account_store_finalize; +/****************************************************************************** + *****************************************************************************/ +pidgin_account_store_new(void) { + return GTK_LIST_STORE(g_object_new(PIDGIN_TYPE_ACCOUNT_STORE, NULL)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginaccountstore.h Tue Sep 15 21:54:10 2020 -0500
@@ -0,0 +1,83 @@
+ * 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 + * 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 2 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 PIDGIN_ACCOUNT_STORE_H +#define PIDGIN_ACCOUNT_STORE_H + * SECTION:pidginaccountstore + * @section_id: pidgin-account-store + * @short_description: A GtkListStore that keeps track of accounts + * @title: Account Store + * #PidginAccountStore is a #GtkListStore that automatically keeps track of + * what accounts are currently available in libpurple. It's intended to be + * used any time that you need to present an account selection to the user. + PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT, + PIDGIN_ACCOUNT_STORE_COLUMN_MARKUP, + PIDGIN_ACCOUNT_STORE_COLUMN_ICON, + PIDGIN_ACCOUNT_STORE_N_COLUMNS, +} PidginAccountStoreColumn; +#define PIDGIN_TYPE_ACCOUNT_STORE pidgin_account_store_get_type() +G_DECLARE_FINAL_TYPE(PidginAccountStore, pidgin_account_store, PIDGIN, + ACCOUNT_STORE, GtkListStore) + * pidgin_account_store_new: + * Creates a new #PidginAccountStore that can be used anywhere a #GtkListStore + * Returns: (transfer full): The new #PidginAccountStore instance. +GtkListStore *pidgin_account_store_new(void); + * pidgin_account_store_filter_connected: + * @model: The #GtkTreeModel that's being filtered. + * @iter: The #GtkTreeIter to check. + * @data: Userdata passed to gtk_tree_model_filter_set_visible_func(). + * pidgin_account_store_filter_connected() is a #GtkTreeModelFilterVisibleFunc + * that can be set on a #GtkTreeModelFilter via + * gtk_tree_model_filter_set_visible_func(), to only show accounts that are + * Returns: %TRUE if the account will be displayed, %FALSE otherwise. +gboolean pidgin_account_store_filter_connected(GtkTreeModel *model, GtkTreeIter *iter, gpointer data); +#endif /* PIDGIN_ACCOUNT_STORE_H */ --- a/pidgin/plugins/contact_priority.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/plugins/contact_priority.c Tue Sep 15 21:54:10 2020 -0500
@@ -29,17 +29,19 @@
#define CONTACT_PRIORITY_PLUGIN_ID "gtk-contact-priority"
-select_account(GtkWidget *chooser, gpointer data)
+select_account(GtkWidget *widget, gpointer data) + PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(widget); PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(data),
(gdouble)purple_account_get_int(account, "score", 0));
-account_update(GtkWidget *widget, GtkWidget *chooser)
+account_update(GtkWidget *widget, gpointer data) PurpleAccount *account = NULL;
+ PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(data); account = pidgin_account_chooser_get_selected(chooser);
purple_account_set_int(account, "score", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)));
@@ -79,6 +81,7 @@
GtkWidget *chooser = NULL;
GtkAdjustment *adj = NULL;
+ GtkListStore *store = NULL; PurpleAccount *account = NULL;
@@ -145,12 +148,15 @@
adj = GTK_ADJUSTMENT(gtk_adjustment_new(0, -500, 500, 1, 1, 1));
spin = gtk_spin_button_new(adj, 1, 0);
- chooser = pidgin_account_chooser_new(NULL, TRUE);
+ store = pidgin_account_store_new(); + chooser = pidgin_account_chooser_new(); + gtk_combo_box_set_model(GTK_COMBO_BOX(chooser), GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); gtk_box_pack_start(GTK_BOX(hbox), chooser, FALSE, FALSE, 0);
g_signal_connect(chooser, "changed", G_CALLBACK(select_account), spin);
/* this is where we set up the spin button we made above */
- account = pidgin_account_chooser_get_selected(chooser);
+ account = pidgin_account_chooser_get_selected(PIDGIN_ACCOUNT_CHOOSER(chooser)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin),
(gdouble)purple_account_get_int(account, "score", 0));
gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(spin), GTK_ADJUSTMENT(adj));
--- a/pidgin/plugins/disco/gtkdisco.c Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/plugins/disco/gtkdisco.c Tue Sep 15 21:54:10 2020 -0500
@@ -145,7 +145,7 @@
dialog_select_account_cb(GtkWidget *chooser, PidginDiscoDialog *dialog)
- PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
+ 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);
@@ -414,11 +414,6 @@
gtk_widget_destroy(GTK_WIDGET(dialog));
-static gboolean account_filter_func(PurpleAccount *account)
- return purple_strequal(purple_account_get_protocol_id(account), XMPP_PROTOCOL_ID);
disco_paint_tooltip(GtkWidget *tipwindow, cairo_t *cr, gpointer data)
@@ -520,6 +515,8 @@
PidginDiscoList *list = dialog->discolist;
if (list && list->pc == pc) {
+ PurpleAccount *account = NULL; pidgin_disco_list_set_in_progress(list, FALSE);
@@ -528,10 +525,12 @@
pidgin_disco_list_unref(list);
dialog->discolist = NULL;
+ account = pidgin_account_chooser_get_selected( + PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser)); gtk_widget_set_sensitive(
- pidgin_account_chooser_get_selected(
- dialog->account_chooser) != NULL);
gtk_widget_set_sensitive(dialog->register_button, FALSE);
gtk_widget_set_sensitive(dialog->add_button, FALSE);
@@ -609,11 +608,8 @@
gtk_widget_init_template(GTK_WIDGET(dialog));
/* accounts dropdown list */
- pidgin_account_chooser_set_filter_func(
- PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser),
- pidgin_account_chooser_get_selected(dialog->account_chooser);
+ dialog->account = pidgin_account_chooser_get_selected( + PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser)); gtk_widget_set_sensitive(dialog->browse_button, dialog->account != NULL);
--- a/pidgin/plugins/disco/resources/disco.ui Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/plugins/disco/resources/disco.ui Tue Sep 15 21:54:10 2020 -0500
@@ -26,6 +26,14 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+ <object class="PidginAccountStore" id="accounts"/> + <object class="PidginAccountFilterConnected" id="accounts_connected"> + <property name="child_model">accounts</property> + <object class="PidginAccountFilterProtocol" id="xmpp_accounts"> + <property name="child_model">accounts_connected</property> + <property name="protocol_id">prpl-jabber</property> <object class="GtkTreeStore" id="model">
<!-- column-name pixbuf -->
@@ -168,6 +176,8 @@
<object class="PidginAccountChooser" id="account_chooser">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="model">xmpp_accounts</property> + <property name="active">0</property> <signal name="changed" handler="dialog_select_account_cb" object="PidginDiscoDialog" swapped="no"/>
--- a/pidgin/resources/Accounts/chooser.ui Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/resources/Accounts/chooser.ui Tue Sep 15 21:54:10 2020 -0500
@@ -25,25 +25,13 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <object class="GtkListStore" id="model">
- <!-- column-name icon -->
- <column type="GdkPixbuf"/>
- <!-- column-name name -->
- <column type="gchararray"/>
- <!-- column-name account -->
- <column type="PurpleAccount"/>
<template class="PidginAccountChooser" parent="GtkComboBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="model">model</property>
- <signal name="destroy" handler="account_menu_destroyed_cb" swapped="no"/>
<object class="GtkCellRendererPixbuf"/>
- <attribute name="pixbuf">0</attribute>
+ <attribute name="pixbuf">2</attribute> --- a/pidgin/resources/Privacy/dialog.ui Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/resources/Privacy/dialog.ui Tue Sep 15 21:54:10 2020 -0500
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1
+<!-- Generated with glade 3.22.1 Pidgin - Internet Messenger
Copyright (C) Pidgin Developers <devel@pidgin.im>
@@ -26,6 +26,10 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+ <object class="PidginAccountStore" id="account_store"/> + <object class="PidginAccountFilterConnected" id="connected_account_store"> + <property name="child_model">account_store</property> <object class="GtkListStore" id="allow_store">
<!-- column-name column1 -->
@@ -169,6 +173,8 @@
<object class="PidginAccountChooser" id="account_chooser">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="model">connected_account_store</property> + <property name="active">0</property> <signal name="changed" handler="select_account_cb" object="PidginPrivacyDialog" swapped="no"/>
<relation type="labelled-by" target="label1"/>
--- a/pidgin/resources/Roomlist/roomlist.ui Tue Sep 15 20:26:57 2020 -0500
+++ b/pidgin/resources/Roomlist/roomlist.ui Tue Sep 15 21:54:10 2020 -0500
@@ -26,6 +26,7 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+ <object class="PidginAccountStore" id="accounts"/> <object class="GtkImage" id="add_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -179,6 +180,8 @@
<object class="PidginAccountChooser" id="account_widget">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="model">accounts</property> + <property name="active">0</property> <signal name="changed" handler="dialog_select_account_cb" object="PidginRoomlistDialog" swapped="no"/>
<relation type="labelled-by" target="label1"/>
--- a/po/POTFILES.in Tue Sep 15 20:26:57 2020 -0500
+++ b/po/POTFILES.in Tue Sep 15 21:54:10 2020 -0500
@@ -344,6 +344,9 @@
+pidgin/pidginaccountfilterconnected.c +pidgin/pidginaccountfilterprotocol.c +pidgin/pidginaccountstore.c pidgin/pidginattachment.c
pidgin/pidginclosebutton.c
pidgin/pidgincontactcompletion.c