--- a/ChangeLog Mon Jun 20 06:07:38 2011 +0000
+++ b/ChangeLog Mon Jun 20 06:07:46 2011 +0000
@@ -1,5 +1,7 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
+version 2.9.0 (MM/DD/YYYY): version 2.8.1 (MM/DD/YYYY):
* Fix Conversation->Add on AIM and MSN.
--- a/ChangeLog.API Mon Jun 20 06:07:38 2011 +0000
+++ b/ChangeLog.API Mon Jun 20 06:07:46 2011 +0000
@@ -1,5 +1,18 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
+version 2.9.0 (MM/DD/YYYY): + * Hash table and equivalence function to PurpleConvChat struct, + which makes purple_conv_chat_cb_find O(1). The equivalence + function should only be set by a prpl, and must only be set + before any occupants are in the room. + * ui_data opaque pointer to PurpleConvChatBuddy struct. + * purple_conv_chat_set_users + * PurpleConvChat in_room list version 2.8.0 (06/07/2011):
--- a/configure.ac Mon Jun 20 06:07:38 2011 +0000
+++ b/configure.ac Mon Jun 20 06:07:46 2011 +0000
@@ -43,10 +43,10 @@
# Make sure to update finch/libgnt/configure.ac with libgnt version changes.
-m4_define([purple_lt_current], [8])
+m4_define([purple_lt_current], [9]) m4_define([purple_major_version], [2])
-m4_define([purple_minor_version], [8])
-m4_define([purple_micro_version], [1])
+m4_define([purple_minor_version], [9]) +m4_define([purple_micro_version], [0]) m4_define([purple_version_suffix], [devel])
m4_define([purple_version],
[purple_major_version.purple_minor_version.purple_micro_version])
--- a/libpurple/conversation.c Mon Jun 20 06:07:38 2011 +0000
+++ b/libpurple/conversation.c Mon Jun 20 06:07:46 2011 +0000
@@ -70,6 +70,25 @@
+static guint _purple_conversation_user_hash(gconstpointer data) + const gchar *name = data; + gchar *casefold, *collated; + casefold = g_utf8_casefold(name, -1); + collated = g_utf8_collate_key(casefold, -1); + hash = g_str_hash(collated); +static gboolean _purple_conversation_user_equal(gconstpointer a, gconstpointer b) + return !purple_utf8_strcasecmp(a, b); purple_conversations_set_ui_ops(PurpleConversationUiOps *ops)
@@ -393,6 +412,10 @@
conv->u.chat = g_new0(PurpleConvChat, 1);
conv->u.chat->conv = conv;
+ conv->u.chat->user_hash_func = _purple_conversation_user_hash; + conv->u.chat->user_eq_func = _purple_conversation_user_equal; + conv->u.chat->users = g_hash_table_new_full(_purple_conversation_user_hash, + _purple_conversation_user_equal, NULL, NULL); PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat);
chats = g_list_prepend(chats, conv);
@@ -547,6 +570,8 @@
else if (conv->type == PURPLE_CONV_TYPE_CHAT) {
+ g_hash_table_destroy(conv->u.chat->users); + conv->u.chat->users = NULL; g_list_foreach(conv->u.chat->in_room, (GFunc)purple_conv_chat_cb_destroy, NULL);
g_list_free(conv->u.chat->in_room);
@@ -1677,9 +1702,9 @@
cbuddy = purple_conv_chat_cb_new(user, alias, flag);
cbuddy->buddy = purple_find_buddy(conv->account, user) != NULL;
- /* This seems dumb. Why should we set users thousands of times? */
- purple_conv_chat_set_users(chat,
- g_list_prepend(chat->in_room, cbuddy));
+ chat->in_room = g_list_prepend(chat->in_room, cbuddy); + g_hash_table_replace(chat->users, cbuddy->name, cbuddy); cbuddies = g_list_prepend(cbuddies, cbuddy);
@@ -1771,8 +1796,9 @@
flags = purple_conv_chat_user_get_flags(chat, old_user);
cb = purple_conv_chat_cb_new(new_user, new_alias, flags);
cb->buddy = purple_find_buddy(conv->account, new_user) != NULL;
- purple_conv_chat_set_users(chat,
- g_list_prepend(chat->in_room, cb));
+ chat->in_room = g_list_prepend(chat->in_room, cb); + g_hash_table_replace(chat->users, cb->name, cb); if (ops != NULL && ops->chat_rename_user != NULL)
ops->chat_rename_user(conv, old_user, new_user, new_alias);
@@ -1780,8 +1806,8 @@
cb = purple_conv_chat_cb_find(chat, old_user);
- purple_conv_chat_set_users(chat,
- g_list_remove(chat->in_room, cb));
+ chat->in_room = g_list_remove(chat->in_room, cb); + g_hash_table_remove(chat->users, cb->name); purple_conv_chat_cb_destroy(cb);
@@ -1874,8 +1900,8 @@
cb = purple_conv_chat_cb_find(chat, user);
- purple_conv_chat_set_users(chat,
- g_list_remove(chat->in_room, cb));
+ chat->in_room = g_list_remove(chat->in_room, cb); + g_hash_table_remove(chat->users, cb); purple_conv_chat_cb_destroy(cb);
@@ -1943,6 +1969,8 @@
+ g_hash_table_remove_all(chat->users); for (l = users; l; l = l->next)
PurpleConvChatBuddy *cb = l->data;
@@ -1956,7 +1984,7 @@
- purple_conv_chat_set_users(chat, NULL);
@@ -2146,19 +2174,10 @@
purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name)
- PurpleConvChatBuddy *cb = NULL;
g_return_val_if_fail(chat != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
- for (l = purple_conv_chat_get_users(chat); l; l = l->next) {
- if (!g_utf8_collate(cb->name, name))
+ return g_hash_table_lookup(chat->users, name); --- a/libpurple/conversation.h Mon Jun 20 06:07:38 2011 +0000
+++ b/libpurple/conversation.h Mon Jun 20 06:07:46 2011 +0000
@@ -271,7 +271,9 @@
PurpleConversation *conv; /**< The parent conversation. */
- GList *in_room; /**< The users in the room. */
+ GList *in_room; /**< The users in the room. + * @deprecated Will be removed in 3.0.0 GList *ignored; /**< Ignored users. */
char *who; /**< The person who set the topic. */
char *topic; /**< The topic. */
@@ -279,6 +281,19 @@
char *nick; /**< Your nick in this chat. */
gboolean left; /**< We left the chat and kept the window open */
+ GHashTable *users; /**< Hash table of the users in the room. + GHashFunc user_hash_func; /**< Function used to hash entries into + * the users hash. Defaults to a + * case-insensitive collation function. + GEqualFunc user_eq_func; /**< Function used for equality in the + * users hash. Defaults to a wrapper + * around purple_utf8_strcasecmp. @@ -304,6 +319,7 @@
GHashTable *attributes; /**< A hash table of attributes about the user, such as
* real name, user@host, etc.
+ gpointer ui_data; /** < The UI can put whatever it wants here. */ @@ -1065,6 +1081,8 @@
* @param users The list of users.
* @return The list passed.
+ * @deprecated This function will be removed in 3.0.0. You shouldn't be using it anyway. GList *purple_conv_chat_set_users(PurpleConvChat *chat, GList *users);