Add a custom filter to PidginContactList to filter out disconnected accounts

Thu, 13 Jul 2023 23:00:00 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Thu, 13 Jul 2023 23:00:00 -0500
changeset 42237
57c9deea59c8
parent 42236
c4867c8a7906
child 42238
48bb3244b5ea

Add a custom filter to PidginContactList to filter out disconnected accounts

Testing Done:
Connected a demo protocol account as well as an xmpp account. And then disconnected the accounts and verified that their contacts were removed from the list.

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

pidgin/pidgincontactlist.c file | annotate | diff | comparison | revisions
pidgin/resources/ContactList/widget.ui file | annotate | diff | comparison | revisions
--- a/pidgin/pidgincontactlist.c	Wed Jul 12 21:32:27 2023 -0500
+++ b/pidgin/pidgincontactlist.c	Thu Jul 13 23:00:00 2023 -0500
@@ -30,6 +30,7 @@
 	GtkBox parent;
 
 	GtkFilterListModel *filter_model;
+	GtkCustomFilter *account_connected_filter;
 	GtkCustomFilter *search_filter;
 
 	GtkWidget *search_entry;
@@ -42,6 +43,64 @@
  * Helpers
  *****************************************************************************/
 static gboolean
+pidgin_contact_list_account_connected_filter(GObject *item,
+                                             G_GNUC_UNUSED gpointer data)
+{
+	PurplePerson *person = PURPLE_PERSON(item);
+	PurpleContactInfo *info = NULL;
+
+	info = purple_person_get_priority_contact_info(person);
+	if(!PURPLE_IS_CONTACT_INFO(info)) {
+		return FALSE;
+	}
+
+	/* This should always be a PurpleContact as it's in the contact manager,
+	 * but it doesn't hurt to check.
+	 */
+	if(PURPLE_IS_CONTACT(info)) {
+		PurpleConnection *connection = NULL;
+		PurpleContact *contact = PURPLE_CONTACT(info);
+		PurpleAccount *account = NULL;
+
+		account = purple_contact_get_account(contact);
+		connection = purple_account_get_connection(account);
+
+		if(PURPLE_IS_CONNECTION(connection)) {
+			PurpleConnectionState state = PURPLE_CONNECTION_STATE_DISCONNECTED;
+
+			state = purple_connection_get_state(connection);
+
+			return (state == PURPLE_CONNECTION_STATE_CONNECTED);
+		}
+
+	}
+
+	return FALSE;
+}
+
+static void
+pidgin_contact_list_account_connected_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
+                                         G_GNUC_UNUSED PurpleAccount *account,
+                                         gpointer data)
+{
+	PidginContactList *list = data;
+
+	gtk_filter_changed(GTK_FILTER(list->account_connected_filter),
+	                   GTK_FILTER_CHANGE_LESS_STRICT);
+}
+
+static void
+pidgin_contact_list_account_disconnected_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
+                                            G_GNUC_UNUSED PurpleAccount *account,
+                                            gpointer data)
+{
+	PidginContactList *list = data;
+
+	gtk_filter_changed(GTK_FILTER(list->account_connected_filter),
+	                   GTK_FILTER_CHANGE_MORE_STRICT);
+}
+
+static gboolean
 pidgin_contact_list_search_filter(GObject *item, gpointer data) {
 	PidginContactList *list = data;
 	PurplePerson *person = PURPLE_PERSON(item);
@@ -227,13 +286,29 @@
  *****************************************************************************/
 static void
 pidgin_contact_list_init(PidginContactList *list) {
-	PurpleContactManager *manager = NULL;
+	PurpleAccountManager *account_manager = NULL;
+	PurpleContactManager *contact_manager = NULL;
 
 	gtk_widget_init_template(GTK_WIDGET(list));
 
-	manager = purple_contact_manager_get_default();
-	gtk_filter_list_model_set_model(list->filter_model, G_LIST_MODEL(manager));
+	contact_manager = purple_contact_manager_get_default();
+	gtk_filter_list_model_set_model(list->filter_model,
+	                                G_LIST_MODEL(contact_manager));
+
 
+	/* Setup the filter connected accounts. */
+	account_manager = purple_account_manager_get_default();
+	gtk_custom_filter_set_filter_func(list->account_connected_filter,
+	                                  (GtkCustomFilterFunc)pidgin_contact_list_account_connected_filter,
+	                                  list, NULL);
+	g_signal_connect_object(account_manager, "account-connected",
+	                        G_CALLBACK(pidgin_contact_list_account_connected_cb),
+	                        list, 0);
+	g_signal_connect_object(account_manager, "account-disconnected",
+	                        G_CALLBACK(pidgin_contact_list_account_disconnected_cb),
+	                        list, 0);
+
+	/* Setup the search filter. */
 	gtk_custom_filter_set_filter_func(list->search_filter,
 	                                  (GtkCustomFilterFunc)pidgin_contact_list_search_filter,
 	                                  list, NULL);
@@ -251,6 +326,8 @@
 	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
 	                                     filter_model);
 	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
+	                                     account_connected_filter);
+	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
 	                                     search_filter);
 
 	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
--- a/pidgin/resources/ContactList/widget.ui	Wed Jul 12 21:32:27 2023 -0500
+++ b/pidgin/resources/ContactList/widget.ui	Thu Jul 13 23:00:00 2023 -0500
@@ -146,7 +146,14 @@
               <object class="GtkFilterListModel" id="filter_model">
                 <property name="incremental">0</property>
                 <property name="filter">
-                  <object class="GtkCustomFilter" id="search_filter"/>
+                  <object class="GtkEveryFilter">
+                    <child>
+                      <object class="GtkCustomFilter" id="account_connected_filter"/>
+                    </child>
+                    <child>
+                      <object class="GtkCustomFilter" id="search_filter"/>
+                    </child>
+                  </object>
                 </property>
               </object>
             </property>

mercurial