| 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(), |
| 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 { |