Convert PidginAccountsDisabledMenu to the list model

Tue, 01 Apr 2025 00:12:31 -0500

author
Elliott Sales de Andrade <quantum.analyst@gmail.com>
date
Tue, 01 Apr 2025 00:12:31 -0500
changeset 43220
583158d1e6c2
parent 43219
778ca78c80c9
child 43221
44fffd2f5564

Convert PidginAccountsDisabledMenu to the list model

This isn't exactly what PIDGIN-18067 requested, but should be a reasonable version of it.

Testing Done:
Started Pidgin with all accounts enabled, and the menu showed the placeholder "No disabled accounts". Disabled an account, and that was replaced by the disabled account. Enabled the account again, and the placeholder text returned.

Also, started Pidgin with an account disabled, and it was in the menu without the placeholder.

Bugs closed: PIDGIN-18067

Reviewed at https://reviews.imfreedom.org/r/3952/

pidgin/pidginaccountsdisabledmenu.c file | annotate | diff | comparison | revisions
--- a/pidgin/pidginaccountsdisabledmenu.c	Tue Apr 01 00:10:42 2025 -0500
+++ b/pidgin/pidginaccountsdisabledmenu.c	Tue Apr 01 00:12:31 2025 -0500
@@ -27,7 +27,7 @@
 struct _PidginAccountsDisabledMenu {
 	GMenuModel parent;
 
-	GList *accounts;
+	GListModel *accounts;
 };
 
 G_DEFINE_FINAL_TYPE(PidginAccountsDisabledMenu, pidgin_accounts_disabled_menu,
@@ -37,39 +37,29 @@
  * Callbacks
  *****************************************************************************/
 static void
-pidgin_accounts_disabled_menu_refresh(PidginAccountsDisabledMenu *menu) {
-	PurpleAccountManager *manager = NULL;
-	gint removed = 0, added = 0;
-
-	/* When refreshing we're always removing at least 1 item because of the
-	 * "no disabled accounts" item that we put in place when all accounts
-	 * are enabled.
-	 */
-	removed = MAX(1, g_list_length(menu->accounts));
-
-	/* Grab the manager and get all the disabled accounts. */
-	manager = purple_account_manager_get_default();
-	g_list_free(menu->accounts);
-	menu->accounts = purple_account_manager_get_disabled(manager);
-
-	/* Similar to the above note about removed items, if every account is
-	 * enabled, we add an item saying "no disabled accounts".
-	 */
-	added = MAX(1, g_list_length(menu->accounts));
-
-	/* Tell any listeners that our menu has changed. */
-	g_menu_model_items_changed(G_MENU_MODEL(menu), 0, removed, added);
-}
-
-static void
-pidgin_accounts_disabled_menu_changed_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
-                                         G_GNUC_UNUSED PurpleAccount *account,
-                                         G_GNUC_UNUSED GParamSpec *pspec,
-                                         gpointer data)
+pidgin_accounts_disabled_menu_items_changed_cb(GListModel *model,
+                                               guint position,
+                                               guint removed,
+                                               guint added,
+                                               gpointer data)
 {
 	PidginAccountsDisabledMenu *menu = data;
+	guint n_items = g_list_model_get_n_items(model);
 
-	pidgin_accounts_disabled_menu_refresh(menu);
+	if(n_items == 0) {
+		/* If every account is enabled, this model will be empty, but we add an
+		 * item saying "no disabled accounts".
+		 */
+		added = 1;
+	} else if(n_items == (added - removed) && position == 0) {
+		/* In this case, there were no accounts in the model *before*. This
+		 * means we need to remove the "no disabled accounts" item that we put
+		 * in place when all accounts are enabled.
+		 */
+		removed = 1;
+	}
+
+	g_menu_model_items_changed(G_MENU_MODEL(menu), position, removed, added);
 }
 
 /******************************************************************************
@@ -86,11 +76,10 @@
 
 	menu = PIDGIN_ACCOUNTS_DISABLED_MENU(model);
 
-	if(menu->accounts == NULL) {
-		return 1;
-	}
-
-	return g_list_length(menu->accounts);
+	/* If every account is enabled, we add an item saying "no disabled
+	 * accounts", so there's always at least 1.
+	 */
+	return MAX(1, g_list_model_get_n_items(menu->accounts));
 }
 
 static void
@@ -114,7 +103,7 @@
 	/* If we don't have any disabled accounts, just return a single item,
 	 * stating as much.
 	 */
-	if(menu->accounts == NULL) {
+	if(g_list_model_get_n_items(menu->accounts) == 0) {
 		value = g_variant_new_string(_("No disabled accounts"));
 		g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_LABEL,
 		                    g_variant_ref_sink(value));
@@ -126,7 +115,7 @@
 		return;
 	}
 
-	account = g_list_nth_data(menu->accounts, index);
+	account = g_list_model_get_item(menu->accounts, index);
 	if(account == NULL) {
 		return;
 	}
@@ -156,6 +145,8 @@
 	value = g_variant_new_printf("%s", purple_account_get_id(account));
 	g_hash_table_insert(*attributes, G_MENU_ATTRIBUTE_TARGET,
 	                    g_variant_ref_sink(value));
+
+	g_clear_object(&account);
 }
 
 static void
@@ -172,18 +163,23 @@
  *****************************************************************************/
 static void
 pidgin_accounts_disabled_menu_constructed(GObject *obj) {
+	PidginAccountsDisabledMenu *menu = PIDGIN_ACCOUNTS_DISABLED_MENU(obj);
+	guint count = 0;
+
 	G_OBJECT_CLASS(pidgin_accounts_disabled_menu_parent_class)->constructed(obj);
 
-	pidgin_accounts_disabled_menu_refresh(PIDGIN_ACCOUNTS_DISABLED_MENU(obj));
+	count = g_list_model_get_n_items(menu->accounts);
+	g_menu_model_items_changed(G_MENU_MODEL(obj), 0, 0, count);
 }
 
 static void
 pidgin_accounts_disabled_menu_init(PidginAccountsDisabledMenu *menu) {
 	PurpleAccountManager *manager = purple_account_manager_get_default();
 
-	g_signal_connect_object(manager, "account-changed::enabled",
-	                        G_CALLBACK(pidgin_accounts_disabled_menu_changed_cb),
-	                        menu, 0);
+	menu->accounts = purple_account_manager_get_disabled_model(manager);
+	g_signal_connect_object(menu->accounts, "items-changed",
+	                        G_CALLBACK(pidgin_accounts_disabled_menu_items_changed_cb),
+	                        menu, G_CONNECT_DEFAULT);
 }
 
 static void

mercurial