libpurple/conversation.c

branch
next.minor
changeset 31900
bd3ee9587add
parent 31643
805b37d317a2
child 31903
d4cd826f9477
equal deleted inserted replaced
31899:c3052075f1cd 31900:bd3ee9587add
68 { 68 {
69 g_free(hc->name); 69 g_free(hc->name);
70 g_free(hc); 70 g_free(hc);
71 } 71 }
72 72
73 static guint _purple_conversation_user_hash(gconstpointer data)
74 {
75 const gchar *name = data;
76 gchar *casefold, *collated;
77 guint hash;
78
79 casefold = g_utf8_casefold(name, -1);
80 collated = g_utf8_collate_key(casefold, -1);
81 hash = g_str_hash(collated);
82 g_free(collated);
83 g_free(casefold);
84 return hash;
85 }
86
87 static gboolean _purple_conversation_user_equal(gconstpointer a, gconstpointer b)
88 {
89 return !purple_utf8_strcasecmp(a, b);
90 }
91
73 void 92 void
74 purple_conversations_set_ui_ops(PurpleConversationUiOps *ops) 93 purple_conversations_set_ui_ops(PurpleConversationUiOps *ops)
75 { 94 {
76 default_ops = ops; 95 default_ops = ops;
77 } 96 }
391 { 410 {
392 const char *disp; 411 const char *disp;
393 412
394 conv->u.chat = g_new0(PurpleConvChat, 1); 413 conv->u.chat = g_new0(PurpleConvChat, 1);
395 conv->u.chat->conv = conv; 414 conv->u.chat->conv = conv;
415 conv->u.chat->user_hash_func = _purple_conversation_user_hash;
416 conv->u.chat->user_eq_func = _purple_conversation_user_equal;
417 conv->u.chat->users = g_hash_table_new_full(_purple_conversation_user_hash,
418 _purple_conversation_user_equal, NULL, NULL);
396 PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat); 419 PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat);
397 420
398 chats = g_list_prepend(chats, conv); 421 chats = g_list_prepend(chats, conv);
399 422
400 if ((disp = purple_connection_get_display_name(account->gc))) 423 if ((disp = purple_connection_get_display_name(account->gc)))
545 PURPLE_DBUS_UNREGISTER_POINTER(conv->u.im); 568 PURPLE_DBUS_UNREGISTER_POINTER(conv->u.im);
546 g_free(conv->u.im); 569 g_free(conv->u.im);
547 conv->u.im = NULL; 570 conv->u.im = NULL;
548 } 571 }
549 else if (conv->type == PURPLE_CONV_TYPE_CHAT) { 572 else if (conv->type == PURPLE_CONV_TYPE_CHAT) {
573 g_hash_table_destroy(conv->u.chat->users);
574 conv->u.chat->users = NULL;
550 575
551 g_list_foreach(conv->u.chat->in_room, (GFunc)purple_conv_chat_cb_destroy, NULL); 576 g_list_foreach(conv->u.chat->in_room, (GFunc)purple_conv_chat_cb_destroy, NULL);
552 g_list_free(conv->u.chat->in_room); 577 g_list_free(conv->u.chat->in_room);
553 578
554 g_list_foreach(conv->u.chat->ignored, (GFunc)g_free, NULL); 579 g_list_foreach(conv->u.chat->ignored, (GFunc)g_free, NULL);
1675 "chat-buddy-joining", conv, user, flag)) || 1700 "chat-buddy-joining", conv, user, flag)) ||
1676 purple_conv_chat_is_user_ignored(chat, user); 1701 purple_conv_chat_is_user_ignored(chat, user);
1677 1702
1678 cbuddy = purple_conv_chat_cb_new(user, alias, flag); 1703 cbuddy = purple_conv_chat_cb_new(user, alias, flag);
1679 cbuddy->buddy = purple_find_buddy(conv->account, user) != NULL; 1704 cbuddy->buddy = purple_find_buddy(conv->account, user) != NULL;
1680 /* This seems dumb. Why should we set users thousands of times? */ 1705
1681 purple_conv_chat_set_users(chat, 1706 chat->in_room = g_list_prepend(chat->in_room, cbuddy);
1682 g_list_prepend(chat->in_room, cbuddy)); 1707 g_hash_table_replace(chat->users, cbuddy->name, cbuddy);
1683 1708
1684 cbuddies = g_list_prepend(cbuddies, cbuddy); 1709 cbuddies = g_list_prepend(cbuddies, cbuddy);
1685 1710
1686 if (!quiet && new_arrivals) { 1711 if (!quiet && new_arrivals) {
1687 char *alias_esc = g_markup_escape_text(alias, -1); 1712 char *alias_esc = g_markup_escape_text(alias, -1);
1769 } 1794 }
1770 1795
1771 flags = purple_conv_chat_user_get_flags(chat, old_user); 1796 flags = purple_conv_chat_user_get_flags(chat, old_user);
1772 cb = purple_conv_chat_cb_new(new_user, new_alias, flags); 1797 cb = purple_conv_chat_cb_new(new_user, new_alias, flags);
1773 cb->buddy = purple_find_buddy(conv->account, new_user) != NULL; 1798 cb->buddy = purple_find_buddy(conv->account, new_user) != NULL;
1774 purple_conv_chat_set_users(chat, 1799
1775 g_list_prepend(chat->in_room, cb)); 1800 chat->in_room = g_list_prepend(chat->in_room, cb);
1801 g_hash_table_replace(chat->users, cb->name, cb);
1776 1802
1777 if (ops != NULL && ops->chat_rename_user != NULL) 1803 if (ops != NULL && ops->chat_rename_user != NULL)
1778 ops->chat_rename_user(conv, old_user, new_user, new_alias); 1804 ops->chat_rename_user(conv, old_user, new_user, new_alias);
1779 1805
1780 cb = purple_conv_chat_cb_find(chat, old_user); 1806 cb = purple_conv_chat_cb_find(chat, old_user);
1781 1807
1782 if (cb) { 1808 if (cb) {
1783 purple_conv_chat_set_users(chat, 1809 chat->in_room = g_list_remove(chat->in_room, cb);
1784 g_list_remove(chat->in_room, cb)); 1810 g_hash_table_remove(chat->users, cb->name);
1785 purple_conv_chat_cb_destroy(cb); 1811 purple_conv_chat_cb_destroy(cb);
1786 } 1812 }
1787 1813
1788 if (purple_conv_chat_is_user_ignored(chat, old_user)) { 1814 if (purple_conv_chat_is_user_ignored(chat, old_user)) {
1789 purple_conv_chat_unignore(chat, old_user); 1815 purple_conv_chat_unignore(chat, old_user);
1872 purple_conv_chat_is_user_ignored(chat, user); 1898 purple_conv_chat_is_user_ignored(chat, user);
1873 1899
1874 cb = purple_conv_chat_cb_find(chat, user); 1900 cb = purple_conv_chat_cb_find(chat, user);
1875 1901
1876 if (cb) { 1902 if (cb) {
1877 purple_conv_chat_set_users(chat, 1903 chat->in_room = g_list_remove(chat->in_room, cb);
1878 g_list_remove(chat->in_room, cb)); 1904 g_hash_table_remove(chat->users, cb);
1879 purple_conv_chat_cb_destroy(cb); 1905 purple_conv_chat_cb_destroy(cb);
1880 } 1906 }
1881 1907
1882 /* NOTE: Don't remove them from ignored in case they re-enter. */ 1908 /* NOTE: Don't remove them from ignored in case they re-enter. */
1883 1909
1941 } 1967 }
1942 ops->chat_remove_users(conv, names); 1968 ops->chat_remove_users(conv, names);
1943 g_list_free(names); 1969 g_list_free(names);
1944 } 1970 }
1945 1971
1972 g_hash_table_remove_all(chat->users);
1973
1946 for (l = users; l; l = l->next) 1974 for (l = users; l; l = l->next)
1947 { 1975 {
1948 PurpleConvChatBuddy *cb = l->data; 1976 PurpleConvChatBuddy *cb = l->data;
1949 1977
1950 purple_signal_emit(purple_conversations_get_handle(), 1978 purple_signal_emit(purple_conversations_get_handle(),
1954 1982
1955 purple_conv_chat_cb_destroy(cb); 1983 purple_conv_chat_cb_destroy(cb);
1956 } 1984 }
1957 1985
1958 g_list_free(users); 1986 g_list_free(users);
1959 purple_conv_chat_set_users(chat, NULL); 1987 chat->in_room = NULL;
1960 } 1988 }
1961 1989
1962 1990
1963 gboolean 1991 gboolean
1964 purple_conv_chat_find_user(PurpleConvChat *chat, const char *user) 1992 purple_conv_chat_find_user(PurpleConvChat *chat, const char *user)
2144 } 2172 }
2145 2173
2146 PurpleConvChatBuddy * 2174 PurpleConvChatBuddy *
2147 purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name) 2175 purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name)
2148 { 2176 {
2149 GList *l;
2150 PurpleConvChatBuddy *cb = NULL;
2151
2152 g_return_val_if_fail(chat != NULL, NULL); 2177 g_return_val_if_fail(chat != NULL, NULL);
2153 g_return_val_if_fail(name != NULL, NULL); 2178 g_return_val_if_fail(name != NULL, NULL);
2154 2179
2155 for (l = purple_conv_chat_get_users(chat); l; l = l->next) { 2180 return g_hash_table_lookup(chat->users, name);
2156 cb = l->data;
2157 if (!g_utf8_collate(cb->name, name))
2158 return cb;
2159 }
2160
2161 return NULL;
2162 } 2181 }
2163 2182
2164 void 2183 void
2165 purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb) 2184 purple_conv_chat_cb_destroy(PurpleConvChatBuddy *cb)
2166 { 2185 {

mercurial