# HG changeset patch # User Richard Laager # Date 1136842193 0 # Node ID eda1572c788b3646e421dd56a77c0171b401c8ff # Parent e8db8f94a2dbaf4b3c4a071815769d4f9f8e75f4 [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 diff -r e8db8f94a2db -r eda1572c788b plugins/ChangeLog.API --- a/plugins/ChangeLog.API Mon Jan 09 16:04:04 2006 +0000 +++ b/plugins/ChangeLog.API Mon Jan 09 21:29:53 2006 +0000 @@ -132,6 +132,7 @@ * GaimConvImFlags and GaimConvChatFlags; use GaimMessageFlags instead * cb and user_data from the ops in GaimNotifyUiOps: This is now handled by the notify API in the core. + * GaimConversationUiOps.updated: use the conversation-updated signal Added: * gaim_prefs_disconnect_by_handle() @@ -226,19 +227,20 @@ * Signal propagation now stops after a handler returns a non-NULL value. This value is now returned. Previously, all registered handlers were called and the value from the last handler was used. + * "buddy-typing" and "buddy-typing-stopped": replaced the GaimConversation* + with GaimAccount*, const char *name. Also, the signal is now emitted + regardless of whether a conversation exists and regardless of whether + the user is on the buddy list. + * "chat-invited" handlers can now return a value to control what happens + to the invite (accept, reject, prompt the user). + * "chat-left": Emitted *after* setting chat->left to TRUE. + * "drawing-tooltip": the second argument is now a GString* instead of + a char** + * "drawing-tooltip": added the "full" argument * "received-im-msg" and "received-chat-msg" to match, both now pass a conversation pointer and flags * "receiving-im-msg" and "receving-chat-msg" to match, both now pass a conversation pointer and a pointer to the flags. - * "drawing-tooltip": the second argument is now a GString* instead of - a char** - * "drawing-tooltip": added the "full" argument - * "chat-invited" handlers can now return a value to control what happens - to the invite (accept, reject, prompt the user). - * "buddy-typing" and "buddy-typing-stopped": replaced the GaimConversation* - with GaimAccount*, const char *name. Also, the signal is now emitted - regardless of whether a conversation exists and regardless of whether - the user is on the buddy list. Signals - Added: (See the Doxygen docs for details on all signals.) * "account-disabled" @@ -275,7 +277,7 @@ * "buddy-idle": replaced by buddy-idle-changed * "buddy-unidle": replaced by buddy-idle-changed * "buddy-icon-cached": replaced by buddy-icon-changed - * "conversation-drag-end": replaced by "conversation-dragging" + * "conversation-drag-end": replaced by conversation-dragging * "conversation-switching" version 1.5.0 (8/11/2005): diff -r e8db8f94a2db -r eda1572c788b src/blist.c --- a/src/blist.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/blist.c Mon Jan 09 21:29:53 2006 +0000 @@ -741,7 +741,6 @@ GaimBlistUiOps *ops = gaimbuddylist->ui_ops; GaimPresence *presence; GaimStatus *status; - GaimConversation *conv; g_return_if_fail(buddy != NULL); @@ -785,9 +784,6 @@ gaim_contact_invalidate_priority_buddy(gaim_buddy_get_contact(buddy)); if (ops && ops->update) ops->update(gaimbuddylist, (GaimBlistNode *)buddy); - - if ((conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account))) - gaim_conversation_update(conv, GAIM_CONV_UPDATE_AWAY); } void gaim_blist_update_buddy_icon(GaimBuddy *buddy) diff -r e8db8f94a2db -r eda1572c788b src/conversation.c --- a/src/conversation.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/conversation.c Mon Jan 09 21:29:53 2006 +0000 @@ -943,15 +943,8 @@ void gaim_conversation_update(GaimConversation *conv, GaimConvUpdateType type) { - GaimConversationUiOps *ops; - g_return_if_fail(conv != NULL); - ops = gaim_conversation_get_ui_ops(conv); - - if (ops != NULL && ops->updated != NULL) - ops->updated(conv, type); - gaim_signal_emit(gaim_conversations_get_handle(), "conversation-updated", conv, type); } @@ -997,7 +990,21 @@ { g_return_if_fail(im != NULL); - im->typing_state = state; + if (im->typing_state != state) + { + im->typing_state = state; + + if (state == GAIM_TYPING) + { + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing", im->conv->account, im->conv->name); + } + else + { + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing-stopped", im->conv->account, im->conv->name); + } + } } GaimTypingState diff -r e8db8f94a2db -r eda1572c788b src/conversation.h --- a/src/conversation.h Mon Jan 09 16:04:04 2006 +0000 +++ b/src/conversation.h Mon Jan 09 21:29:53 2006 +0000 @@ -169,10 +169,6 @@ void (*custom_smiley_write)(GaimConversation *conv, const char *smile, const guchar *data, gsize size); void (*custom_smiley_close)(GaimConversation *conv, const char *smile); - - /* Events */ - void (*updated)(GaimConversation *conv, GaimConvUpdateType type); - }; /** diff -r e8db8f94a2db -r eda1572c788b src/gtkblist.c --- a/src/gtkblist.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/gtkblist.c Mon Jan 09 21:29:53 2006 +0000 @@ -2550,7 +2550,7 @@ { N_("/Buddies/_Add Buddy..."), "B", gaim_gtk_blist_add_buddy_cb, 0, "", GTK_STOCK_ADD }, { N_("/Buddies/Add C_hat..."), NULL, gaim_gtk_blist_add_chat_cb, 0, "", GTK_STOCK_ADD }, { N_("/Buddies/Add _Group..."), NULL, gaim_blist_request_add_group, 0, "", GTK_STOCK_ADD }, - { "/Buddies/sep2", NULL, NULL, 0, "", NULL }, + { "/Buddies/sep3", NULL, NULL, 0, "" }, { N_("/Buddies/_Quit"), "Q", gaim_core_quit, 0, "", GTK_STOCK_QUIT }, /* Accounts menu */ @@ -4213,7 +4213,7 @@ static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node) { - if(!gtkblist) + if(!gtkblist || !node) return; switch(node->type) { @@ -4383,7 +4383,6 @@ c = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, data->account); if (c != NULL) { gaim_buddy_icon_update(gaim_conv_im_get_icon(GAIM_CONV_IM(c))); - gaim_conversation_update(c, GAIM_CONV_UPDATE_ADD); } } @@ -4534,8 +4533,6 @@ GaimChat *chat; GaimGroup *group; const char *group_name; - char *chat_name = NULL; - GaimConversation *conv = NULL; const char *value; components = g_hash_table_new_full(g_str_hash, g_str_equal, @@ -4575,20 +4572,6 @@ if (chat != NULL) { gaim_blist_add_chat(chat, group, NULL); - - if (GAIM_PLUGIN_PROTOCOL_INFO(data->account->gc->prpl)->get_chat_name != NULL) - chat_name = GAIM_PLUGIN_PROTOCOL_INFO( - data->account->gc->prpl)->get_chat_name(chat->components); - - if (chat_name != NULL) { - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, - chat_name, - data->account); - g_free(chat_name); - } - - if (conv != NULL) - gaim_conversation_update(conv, GAIM_CONV_UPDATE_ADD); } gtk_widget_destroy(data->window); @@ -5014,21 +4997,12 @@ static gboolean buddy_signonoff_timeout_cb(GaimBuddy *buddy) { struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode*)buddy)->ui_data; - GaimConversation *conv; gtknode->recent_signonoff = FALSE; gtknode->recent_signonoff_timer = 0; gaim_gtk_blist_update(NULL, (GaimBlistNode*)buddy); - if((conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account))) { - if(GAIM_BUDDY_IS_ONLINE(buddy)) { - gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE); - } else { - gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_OFFLINE); - } - } - return FALSE; } diff -r e8db8f94a2db -r eda1572c788b src/gtkconv.c --- a/src/gtkconv.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/gtkconv.c Mon Jan 09 21:29:53 2006 +0000 @@ -70,6 +70,19 @@ #define AUTO_RESPONSE "<AUTO-REPLY> : " +typedef enum +{ + GAIM_GTKCONV_SET_TITLE = 1 << 0, + GAIM_GTKCONV_BUDDY_ICON = 1 << 1, + GAIM_GTKCONV_MENU = 1 << 2, + GAIM_GTKCONV_TAB_ICON = 1 << 3, + GAIM_GTKCONV_TOPIC = 1 << 4, + GAIM_GTKCONV_SMILEY_THEME = 1 << 5, + GAIM_GTKCONV_COLORIZE_TITLE = 1 << 6 +}GaimGtkConvFields; + +#define GAIM_GTKCONV_ALL ((1 << 7) - 1) + #define SEND_COLOR "#204a87" #define RECV_COLOR "#cc0000" #define HIGHLIGHT_COLOR "#AF7F00" @@ -152,6 +165,7 @@ static void gaim_gtkconv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data); static GdkColor* generate_nick_colors(guint numcolors, GdkColor background); static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); +static void gaim_gtkconv_update_fields(GaimConversation *conv, GaimGtkConvFields fields); static GdkColor *get_nick_color(GaimGtkConversation *gtkconv, const char *name) { static GdkColor col; @@ -2006,7 +2020,6 @@ gtk_window_set_title(GTK_WINDOW(gtkconv->win->window), gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); - gaim_conversation_update(conv, GAIM_CONV_UPDATE_ACCOUNT); gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), gaim_account_get_protocol_name(conv->account)); } @@ -2131,6 +2144,9 @@ gtkconv = GAIM_GTK_CONVERSATION(conv); win = gtkconv->win; + if (conv != gtkconv->active_conv) + return; + name = gaim_conversation_get_name(conv); account = gaim_conversation_get_account(conv); @@ -3014,6 +3030,7 @@ } else { + GList *list = NULL, *iter; for (l = buds; l != NULL; l = l->next) { GaimBlistNode *node; @@ -3030,10 +3047,25 @@ account = gaim_buddy_get_account(buddy); if (gaim_account_is_connected(account)) - create_sendto_item(menu, sg, &group, buddy, account, gaim_buddy_get_name(buddy)); + { + /* Use the GaimPresence to get unique buddies. */ + GaimPresence *presence = gaim_buddy_get_presence(buddy); + if (!g_list_find(list, presence)) + list = g_list_prepend(list, presence); + } } } + /* Loop over the list backwards so we get the items in the right order, + * since we did a g_list_prepend() earlier. */ + for (iter = g_list_last(list); iter != NULL; iter = iter->prev) + { + GaimPresence *pre = iter->data; + GaimBuddy *buddy = gaim_presence_get_buddies(pre)->data; + create_sendto_item(menu, sg, &group, buddy, + gaim_buddy_get_account(buddy), gaim_buddy_get_name(buddy)); + } + g_list_free(list); g_slist_free(buds); } } @@ -4140,7 +4172,7 @@ if (gaim_conversation_get_type(conv) != GAIM_CONV_TYPE_IM) continue; - gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE); + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_MENU); } } @@ -5417,42 +5449,61 @@ } } - static void -gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type) -{ +gaim_gtkconv_update_fields(GaimConversation *conv, GaimGtkConvFields fields) +{ + GaimGtkConversation *gtkconv; GaimGtkWindow *win; - GaimGtkConversation *gtkconv; - GaimGtkChatPane *gtkchat; - GaimConvChat *chat; - - g_return_if_fail(conv != NULL); gtkconv = GAIM_GTK_CONVERSATION(conv); - win = gtkconv->win; - conv = gtkconv->active_conv; /* Gross hack */ - /* Maybe we should just ignore it if conv != gtkconv->active_conv, - * instead of the gross hack? - */ - - if (type == GAIM_CONV_UPDATE_ACCOUNT) + if (!gtkconv) + return; + win = gaim_gtkconv_get_window(gtkconv); + if (!win) + return; + + if (fields & GAIM_GTKCONV_SET_TITLE) { gaim_conversation_autoset_title(conv); - + } + + if (fields & GAIM_GTKCONV_BUDDY_ICON) + { if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) gaim_gtkconv_update_buddy_icon(conv); - - gaim_gtkconv_update_buttons_by_protocol(conv); - - update_send_to_selection(win); - - gaim_gtkthemes_smiley_themeize(gtkconv->imhtml); - + } + + if (fields & GAIM_GTKCONV_MENU) + { + gray_stuff_out(GAIM_GTK_CONVERSATION(conv)); + generate_send_to_items(win); + } + + if (fields & GAIM_GTKCONV_TAB_ICON) + { update_tab_icon(conv); - } - else if (type == GAIM_CONV_UPDATE_TYPING || - type == GAIM_CONV_UPDATE_UNSEEN || - type == GAIM_CONV_UPDATE_TITLE) + generate_send_to_items(win); /* To update the icons in SendTo menu */ + } + + if ((fields & GAIM_GTKCONV_TOPIC) && + gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) + { + const char *topic; + GaimConvChat *chat = GAIM_CONV_CHAT(conv); + GaimGtkChatPane *gtkchat = gtkconv->u.chat; + + topic = gaim_conv_chat_get_topic(chat); + + gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : ""); + gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, + topic ? topic : "", NULL); + } + + if (fields & GAIM_GTKCONV_SMILEY_THEME) + gaim_gtkthemes_smiley_themeize(GAIM_GTK_CONVERSATION(conv)->imhtml); + + if ((fields & GAIM_GTKCONV_COLORIZE_TITLE) || + (fields & GAIM_GTKCONV_SET_TITLE)) { char *title; GaimConvIm *im = NULL; @@ -5516,52 +5567,60 @@ if (gaim_gtk_conv_window_is_active_conversation(conv)) update_typing_icon(gtkconv); - if (type == GAIM_CONV_UPDATE_TITLE) { - gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title); - if (gaim_gtk_conv_window_is_active_conversation(conv)) - gtk_window_set_title(GTK_WINDOW(win->window), title); - } + gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title); + if (gaim_gtk_conv_window_is_active_conversation(conv)) + gtk_window_set_title(GTK_WINDOW(win->window), title); g_free(title); } +} + +static void +gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type) +{ + GaimGtkConvFields flags = 0; + + g_return_if_fail(conv != NULL); + + if (type == GAIM_CONV_UPDATE_ACCOUNT) + { + flags = GAIM_GTKCONV_ALL; + } + else if (type == GAIM_CONV_UPDATE_TYPING || + type == GAIM_CONV_UPDATE_UNSEEN || + type == GAIM_CONV_UPDATE_TITLE) + { + flags = GAIM_GTKCONV_COLORIZE_TITLE; + } else if (type == GAIM_CONV_UPDATE_TOPIC) { - const char *topic; - chat = GAIM_CONV_CHAT(conv); - gtkchat = gtkconv->u.chat; - - topic = gaim_conv_chat_get_topic(chat); - - gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : ""); - gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, - topic ? topic : "", NULL); + flags = GAIM_GTKCONV_TOPIC; } else if (type == GAIM_CONV_ACCOUNT_ONLINE || - type == GAIM_CONV_ACCOUNT_OFFLINE) + type == GAIM_CONV_ACCOUNT_OFFLINE) { - gray_stuff_out(GAIM_GTK_CONVERSATION(gaim_gtk_conv_window_get_active_conversation(win))); - generate_send_to_items(win); - update_tab_icon(conv); - gaim_conversation_autoset_title(conv); + flags = GAIM_GTKCONV_MENU | GAIM_GTKCONV_TAB_ICON | GAIM_GTKCONV_SET_TITLE; } else if (type == GAIM_CONV_UPDATE_AWAY) { - update_tab_icon(conv); - } - else if (type == GAIM_CONV_UPDATE_ADD || type == GAIM_CONV_UPDATE_REMOVE || + flags = GAIM_GTKCONV_TAB_ICON; + } + else if (type == GAIM_CONV_UPDATE_ADD || + type == GAIM_CONV_UPDATE_REMOVE || type == GAIM_CONV_UPDATE_CHATLEFT) { - gaim_conversation_autoset_title(conv); - gray_stuff_out(GAIM_GTK_CONVERSATION(conv)); + flags = GAIM_GTKCONV_SET_TITLE | GAIM_GTKCONV_MENU; } else if (type == GAIM_CONV_UPDATE_ICON) { - gaim_gtkconv_update_buddy_icon(conv); + flags = GAIM_GTKCONV_BUDDY_ICON; } else if (type == GAIM_CONV_UPDATE_FEATURES) { - gray_stuff_out(GAIM_GTK_CONVERSATION(conv)); - } + flags = GAIM_GTKCONV_MENU; + } + + gaim_gtkconv_update_fields(conv, flags); } static GaimConversationUiOps conversation_ui_ops = @@ -5580,8 +5639,7 @@ gaim_gtkconv_has_focus, /* has_focus */ gaim_gtkconv_custom_smiley_add, /* custom_smiley_add */ gaim_gtkconv_custom_smiley_write, /* custom_smiley_write */ - gaim_gtkconv_custom_smiley_close, /* custom_smiley_close */ - gaim_gtkconv_updated /* updated */ + gaim_gtkconv_custom_smiley_close /* custom_smiley_close */ }; GaimConversationUiOps * @@ -5626,6 +5684,8 @@ gtkconv = GAIM_GTK_CONVERSATION(conv); win = gtkconv->win; + if (conv != gtkconv->active_conv) + return; if (!gtkconv->u.im->show_icon) return; @@ -6082,6 +6142,24 @@ gaim_gtkconv_placement_set_current_func(func); } +static GaimGtkConversation * +get_gtkconv_with_contact(GaimContact *contact) +{ + GaimBlistNode *node; + + node = ((GaimBlistNode*)contact)->child; + + for (; node; node = node->next) + { + GaimBuddy *buddy = (GaimBuddy*)node; + GaimConversation *conv; + conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account); + if (conv) + return GAIM_GTK_CONVERSATION(conv); + } + return NULL; +} + static void account_signed_off_cb(GaimConnection *gc, gpointer event) { @@ -6094,9 +6172,119 @@ { GaimConversation *conv = iter->data; - if (gaim_conversation_get_account(conv) == account) - gaim_conversation_update(conv, GPOINTER_TO_INT(event)); - } + /* This seems fine in theory, but we also need to cover the + * case of this account matching one of the other buddies in + * one of the contacts containing the buddy corresponding to + * a conversation. It's easier to just update them all. */ + /* if (gaim_conversation_get_account(conv) == account) */ + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON | + GAIM_GTKCONV_MENU | GAIM_GTKCONV_COLORIZE_TITLE); + } +} + +static gboolean +update_buddy_status_timeout(GaimBuddy *buddy) +{ + /* To remove the signing-on/off door icon */ + GaimConversation *conv; + + conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account); + if (conv) + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON); + + return FALSE; +} + +static void +update_buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *newstatus) +{ + GaimGtkConversation *gtkconv; + GaimConversation *conv; + + gtkconv = get_gtkconv_with_contact(gaim_buddy_get_contact(buddy)); + if (gtkconv) + { + conv = gtkconv->active_conv; + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON | GAIM_GTKCONV_COLORIZE_TITLE); + if ((gaim_status_is_online(old) ^ gaim_status_is_online(newstatus)) != 0) + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_MENU); + } + + /* In case a conversation is started after the buddy has signed-on/off */ + g_timeout_add(11000, (GSourceFunc)update_buddy_status_timeout, buddy); +} + +static void +update_buddy_idle_changed(GaimBuddy *buddy, gboolean old, gboolean newidle) +{ + GaimConversation *conv; + + conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account); + if (conv) + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON); +} + +static void +update_buddy_icon(GaimBuddy *buddy) +{ + GaimConversation *conv; + + conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account); + if (conv) + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_BUDDY_ICON); +} + +static void +update_buddy_sign(GaimBuddy *buddy, const char *which) +{ + GaimPresence *presence; + GaimStatus *on, *off; + + presence = gaim_buddy_get_presence(buddy); + if (!presence) + return; + off = gaim_presence_get_status(presence, "offline"); + on = gaim_presence_get_status(presence, "available"); + + if (*(which+1) == 'f') + update_buddy_status_changed(buddy, on, off); + else + update_buddy_status_changed(buddy, off, on); +} + +static void +update_conversation_switched(GaimConversation *conv) +{ + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TAB_ICON | GAIM_GTKCONV_SET_TITLE | + GAIM_GTKCONV_MENU | GAIM_GTKCONV_BUDDY_ICON); +} + +static void +update_buddy_typing(GaimAccount *account, const char *who) +{ + GaimConversation *conv; + GaimGtkConversation *gtkconv; + + conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, account); + if (!conv) + return; + + gtkconv = GAIM_GTK_CONVERSATION(conv); + if (gtkconv && gtkconv->active_conv == conv) + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_COLORIZE_TITLE); +} + +static void +update_chat(GaimConversation *conv) +{ + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TOPIC | + GAIM_GTKCONV_MENU | GAIM_GTKCONV_SET_TITLE); +} + +static void +update_chat_topic(GaimConversation *conv, const char *old, const char *new) +{ + gaim_gtkconv_update_fields(conv, GAIM_GTKCONV_TOPIC); } void * @@ -6276,11 +6464,6 @@ G_CALLBACK(account_signed_off_cb), GINT_TO_POINTER(GAIM_CONV_ACCOUNT_OFFLINE)); - gaim_signal_connect(blist_handle, "buddy-added", handle, - G_CALLBACK(buddy_update_cb), NULL); - gaim_signal_connect(blist_handle, "buddy-removed", handle, - G_CALLBACK(buddy_update_cb), NULL); - gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", handle, G_CALLBACK(received_im_msg_cb), NULL); @@ -6291,6 +6474,36 @@ gaim_signal_connect(gaim_accounts_get_handle(), "account-status-changed", handle, GAIM_CALLBACK(account_status_changed_cb), NULL); + + /* Callbacks to update a conversation */ + gaim_signal_connect(blist_handle, "buddy-added", handle, + G_CALLBACK(buddy_update_cb), NULL); + gaim_signal_connect(blist_handle, "buddy-removed", handle, + G_CALLBACK(buddy_update_cb), NULL); + gaim_signal_connect(blist_handle, "buddy-signed-on", + handle, GAIM_CALLBACK(update_buddy_sign), "on"); + gaim_signal_connect(blist_handle, "buddy-signed-off", + handle, GAIM_CALLBACK(update_buddy_sign), "off"); + gaim_signal_connect(blist_handle, "buddy-status-changed", + handle, GAIM_CALLBACK(update_buddy_status_changed), NULL); + gaim_signal_connect(blist_handle, "buddy-idle-changed", + handle, GAIM_CALLBACK(update_buddy_idle_changed), NULL); + gaim_signal_connect(blist_handle, "buddy-icon-changed", + handle, GAIM_CALLBACK(update_buddy_icon), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing", + handle, GAIM_CALLBACK(update_buddy_typing), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "buddy-typing-stopped", + handle, GAIM_CALLBACK(update_buddy_typing), NULL); + gaim_signal_connect(gaim_gtk_conversations_get_handle(), "conversation-switched", + handle, GAIM_CALLBACK(update_conversation_switched), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "chat-left", handle, + GAIM_CALLBACK(update_chat), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "chat-joined", handle, + GAIM_CALLBACK(update_chat), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "chat-topic-changed", handle, + GAIM_CALLBACK(update_chat_topic), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "conversation-updated", handle, + GAIM_CALLBACK(gaim_gtkconv_updated), NULL); } void @@ -6487,8 +6700,7 @@ gtkconv->unseen_state = state; } - /* emit update signal to notify of count and possible unseen state change */ - gaim_conversation_update(gtkconv->active_conv, GAIM_CONV_UPDATE_UNSEEN); + gaim_gtkconv_update_fields(gtkconv->active_conv, GAIM_GTKCONV_COLORIZE_TITLE); } /* diff -r e8db8f94a2db -r eda1572c788b src/gtkdialogs.c --- a/src/gtkdialogs.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/gtkdialogs.c Mon Jan 09 21:29:53 2006 +0000 @@ -886,18 +886,11 @@ while (bnode) { GaimBuddy *buddy; if (GAIM_BLIST_NODE_IS_BUDDY(bnode)) { - GaimConversation *conv; buddy = (GaimBuddy*)bnode; bnode = bnode->next; - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, - buddy->name, - buddy->account); if (gaim_account_is_connected(buddy->account)) { gaim_account_remove_buddy(buddy->account, buddy, group); gaim_blist_remove_buddy(buddy); - if (conv) - gaim_conversation_update(conv, - GAIM_CONV_UPDATE_REMOVE); } } else { bnode = bnode->next; @@ -938,7 +931,6 @@ gaim_gtkdialogs_remove_buddy_cb(GaimBuddy *buddy) { GaimGroup *group; - GaimConversation *conv; gchar *name; GaimAccount *account; @@ -951,10 +943,6 @@ gaim_account_remove_buddy(buddy->account, buddy, group); gaim_blist_remove_buddy(buddy); - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, name, account); - if (conv != NULL) - gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); - g_free(name); } @@ -978,24 +966,7 @@ static void gaim_gtkdialogs_remove_chat_cb(GaimChat *chat) { - char *name = NULL; - GaimAccount *account; - GaimConversation *conv = NULL; - - account = chat->account; - - if (GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl)->get_chat_name != NULL) - name = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl)->get_chat_name(chat->components); - gaim_blist_remove_chat(chat); - - if (name != NULL) { - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, name, account); - g_free(name); - } - - if (conv != NULL) - gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); } void diff -r e8db8f94a2db -r eda1572c788b src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/protocols/yahoo/yahoo.c Mon Jan 09 21:29:53 2006 +0000 @@ -1706,7 +1706,6 @@ static void ignore_buddy(GaimBuddy *buddy) { GaimGroup *group; - GaimConversation *conv; GaimAccount *account; gchar *name; @@ -1724,12 +1723,6 @@ serv_add_deny(account->gc, name); - /* The follow should really be done by the core... */ - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, name, account); - - if (conv != NULL) - gaim_conversation_update(conv, GAIM_CONV_UPDATE_REMOVE); - g_free(name); } diff -r e8db8f94a2db -r eda1572c788b src/server.c --- a/src/server.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/server.c Mon Jan 09 21:29:53 2006 +0000 @@ -593,17 +593,17 @@ gaim_conv_im_set_typing_state(im, state); gaim_conv_im_update_typing(im); - } - - if (state == GAIM_TYPING) - { - gaim_signal_emit(gaim_conversations_get_handle(), - "buddy-typing", gc->account, name); - } - else - { - gaim_signal_emit(gaim_conversations_get_handle(), - "buddy-typing-stopped", gc->account, name); + } else { + if (state == GAIM_TYPING) + { + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing", gc->account, name); + } + else + { + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing-stopped", gc->account, name); + } } if (conv != NULL && timeout > 0) @@ -719,7 +719,6 @@ gaim_conv_chat_set_id(chat, id); - gaim_signal_emit(gaim_conversations_get_handle(), "chat-joined", conv); return conv; @@ -748,14 +747,14 @@ if (!conv) return; - gaim_signal_emit(gaim_conversations_get_handle(), "chat-left", conv); - gaim_debug(GAIM_DEBUG_INFO, "server", "Leaving room: %s\n", gaim_conversation_get_name(conv)); g->buddy_chats = g_slist_remove(g->buddy_chats, conv); gaim_conv_chat_left(GAIM_CONV_CHAT(conv)); + + gaim_signal_emit(gaim_conversations_get_handle(), "chat-left", conv); } void serv_got_chat_in(GaimConnection *g, int id, const char *who, diff -r e8db8f94a2db -r eda1572c788b src/status.c --- a/src/status.c Mon Jan 09 16:04:04 2006 +0000 +++ b/src/status.c Mon Jan 09 21:29:53 2006 +0000 @@ -1275,7 +1275,6 @@ time_t current_time, gboolean old_idle, gboolean idle) { GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; - GaimConversation *conv; if (!old_idle && idle) { @@ -1316,17 +1315,6 @@ if (ops != NULL && ops->update != NULL) ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); - - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, - gaim_buddy_get_name(buddy), - gaim_buddy_get_account(buddy)); - if (conv) - { - GaimConversationUiOps *conv_ops; - conv_ops = gaim_conversation_get_ui_ops(conv); - if (conv_ops && conv_ops->updated) - conv_ops->updated(conv, GAIM_CONV_UPDATE_AWAY); - } } void