changeset 8256:1d86096ae0f4

[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 <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sat, 14 Feb 2004 21:07:29 +0000
parents 4de49af535b3
children 04a3210e2fba
files ChangeLog src/conversation.c src/conversation.h src/gtkconv.c src/protocols/irc/msgs.c src/server.c
diffstat 6 files changed, 106 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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
  **************************************************************************/
--- 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);
+
 /*@}*/
 
 /**************************************************************************/
--- 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);
 	}
--- 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]);
 	}
--- 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,