# HG changeset patch # User Christian Hammond # Date 1076792849 0 # Node ID 1d86096ae0f4ba5e1432d70a96f951bab90933fa # Parent 4de49af535b33c879675dd937fc6a4b5d804a6c7 [gaim-migrate @ 8979] Tim Ringenbach says this shouldn't have gotten into 0.76, because 0.76 should have been release two weeks ago. He also doesn't have a good description, so I'll just say it fixed a bunch of idiot mistakes and ugly hacks on my part regarding the removing of users from the chat lists and parting chats/channels. Thanks Tim. committer: Tailor Script diff -r 4de49af535b3 -r 1d86096ae0f4 ChangeLog --- a/ChangeLog Sat Feb 14 20:45:28 2004 +0000 +++ b/ChangeLog Sat Feb 14 21:07:29 2004 +0000 @@ -9,6 +9,9 @@ * Keyboard access to context menus via Shift+F10 (Marc Mulcahy) * Non-ascii character support in AIM chats (Uli Luckas and Marco Ziech) * Improved local IP address detection (Tim Ringenbach) + * Fixed a bug where only the first user in a chat room list was removed + sometimes when trying to remove a group of users (Tim Ringenbach) + * Improved chat parting logic (Tim Ringenbach) * Local IP address information can be changed in Preferences (Tim Ringenbach) * Yet Another IRC channel user duplication bugfix (Tim Ringenbach) diff -r 4de49af535b3 -r 1d86096ae0f4 src/conversation.c --- a/src/conversation.c Sat Feb 14 20:45:28 2004 +0000 +++ b/src/conversation.c Sat Feb 14 21:07:29 2004 +0000 @@ -745,6 +745,27 @@ /************************************************************************** * Conversation API **************************************************************************/ +static void +gaim_conversation_chat_cleanup_for_rejoin(GaimConversation *conv) +{ + const char *disp; + GaimAccount *account; + + account = gaim_conversation_get_account(conv); + + if ((disp = gaim_connection_get_display_name(gaim_account_get_connection(account)))) { + gaim_conv_chat_set_nick(conv->u.chat, disp); + } else { + gaim_conv_chat_set_nick(conv->u.chat, gaim_account_get_username(account)); + } + + gaim_conv_chat_clear_users(conv->u.chat); + gaim_conv_chat_set_topic(conv->u.chat, NULL, NULL); + conv->u.chat->left = FALSE; + + gaim_conversation_update(conv, GAIM_CONV_UPDATE_CHATLEFT); +} + GaimConversation * gaim_conversation_new(GaimConversationType type, GaimAccount *account, const char *name) @@ -756,8 +777,17 @@ g_return_val_if_fail(name != NULL, NULL); /* Check if this conversation already exists. */ - if ((conv = gaim_find_conversation_with_account(name, account)) != NULL) - return conv; + if (((conv = gaim_find_conversation_with_account(name, account)) != NULL) && + (gaim_conversation_get_type(conv) == type)) { + + if (gaim_conversation_get_type(conv) != GAIM_CONV_CHAT || + gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv))) { + if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) + gaim_conversation_chat_cleanup_for_rejoin(conv); + + return conv; + } + } conv = g_new0(GaimConversation, 1); @@ -869,6 +899,7 @@ prpl_info->convo_closed(gc, name); } else if (gaim_conversation_get_type(conv) == GAIM_CONV_CHAT) { + #if 0 /* * This is unfortunately necessary, because calling * serv_chat_leave() calls this gaim_conversation_destroy(), @@ -892,6 +923,12 @@ return; } + #endif + /* + * Instead of all of that, lets just close the window when the user tells + * us to, and let the prpl deal with the internals on it's own time. + */ + serv_chat_leave(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv))); } } @@ -1406,7 +1443,7 @@ } } } - + if (gaim_conversation_is_logging(conv)) gaim_log_write(conv->log, flags, who, mtime, message); ops->write_conv(conv, who, message, flags, mtime); @@ -1457,9 +1494,9 @@ } /* - * TODO: Need to make sure calls to this function happen in the core - * instead of the UI. That way UIs have less work to do, and the - * core/UI split is cleaner. Also need to make sure this is called + * TODO: Need to make sure calls to this function happen in the core + * instead of the UI. That way UIs have less work to do, and the + * core/UI split is cleaner. Also need to make sure this is called * when chats are added/removed from the blist. */ void @@ -2180,6 +2217,23 @@ return NULL; } +void +gaim_conv_chat_left(GaimConvChat *chat) +{ + g_return_if_fail(chat != NULL); + + chat->left = TRUE; + gaim_conversation_update(chat->conv, GAIM_CONV_UPDATE_CHATLEFT); +} + +gboolean +gaim_conv_chat_has_left(GaimConvChat *chat) +{ + g_return_val_if_fail(chat != NULL, TRUE); + + return chat->left; +} + /************************************************************************** * Conversation placement functions **************************************************************************/ diff -r 4de49af535b3 -r 1d86096ae0f4 src/conversation.h --- a/src/conversation.h Sat Feb 14 20:45:28 2004 +0000 +++ b/src/conversation.h Sat Feb 14 21:07:29 2004 +0000 @@ -86,7 +86,8 @@ GAIM_CONV_ACCOUNT_OFFLINE, /**< One of the user's accounts went offline. */ GAIM_CONV_UPDATE_AWAY, /**< The other user went away. */ GAIM_CONV_UPDATE_ICON, /**< The other user's buddy icon changed. */ - GAIM_CONV_UPDATE_TITLE + GAIM_CONV_UPDATE_TITLE, + GAIM_CONV_UPDATE_CHATLEFT } GaimConvUpdateType; @@ -224,6 +225,8 @@ char *topic; /**< The topic. */ int id; /**< The chat ID. */ char *nick; /**< Your nick in this chat. */ + + gboolean left; /**< We left the chat and kept the window open */ }; /** @@ -1206,6 +1209,25 @@ */ GaimConversation *gaim_find_chat(const GaimConnection *gc, int id); +/** + * Lets the core know we left a chat, without destroying it. + * Called from serv_got_chat_left(). + * + * @param chat The chat. + */ +void gaim_conv_chat_left(GaimConvChat *chat); + +/** + * Returns true if we're no longer in this chat, + * and just left the window open. + * + * @param chat The chat. + * + * @return @c TRUE if we left the chat already, @c FALSE if + * we're still there. + */ +gboolean gaim_conv_chat_has_left(GaimConvChat *chat); + /*@}*/ /**************************************************************************/ diff -r 4de49af535b3 -r 1d86096ae0f4 src/gtkconv.c --- a/src/gtkconv.c Sat Feb 14 20:45:28 2004 +0000 +++ b/src/gtkconv.c Sat Feb 14 21:07:29 2004 +0000 @@ -2466,7 +2466,9 @@ * Handle graying stuff out based on whether an account is connected * and what features that account supports. */ - if (gc != NULL) { + if ((gc != NULL) && + ( (gaim_conversation_get_type(conv) != GAIM_CONV_CHAT) || + !gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv)) )) { /* Account is online */ /* Deal with buttons */ @@ -2523,6 +2525,7 @@ (prpl_info->options & OPT_PROTO_IM_IMAGE)); } else { /* Account is offline */ + /* Or it's a chat where we left. */ /* Deal with buttons */ gtk_widget_set_sensitive(gtkconv->add, FALSE); @@ -5245,7 +5248,7 @@ GList *l; char tmp[BUF_LONG]; int num_users; - int f = 1; + gboolean f; chat = GAIM_CONV_CHAT(conv); gtkconv = GAIM_GTK_CONVERSATION(conv); @@ -5268,7 +5271,7 @@ &iter)) break; - while (f != 0) { + do { char *val; gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, @@ -5280,7 +5283,7 @@ f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); g_free(val); - } + } while (f); break; } @@ -5410,7 +5413,8 @@ if (gaim_prefs_get_bool("/gaim/gtk/conversations/icons_on_tabs")) update_tab_icon(conv); } - else if (type == GAIM_CONV_UPDATE_ADD || type == GAIM_CONV_UPDATE_REMOVE) + else if (type == GAIM_CONV_UPDATE_ADD || type == GAIM_CONV_UPDATE_REMOVE || + type == GAIM_CONV_UPDATE_CHATLEFT) { gray_stuff_out(conv); } diff -r 4de49af535b3 -r 1d86096ae0f4 src/protocols/irc/msgs.c --- a/src/protocols/irc/msgs.c Sat Feb 14 20:45:28 2004 +0000 +++ b/src/protocols/irc/msgs.c Sat Feb 14 21:07:29 2004 +0000 @@ -592,10 +592,7 @@ buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]); gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[0], buf, GAIM_MESSAGE_SYSTEM, time(NULL)); g_free(buf); - /*g_slist_remove(irc->gc->buddy_chats, convo); - gaim_conversation_set_account(convo, NULL);*/ - /*g_list_free(gaim_conv_chat_get_users(GAIM_CONV_CHAT(convo))); - gaim_conv_chat_set_users(GAIM_CONV_CHAT(convo), NULL);*/ + serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo))); } else { buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]); gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), args[1], buf); @@ -723,6 +720,7 @@ (args[1] && *args[1]) ? ": " : "", args[1]); gaim_conv_chat_write(GAIM_CONV_CHAT(convo), args[0], msg, GAIM_MESSAGE_SYSTEM, time(NULL)); g_free(msg); + serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo))); } else { gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo), nick, args[1]); } diff -r 4de49af535b3 -r 1d86096ae0f4 src/server.c --- a/src/server.c Sat Feb 14 20:45:28 2004 +0000 +++ b/src/server.c Sat Feb 14 21:07:29 2004 +0000 @@ -740,6 +740,12 @@ g_free(buffy); } +/* Ya know, nothing uses this except gaim_conversation_destroy(), + * I think I'll just merge it into that later... + * Then again, something might want to use this, from outside prpl-land + * to leave a chat without destroying the conversation. + */ + void serv_chat_leave(GaimConnection *g, int id) { GaimPluginProtocolInfo *prpl_info = NULL; @@ -1364,7 +1370,8 @@ conv = gaim_conversation_new(GAIM_CONV_CHAT, account, name); chat = GAIM_CONV_CHAT(conv); - gc->buddy_chats = g_slist_append(gc->buddy_chats, conv); + if (!g_slist_find(gc->buddy_chats, conv)) + gc->buddy_chats = g_slist_append(gc->buddy_chats, conv); gaim_conv_chat_set_id(chat, id); @@ -1407,7 +1414,7 @@ g->buddy_chats = g_slist_remove(g->buddy_chats, conv); - gaim_conversation_destroy(conv); + gaim_conv_chat_left(GAIM_CONV_CHAT(conv)); } void serv_got_chat_in(GaimConnection *g, int id, const char *who,