--- a/ChangeLog.API Sat Dec 30 01:50:32 2023 -0600
+++ b/ChangeLog.API Sat Dec 30 18:22:52 2023 -0600
@@ -990,6 +990,8 @@
* pidgin_blist_visibility_manager_add
* pidgin_blist_visibility_manager_remove
+ * PidginBuddyCompletionEntry + * PidginFilterBuddyCompletionEntryFunc * pidgin_buddy_icon_chooser_new
* pidgin_buddy_icon_get_scale_size
* PidginBuddyList.connection_errors
@@ -1150,6 +1152,7 @@
* pidgin_request_add_block
+ * pidgin_screenname_autocomplete_default_filter * pidgin_scroll_book_get_notebook
@@ -1160,6 +1163,7 @@
* pidgin_set_sensitive_if_input
* pidgin_set_urgent, use gtk_window_set_urgency_hint instead.
+ * pidgin_setup_screenname_autocomplete * pidgin_setup_screenname_autocomplete_with_filter
* pidgin_smiley_add_to_list
--- a/pidgin/gtkrequest.c Sat Dec 30 01:50:32 2023 -0600
+++ b/pidgin/gtkrequest.c Sat Dec 30 18:22:52 2023 -0600
@@ -1960,28 +1960,8 @@
- /* Link autocompletion of entry widgets to account if we found any. */
- if(username_widgets != NULL && account_hint != NULL) {
- while(username_widgets != NULL) {
- PurpleKeyValuePair *pair = username_widgets->data;
- const char *type_hint = pair->key;
- GtkWidget *entry = pair->value;
- show_all = purple_strequal(type_hint, "screenname-all");
- pidgin_setup_screenname_autocomplete(entry, account_hint,
- pidgin_screenname_autocomplete_default_filter,
- GINT_TO_POINTER(show_all));
- purple_key_value_pair_free(pair);
- username_widgets = g_slist_delete_link(username_widgets,
- g_slist_free_full(username_widgets,
- (GDestroyNotify)purple_key_value_pair_free);
+ g_slist_free_full(username_widgets, + (GDestroyNotify)purple_key_value_pair_free); --- a/pidgin/gtkutils.c Sat Dec 30 01:50:32 2023 -0600
+++ b/pidgin/gtkutils.c Sat Dec 30 18:22:52 2023 -0600
@@ -21,12 +21,7 @@
#include <purpleconfig.h>
#include <glib/gi18n-lib.h>
-#include <glib/gstdio.h>
-#include <gdk/gdkkeysyms.h>
@@ -35,46 +30,8 @@
-#include "pidginaccountchooser.h"
-/******************************************************************************
- *****************************************************************************/
- COMPLETION_DISPLAYED_COLUMN, /* displayed completion value */
- COMPLETION_BUDDY_COLUMN, /* buddy name */
- COMPLETION_NORMALIZED_COLUMN, /* UTF-8 normalized & casefolded buddy name */
- COMPLETION_COMPARISON_COLUMN, /* UTF-8 normalized & casefolded value for comparison */
- COMPLETION_ACCOUNT_COLUMN, /* account */
- COMPLETION_COLUMN_COUNT
-/******************************************************************************
- *****************************************************************************/
- PidginFilterBuddyCompletionEntryFunc filter_func;
- gpointer filter_func_user_data;
/******************************************************************************
@@ -134,300 +91,6 @@
-buddyname_completion_match_func(GtkEntryCompletion *completion,
- const char *key, GtkTreeIter *iter,
- G_GNUC_UNUSED gpointer user_data)
- model = gtk_entry_completion_get_model(completion);
- gtk_tree_model_get_value(model, iter, COMPLETION_NORMALIZED_COLUMN, &val1);
- tmp = g_value_get_string(&val1);
- if (tmp != NULL && g_str_has_prefix(tmp, key)) {
- gtk_tree_model_get_value(model, iter, COMPLETION_COMPARISON_COLUMN, &val2);
- tmp = g_value_get_string(&val2);
- if (tmp != NULL && g_str_has_prefix(tmp, key)) {
-buddyname_completion_match_selected_cb(G_GNUC_UNUSED GtkEntryCompletion *completion,
- GtkTreeModel *model, GtkTreeIter *iter,
- PidginCompletionData *data)
- PurpleAccount *account = NULL;
- gtk_tree_model_get_value(model, iter, COMPLETION_BUDDY_COLUMN, &val);
- gtk_editable_set_text(GTK_EDITABLE(data->entry), g_value_get_string(&val));
- gtk_tree_model_get_value(model, iter, COMPLETION_ACCOUNT_COLUMN, &val);
- account = g_value_get_pointer(&val);
- if(!PURPLE_IS_ACCOUNT(account)) {
- if(PIDGIN_IS_ACCOUNT_CHOOSER(data->chooser)) {
- pidgin_account_chooser_set_selected(PIDGIN_ACCOUNT_CHOOSER(data->chooser),
-add_buddyname_autocomplete_entry(GtkListStore *store, const char *buddy_alias, const char *contact_alias,
- const PurpleAccount *account, const char *buddyname)
- gboolean completion_added = FALSE;
- gchar *normalized_buddyname;
- tmp = g_utf8_normalize(buddyname, -1, G_NORMALIZE_DEFAULT);
- normalized_buddyname = g_utf8_casefold(tmp, -1);
- /* There's no sense listing things like: 'xxx "xxx"'
- when the name and buddy alias match. */
- if (buddy_alias && !purple_strequal(buddy_alias, buddyname)) {
- char *completion_entry = g_strdup_printf("%s \"%s\"", buddyname, buddy_alias);
- char *tmp2 = g_utf8_normalize(buddy_alias, -1, G_NORMALIZE_DEFAULT);
- tmp = g_utf8_casefold(tmp2, -1);
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- COMPLETION_DISPLAYED_COLUMN, completion_entry,
- COMPLETION_BUDDY_COLUMN, buddyname,
- COMPLETION_NORMALIZED_COLUMN, normalized_buddyname,
- COMPLETION_COMPARISON_COLUMN, tmp,
- COMPLETION_ACCOUNT_COLUMN, account,
- g_free(completion_entry);
- completion_added = TRUE;
- /* There's no sense listing things like: 'xxx "xxx"'
- when the name and contact alias match. */
- if (contact_alias && !purple_strequal(contact_alias, buddyname)) {
- /* We don't want duplicates when the contact and buddy alias match. */
- if (!purple_strequal(contact_alias, buddy_alias)) {
- char *completion_entry = g_strdup_printf("%s \"%s\"",
- buddyname, contact_alias);
- char *tmp2 = g_utf8_normalize(contact_alias, -1, G_NORMALIZE_DEFAULT);
- tmp = g_utf8_casefold(tmp2, -1);
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- COMPLETION_DISPLAYED_COLUMN, completion_entry,
- COMPLETION_BUDDY_COLUMN, buddyname,
- COMPLETION_NORMALIZED_COLUMN, normalized_buddyname,
- COMPLETION_COMPARISON_COLUMN, tmp,
- COMPLETION_ACCOUNT_COLUMN, account,
- g_free(completion_entry);
- completion_added = TRUE;
- if (completion_added == FALSE) {
- /* Add the buddy's name. */
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- COMPLETION_DISPLAYED_COLUMN, buddyname,
- COMPLETION_BUDDY_COLUMN, buddyname,
- COMPLETION_NORMALIZED_COLUMN, normalized_buddyname,
- COMPLETION_COMPARISON_COLUMN, NULL,
- COMPLETION_ACCOUNT_COLUMN, account,
- g_free(normalized_buddyname);
-add_completion_list(PidginCompletionData *data)
- PurpleBlistNode *gnode, *cnode, *bnode;
- PidginFilterBuddyCompletionEntryFunc filter_func = data->filter_func;
- gpointer user_data = data->filter_func_user_data;
- gtk_list_store_clear(data->store);
- for (gnode = purple_blist_get_default_root(); gnode != NULL;
- if (!PURPLE_IS_GROUP(gnode))
- for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
- if (!PURPLE_IS_META_CONTACT(cnode))
- g_object_get(cnode, "alias", &alias, NULL);
- for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
- PidginBuddyCompletionEntry entry;
- entry.buddy = (PurpleBuddy *) bnode;
- if (filter_func(&entry, user_data)) {
- add_buddyname_autocomplete_entry(data->store,
- purple_buddy_get_contact_alias(entry.buddy),
- purple_buddy_get_account(entry.buddy),
- purple_buddy_get_name(entry.buddy)
-repopulate_autocomplete(G_GNUC_UNUSED gpointer something, gpointer data)
- add_completion_list(data);
-autocomplete_account_added_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
- G_GNUC_UNUSED PurpleAccount *account,
- add_completion_list(data);
-autocomplete_account_removed_cb(G_GNUC_UNUSED PurpleAccountManager *manager,
- G_GNUC_UNUSED PurpleAccount *account,
- add_completion_list(data);
-buddyname_autocomplete_destroyed_cb(GtkWidget *widget, gpointer data)
- PurpleAccountManager *manager = purple_account_manager_get_default();
- purple_signals_disconnect_by_handle(widget);
- g_signal_handlers_disconnect_by_func(manager,
- autocomplete_account_added_cb, data);
- g_signal_handlers_disconnect_by_func(manager,
- autocomplete_account_removed_cb,
-pidgin_setup_screenname_autocomplete(
- GtkWidget *entry, GtkWidget *chooser,
- PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data)
- PidginCompletionData *data;
- PurpleAccountManager *manager = NULL;
- * Store the displayed completion value, the buddy name, the UTF-8
- * normalized & casefolded buddy name, the UTF-8 normalized &
- * casefolded value for comparison, and the account.
- GtkEntryCompletion *completion;
- data = g_new0(PidginCompletionData, 1);
- store = gtk_list_store_new(COMPLETION_COLUMN_COUNT, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
- data->chooser = chooser;
- if (filter_func == NULL) {
- data->filter_func = pidgin_screenname_autocomplete_default_filter;
- data->filter_func_user_data = NULL;
- data->filter_func = filter_func;
- data->filter_func_user_data = user_data;
- add_completion_list(data);
- /* Sort the completion list by buddy name */
- gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),
- COMPLETION_BUDDY_COLUMN,
- completion = gtk_entry_completion_new();
- gtk_entry_completion_set_match_func(completion, buddyname_completion_match_func, NULL, NULL);
- g_signal_connect(G_OBJECT(completion), "match-selected",
- G_CALLBACK(buddyname_completion_match_selected_cb), data);
- gtk_entry_set_completion(GTK_ENTRY(entry), completion);
- g_object_unref(completion);
- gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store));
- gtk_entry_completion_set_text_column(completion, COMPLETION_DISPLAYED_COLUMN);
- purple_signal_connect(purple_connections_get_handle(), "signed-on", entry,
- G_CALLBACK(repopulate_autocomplete), data);
- purple_signal_connect(purple_connections_get_handle(), "signed-off", entry,
- G_CALLBACK(repopulate_autocomplete), data);
- manager = purple_account_manager_get_default();
- g_signal_connect(manager, "added",
- G_CALLBACK(autocomplete_account_added_cb), data);
- g_signal_connect(manager, "removed",
- G_CALLBACK(autocomplete_account_removed_cb), data);
- g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(buddyname_autocomplete_destroyed_cb), data);
-pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *completion_entry, gpointer all_accounts) {
- gboolean all = GPOINTER_TO_INT(all_accounts);
- return all || purple_account_is_connected(purple_buddy_get_account(completion_entry->buddy));
pidgin_add_widget_to_vbox(GtkBox *vbox, const char *widget_label, GtkSizeGroup *sg, GtkWidget *widget, gboolean expand, GtkWidget **p_label)
--- a/pidgin/gtkutils.h Sat Dec 30 01:50:32 2023 -0600
+++ b/pidgin/gtkutils.h Sat Dec 30 18:22:52 2023 -0600
@@ -32,54 +32,10 @@
#include "pidginversion.h"
-PIDGIN_AVAILABLE_TYPE_IN_2_1
-} PidginBuddyCompletionEntry;
-PIDGIN_AVAILABLE_TYPE_IN_2_1
-typedef gboolean (*PidginFilterBuddyCompletionEntryFunc) (const PidginBuddyCompletionEntry *completion_entry, gpointer user_data);
- * pidgin_setup_screenname_autocomplete:
- * @entry: The GtkEntry on which to setup autocomplete.
- * @chooser: A menu for accounts, returned by pidgin_account_chooser_new(). If
- * @chooser is not %NULL, it'll be updated when a username is chosen
- * from the autocomplete list.
- * @filter_func: (scope call): A function for checking if an autocomplete entry
- * should be shown. This can be %NULL.
- * @user_data: The data to be passed to the filter_func function.
- * Add autocompletion of screenames to an entry, supporting a filtering
-void pidgin_setup_screenname_autocomplete(
- GtkWidget *entry, GtkWidget *chooser,
- PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data);
- * pidgin_screenname_autocomplete_default_filter:
- * @completion_entry: The completion entry to filter.
- * @all_accounts: If this is %FALSE, only the autocompletion entries
- * which belong to an online account will be filtered.
- * The default filter function for username autocomplete.
- * Returns: Returns %TRUE if the autocompletion entry is filtered.
-gboolean pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *completion_entry, gpointer all_accounts);
* pidgin_retrieve_user_info:
* @conn: The connection to get information from.
* @name: The user to get information about.