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