pidgin/pidgincontactlist.c

changeset 42059
e6dcbf0db616
parent 42054
7aa77854392d
child 42062
ab77968cc8e2
--- a/pidgin/pidgincontactlist.c	Fri Feb 17 04:54:38 2023 -0600
+++ b/pidgin/pidgincontactlist.c	Fri Feb 17 19:32:38 2023 -0600
@@ -27,16 +27,44 @@
 #include "pidgin/pidgincontactlist.h"
 
 struct _PidginContactList {
-	AdwBin parent;
+	GtkBox parent;
 
+	GtkFilterListModel *filter_model;
+	GtkCustomFilter *search_filter;
+
+	GtkWidget *search_entry;
 	GtkWidget *view;
 };
 
-G_DEFINE_TYPE(PidginContactList, pidgin_contact_list, ADW_TYPE_BIN)
+G_DEFINE_TYPE(PidginContactList, pidgin_contact_list, GTK_TYPE_BOX)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static gboolean
+pidgin_contact_list_search_filter(GObject *item, gpointer data) {
+	PidginContactList *list = data;
+	PurplePerson *person = PURPLE_PERSON(item);
+	const char *needle = NULL;
+
+	needle = gtk_editable_get_text(GTK_EDITABLE(list->search_entry));
+
+	return purple_person_matches(person, needle);
+}
 
 /******************************************************************************
  * Callbacks
  *****************************************************************************/
+static void
+pidgin_contact_list_search_changed_cb(G_GNUC_UNUSED GtkSearchEntry *self,
+                                      gpointer data)
+{
+	PidginContactList *list = data;
+
+	gtk_filter_changed(GTK_FILTER(list->search_filter),
+	                   GTK_FILTER_CHANGE_DIFFERENT);
+}
+
 static GdkTexture *
 pidgin_contact_list_avatar_cb(G_GNUC_UNUSED GObject *self,
                               PurplePerson *person,
@@ -53,6 +81,13 @@
 		return gdk_texture_new_for_pixbuf(pixbuf);
 	}
 
+	/* When filtering we get called for rows that have been filtered out. I'm
+	 * not sure why, but this does appear to be the case.
+	 */
+	if(person == NULL) {
+		return NULL;
+	}
+
 	info = purple_person_get_priority_contact_info(person);
 
 	/* All of the contact info in the manager are PurpleContact's so this cast
@@ -135,15 +170,15 @@
 static void
 pidgin_contact_list_init(PidginContactList *list) {
 	PurpleContactManager *manager = NULL;
-	GtkSingleSelection *selection = NULL;
 
 	gtk_widget_init_template(GTK_WIDGET(list));
 
 	manager = purple_contact_manager_get_default();
-	selection = gtk_single_selection_new(G_LIST_MODEL(manager));
+	gtk_filter_list_model_set_model(list->filter_model, G_LIST_MODEL(manager));
 
-	gtk_list_view_set_model(GTK_LIST_VIEW(list->view),
-	                        GTK_SELECTION_MODEL(selection));
+	gtk_custom_filter_set_filter_func(list->search_filter,
+	                                  (GtkCustomFilterFunc)pidgin_contact_list_search_filter,
+	                                  list, NULL);
 }
 
 static void
@@ -156,9 +191,18 @@
 	);
 
 	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
+	                                     filter_model);
+	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
+	                                     search_filter);
+
+	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
+	                                     search_entry);
+	gtk_widget_class_bind_template_child(widget_class, PidginContactList,
 	                                     view);
 
 	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_contact_list_search_changed_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_contact_list_avatar_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_contact_list_activate_cb);

mercurial