--- a/finch/gntaccount.c Fri Oct 28 03:42:47 2022 -0500
+++ b/finch/gntaccount.c Fri Oct 28 03:44:19 2022 -0500
@@ -736,9 +736,9 @@
GntTree *tree = GNT_TREE(widget);
PurpleAccountManager *manager = NULL;
+ GListModel *manager_model = NULL; PurpleAccount *account = gnt_tree_get_selection_data(tree);
@@ -755,20 +755,28 @@
manager = purple_account_manager_get_default();
- accounts = purple_account_manager_get_all(manager);
- count = g_list_length(accounts);
- pos = g_list_index(accounts, account);
- pos = (move + pos + count + 1) % (count + 1);
- purple_account_manager_reorder(manager, account, pos);
+ manager_model = G_LIST_MODEL(manager); + count = g_list_model_get_n_items(manager_model); + for(pos = 0; pos < count; pos++) { + PurpleAccount *acct = g_list_model_get_item(manager_model, pos); + pos = (move + pos + count + 1) % (count + 1); + purple_account_manager_reorder(manager, account, pos); /* I don't like this, but recreating the entire list seems to be
* the easiest way of doing it */
gnt_tree_remove_all(tree);
- accounts = purple_account_manager_get_all(manager);
- for (; accounts; accounts = accounts->next)
- account_add(accounts->data);
+ for(pos = 0; pos < count; pos++) { + PurpleAccount *account = g_list_model_get_item(manager_model, pos); + g_object_unref(account); gnt_tree_set_selected(tree, account);
@@ -784,8 +792,8 @@
finch_accounts_show_all(void)
- PurpleAccountManager *manager = NULL;
+ GListModel *manager_model = NULL; @@ -808,12 +816,12 @@
accounts.tree = gnt_tree_new_with_columns(2);
gnt_widget_set_has_border(accounts.tree, FALSE);
- manager = purple_account_manager_get_default();
- iter = purple_account_manager_get_all(manager);
- for(; iter; iter = iter->next) {
- PurpleAccount *account = iter->data;
+ manager_model = purple_account_manager_get_default_as_model(); + n_items = g_list_model_get_n_items(manager_model); + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = g_list_model_get_item(manager_model, index); + g_object_unref(account); g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL);
@@ -894,10 +902,12 @@
finch_accounts_init(void)
PurpleAccountManager *manager = NULL;
+ GListModel *manager_model = NULL; gpointer account_handle = NULL;
manager = purple_account_manager_get_default();
+ manager_model = G_LIST_MODEL(manager); account_handle = purple_accounts_get_handle();
g_signal_connect(manager, "added", G_CALLBACK(account_added_callback),
@@ -911,14 +921,26 @@
finch_accounts_get_handle(),
G_CALLBACK(account_abled_cb), GINT_TO_POINTER(TRUE));
- iter = purple_account_manager_get_all(manager);
- for (; iter; iter = iter->next) {
- if (purple_account_get_enabled(iter->data))
+ n_items = g_list_model_get_n_items(manager_model); + gboolean has_enabled_account = FALSE; + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = NULL; + account = g_list_model_get_item(manager_model, index); + if(purple_account_get_enabled(account)) { + has_enabled_account = TRUE; + g_object_unref(account); + g_object_unref(account);
+ if(!has_enabled_account) { finch_accounts_show_all();
finch_accounts_show_all();
--- a/finch/gntstatus.c Fri Oct 28 03:42:47 2022 -0500
+++ b/finch/gntstatus.c Fri Oct 28 03:44:19 2022 -0500
@@ -491,12 +491,12 @@
void finch_savedstatus_edit(PurpleSavedStatus *saved)
- PurpleAccountManager *manager = NULL;
+ GListModel *manager_model = NULL; GntWidget *window, *box, *button, *entry, *combo, *label, *tree;
PurpleStatusPrimitive prims[] = {PURPLE_STATUS_AVAILABLE, PURPLE_STATUS_AWAY,
PURPLE_STATUS_INVISIBLE, PURPLE_STATUS_OFFLINE, PURPLE_STATUS_UNSET}, current;
@@ -567,10 +567,12 @@
gnt_tree_set_col_width(GNT_TREE(tree), 1, 10);
gnt_tree_set_col_width(GNT_TREE(tree), 2, 30);
- manager = purple_account_manager_get_default();
- iter = purple_account_manager_get_all(manager);
- for(; iter; iter = iter->next) {
- add_substatus(edit, iter->data);
+ manager_model = purple_account_manager_get_default_as_model(); + n_items = g_list_model_get_n_items(manager_model); + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = g_list_model_get_item(manager_model, index); + add_substatus(edit, account); + g_object_unref(account); g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(popup_substatus), edit);
--- a/libpurple/buddylist.c Fri Oct 28 03:42:47 2022 -0500
+++ b/libpurple/buddylist.c Fri Oct 28 03:44:19 2022 -0500
@@ -361,10 +361,10 @@
- PurpleAccountManager *manager = purple_account_manager_get_default();
+ GListModel *manager_model = NULL; PurpleXmlNode *node, *child, *grandchild;
const gchar *localized_default;
node = purple_xmlnode_new("purple");
@@ -394,11 +394,13 @@
/* Write privacy settings */
child = purple_xmlnode_new_child(node, "privacy");
- for(cur = purple_account_manager_get_all(manager); cur != NULL;
- grandchild = accountprivacy_to_xmlnode(cur->data);
+ manager_model = purple_account_manager_get_default_as_model(); + n_items = g_list_model_get_n_items(manager_model); + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = g_list_model_get_item(manager_model, index); + grandchild = accountprivacy_to_xmlnode(account); purple_xmlnode_insert_child(child, grandchild);
+ g_object_unref(account); @@ -745,18 +747,21 @@
- PurpleAccountManager *manager = NULL;
+ GListModel *manager_model = NULL; PurpleBuddyList *gbl = g_object_new(buddy_list_type, NULL);
buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify)g_hash_table_destroy);
groups_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
- manager = purple_account_manager_get_default();
- for(l = purple_account_manager_get_all(manager); l != NULL; l = l->next) {
- purple_blist_buddies_cache_add_account(PURPLE_ACCOUNT(l->data));
+ manager_model = purple_account_manager_get_default_as_model(); + n_items = g_list_model_get_n_items(manager_model); + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = g_list_model_get_item(manager_model, index); + purple_blist_buddies_cache_add_account(account); + g_object_unref(account); --- a/libpurple/purpleaccountmanager.c Fri Oct 28 03:42:47 2022 -0500
+++ b/libpurple/purpleaccountmanager.c Fri Oct 28 03:44:19 2022 -0500
@@ -33,23 +33,60 @@
struct _PurpleAccountManager {
static PurpleAccountManager *default_manager = NULL;
-G_DEFINE_TYPE(PurpleAccountManager, purple_account_manager, G_TYPE_OBJECT)
+/****************************************************************************** + * GListModel Implementation + *****************************************************************************/ +purple_account_get_item_type(G_GNUC_UNUSED GListModel *list) { + return PURPLE_TYPE_ACCOUNT; +purple_account_get_n_items(GListModel *list) { + PurpleAccountManager *manager = PURPLE_ACCOUNT_MANAGER(list); + return manager->accounts->len; +purple_account_get_item(GListModel *list, guint position) { + PurpleAccountManager *manager = PURPLE_ACCOUNT_MANAGER(list); + PurpleAccount *account = NULL; + if(position < manager->accounts->len) { + account = g_ptr_array_index(manager->accounts, position); +purple_account_manager_list_model_init(GListModelInterface *iface) { + iface->get_item_type = purple_account_get_item_type; + iface->get_n_items = purple_account_get_n_items; + iface->get_item = purple_account_get_item; /******************************************************************************
*****************************************************************************/
+G_DEFINE_TYPE_EXTENDED(PurpleAccountManager, purple_account_manager, + G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, + purple_account_manager_list_model_init)) purple_account_manager_finalize(GObject *obj) {
PurpleAccountManager *manager = PURPLE_ACCOUNT_MANAGER(obj);
- for(l = manager->accounts; l != NULL; l = l->next) {
- g_object_unref(l->data);
+ if(manager->accounts != NULL) { + g_ptr_array_free(manager->accounts, TRUE); G_OBJECT_CLASS(purple_account_manager_parent_class)->finalize(obj);
@@ -57,6 +94,7 @@
purple_account_manager_init(PurpleAccountManager *manager) {
+ manager->accounts = g_ptr_array_new_full(0, (GDestroyNotify)g_object_unref); @@ -131,6 +169,11 @@
+purple_account_manager_get_default_as_model(void) { + return G_LIST_MODEL(default_manager); purple_account_manager_add(PurpleAccountManager *manager,
@@ -139,7 +182,7 @@
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
/* If the manager already knows about the account, we do nothing. */
- if(g_list_find(manager->accounts, account) != NULL) {
+ if(g_ptr_array_find(manager->accounts, account, NULL)) { @@ -148,21 +191,27 @@
* interfaces and the most likely to have configuration issues as it's a
- manager->accounts = g_list_prepend(manager->accounts, account);
+ g_ptr_array_insert(manager->accounts, 0, account); purple_accounts_schedule_save();
g_signal_emit(manager, signals[SIG_ADDED], 0, account);
+ g_list_model_items_changed(G_LIST_MODEL(manager), 0, 0, 1); purple_account_manager_remove(PurpleAccountManager *manager,
g_return_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager));
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
- manager->accounts = g_list_remove(manager->accounts, account);
+ if(g_ptr_array_find(manager->accounts, account, &index)) { + g_ptr_array_steal_index(manager->accounts, index); + g_list_model_items_changed(G_LIST_MODEL(manager), index, 1, 0); purple_accounts_schedule_save();
@@ -175,20 +224,13 @@
-purple_account_manager_get_all(PurpleAccountManager *manager) {
- g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
- return manager->accounts;
purple_account_manager_get_enabled(PurpleAccountManager *manager) {
- GList *enabled = NULL, *l = NULL;
g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
- for(l = manager->accounts; l != NULL; l = l->next) {
- PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+ for(guint index = 0; index < manager->accounts->len; index++) { + PurpleAccount *account = g_ptr_array_index(manager->accounts, index); if(purple_account_get_enabled(account)) {
enabled = g_list_append(enabled, account);
@@ -200,12 +242,12 @@
purple_account_manager_get_disabled(PurpleAccountManager *manager) {
- GList *disabled = NULL, *l = NULL;
+ GList *disabled = NULL; g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
- for(l = manager->accounts; l != NULL; l = l->next) {
- PurpleAccount *account = l->data;
+ for(guint index = 0; index < manager->accounts->len; index++) { + PurpleAccount *account = g_ptr_array_index(manager->accounts, index); if(!purple_account_get_enabled(account)) {
disabled = g_list_append(disabled, account);
@@ -220,42 +262,31 @@
- gboolean found = FALSE;
g_return_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager));
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
- /* Iterate over the known accounts until we have found a matching account
- * or exhausted the list. For each iteration increment idx.
- for(l = manager->accounts; l != NULL; l = l->next, index++) {
- if(PURPLE_ACCOUNT(l->data) == account) {
- manager->accounts = g_list_delete_link(manager->accounts, l);
+ if(g_ptr_array_find(manager->accounts, account, &index)) { + g_ptr_array_steal_index(manager->accounts, index); + g_list_model_items_changed(G_LIST_MODEL(manager), index, 1, 0); - /* If new_index is greater than the current index, we need to
- * decrement new_index by 1 to account for the move as we'll be
- * inserting into a list with one less item.
- if(new_index > index) {
+ /* If new_index is greater than the current index, we need to + * decrement new_index by 1 to account for the move as we'll be + * inserting into a list with one less item. + if(new_index > index) {
g_critical("Unregistered account (%s) found during reorder!",
purple_account_get_username(account));
/* Insert the account into its new position. */
- manager->accounts = g_list_insert(manager->accounts, account, new_index);
+ g_ptr_array_insert(manager->accounts, new_index, account); + g_list_model_items_changed(G_LIST_MODEL(manager), new_index, 0, 1); purple_accounts_schedule_save();
@@ -264,13 +295,11 @@
purple_account_manager_find_by_id(PurpleAccountManager *manager,
g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
g_return_val_if_fail(id != NULL, NULL);
- for(l = manager->accounts; l != NULL; l = l->next) {
- PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+ for(guint index = 0; index < manager->accounts->len; index++) { + PurpleAccount *account = g_ptr_array_index(manager->accounts, index); if(purple_strequal(purple_account_get_id(account), id)) {
@@ -284,14 +313,12 @@
purple_account_manager_find(PurpleAccountManager *manager,
const gchar *username, const gchar *protocol_id)
g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
g_return_val_if_fail(username != NULL, NULL);
g_return_val_if_fail(protocol_id != NULL, NULL);
- for(l = manager->accounts; l != NULL; l = l->next) {
- PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+ for(guint index = 0; index < manager->accounts->len; index++) { + PurpleAccount *account = g_ptr_array_index(manager->accounts, index); gchar *normalized = NULL;
const gchar *existing_protocol_id = NULL;
const gchar *existing_username = NULL;
@@ -323,17 +350,15 @@
purple_account_manager_find_custom(PurpleAccountManager *manager,
GEqualFunc func, gconstpointer data)
g_return_val_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager), NULL);
g_return_val_if_fail(func != NULL, NULL);
- for(l = manager->accounts; l != NULL; l = l->next) {
- PurpleAccount *account = PURPLE_ACCOUNT(l->data);
+ if(g_ptr_array_find_with_equal_func(manager->accounts, data, func, &index)) { + PurpleAccount *account = g_ptr_array_index(manager->accounts, index); - if(func(account, data)) {
@@ -344,12 +369,11 @@
PurpleAccountManagerForeachFunc callback,
g_return_if_fail(PURPLE_IS_ACCOUNT_MANAGER(manager));
g_return_if_fail(callback != NULL);
- for(l = manager->accounts; l != NULL; l = l->next) {
- callback(PURPLE_ACCOUNT(l->data), data);
+ for(guint index = 0; index < manager->accounts->len; index++) { + PurpleAccount *account = g_ptr_array_index(manager->accounts, index); + callback(account, data); --- a/libpurple/purpleaccountmanager.h Fri Oct 28 03:42:47 2022 -0500
+++ b/libpurple/purpleaccountmanager.h Fri Oct 28 03:44:19 2022 -0500
@@ -66,6 +66,17 @@
PurpleAccountManager *purple_account_manager_get_default(void);
+ * purple_account_manager_get_default_as_model: + * Gets the default account manager for libpurple as a list model. + * Returns: (transfer none): The default account manager for libpurple. +GListModel *purple_account_manager_get_default_as_model(void); * purple_account_manager_add:
* @manager: The account manager instance.
* @account: (transfer full): The account to add.
@@ -100,19 +111,6 @@
void purple_account_manager_reorder(PurpleAccountManager *manager, PurpleAccount *account, guint new_index);
- * purple_account_manager_get_all:
- * @manager: The account manager instance.
- * Gets the list of all accounts.
- * Returns: (transfer none) (element-type PurpleAccount): The list of all
-GList *purple_account_manager_get_all(PurpleAccountManager *manager);
* purple_account_manager_get_enabled:
* @manager: The account manager instance.
--- a/libpurple/tests/test_account_manager.c Fri Oct 28 03:42:47 2022 -0500
+++ b/libpurple/tests/test_account_manager.c Fri Oct 28 03:44:19 2022 -0500
@@ -59,7 +59,6 @@
test_purple_account_manager_add_remove(void) {
PurpleAccount *account = NULL;
PurpleAccountManager *manager = NULL;
- GList *accounts = NULL;
gboolean signal_called = FALSE;
account = purple_account_new("test", "test");
@@ -72,15 +71,13 @@
G_CALLBACK(test_purple_account_manager_signal_called),
- accounts = purple_account_manager_get_all(manager);
- g_assert_true(g_list_length(accounts) == 0);
+ g_assert_cmpuint(g_list_model_get_n_items(G_LIST_MODEL(manager)), ==, 0); /* Add the account and verify that it was added and that the signal was
purple_account_manager_add(manager, account);
- accounts = purple_account_manager_get_all(manager);
- g_assert_true(g_list_length(accounts) == 1);
+ g_assert_cmpuint(g_list_model_get_n_items(G_LIST_MODEL(manager)), ==, 1); g_assert_true(signal_called);
@@ -89,8 +86,7 @@
purple_account_manager_remove(manager, account);
- accounts = purple_account_manager_get_all(manager);
- g_assert_true(g_list_length(accounts) == 0);
+ g_assert_cmpuint(g_list_model_get_n_items(G_LIST_MODEL(manager)), ==, 0); g_assert_true(signal_called);
--- a/libpurple/util.c Fri Oct 28 03:42:47 2022 -0500
+++ b/libpurple/util.c Fri Oct 28 03:44:19 2022 -0500
@@ -933,19 +933,27 @@
void purple_util_set_current_song(const char *title, const char *artist, const char *album)
- PurpleAccountManager *manager = purple_account_manager_get_default();
- GList *list = purple_account_manager_get_all(manager);
- for (; list; list = list->next) {
+ GListModel *manager_model = NULL; + manager_model = purple_account_manager_get_default_as_model(); + n_items = g_list_model_get_n_items(manager_model); + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = g_list_model_get_item(manager_model, index); PurplePresence *presence;
- PurpleAccount *account = list->data;
- if (!purple_account_get_enabled(account))
+ if (!purple_account_get_enabled(account)) { + g_object_unref(account); presence = purple_account_get_presence(account);
tune = purple_presence_get_status(presence, "tune");
+ g_object_unref(account); GHashTable *attributes = g_hash_table_new(g_str_hash, g_str_equal);
@@ -962,6 +970,8 @@
purple_status_set_active(tune, FALSE);
+ g_object_unref(account); --- a/pidgin/pidginmooddialog.c Fri Oct 28 03:42:47 2022 -0500
+++ b/pidgin/pidginmooddialog.c Fri Oct 28 03:44:19 2022 -0500
@@ -95,12 +95,15 @@
update_status_with_mood(account, mood, text);
- PurpleAccountManager *manager = purple_account_manager_get_default();
- GList *accounts = purple_account_manager_get_all(manager);
+ GListModel *manager_model = NULL; - for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) {
- PurpleAccount *account = (PurpleAccount *) accounts->data;
+ manager_model = purple_account_manager_get_default_as_model(); + n_items = g_list_model_get_n_items(manager_model); + for(guint index = 0; index < n_items; index++) { + PurpleAccount *account = NULL; + account = g_list_model_get_item(manager_model, index); connection = purple_account_get_connection(account);
if(PURPLE_IS_CONNECTION(connection)) {
PurpleConnectionFlags flags;
@@ -110,6 +113,8 @@
update_status_with_mood(account, mood, NULL);
+ g_object_unref(account);