comparison src/gtkconv.c @ 12797:eda1572c788b

[gaim-migrate @ 15144] SF Patch #1390008 from Sadrul "GaimGtkConv: Update tab icons, and some other small changes" This seems to make the Send To menu update better. I haven't seen this patch make anything worse yet, so I'm committing it. If you start seeing weird update errors, let Sadrul or me know. I thought I had a case of the Send To menu not updating even with this patch, but I haven't yet been able to duplicate it. Sadrul's description: '1. Fixes the tab-icons/send-to menu updates by listening for the appropriate signals. This patch removes the "updated" field from conversation-uiops. There is an existing "-updated" signal which can replace the uiops. 2. If having conversations with more than one accounts of a contact, and the buddy-icon of an inactive account is changed, then the new icon is showed (I think), even though it is not the buddy icon for the currently active conversation. This patch fixes that. 3. Emit "buddy-typing" and "-stopped" signal whenever the typing-state is changed. Currently, the typing-state of a conversation is sometimes changed without emitting the signal. This patch fixes that.' I rejected #4. '5. Emits the "chat-left" signal *after* setting "chat->left" to TRUE. 6. Show a buddy for an account only once in the SendTo menu (currently Gaim shows the same buddy more than once if the buddy exists in more than one groups). This is done by keeping a list of GaimPresence -- since that's the only thing the blist-nodes for the same buddy share.' committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Mon, 09 Jan 2006 21:29:53 +0000
parents ca1144227826
children d24bc9737de8
comparison
equal deleted inserted replaced
12796:e8db8f94a2db 12797:eda1572c788b
68 68
69 #include "gtknickcolors.h" 69 #include "gtknickcolors.h"
70 70
71 #define AUTO_RESPONSE "&lt;AUTO-REPLY&gt; : " 71 #define AUTO_RESPONSE "&lt;AUTO-REPLY&gt; : "
72 72
73 typedef enum
74 {
75 GAIM_GTKCONV_SET_TITLE = 1 << 0,
76 GAIM_GTKCONV_BUDDY_ICON = 1 << 1,
77 GAIM_GTKCONV_MENU = 1 << 2,
78 GAIM_GTKCONV_TAB_ICON = 1 << 3,
79 GAIM_GTKCONV_TOPIC = 1 << 4,
80 GAIM_GTKCONV_SMILEY_THEME = 1 << 5,
81 GAIM_GTKCONV_COLORIZE_TITLE = 1 << 6
82 }GaimGtkConvFields;
83
84 #define GAIM_GTKCONV_ALL ((1 << 7) - 1)
85
73 #define SEND_COLOR "#204a87" 86 #define SEND_COLOR "#204a87"
74 #define RECV_COLOR "#cc0000" 87 #define RECV_COLOR "#cc0000"
75 #define HIGHLIGHT_COLOR "#AF7F00" 88 #define HIGHLIGHT_COLOR "#AF7F00"
76 89
77 /* Undef this to turn off "custom-smiley" debug messages */ 90 /* Undef this to turn off "custom-smiley" debug messages */
150 gboolean gaim_gtkconv_has_focus(GaimConversation *conv); 163 gboolean gaim_gtkconv_has_focus(GaimConversation *conv);
151 static void gaim_gtkconv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data); 164 static void gaim_gtkconv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data);
152 static void gaim_gtkconv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data); 165 static void gaim_gtkconv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data);
153 static GdkColor* generate_nick_colors(guint numcolors, GdkColor background); 166 static GdkColor* generate_nick_colors(guint numcolors, GdkColor background);
154 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 167 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
168 static void gaim_gtkconv_update_fields(GaimConversation *conv, GaimGtkConvFields fields);
155 169
156 static GdkColor *get_nick_color(GaimGtkConversation *gtkconv, const char *name) { 170 static GdkColor *get_nick_color(GaimGtkConversation *gtkconv, const char *name) {
157 static GdkColor col; 171 static GdkColor col;
158 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml); 172 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
159 float scale; 173 float scale;
2004 update_typing_icon(gtkconv); 2018 update_typing_icon(gtkconv);
2005 2019
2006 gtk_window_set_title(GTK_WINDOW(gtkconv->win->window), 2020 gtk_window_set_title(GTK_WINDOW(gtkconv->win->window),
2007 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); 2021 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
2008 2022
2009 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ACCOUNT);
2010 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), 2023 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
2011 gaim_account_get_protocol_name(conv->account)); 2024 gaim_account_get_protocol_name(conv->account));
2012 } 2025 }
2013 2026
2014 static void 2027 static void
2129 2142
2130 g_return_if_fail(conv != NULL); 2143 g_return_if_fail(conv != NULL);
2131 2144
2132 gtkconv = GAIM_GTK_CONVERSATION(conv); 2145 gtkconv = GAIM_GTK_CONVERSATION(conv);
2133 win = gtkconv->win; 2146 win = gtkconv->win;
2147 if (conv != gtkconv->active_conv)
2148 return;
2149
2134 name = gaim_conversation_get_name(conv); 2150 name = gaim_conversation_get_name(conv);
2135 account = gaim_conversation_get_account(conv); 2151 account = gaim_conversation_get_account(conv);
2136 2152
2137 status = gaim_gtkconv_get_tab_icon(conv, TRUE); 2153 status = gaim_gtkconv_get_tab_icon(conv, TRUE);
2138 2154
3012 /* The user isn't on the buddy list. */ 3028 /* The user isn't on the buddy list. */
3013 create_sendto_item(menu, sg, &group, NULL, gtkconv->active_conv->account, gtkconv->active_conv->name); 3029 create_sendto_item(menu, sg, &group, NULL, gtkconv->active_conv->account, gtkconv->active_conv->name);
3014 } 3030 }
3015 else 3031 else
3016 { 3032 {
3033 GList *list = NULL, *iter;
3017 for (l = buds; l != NULL; l = l->next) 3034 for (l = buds; l != NULL; l = l->next)
3018 { 3035 {
3019 GaimBlistNode *node; 3036 GaimBlistNode *node;
3020 3037
3021 node = (GaimBlistNode *) gaim_buddy_get_contact((GaimBuddy *)l->data); 3038 node = (GaimBlistNode *) gaim_buddy_get_contact((GaimBuddy *)l->data);
3028 if (!GAIM_BLIST_NODE_IS_BUDDY(node)) 3045 if (!GAIM_BLIST_NODE_IS_BUDDY(node))
3029 continue; 3046 continue;
3030 3047
3031 account = gaim_buddy_get_account(buddy); 3048 account = gaim_buddy_get_account(buddy);
3032 if (gaim_account_is_connected(account)) 3049 if (gaim_account_is_connected(account))
3033 create_sendto_item(menu, sg, &group, buddy, account, gaim_buddy_get_name(buddy)); 3050 {
3051 /* Use the GaimPresence to get unique buddies. */
3052 GaimPresence *presence = gaim_buddy_get_presence(buddy);
3053 if (!g_list_find(list, presence))
3054 list = g_list_prepend(list, presence);
3055 }
3034 } 3056 }
3035 } 3057 }
3036 3058
3059 /* Loop over the list backwards so we get the items in the right order,
3060 * since we did a g_list_prepend() earlier. */
3061 for (iter = g_list_last(list); iter != NULL; iter = iter->prev)
3062 {
3063 GaimPresence *pre = iter->data;
3064 GaimBuddy *buddy = gaim_presence_get_buddies(pre)->data;
3065 create_sendto_item(menu, sg, &group, buddy,
3066 gaim_buddy_get_account(buddy), gaim_buddy_get_name(buddy));
3067 }
3068 g_list_free(list);
3037 g_slist_free(buds); 3069 g_slist_free(buds);
3038 } 3070 }
3039 } 3071 }
3040 3072
3041 g_object_unref(sg); 3073 g_object_unref(sg);
4138 GaimConversation *conv = gaim_gtk_conv_window_get_active_conversation(win); 4170 GaimConversation *conv = gaim_gtk_conv_window_get_active_conversation(win);
4139 4171
4140 if (gaim_conversation_get_type(conv) != GAIM_CONV_TYPE_IM) 4172 if (gaim_conversation_get_type(conv) != GAIM_CONV_TYPE_IM)
4141 continue; 4173 continue;
4142 4174
4143 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE); 4175 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_MENU);
4144 } 4176 }
4145 } 4177 }
4146 4178
4147 /************************************************************************** 4179 /**************************************************************************
4148 * Conversation UI operations 4180 * Conversation UI operations
5415 if (window_icon != NULL) 5447 if (window_icon != NULL)
5416 g_object_unref(G_OBJECT(window_icon)); 5448 g_object_unref(G_OBJECT(window_icon));
5417 } 5449 }
5418 } 5450 }
5419 5451
5420 5452 static void
5421 static void 5453 gaim_gtkconv_update_fields(GaimConversation *conv, GaimGtkConvFields fields)
5422 gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type) 5454 {
5423 { 5455 GaimGtkConversation *gtkconv;
5424 GaimGtkWindow *win; 5456 GaimGtkWindow *win;
5425 GaimGtkConversation *gtkconv;
5426 GaimGtkChatPane *gtkchat;
5427 GaimConvChat *chat;
5428
5429 g_return_if_fail(conv != NULL);
5430 5457
5431 gtkconv = GAIM_GTK_CONVERSATION(conv); 5458 gtkconv = GAIM_GTK_CONVERSATION(conv);
5432 win = gtkconv->win; 5459 if (!gtkconv)
5433 conv = gtkconv->active_conv; /* Gross hack */ 5460 return;
5434 /* Maybe we should just ignore it if conv != gtkconv->active_conv, 5461 win = gaim_gtkconv_get_window(gtkconv);
5435 * instead of the gross hack? 5462 if (!win)
5436 */ 5463 return;
5437 5464
5438 if (type == GAIM_CONV_UPDATE_ACCOUNT) 5465 if (fields & GAIM_GTKCONV_SET_TITLE)
5439 { 5466 {
5440 gaim_conversation_autoset_title(conv); 5467 gaim_conversation_autoset_title(conv);
5441 5468 }
5469
5470 if (fields & GAIM_GTKCONV_BUDDY_ICON)
5471 {
5442 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) 5472 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM)
5443 gaim_gtkconv_update_buddy_icon(conv); 5473 gaim_gtkconv_update_buddy_icon(conv);
5444 5474 }
5445 gaim_gtkconv_update_buttons_by_protocol(conv); 5475
5446 5476 if (fields & GAIM_GTKCONV_MENU)
5447 update_send_to_selection(win); 5477 {
5448 5478 gray_stuff_out(GAIM_GTK_CONVERSATION(conv));
5449 gaim_gtkthemes_smiley_themeize(gtkconv->imhtml); 5479 generate_send_to_items(win);
5450 5480 }
5481
5482 if (fields & GAIM_GTKCONV_TAB_ICON)
5483 {
5451 update_tab_icon(conv); 5484 update_tab_icon(conv);
5452 } 5485 generate_send_to_items(win); /* To update the icons in SendTo menu */
5453 else if (type == GAIM_CONV_UPDATE_TYPING || 5486 }
5454 type == GAIM_CONV_UPDATE_UNSEEN || 5487
5455 type == GAIM_CONV_UPDATE_TITLE) 5488 if ((fields & GAIM_GTKCONV_TOPIC) &&
5489 gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT)
5490 {
5491 const char *topic;
5492 GaimConvChat *chat = GAIM_CONV_CHAT(conv);
5493 GaimGtkChatPane *gtkchat = gtkconv->u.chat;
5494
5495 topic = gaim_conv_chat_get_topic(chat);
5496
5497 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
5498 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
5499 topic ? topic : "", NULL);
5500 }
5501
5502 if (fields & GAIM_GTKCONV_SMILEY_THEME)
5503 gaim_gtkthemes_smiley_themeize(GAIM_GTK_CONVERSATION(conv)->imhtml);
5504
5505 if ((fields & GAIM_GTKCONV_COLORIZE_TITLE) ||
5506 (fields & GAIM_GTKCONV_SET_TITLE))
5456 { 5507 {
5457 char *title; 5508 char *title;
5458 GaimConvIm *im = NULL; 5509 GaimConvIm *im = NULL;
5459 GaimAccount *account = gaim_conversation_get_account(conv); 5510 GaimAccount *account = gaim_conversation_get_account(conv);
5460 /* I think this is a little longer than it needs to be but I'm lazy. */ 5511 /* I think this is a little longer than it needs to be but I'm lazy. */
5514 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title); 5565 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title);
5515 5566
5516 if (gaim_gtk_conv_window_is_active_conversation(conv)) 5567 if (gaim_gtk_conv_window_is_active_conversation(conv))
5517 update_typing_icon(gtkconv); 5568 update_typing_icon(gtkconv);
5518 5569
5519 if (type == GAIM_CONV_UPDATE_TITLE) { 5570 gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title);
5520 gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title); 5571 if (gaim_gtk_conv_window_is_active_conversation(conv))
5521 if (gaim_gtk_conv_window_is_active_conversation(conv)) 5572 gtk_window_set_title(GTK_WINDOW(win->window), title);
5522 gtk_window_set_title(GTK_WINDOW(win->window), title);
5523 }
5524 5573
5525 g_free(title); 5574 g_free(title);
5575 }
5576 }
5577
5578 static void
5579 gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type)
5580 {
5581 GaimGtkConvFields flags = 0;
5582
5583 g_return_if_fail(conv != NULL);
5584
5585 if (type == GAIM_CONV_UPDATE_ACCOUNT)
5586 {
5587 flags = GAIM_GTKCONV_ALL;
5588 }
5589 else if (type == GAIM_CONV_UPDATE_TYPING ||
5590 type == GAIM_CONV_UPDATE_UNSEEN ||
5591 type == GAIM_CONV_UPDATE_TITLE)
5592 {
5593 flags = GAIM_GTKCONV_COLORIZE_TITLE;
5526 } 5594 }
5527 else if (type == GAIM_CONV_UPDATE_TOPIC) 5595 else if (type == GAIM_CONV_UPDATE_TOPIC)
5528 { 5596 {
5529 const char *topic; 5597 flags = GAIM_GTKCONV_TOPIC;
5530 chat = GAIM_CONV_CHAT(conv);
5531 gtkchat = gtkconv->u.chat;
5532
5533 topic = gaim_conv_chat_get_topic(chat);
5534
5535 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
5536 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
5537 topic ? topic : "", NULL);
5538 } 5598 }
5539 else if (type == GAIM_CONV_ACCOUNT_ONLINE || 5599 else if (type == GAIM_CONV_ACCOUNT_ONLINE ||
5540 type == GAIM_CONV_ACCOUNT_OFFLINE) 5600 type == GAIM_CONV_ACCOUNT_OFFLINE)
5541 { 5601 {
5542 gray_stuff_out(GAIM_GTK_CONVERSATION(gaim_gtk_conv_window_get_active_conversation(win))); 5602 flags = GAIM_GTKCONV_MENU | GAIM_GTKCONV_TAB_ICON | GAIM_GTKCONV_SET_TITLE;
5543 generate_send_to_items(win);
5544 update_tab_icon(conv);
5545 gaim_conversation_autoset_title(conv);
5546 } 5603 }
5547 else if (type == GAIM_CONV_UPDATE_AWAY) 5604 else if (type == GAIM_CONV_UPDATE_AWAY)
5548 { 5605 {
5549 update_tab_icon(conv); 5606 flags = GAIM_GTKCONV_TAB_ICON;
5550 } 5607 }
5551 else if (type == GAIM_CONV_UPDATE_ADD || type == GAIM_CONV_UPDATE_REMOVE || 5608 else if (type == GAIM_CONV_UPDATE_ADD ||
5609 type == GAIM_CONV_UPDATE_REMOVE ||
5552 type == GAIM_CONV_UPDATE_CHATLEFT) 5610 type == GAIM_CONV_UPDATE_CHATLEFT)
5553 { 5611 {
5554 gaim_conversation_autoset_title(conv); 5612 flags = GAIM_GTKCONV_SET_TITLE | GAIM_GTKCONV_MENU;
5555 gray_stuff_out(GAIM_GTK_CONVERSATION(conv));
5556 } 5613 }
5557 else if (type == GAIM_CONV_UPDATE_ICON) 5614 else if (type == GAIM_CONV_UPDATE_ICON)
5558 { 5615 {
5559 gaim_gtkconv_update_buddy_icon(conv); 5616 flags = GAIM_GTKCONV_BUDDY_ICON;
5560 } 5617 }
5561 else if (type == GAIM_CONV_UPDATE_FEATURES) 5618 else if (type == GAIM_CONV_UPDATE_FEATURES)
5562 { 5619 {
5563 gray_stuff_out(GAIM_GTK_CONVERSATION(conv)); 5620 flags = GAIM_GTKCONV_MENU;
5564 } 5621 }
5622
5623 gaim_gtkconv_update_fields(conv, flags);
5565 } 5624 }
5566 5625
5567 static GaimConversationUiOps conversation_ui_ops = 5626 static GaimConversationUiOps conversation_ui_ops =
5568 { 5627 {
5569 gaim_gtkconv_new, 5628 gaim_gtkconv_new,
5578 gaim_gtkconv_chat_update_user, /* chat_update_user */ 5637 gaim_gtkconv_chat_update_user, /* chat_update_user */
5579 gaim_gtkconv_present_conversation, /* present */ 5638 gaim_gtkconv_present_conversation, /* present */
5580 gaim_gtkconv_has_focus, /* has_focus */ 5639 gaim_gtkconv_has_focus, /* has_focus */
5581 gaim_gtkconv_custom_smiley_add, /* custom_smiley_add */ 5640 gaim_gtkconv_custom_smiley_add, /* custom_smiley_add */
5582 gaim_gtkconv_custom_smiley_write, /* custom_smiley_write */ 5641 gaim_gtkconv_custom_smiley_write, /* custom_smiley_write */
5583 gaim_gtkconv_custom_smiley_close, /* custom_smiley_close */ 5642 gaim_gtkconv_custom_smiley_close /* custom_smiley_close */
5584 gaim_gtkconv_updated /* updated */
5585 }; 5643 };
5586 5644
5587 GaimConversationUiOps * 5645 GaimConversationUiOps *
5588 gaim_gtk_conversations_get_conv_ui_ops(void) 5646 gaim_gtk_conversations_get_conv_ui_ops(void)
5589 { 5647 {
5624 g_return_if_fail(GAIM_IS_GTK_CONVERSATION(conv)); 5682 g_return_if_fail(GAIM_IS_GTK_CONVERSATION(conv));
5625 g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM); 5683 g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM);
5626 5684
5627 gtkconv = GAIM_GTK_CONVERSATION(conv); 5685 gtkconv = GAIM_GTK_CONVERSATION(conv);
5628 win = gtkconv->win; 5686 win = gtkconv->win;
5687 if (conv != gtkconv->active_conv)
5688 return;
5629 5689
5630 if (!gtkconv->u.im->show_icon) 5690 if (!gtkconv->u.im->show_icon)
5631 return; 5691 return;
5632 5692
5633 account = gaim_conversation_get_account(conv); 5693 account = gaim_conversation_get_account(conv);
6080 return; 6140 return;
6081 6141
6082 gaim_gtkconv_placement_set_current_func(func); 6142 gaim_gtkconv_placement_set_current_func(func);
6083 } 6143 }
6084 6144
6145 static GaimGtkConversation *
6146 get_gtkconv_with_contact(GaimContact *contact)
6147 {
6148 GaimBlistNode *node;
6149
6150 node = ((GaimBlistNode*)contact)->child;
6151
6152 for (; node; node = node->next)
6153 {
6154 GaimBuddy *buddy = (GaimBuddy*)node;
6155 GaimConversation *conv;
6156 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account);
6157 if (conv)
6158 return GAIM_GTK_CONVERSATION(conv);
6159 }
6160 return NULL;
6161 }
6162
6085 static void 6163 static void
6086 account_signed_off_cb(GaimConnection *gc, gpointer event) 6164 account_signed_off_cb(GaimConnection *gc, gpointer event)
6087 { 6165 {
6088 GList *iter; 6166 GList *iter;
6089 GaimAccount *account; 6167 GaimAccount *account;
6092 6170
6093 for (iter = gaim_get_conversations(); iter; iter = iter->next) 6171 for (iter = gaim_get_conversations(); iter; iter = iter->next)
6094 { 6172 {
6095 GaimConversation *conv = iter->data; 6173 GaimConversation *conv = iter->data;
6096 6174
6097 if (gaim_conversation_get_account(conv) == account) 6175 /* This seems fine in theory, but we also need to cover the
6098 gaim_conversation_update(conv, GPOINTER_TO_INT(event)); 6176 * case of this account matching one of the other buddies in
6099 } 6177 * one of the contacts containing the buddy corresponding to
6178 * a conversation. It's easier to just update them all. */
6179 /* if (gaim_conversation_get_account(conv) == account) */
6180 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON |
6181 GAIM_GTKCONV_MENU | GAIM_GTKCONV_COLORIZE_TITLE);
6182 }
6183 }
6184
6185 static gboolean
6186 update_buddy_status_timeout(GaimBuddy *buddy)
6187 {
6188 /* To remove the signing-on/off door icon */
6189 GaimConversation *conv;
6190
6191 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account);
6192 if (conv)
6193 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON);
6194
6195 return FALSE;
6196 }
6197
6198 static void
6199 update_buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *newstatus)
6200 {
6201 GaimGtkConversation *gtkconv;
6202 GaimConversation *conv;
6203
6204 gtkconv = get_gtkconv_with_contact(gaim_buddy_get_contact(buddy));
6205 if (gtkconv)
6206 {
6207 conv = gtkconv->active_conv;
6208 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON | GAIM_GTKCONV_COLORIZE_TITLE);
6209 if ((gaim_status_is_online(old) ^ gaim_status_is_online(newstatus)) != 0)
6210 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_MENU);
6211 }
6212
6213 /* In case a conversation is started after the buddy has signed-on/off */
6214 g_timeout_add(11000, (GSourceFunc)update_buddy_status_timeout, buddy);
6215 }
6216
6217 static void
6218 update_buddy_idle_changed(GaimBuddy *buddy, gboolean old, gboolean newidle)
6219 {
6220 GaimConversation *conv;
6221
6222 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account);
6223 if (conv)
6224 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON);
6225 }
6226
6227 static void
6228 update_buddy_icon(GaimBuddy *buddy)
6229 {
6230 GaimConversation *conv;
6231
6232 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account);
6233 if (conv)
6234 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_BUDDY_ICON);
6235 }
6236
6237 static void
6238 update_buddy_sign(GaimBuddy *buddy, const char *which)
6239 {
6240 GaimPresence *presence;
6241 GaimStatus *on, *off;
6242
6243 presence = gaim_buddy_get_presence(buddy);
6244 if (!presence)
6245 return;
6246 off = gaim_presence_get_status(presence, "offline");
6247 on = gaim_presence_get_status(presence, "available");
6248
6249 if (*(which+1) == 'f')
6250 update_buddy_status_changed(buddy, on, off);
6251 else
6252 update_buddy_status_changed(buddy, off, on);
6253 }
6254
6255 static void
6256 update_conversation_switched(GaimConversation *conv)
6257 {
6258 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON | GAIM_GTKCONV_SET_TITLE |
6259 GAIM_GTKCONV_MENU | GAIM_GTKCONV_BUDDY_ICON);
6260 }
6261
6262 static void
6263 update_buddy_typing(GaimAccount *account, const char *who)
6264 {
6265 GaimConversation *conv;
6266 GaimGtkConversation *gtkconv;
6267
6268 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, account);
6269 if (!conv)
6270 return;
6271
6272 gtkconv = GAIM_GTK_CONVERSATION(conv);
6273 if (gtkconv && gtkconv->active_conv == conv)
6274 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_COLORIZE_TITLE);
6275 }
6276
6277 static void
6278 update_chat(GaimConversation *conv)
6279 {
6280 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TOPIC |
6281 GAIM_GTKCONV_MENU | GAIM_GTKCONV_SET_TITLE);
6282 }
6283
6284 static void
6285 update_chat_topic(GaimConversation *conv, const char *old, const char *new)
6286 {
6287 gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TOPIC);
6100 } 6288 }
6101 6289
6102 void * 6290 void *
6103 gaim_gtk_conversations_get_handle(void) 6291 gaim_gtk_conversations_get_handle(void)
6104 { 6292 {
6274 GINT_TO_POINTER(GAIM_CONV_ACCOUNT_ONLINE)); 6462 GINT_TO_POINTER(GAIM_CONV_ACCOUNT_ONLINE));
6275 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", handle, 6463 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", handle,
6276 G_CALLBACK(account_signed_off_cb), 6464 G_CALLBACK(account_signed_off_cb),
6277 GINT_TO_POINTER(GAIM_CONV_ACCOUNT_OFFLINE)); 6465 GINT_TO_POINTER(GAIM_CONV_ACCOUNT_OFFLINE));
6278 6466
6467 gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg",
6468 handle, G_CALLBACK(received_im_msg_cb), NULL);
6469
6470 gaim_conversations_set_ui_ops(&conversation_ui_ops);
6471
6472 hidden_convwin = gaim_gtk_conv_window_new();
6473 window_list = g_list_remove(window_list, hidden_convwin);
6474
6475 gaim_signal_connect(gaim_accounts_get_handle(), "account-status-changed",
6476 handle, GAIM_CALLBACK(account_status_changed_cb), NULL);
6477
6478 /* Callbacks to update a conversation */
6279 gaim_signal_connect(blist_handle, "buddy-added", handle, 6479 gaim_signal_connect(blist_handle, "buddy-added", handle,
6280 G_CALLBACK(buddy_update_cb), NULL); 6480 G_CALLBACK(buddy_update_cb), NULL);
6281 gaim_signal_connect(blist_handle, "buddy-removed", handle, 6481 gaim_signal_connect(blist_handle, "buddy-removed", handle,
6282 G_CALLBACK(buddy_update_cb), NULL); 6482 G_CALLBACK(buddy_update_cb), NULL);
6283 6483 gaim_signal_connect(blist_handle, "buddy-signed-on",
6284 gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", 6484 handle, GAIM_CALLBACK(update_buddy_sign), "on");
6285 handle, G_CALLBACK(received_im_msg_cb), NULL); 6485 gaim_signal_connect(blist_handle, "buddy-signed-off",
6286 6486 handle, GAIM_CALLBACK(update_buddy_sign), "off");
6287 gaim_conversations_set_ui_ops(&conversation_ui_ops); 6487 gaim_signal_connect(blist_handle, "buddy-status-changed",
6288 6488 handle, GAIM_CALLBACK(update_buddy_status_changed), NULL);
6289 hidden_convwin = gaim_gtk_conv_window_new(); 6489 gaim_signal_connect(blist_handle, "buddy-idle-changed",
6290 window_list = g_list_remove(window_list, hidden_convwin); 6490 handle, GAIM_CALLBACK(update_buddy_idle_changed), NULL);
6291 6491 gaim_signal_connect(blist_handle, "buddy-icon-changed",
6292 gaim_signal_connect(gaim_accounts_get_handle(), "account-status-changed", 6492 handle, GAIM_CALLBACK(update_buddy_icon), NULL);
6293 handle, GAIM_CALLBACK(account_status_changed_cb), NULL); 6493 gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing",
6494 handle, GAIM_CALLBACK(update_buddy_typing), NULL);
6495 gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing-stopped",
6496 handle, GAIM_CALLBACK(update_buddy_typing), NULL);
6497 gaim_signal_connect(gaim_gtk_conversations_get_handle(), "conversation-switched",
6498 handle, GAIM_CALLBACK(update_conversation_switched), NULL);
6499 gaim_signal_connect(gaim_conversations_get_handle(), "chat-left", handle,
6500 GAIM_CALLBACK(update_chat), NULL);
6501 gaim_signal_connect(gaim_conversations_get_handle(), "chat-joined", handle,
6502 GAIM_CALLBACK(update_chat), NULL);
6503 gaim_signal_connect(gaim_conversations_get_handle(), "chat-topic-changed", handle,
6504 GAIM_CALLBACK(update_chat_topic), NULL);
6505 gaim_signal_connect(gaim_conversations_get_handle(), "conversation-updated", handle,
6506 GAIM_CALLBACK(gaim_gtkconv_updated), NULL);
6294 } 6507 }
6295 6508
6296 void 6509 void
6297 gaim_gtk_conversations_uninit(void) 6510 gaim_gtk_conversations_uninit(void)
6298 { 6511 {
6485 6698
6486 if (state > gtkconv->unseen_state) 6699 if (state > gtkconv->unseen_state)
6487 gtkconv->unseen_state = state; 6700 gtkconv->unseen_state = state;
6488 } 6701 }
6489 6702
6490 /* emit update signal to notify of count and possible unseen state change */ 6703 gaim_gtkconv_update_fields(gtkconv->active_conv, GAIM_GTKCONV_COLORIZE_TITLE);
6491 gaim_conversation_update(gtkconv->active_conv, GAIM_CONV_UPDATE_UNSEEN);
6492 } 6704 }
6493 6705
6494 /* 6706 /*
6495 * When a conversation window is focused, we know the user 6707 * When a conversation window is focused, we know the user
6496 * has looked at it so we know there are no longer unseen 6708 * has looked at it so we know there are no longer unseen