Move PidginAccountChooser to GtkDropDown
The chooser connects to the default account manager automatically.
Additionally, re-parent the `GtkTreeModelFilter` subclasses to `GtkFilter`, and use them on the `filter` property.
This also means the previous `filter_func` that was moved to `GtkFilter` in /r/1995 are now used again.
Testing Done:
Opened most of the affected dialogs. Disabled XMPP account and saw that it was removed from all connected-only filtered choosers. Re-enabled account and it was back in the choosers.
Confirmed that only XMPP, and not Demo accounts appeared in the two XMPP-specific plugins.
Request API is still only compile-tested.
Reviewed at https://reviews.imfreedom.org/r/1992/
--- a/pidgin/gtkblist.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/gtkblist.c Sun Oct 30 03:29:33 2022 -0500
@@ -37,7 +37,6 @@
#include "pidgin/pidginaccountchooser.h"
#include "pidgin/pidginaccountfilterconnected.h"
-#include "pidgin/pidginaccountstore.h"
#include "pidgin/pidginactiongroup.h"
#include "pidgin/pidginaddbuddydialog.h"
#include "pidgin/pidginaddchatdialog.h"
@@ -995,8 +994,8 @@
- GtkTreeModel *model = NULL, *filter = NULL;
- GtkCustomFilter *custom_filter = NULL;
+ GtkEveryFilter *every = NULL; + GtkFilter *filter = NULL; PidginBuddyList *gtkblist;
@@ -1034,25 +1033,22 @@
data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
- 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));
+ every = gtk_every_filter_new(); + filter = pidgin_account_filter_connected_new(); + gtk_multi_filter_append(GTK_MULTI_FILTER(every), filter); + filter = GTK_FILTER(gtk_custom_filter_new(filter_func, NULL, NULL)); + gtk_multi_filter_append(GTK_MULTI_FILTER(every), filter); + pidgin_account_chooser_set_filter( + PIDGIN_ACCOUNT_CHOOSER(data->account_menu), 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);
- custom_filter = gtk_custom_filter_new(filter_func, NULL, NULL);
- pidgin_account_chooser_set_filter(
- PIDGIN_ACCOUNT_CHOOSER(data->account_menu),
- GTK_FILTER(custom_filter));
- g_object_unref(custom_filter);
pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("A_ccount"), data->sg, data->account_menu, TRUE, NULL);
g_signal_connect(data->account_menu, "notify::account",
G_CALLBACK(callback_func), data);
@@ -1162,7 +1158,9 @@
PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
g_return_if_fail(data != NULL);
- g_return_if_fail(account != NULL);
if (purple_strequal(purple_account_get_protocol_id(data->rq_data.account),
purple_account_get_protocol_id(account)))
--- a/pidgin/gtkprivacy.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/gtkprivacy.c Sun Oct 30 03:29:33 2022 -0500
@@ -28,7 +28,6 @@
#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,
--- a/pidgin/gtkrequest.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/gtkrequest.c Sun Oct 30 03:29:33 2022 -0500
@@ -30,7 +30,6 @@
#include "pidginaccountchooser.h"
#include "pidginaccountfilterconnected.h"
-#include "pidginaccountstore.h"
#include "pidgindialog.h"
@@ -1401,40 +1400,32 @@
- GtkCustomFilter *custom_filter = NULL;
+ GtkFilter *filter = NULL; 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));
+ filter = GTK_FILTER(gtk_custom_filter_new( + field_custom_account_filter_cb, + purple_request_field_account_get_filter(field), + if(!purple_request_field_account_get_show_all(field)) { + GtkEveryFilter *every = NULL; + every = gtk_every_filter_new(); + gtk_multi_filter_append(GTK_MULTI_FILTER(every), filter); + filter = pidgin_account_filter_connected_new(); + gtk_multi_filter_append(GTK_MULTI_FILTER(every), filter); + filter = GTK_FILTER(every); pidgin_account_chooser_set_selected(PIDGIN_ACCOUNT_CHOOSER(widget),
- custom_filter = gtk_custom_filter_new(
- field_custom_account_filter_cb,
- purple_request_field_account_get_filter(field),
- pidgin_account_chooser_set_filter(
- PIDGIN_ACCOUNT_CHOOSER(widget),
- GTK_FILTER(custom_filter));
- g_object_unref(custom_filter);
+ pidgin_account_chooser_set_filter(PIDGIN_ACCOUNT_CHOOSER(widget), filter); + g_object_unref(filter); g_signal_connect(widget, "notify::account", G_CALLBACK(field_account_cb),
--- a/pidgin/meson.build Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/meson.build Sun Oct 30 03:29:33 2022 -0500
@@ -28,7 +28,6 @@
'pidginaccountmanager.c',
'pidginaccountsdisabledmenu.c',
'pidginaccountsenabledmenu.c',
- 'pidginaccountstore.c',
'pidginaddbuddydialog.c',
@@ -97,7 +96,6 @@
'pidginaccountmanager.h',
'pidginaccountsdisabledmenu.h',
'pidginaccountsenabledmenu.h',
- 'pidginaccountstore.h',
'pidginaddbuddydialog.h',
@@ -149,7 +147,6 @@
- 'pidginaccountstore.h',
--- a/pidgin/pidginaccountchooser.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaccountchooser.c Sun Oct 30 03:29:33 2022 -0500
@@ -20,16 +20,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+#include <glib/gi18n-lib.h> #include "pidginaccountchooser.h"
-#include "pidginaccountstore.h"
+struct _PidginAccountChooser { -struct _PidginAccountChooser {
+ GtkFilterListModel *filter; @@ -45,15 +46,60 @@
/******************************************************************************
*****************************************************************************/
+pidgin_account_chooser_icon_name_cb(G_GNUC_UNUSED GObject *self, + PurpleAccount *account, + G_GNUC_UNUSED gpointer data) + const char *icon_name = NULL; + if(PURPLE_IS_ACCOUNT(account)) { + PurpleProtocol *protocol = purple_account_get_protocol(account); + icon_name = purple_protocol_get_icon_name(protocol); + return g_strdup(icon_name); +pidgin_account_chooser_label_cb(G_GNUC_UNUSED GObject *self, + PurpleAccount *account, + G_GNUC_UNUSED gpointer data) + const gchar *alias = NULL; + if(!PURPLE_IS_ACCOUNT(account)) { + 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)); -pidgin_account_chooser_changed_cb(GtkComboBox *widget, gpointer user_data) {
- g_object_notify_by_pspec(G_OBJECT(widget), properties[PROP_ACCOUNT]);
+pidgin_account_chooser_changed_cb(G_GNUC_UNUSED GObject *obj, + G_GNUC_UNUSED GParamSpec *pspec, + g_object_notify_by_pspec(G_OBJECT(data), properties[PROP_ACCOUNT]); /******************************************************************************
*****************************************************************************/
-G_DEFINE_TYPE(PidginAccountChooser, pidgin_account_chooser, GTK_TYPE_COMBO_BOX)
+G_DEFINE_TYPE(PidginAccountChooser, pidgin_account_chooser, ADW_TYPE_BIN) pidgin_account_chooser_get_property(GObject *object, guint prop_id,
@@ -121,15 +167,28 @@
gtk_widget_class_set_template_from_resource(
widget_class, "/im/pidgin/Pidgin3/Accounts/chooser.ui");
+ gtk_widget_class_bind_template_child(widget_class, PidginAccountChooser, + gtk_widget_class_bind_template_child(widget_class, PidginAccountChooser, + gtk_widget_class_bind_template_callback(widget_class, + pidgin_account_chooser_icon_name_cb); + gtk_widget_class_bind_template_callback(widget_class, + pidgin_account_chooser_label_cb); + gtk_widget_class_bind_template_callback(widget_class, + pidgin_account_chooser_changed_cb); pidgin_account_chooser_init(PidginAccountChooser *chooser) {
+ GListModel *model = NULL; gtk_widget_init_template(GTK_WIDGET(chooser));
- /* this callback emits the notify for the account property */
- g_signal_connect(chooser, "changed",
- G_CALLBACK(pidgin_account_chooser_changed_cb), NULL);
+ model = purple_account_manager_get_default_as_model(); + gtk_filter_list_model_set_model(chooser->filter, model); /******************************************************************************
@@ -148,7 +207,7 @@
pidgin_account_chooser_get_filter(PidginAccountChooser *chooser) {
g_return_val_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser), NULL);
- return chooser->filter;
+ return gtk_filter_list_model_get_filter(chooser->filter); @@ -157,56 +216,44 @@
g_return_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser));
- if(g_set_object(&chooser->filter, filter)) {
- g_object_notify_by_pspec(G_OBJECT(chooser), properties[PROP_FILTER]);
+ gtk_filter_list_model_set_filter(chooser->filter, filter); + g_object_notify_by_pspec(G_OBJECT(chooser), properties[PROP_FILTER]); pidgin_account_chooser_get_selected(PidginAccountChooser *chooser) {
- gpointer account = NULL;
g_return_val_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser), NULL);
- 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);
+ return gtk_drop_down_get_selected_item(chooser->chooser); pidgin_account_chooser_set_selected(PidginAccountChooser *chooser,
- GtkTreeModel *model = NULL;
- PurpleAccount *acc = NULL;
+ GListModel *model = NULL; g_return_if_fail(PIDGIN_IS_ACCOUNT_CHOOSER(chooser));
- model = gtk_combo_box_get_model(GTK_COMBO_BOX(chooser));
- g_return_if_fail(GTK_IS_TREE_MODEL(model));
+ model = gtk_drop_down_get_model(chooser->chooser); + g_return_if_fail(G_IS_LIST_MODEL(model)); + n_items = g_list_model_get_n_items(model); + for(guint position = 0; position < n_items; position++) { + PurpleAccount *acc = g_list_model_get_item(model, position); - 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);
+ /* NOTE: Property notification occurs in 'changed' signal + gtk_drop_down_set_selected(chooser->chooser, position); - g_object_unref(G_OBJECT(acc));
- g_object_unref(G_OBJECT(acc));
- } while(gtk_tree_model_iter_next(model, &iter));
--- a/pidgin/pidginaccountchooser.h Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaccountchooser.h Sun Oct 30 03:29:33 2022 -0500
@@ -27,6 +27,7 @@
#define PIDGIN_ACCOUNT_CHOOSER_H
@@ -35,7 +36,7 @@
#define PIDGIN_TYPE_ACCOUNT_CHOOSER (pidgin_account_chooser_get_type())
G_DECLARE_FINAL_TYPE(PidginAccountChooser, pidgin_account_chooser, PIDGIN,
- ACCOUNT_CHOOSER, GtkComboBox)
+ ACCOUNT_CHOOSER, AdwBin) * pidgin_account_chooser_new:
--- a/pidgin/pidginaccountfilterconnected.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaccountfilterconnected.c Sun Oct 30 03:29:33 2022 -0500
@@ -22,12 +22,10 @@
#include "pidgin/pidginaccountfilterconnected.h"
-#include "pidgin/pidginaccountstore.h"
struct _PidginAccountFilterConnected {
- GtkTreeModelFilter parent;
/******************************************************************************
@@ -38,36 +36,35 @@
PidginAccountFilterConnected *filter = NULL;
+ PurpleConnectionState state; filter = PIDGIN_ACCOUNT_FILTER_CONNECTED(data);
- gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter));
+ state = purple_connection_get_state(connection); + gtk_filter_changed(GTK_FILTER(filter), + (state == PURPLE_CONNECTION_STATE_CONNECTED) ? + GTK_FILTER_CHANGE_LESS_STRICT : + GTK_FILTER_CHANGE_MORE_STRICT); /******************************************************************************
- * GObject Implementation
+ * GtkFilter Implementation *****************************************************************************/
+pidgin_account_filter_connected_get_strictness(G_GNUC_UNUSED GtkFilter *self) { + return GTK_FILTER_MATCH_SOME; -pidgin_account_filter_connected_func(GtkTreeModel *model, GtkTreeIter *iter,
+pidgin_account_filter_connected_match(G_GNUC_UNUSED GtkFilter *self, - 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)) {
+ if(PURPLE_IS_ACCOUNT(item)) { + ret = purple_account_is_connected(PURPLE_ACCOUNT(item)); - ret = purple_account_is_connected(account);
- g_object_unref(G_OBJECT(account));
@@ -75,16 +72,12 @@
*****************************************************************************/
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,
@@ -105,19 +98,19 @@
pidgin_account_filter_connected_class_init(PidginAccountFilterConnectedClass *klass) {
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GtkFilterClass *filter_class = GTK_FILTER_CLASS(klass); obj_class->finalize = pidgin_account_filter_connected_finalize;
+ filter_class->get_strictness = pidgin_account_filter_connected_get_strictness; + filter_class->match = pidgin_account_filter_connected_match; /******************************************************************************
*****************************************************************************/
-pidgin_account_filter_connected_new(GtkTreeModel *child_model,
+pidgin_account_filter_connected_new(void) - 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);
+ return g_object_new(PIDGIN_TYPE_ACCOUNT_FILTER_CONNECTED, NULL); --- a/pidgin/pidginaccountfilterconnected.h Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaccountfilterconnected.h Sun Oct 30 03:29:33 2022 -0500
@@ -34,9 +34,10 @@
* PidginAccountFilterConnected:
- * #PidginAccountFilterConnected is a #GtkTreeModelFilter that will only show
- * accounts that are connected. It's intended to be used with
+ * #PidginAccountFilterConnected is a [class@Gtk.Filter] that will only show + * accounts that are connected. It's intended to be used with + * [class@Pidgin.AccountChooser] or a [iface@Gio.ListModel] that contains + * [class@Purple.Account]. @@ -44,21 +45,19 @@
#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)
+ ACCOUNT_FILTER_CONNECTED, GtkFilter) * pidgin_account_filter_connected_new:
- * @child_model: The #GtkTreeModel instance to filter.
- * @root: The #GtkTreePath to start at or %NULL.
* Creates a new #PidginAccountFilterConnected that should be used to filter
- * only online accounts in a #PidginAccountStore.
+ * only online accounts. * Returns: (transfer full): The new #PidginAccountFilterConnected instance.
-GtkTreeModel *pidgin_account_filter_connected_new(GtkTreeModel *child_model, GtkTreePath *root);
+GtkFilter *pidgin_account_filter_connected_new(void); --- a/pidgin/pidginaccountfilterprotocol.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaccountfilterprotocol.c Sun Oct 30 03:29:33 2022 -0500
@@ -22,12 +22,10 @@
#include "pidgin/pidginaccountfilterprotocol.h"
-#include "pidgin/pidginaccountstore.h"
struct _PidginAccountFilterProtocol {
- GtkTreeModelFilter parent;
@@ -48,34 +46,36 @@
g_free(filter->protocol_id);
filter->protocol_id = g_strdup(protocol_id);
+ gtk_filter_changed(GTK_FILTER(filter), GTK_FILTER_CHANGE_DIFFERENT); +/****************************************************************************** + * GtkFilter Implementation + *****************************************************************************/ +pidgin_account_filter_protocol_get_strictness(G_GNUC_UNUSED GtkFilter *self) { + return GTK_FILTER_MATCH_SOME; -pidgin_account_filter_protocol_func(GtkTreeModel *model, GtkTreeIter *iter,
+pidgin_account_filter_protocol_match(G_GNUC_UNUSED GtkFilter *self, - 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);
+ g_return_val_if_fail(PIDGIN_IS_ACCOUNT_FILTER_PROTOCOL(self), FALSE); - filter = PIDGIN_ACCOUNT_FILTER_PROTOCOL(data);
- gtk_tree_model_get(model, iter, PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT,
+ if(PURPLE_IS_ACCOUNT(item)) { + PidginAccountFilterProtocol *filter = NULL; + PurpleAccount *account = NULL; - if(!PURPLE_IS_ACCOUNT(account)) {
+ filter = PIDGIN_ACCOUNT_FILTER_PROTOCOL(self); + account = PURPLE_ACCOUNT(item); + ret = purple_strequal(purple_account_get_protocol_id(account), - ret = purple_strequal(purple_account_get_protocol_id(account),
- g_object_unref(G_OBJECT(account));
@@ -83,7 +83,7 @@
*****************************************************************************/
G_DEFINE_TYPE(PidginAccountFilterProtocol, pidgin_account_filter_protocol,
- GTK_TYPE_TREE_MODEL_FILTER)
pidgin_account_filter_protocol_get_property(GObject *obj, guint param_id,
@@ -130,20 +130,22 @@
-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_init(G_GNUC_UNUSED PidginAccountFilterProtocol *filter) pidgin_account_filter_protocol_class_init(PidginAccountFilterProtocolClass *klass) {
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GtkFilterClass *filter_class = GTK_FILTER_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;
+ filter_class->get_strictness = pidgin_account_filter_protocol_get_strictness; + filter_class->match = pidgin_account_filter_protocol_match; * PidginAccountFilterProtocol:protocol-id:
@@ -160,18 +162,11 @@
/******************************************************************************
*****************************************************************************/
-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_account_filter_protocol_new(const gchar *protocol_id) { PIDGIN_TYPE_ACCOUNT_FILTER_PROTOCOL,
"protocol-id", protocol_id,
- "child-model", child_model,
--- a/pidgin/pidginaccountfilterprotocol.h Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaccountfilterprotocol.h Sun Oct 30 03:29:33 2022 -0500
@@ -34,9 +34,10 @@
* PidginAccountFilterProtocol:
- * #PidginAccountFilterProtocol is a #GtkTreeModelFilter that will only show
+ * #PidginAccountFilterProtocol is a [class@Gtk.Filter] that will only show * accounts for the given protocol. It's intended to be used with
+ * [class@Pidgin.AccountChooser] or a [iface@Gio.ListModel] that contains + * [class@Purple.Account]. @@ -44,24 +45,20 @@
#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)
+ ACCOUNT_FILTER_PROTOCOL, GtkFilter) * 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.
+ * only protocols with the given @protocol_id. * Returns: (transfer full): The new #PidginAccountFilterProtocol instance.
-GtkTreeModel *pidgin_account_filter_protocol_new(const gchar *protocol_id, GtkTreeModel *child_model, GtkTreePath *root);
+GtkFilter *pidgin_account_filter_protocol_new(const gchar *protocol_id); * pidgin_account_filter_protocol_get_protocol_id:
--- a/pidgin/pidginaccountstore.c Sat Oct 29 02:05:16 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
- * 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 <https://www.gnu.org/licenses/>.
-#include <glib/gi18n-lib.h>
-#include "pidgin/pidginaccountstore.h"
-struct _PidginAccountStore {
-/******************************************************************************
- *****************************************************************************/
-pidgin_account_store_add_account(PidginAccountStore *store,
- PurpleAccount *account)
- PurpleProtocol *protocol = NULL;
- const gchar *alias = NULL, *icon_name = NULL;
- protocol = purple_account_get_protocol(account);
- icon_name = purple_protocol_get_icon_name(protocol);
- 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_NAME, icon_name,
-pidgin_account_store_add_account_helper(PurpleAccount *account, gpointer data) {
- if(PURPLE_IS_ACCOUNT(account)) {
- pidgin_account_store_add_account(PIDGIN_ACCOUNT_STORE(data),
- PURPLE_ACCOUNT(account));
-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(G_GNUC_UNUSED PurpleAccountManager *manager,
- PurpleAccount *account,
- pidgin_account_store_add_account(PIDGIN_ACCOUNT_STORE(data), account);
-pidgin_account_store_account_removed_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
- 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) {
- PurpleAccountManager *manager = NULL;
- GType types[PIDGIN_ACCOUNT_STORE_N_COLUMNS] = {
- gtk_list_store_set_column_types(
- PIDGIN_ACCOUNT_STORE_N_COLUMNS,
- /* add the known accounts */
- manager = purple_account_manager_get_default();
- purple_account_manager_foreach(manager,
- pidgin_account_store_add_account_helper,
- /* add the signal handlers to dynamically add/remove accounts */
- g_signal_connect_object(manager, "added",
- G_CALLBACK(pidgin_account_store_account_added_cb),
- g_signal_connect_object(manager, "removed",
- 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));
--- a/pidgin/pidginaccountstore.h Sat Oct 29 02:05:16 2022 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
- * 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 <https://www.gnu.org/licenses/>.
-#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
-# error "only <pidgin.h> may be included directly"
-#ifndef PIDGIN_ACCOUNT_STORE_H
-#define PIDGIN_ACCOUNT_STORE_H
- * #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.
- * PidginAccountStoreColumn:
- * @PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT: This column holds a reference to the
- * @PIDGIN_ACCOUNT_STORE_COLUMN_MARKUP: This column holds a pango markup to
- * display the account to the user.
- * @PIDGIN_ACCOUNT_STORE_COLUMN_ICON: This column holds an icon in a #GdkPixbuf
- * Constants for accessing columns in a #PidginAccountStore.
- PIDGIN_ACCOUNT_STORE_COLUMN_ACCOUNT,
- PIDGIN_ACCOUNT_STORE_COLUMN_MARKUP,
- PIDGIN_ACCOUNT_STORE_COLUMN_ICON_NAME,
- 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/pidginaddbuddydialog.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaddbuddydialog.c Sun Oct 30 03:29:33 2022 -0500
@@ -26,13 +26,12 @@
#include "pidginaccountchooser.h"
-#include "pidginaccountstore.h"
struct _PidginAddBuddyDialog {
+ GtkCustomFilter *filter; @@ -47,30 +46,20 @@
*****************************************************************************/
-pidgin_add_buddy_dialog_filter_accounts(GtkTreeModel *model, GtkTreeIter *iter,
+pidgin_add_buddy_dialog_filter_accounts(gpointer item, + G_GNUC_UNUSED gpointer data) - PurpleAccount *account = NULL;
- PurpleProtocol *protocol = 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(item)) { + PurpleAccount *account = PURPLE_ACCOUNT(item); + PurpleProtocol *protocol = purple_account_get_protocol(account); - if(!PURPLE_IS_ACCOUNT(account)) {
+ if(PURPLE_IS_PROTOCOL(protocol)) { + ret = PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, add_buddy); - protocol = purple_account_get_protocol(account);
- if(PURPLE_IS_PROTOCOL(protocol)) {
- ret = PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, add_buddy);
- g_object_unref(G_OBJECT(account));
@@ -248,12 +237,9 @@
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
- gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(dialog->filter),
- pidgin_add_buddy_dialog_filter_accounts,
- gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(dialog->filter));
- gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->account), 0);
+ gtk_custom_filter_set_filter_func(dialog->filter, + pidgin_add_buddy_dialog_filter_accounts, purple_blist_walk(pidgin_add_buddy_dialog_group_cb, NULL, NULL, NULL,
--- a/pidgin/pidginaddchatdialog.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/pidginaddchatdialog.c Sun Oct 30 03:29:33 2022 -0500
@@ -27,13 +27,12 @@
#include "pidginaccountchooser.h"
-#include "pidginaccountstore.h"
struct _PidginAddChatDialog {
+ GtkCustomFilter *filter; const gchar *default_name;
@@ -183,30 +182,20 @@
-pidgin_add_chat_dialog_filter_accounts(GtkTreeModel *model, GtkTreeIter *iter,
+pidgin_add_chat_dialog_filter_accounts(gpointer item, + G_GNUC_UNUSED gpointer data) - PurpleAccount *account = NULL;
- PurpleProtocol *protocol = 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(item)) { + PurpleAccount *account = PURPLE_ACCOUNT(item); + PurpleProtocol *protocol = purple_account_get_protocol(account); - if(!PURPLE_IS_ACCOUNT(account)) {
+ if(PURPLE_IS_PROTOCOL(protocol)) { + ret = PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info); - protocol = purple_account_get_protocol(account);
- if(PURPLE_IS_PROTOCOL(protocol)) {
- ret = PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info);
- g_object_unref(G_OBJECT(account));
@@ -379,12 +368,9 @@
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
- gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(dialog->filter),
- pidgin_add_chat_dialog_filter_accounts,
- gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(dialog->filter));
- gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->account), 0);
+ gtk_custom_filter_set_filter_func(dialog->filter, + pidgin_add_chat_dialog_filter_accounts, purple_blist_walk(pidgin_add_chat_dialog_group_cb, NULL, NULL, NULL,
--- a/pidgin/plugins/disco/resources/disco.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/plugins/disco/resources/disco.ui Sun Oct 30 03:29:33 2022 -0500
@@ -37,14 +37,6 @@
- <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 -->
@@ -76,8 +68,18 @@
<object class="PidginAccountChooser" id="account_chooser">
- <property name="model">xmpp_accounts</property>
- <property name="active">0</property>
+ <property name="filter"> + <object class="GtkEveryFilter"> + <object class="PidginAccountFilterProtocol"> + <property name="protocol_id">prpl-jabber</property> + <object class="PidginAccountFilterConnected"/> <signal name="notify::account" handler="dialog_select_account_cb" swapped="no"/>
--- a/pidgin/plugins/xmppconsole/console.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/plugins/xmppconsole/console.ui Sun Oct 30 03:29:33 2022 -0500
@@ -106,19 +106,18 @@
<object class="PidginAccountChooser" id="account_chooser">
- <property name="model">
- <object class="PidginAccountFilterProtocol">
- <property name="child-model">
- <object class="PidginAccountFilterConnected">
- <property name="child-model">
- <object class="PidginAccountStore"/>
+ <property name="filter"> + <object class="GtkEveryFilter"> + <object class="PidginAccountFilterProtocol"> + <property name="protocol-id">prpl-jabber</property>
- <property name="protocol-id">prpl-jabber</property>
+ <object class="PidginAccountFilterConnected"/> - <property name="active">0</property>
<property name="hexpand">1</property>
<signal name="notify::account" handler="dropdown_changed_cb" swapped="no"/>
--- a/pidgin/plugins/xmppconsole/xmppconsole.c Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/plugins/xmppconsole/xmppconsole.c Sun Oct 30 03:29:33 2022 -0500
@@ -35,7 +35,7 @@
struct _PidginXmppConsole {
- GtkComboBox *account_chooser;
+ PidginAccountChooser *account_chooser; --- a/pidgin/resources/Accounts/chooser.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/resources/Accounts/chooser.ui Sun Oct 30 03:29:33 2022 -0500
@@ -22,18 +22,52 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <template class="PidginAccountChooser" parent="GtkComboBox">
- <object class="GtkCellRendererPixbuf"/>
- <attribute name="icon-name">2</attribute>
- <object class="GtkCellRendererText"/>
- <attribute name="text">1</attribute>
+ <template class="PidginAccountChooser" parent="AdwBin"> + <property name="child"> + <object class="GtkDropDown" id="chooser"> + <property name="factory"> + <object class="GtkBuilderListItemFactory"> + <property name="bytes"> +<?xml version="1.0" encoding="UTF-8"?> + <template class="GtkListItem"> + <property name="child"> + <object class="GtkBox"> + <property name="orientation">horizontal</property> + <property name="spacing">6</property> + <object class="GtkImage"> + <binding name="icon-name"> + <closure type="gchararray" function="pidgin_account_chooser_icon_name_cb"> + <lookup name="item">GtkListItem</lookup> + <object class="GtkLabel"> + <property name="xalign">0</property> + <closure type="gchararray" function="pidgin_account_chooser_label_cb"> + <lookup name="item">GtkListItem</lookup> + <property name="model"> + <object class="GtkFilterListModel" id="filter"/> + <signal name="notify::selected" handler="pidgin_account_chooser_changed_cb" swapped="no"/> --- a/pidgin/resources/Dialogs/addbuddy.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/resources/Dialogs/addbuddy.ui Sun Oct 30 03:29:33 2022 -0500
@@ -25,13 +25,6 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <object class="PidginAccountStore" id="account_store"/>
- <object class="PidginAccountFilterConnected" id="account_filter_connected">
- <property name="child-model">account_store</property>
- <object class="GtkTreeModelFilter" id="filter">
- <property name="child-model">account_filter_connected</property>
<template class="PidginAddBuddyDialog" parent="GtkDialog">
<property name="title" translatable="1">Add Buddy</property>
<property name="resizable">0</property>
@@ -65,7 +58,16 @@
<object class="PidginAccountChooser" id="account">
<property name="hexpand">1</property>
- <property name="model">filter</property>
+ <property name="filter"> + <object class="GtkEveryFilter"> + <object class="GtkCustomFilter" id="filter"/> + <object class="PidginAccountFilterConnected"/> <signal name="notify::account" handler="pidgin_add_buddy_dialog_account_changed_cb" swapped="no"/>
<relation name="labelled-by">label1</relation>
--- a/pidgin/resources/Dialogs/addchat.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/resources/Dialogs/addchat.ui Sun Oct 30 03:29:33 2022 -0500
@@ -25,13 +25,6 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <object class="PidginAccountStore" id="account_store"/>
- <object class="PidginAccountFilterConnected" id="account_filter_connected">
- <property name="child-model">account_store</property>
- <object class="GtkTreeModelFilter" id="filter">
- <property name="child-model">account_filter_connected</property>
<template class="PidginAddChatDialog" parent="GtkDialog">
<property name="title" translatable="1">Add Chat</property>
<property name="resizable">0</property>
@@ -66,7 +59,16 @@
<object class="PidginAccountChooser" id="account">
<property name="hexpand">1</property>
- <property name="model">filter</property>
+ <property name="filter"> + <object class="GtkEveryFilter"> + <object class="GtkCustomFilter" id="filter"/> + <object class="PidginAccountFilterConnected"/> <signal name="notify::account" handler="pidgin_add_chat_dialog_account_changed_cb" swapped="no"/>
--- a/pidgin/resources/Privacy/dialog.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/resources/Privacy/dialog.ui Sun Oct 30 03:29:33 2022 -0500
@@ -23,10 +23,6 @@
<!-- 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 type="gchararray"/>
@@ -66,8 +62,9 @@
<object class="PidginAccountChooser" id="account_chooser">
<property name="hexpand">1</property>
- <property name="model">connected_account_store</property>
- <property name="active">0</property>
+ <property name="filter"> + <object class="PidginAccountFilterConnected"/> <signal name="notify::account" handler="select_account_cb" swapped="no"/>
<relation name="labelled-by">label1</relation>
--- a/pidgin/resources/Roomlist/roomlist.ui Sat Oct 29 02:05:16 2022 -0500
+++ b/pidgin/resources/Roomlist/roomlist.ui Sun Oct 30 03:29:33 2022 -0500
@@ -23,7 +23,6 @@
<!-- interface-name Pidgin -->
<!-- interface-description Internet Messenger -->
<!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
- <object class="PidginAccountStore" id="accounts"/>
<template class="PidginRoomlistDialog" parent="GtkDialog">
<property name="title" translatable="1">Room List</property>
<signal name="close-request" handler="close_request_cb" swapped="no"/>
@@ -47,8 +46,6 @@
<object class="PidginAccountChooser" id="account_widget">
<property name="hexpand">1</property>
<property name="can-focus">1</property>
- <property name="model">accounts</property>
- <property name="active">0</property>
<signal name="notify::account" handler="dialog_select_account_cb" swapped="no"/>
<relation name="labelled-by">label1</relation>
--- a/po/POTFILES.in Sat Oct 29 02:05:16 2022 -0500
+++ b/po/POTFILES.in Sun Oct 30 03:29:33 2022 -0500
@@ -282,7 +282,6 @@
pidgin/pidginaccountmanager.c
pidgin/pidginaccountsdisabledmenu.c
pidgin/pidginaccountsenabledmenu.c
-pidgin/pidginaccountstore.c
pidgin/pidginactiongroup.c
pidgin/pidginaddbuddydialog.c
pidgin/pidginaddchatdialog.c