Mercurial > pidgin.yaz
comparison libpurple/conversation.c @ 28036:8be4bea98188
merged with im.pidgin.pidgin
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 27 Jul 2009 15:22:00 +0900 |
parents | c81386a2b292 ce3bc26aa8cd |
children | f44718de8b06 |
comparison
equal
deleted
inserted
replaced
28022:c81386a2b292 | 28036:8be4bea98188 |
---|---|
38 static GList *conversations = NULL; | 38 static GList *conversations = NULL; |
39 static GList *ims = NULL; | 39 static GList *ims = NULL; |
40 static GList *chats = NULL; | 40 static GList *chats = NULL; |
41 static PurpleConversationUiOps *default_ops = NULL; | 41 static PurpleConversationUiOps *default_ops = NULL; |
42 | 42 |
43 /** | |
44 * A hash table used for efficient lookups of conversations by name. | |
45 * struct _purple_hconv => PurpleConversation* | |
46 */ | |
47 static GHashTable *conversation_cache = NULL; | |
48 | |
49 struct _purple_hconv { | |
50 PurpleConversationType type; | |
51 char *name; | |
52 const PurpleAccount *account; | |
53 }; | |
54 | |
55 static guint _purple_conversations_hconv_hash(struct _purple_hconv *hc) | |
56 { | |
57 return g_str_hash(hc->name) ^ hc->type ^ g_direct_hash(hc->account); | |
58 } | |
59 | |
60 static guint _purple_conversations_hconv_equal(struct _purple_hconv *hc1, struct _purple_hconv *hc2) | |
61 { | |
62 return (hc1->type == hc2->type && | |
63 hc1->account == hc2->account && | |
64 g_str_equal(hc1->name, hc2->name)); | |
65 } | |
66 | |
67 static void _purple_conversations_hconv_free_key(struct _purple_hconv *hc) | |
68 { | |
69 g_free(hc->name); | |
70 g_free(hc); | |
71 } | |
72 | |
43 void | 73 void |
44 purple_conversations_set_ui_ops(PurpleConversationUiOps *ops) | 74 purple_conversations_set_ui_ops(PurpleConversationUiOps *ops) |
45 { | 75 { |
46 default_ops = ops; | 76 default_ops = ops; |
47 } | 77 } |
285 const char *name) | 315 const char *name) |
286 { | 316 { |
287 PurpleConversation *conv; | 317 PurpleConversation *conv; |
288 PurpleConnection *gc; | 318 PurpleConnection *gc; |
289 PurpleConversationUiOps *ops; | 319 PurpleConversationUiOps *ops; |
320 struct _purple_hconv *hc; | |
290 | 321 |
291 g_return_val_if_fail(type != PURPLE_CONV_TYPE_UNKNOWN, NULL); | 322 g_return_val_if_fail(type != PURPLE_CONV_TYPE_UNKNOWN, NULL); |
292 g_return_val_if_fail(account != NULL, NULL); | 323 g_return_val_if_fail(account != NULL, NULL); |
293 g_return_val_if_fail(name != NULL, NULL); | 324 g_return_val_if_fail(name != NULL, NULL); |
294 | 325 |
340 PurpleBuddyIcon *icon; | 371 PurpleBuddyIcon *icon; |
341 conv->u.im = g_new0(PurpleConvIm, 1); | 372 conv->u.im = g_new0(PurpleConvIm, 1); |
342 conv->u.im->conv = conv; | 373 conv->u.im->conv = conv; |
343 PURPLE_DBUS_REGISTER_POINTER(conv->u.im, PurpleConvIm); | 374 PURPLE_DBUS_REGISTER_POINTER(conv->u.im, PurpleConvIm); |
344 | 375 |
345 ims = g_list_append(ims, conv); | 376 ims = g_list_prepend(ims, conv); |
346 if ((icon = purple_buddy_icons_find(account, name))) | 377 if ((icon = purple_buddy_icons_find(account, name))) |
347 { | 378 { |
348 purple_conv_im_set_icon(conv->u.im, icon); | 379 purple_conv_im_set_icon(conv->u.im, icon); |
349 /* purple_conv_im_set_icon refs the icon. */ | 380 /* purple_conv_im_set_icon refs the icon. */ |
350 purple_buddy_icon_unref(icon); | 381 purple_buddy_icon_unref(icon); |
362 | 393 |
363 conv->u.chat = g_new0(PurpleConvChat, 1); | 394 conv->u.chat = g_new0(PurpleConvChat, 1); |
364 conv->u.chat->conv = conv; | 395 conv->u.chat->conv = conv; |
365 PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat); | 396 PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat); |
366 | 397 |
367 chats = g_list_append(chats, conv); | 398 chats = g_list_prepend(chats, conv); |
368 | 399 |
369 if ((disp = purple_connection_get_display_name(account->gc))) | 400 if ((disp = purple_connection_get_display_name(account->gc))) |
370 purple_conv_chat_set_nick(conv->u.chat, disp); | 401 purple_conv_chat_set_nick(conv->u.chat, disp); |
371 else | 402 else |
372 purple_conv_chat_set_nick(conv->u.chat, | 403 purple_conv_chat_set_nick(conv->u.chat, |
377 purple_conversation_set_logging(conv, TRUE); | 408 purple_conversation_set_logging(conv, TRUE); |
378 open_log(conv); | 409 open_log(conv); |
379 } | 410 } |
380 } | 411 } |
381 | 412 |
382 conversations = g_list_append(conversations, conv); | 413 conversations = g_list_prepend(conversations, conv); |
414 | |
415 hc = g_new(struct _purple_hconv, 1); | |
416 hc->name = g_strdup(purple_normalize(account, conv->name)); | |
417 hc->account = account; | |
418 hc->type = type; | |
419 | |
420 g_hash_table_insert(conversation_cache, hc, conv); | |
383 | 421 |
384 /* Auto-set the title. */ | 422 /* Auto-set the title. */ |
385 purple_conversation_autoset_title(conv); | 423 purple_conversation_autoset_title(conv); |
386 | 424 |
387 /* Don't move this.. it needs to be one of the last things done otherwise | 425 /* Don't move this.. it needs to be one of the last things done otherwise |
403 { | 441 { |
404 PurplePluginProtocolInfo *prpl_info = NULL; | 442 PurplePluginProtocolInfo *prpl_info = NULL; |
405 PurpleConversationUiOps *ops; | 443 PurpleConversationUiOps *ops; |
406 PurpleConnection *gc; | 444 PurpleConnection *gc; |
407 const char *name; | 445 const char *name; |
446 struct _purple_hconv hc; | |
408 | 447 |
409 g_return_if_fail(conv != NULL); | 448 g_return_if_fail(conv != NULL); |
410 | 449 |
411 purple_request_close_with_handle(conv); | 450 purple_request_close_with_handle(conv); |
412 | 451 |
479 if(conv->type==PURPLE_CONV_TYPE_IM) | 518 if(conv->type==PURPLE_CONV_TYPE_IM) |
480 ims = g_list_remove(ims, conv); | 519 ims = g_list_remove(ims, conv); |
481 else if(conv->type==PURPLE_CONV_TYPE_CHAT) | 520 else if(conv->type==PURPLE_CONV_TYPE_CHAT) |
482 chats = g_list_remove(chats, conv); | 521 chats = g_list_remove(chats, conv); |
483 | 522 |
523 hc.name = (gchar *)purple_normalize(conv->account, conv->name); | |
524 hc.account = conv->account; | |
525 hc.type = conv->type; | |
526 | |
527 g_hash_table_remove(conversation_cache, &hc); | |
528 | |
484 purple_signal_emit(purple_conversations_get_handle(), | 529 purple_signal_emit(purple_conversations_get_handle(), |
485 "deleting-conversation", conv); | 530 "deleting-conversation", conv); |
486 | 531 |
487 g_free(conv->name); | 532 g_free(conv->name); |
488 g_free(conv->title); | 533 g_free(conv->title); |
709 } | 754 } |
710 | 755 |
711 void | 756 void |
712 purple_conversation_set_name(PurpleConversation *conv, const char *name) | 757 purple_conversation_set_name(PurpleConversation *conv, const char *name) |
713 { | 758 { |
759 struct _purple_hconv *hc; | |
714 g_return_if_fail(conv != NULL); | 760 g_return_if_fail(conv != NULL); |
715 | 761 |
762 hc = g_new(struct _purple_hconv, 1); | |
763 hc->type = conv->type; | |
764 hc->account = conv->account; | |
765 hc->name = (gchar *)purple_normalize(conv->account, conv->name); | |
766 | |
767 g_hash_table_remove(conversation_cache, hc); | |
716 g_free(conv->name); | 768 g_free(conv->name); |
769 | |
717 conv->name = g_strdup(name); | 770 conv->name = g_strdup(name); |
771 hc->name = g_strdup(purple_normalize(conv->account, conv->name)); | |
772 g_hash_table_insert(conversation_cache, hc, conv); | |
718 | 773 |
719 purple_conversation_autoset_title(conv); | 774 purple_conversation_autoset_title(conv); |
720 } | 775 } |
721 | 776 |
722 const char * | 777 const char * |
821 purple_find_conversation_with_account(PurpleConversationType type, | 876 purple_find_conversation_with_account(PurpleConversationType type, |
822 const char *name, | 877 const char *name, |
823 const PurpleAccount *account) | 878 const PurpleAccount *account) |
824 { | 879 { |
825 PurpleConversation *c = NULL; | 880 PurpleConversation *c = NULL; |
826 gchar *name1; | 881 struct _purple_hconv hc; |
827 const gchar *name2; | |
828 GList *cnv; | |
829 | 882 |
830 g_return_val_if_fail(name != NULL, NULL); | 883 g_return_val_if_fail(name != NULL, NULL); |
884 | |
885 hc.name = (gchar *)purple_normalize(account, name); | |
886 hc.account = account; | |
887 hc.type = type; | |
831 | 888 |
832 switch (type) { | 889 switch (type) { |
833 case PURPLE_CONV_TYPE_IM: | 890 case PURPLE_CONV_TYPE_IM: |
834 cnv = purple_get_ims(); | |
835 break; | |
836 case PURPLE_CONV_TYPE_CHAT: | 891 case PURPLE_CONV_TYPE_CHAT: |
837 cnv = purple_get_chats(); | 892 c = g_hash_table_lookup(conversation_cache, &hc); |
838 break; | 893 break; |
839 case PURPLE_CONV_TYPE_ANY: | 894 case PURPLE_CONV_TYPE_ANY: |
840 cnv = purple_get_conversations(); | 895 hc.type = PURPLE_CONV_TYPE_IM; |
896 c = g_hash_table_lookup(conversation_cache, &hc); | |
897 if (!c) { | |
898 hc.type = PURPLE_CONV_TYPE_CHAT; | |
899 c = g_hash_table_lookup(conversation_cache, &hc); | |
900 } | |
841 break; | 901 break; |
842 default: | 902 default: |
843 g_return_val_if_reached(NULL); | 903 g_return_val_if_reached(NULL); |
844 } | 904 } |
845 | |
846 name1 = g_strdup(purple_normalize(account, name)); | |
847 | |
848 for (; cnv != NULL; cnv = cnv->next) { | |
849 c = (PurpleConversation *)cnv->data; | |
850 name2 = purple_normalize(account, purple_conversation_get_name(c)); | |
851 | |
852 if ((account == purple_conversation_get_account(c)) && | |
853 !purple_utf8_strcasecmp(name1, name2)) { | |
854 | |
855 break; | |
856 } | |
857 | |
858 c = NULL; | |
859 } | |
860 | |
861 g_free(name1); | |
862 | 905 |
863 return c; | 906 return c; |
864 } | 907 } |
865 | 908 |
866 void | 909 void |
2227 void | 2270 void |
2228 purple_conversations_init(void) | 2271 purple_conversations_init(void) |
2229 { | 2272 { |
2230 void *handle = purple_conversations_get_handle(); | 2273 void *handle = purple_conversations_get_handle(); |
2231 | 2274 |
2275 conversation_cache = g_hash_table_new_full((GHashFunc)_purple_conversations_hconv_hash, | |
2276 (GEqualFunc)_purple_conversations_hconv_equal, | |
2277 (GDestroyNotify)_purple_conversations_hconv_free_key, NULL); | |
2278 | |
2232 /********************************************************************** | 2279 /********************************************************************** |
2233 * Register preferences | 2280 * Register preferences |
2234 **********************************************************************/ | 2281 **********************************************************************/ |
2235 | 2282 |
2236 /* Conversations */ | 2283 /* Conversations */ |
2516 void | 2563 void |
2517 purple_conversations_uninit(void) | 2564 purple_conversations_uninit(void) |
2518 { | 2565 { |
2519 while (conversations) | 2566 while (conversations) |
2520 purple_conversation_destroy((PurpleConversation*)conversations->data); | 2567 purple_conversation_destroy((PurpleConversation*)conversations->data); |
2568 g_hash_table_destroy(conversation_cache); | |
2521 purple_signals_unregister_by_instance(purple_conversations_get_handle()); | 2569 purple_signals_unregister_by_instance(purple_conversations_get_handle()); |
2522 } | 2570 } |
2523 | 2571 |