Mon, 03 Feb 2025 21:11:44 -0600
Implement searching the conversation members
This replaces the label that showed how many members are in the conversation
but that text is now used as the placeholder text in the search widget.
Testing Done:
Joined a channel on a local ergo server and tested a few matches.
Bugs closed: PIDGIN-18039
Reviewed at https://reviews.imfreedom.org/r/3808/
| pidgin/pidginconversation.c | file | annotate | diff | comparison | revisions | |
| pidgin/resources/Conversations/conversation.ui | file | annotate | diff | comparison | revisions |
--- a/pidgin/pidginconversation.c Mon Feb 03 21:09:03 2025 -0600 +++ b/pidgin/pidginconversation.c Mon Feb 03 21:11:44 2025 -0600 @@ -48,7 +48,9 @@ GtkWidget *history; GtkAdjustment *history_adjustment; - GtkCustomSorter *memberlist_sorter; + GtkWidget *member_list_search_entry; + GtkCustomFilter *member_list_filter; + GtkCustomSorter *member_list_sorter; GtkWidget *input; @@ -269,6 +271,23 @@ } } +static void +pidgin_conversation_members_search_changed_cb(GtkSearchEntry *self, + gpointer data) +{ + PidginConversation *conversation = data; + + gtk_filter_changed(GTK_FILTER(conversation->member_list_filter), + GTK_FILTER_CHANGE_DIFFERENT); + + /* Make sure the search widget has focus, this allows the user to clear a + * search that has filtered out every item in the list via their keyboard. + */ + if(!gtk_widget_has_focus(GTK_WIDGET(self))) { + gtk_widget_grab_focus(GTK_WIDGET(self)); + } +} + static int pidgin_conversation_member_list_sort(gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data) @@ -287,6 +306,17 @@ return purple_contact_info_compare(info_a, info_b); } +static gboolean +pidgin_conversation_member_list_filter(GObject *item, gpointer data) { + PidginConversation *conversation = data; + PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(item); + const char *needle = NULL; + + needle = gtk_editable_get_text(GTK_EDITABLE(conversation->member_list_search_entry)); + + return purple_conversation_member_matches(member, needle); +} + static void pidgin_conversation_message_setup(G_GNUC_UNUSED GtkSignalListItemFactory *self, GObject *object, @@ -375,9 +405,13 @@ pidgin_conversation_init(PidginConversation *conversation) { gtk_widget_init_template(GTK_WIDGET(conversation)); - gtk_custom_sorter_set_sort_func(conversation->memberlist_sorter, + gtk_custom_sorter_set_sort_func(conversation->member_list_sorter, pidgin_conversation_member_list_sort, NULL, NULL); + + gtk_custom_filter_set_filter_func(conversation->member_list_filter, + (GtkCustomFilterFunc)pidgin_conversation_member_list_filter, + conversation, NULL); } static void @@ -416,7 +450,11 @@ gtk_widget_class_bind_template_child(widget_class, PidginConversation, history_adjustment); gtk_widget_class_bind_template_child(widget_class, PidginConversation, - memberlist_sorter); + member_list_search_entry); + gtk_widget_class_bind_template_child(widget_class, PidginConversation, + member_list_filter); + gtk_widget_class_bind_template_child(widget_class, PidginConversation, + member_list_sorter); gtk_widget_class_bind_template_child(widget_class, PidginConversation, input); gtk_widget_class_bind_template_child(widget_class, PidginConversation, @@ -427,6 +465,8 @@ gtk_widget_class_bind_template_callback(widget_class, pidgin_conversation_escape_topic); gtk_widget_class_bind_template_callback(widget_class, + pidgin_conversation_members_search_changed_cb); + gtk_widget_class_bind_template_callback(widget_class, pidgin_conversation_conversation_members_items_changed); gtk_widget_class_bind_template_callback(widget_class, pidgin_conversation_get_status_label);
--- a/pidgin/resources/Conversations/conversation.ui Mon Feb 03 21:09:03 2025 -0600 +++ b/pidgin/resources/Conversations/conversation.ui Mon Feb 03 21:11:44 2025 -0600 @@ -107,8 +107,8 @@ <property name="orientation">vertical</property> <property name="vexpand">true</property> <child> - <object class="GtkLabel"> - <binding name="label"> + <object class="GtkSearchEntry" id="member_list_search_entry"> + <binding name="placeholder-text"> <closure type="gchararray" function="pidgin_conversation_conversation_members_items_changed"> <lookup name="n_items" type="PurpleConversationMembers"> <lookup name="members" type="PurpleConversation"> @@ -117,6 +117,7 @@ </lookup> </closure> </binding> + <signal name="search-changed" handler="pidgin_conversation_members_search_changed_cb"/> </object> </child> <child> @@ -142,15 +143,23 @@ <object class="GtkSingleSelection"> <property name="autoselect">false</property> <property name="model"> - <object class="GtkSortListModel"> - <property name="sorter"> - <object class="GtkCustomSorter" id="memberlist_sorter"/> + <object class="GtkFilterListModel" id="member_list_filter_model"> + <property name="incremental">0</property> + <property name="filter"> + <object class="GtkCustomFilter" id="member_list_filter"/> </property> - <binding name="model"> - <lookup name="members" type="PurpleConversation"> - <lookup name="conversation">PidginConversation</lookup> - </lookup> - </binding> + <property name="model"> + <object class="GtkSortListModel"> + <property name="sorter"> + <object class="GtkCustomSorter" id="member_list_sorter"/> + </property> + <binding name="model"> + <lookup name="members" type="PurpleConversation"> + <lookup name="conversation">PidginConversation</lookup> + </lookup> + </binding> + </object> + </property> </object> </property> </object>