# HG changeset patch
# Node ID 4cc20776e683
# Parent  2dce52f93848
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -351,6 +351,7 @@
 		  instead.
 		* account-setting-info, account-set-info signals
 		* account-status-changing signal.
+		* chat-topic-changed signal.
 		* file-recv-accept, file-recv-cancel, file-recv-complete,
 		  file-recv-start, file-send-accept, file-send-cancel,
 		  file-send-complete, file-send-start signals. Use
@@ -458,6 +459,12 @@
 		* purple_certificate_compare_pubkeys
 		* purple_certificate_display_x509
 		* purple_certificate_get_fingerprint_sha256
+		* purple_chat_conversation_get_ignored
+		* purple_chat_conversation_get_ignored_user
+		* purple_chat_conversation_ignore
+		* purple_chat_conversation_is_ignored_user
+		* purple_chat_conversation_set_ignored
+		* purple_chat_conversation_unignore
 		* Purple Cipher API (PurpleCipherContext and friends).
 		  Use GLib's GHmac or GChecksum instead.
 		* PurpleCommandsUiOps
diff --git a/libpurple/conversations.c b/libpurple/conversations.c
--- a/libpurple/conversations.c
+++ b/libpurple/conversations.c
@@ -216,11 +216,6 @@
 						 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
 						 PURPLE_TYPE_CHAT_CONVERSATION);
 
-	purple_signal_register(handle, "chat-topic-changed",
-						 purple_marshal_VOID__POINTER_POINTER_POINTER,
-						 G_TYPE_NONE, 3, PURPLE_TYPE_CHAT_CONVERSATION,
-						 G_TYPE_STRING, G_TYPE_STRING);
-
 	purple_signal_register(handle, "cleared-message-history",
 	                       purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
 	                       PURPLE_TYPE_CONVERSATION);
diff --git a/libpurple/purplechatconversation.h b/libpurple/purplechatconversation.h
--- a/libpurple/purplechatconversation.h
+++ b/libpurple/purplechatconversation.h
@@ -107,73 +107,6 @@
 guint purple_chat_conversation_get_users_count(PurpleChatConversation *chat);
 
 /**
- * purple_chat_conversation_ignore:
- * @chat: The chat.
- * @name: The name of the user.
- *
- * Ignores a user in a chat room.
- */
-void purple_chat_conversation_ignore(PurpleChatConversation *chat, const gchar *name);
-
-/**
- * purple_chat_conversation_unignore:
- * @chat: The chat.
- * @name: The name of the user.
- *
- * Unignores a user in a chat room.
- */
-void purple_chat_conversation_unignore(PurpleChatConversation *chat, const gchar *name);
-
-/**
- * purple_chat_conversation_set_ignored:
- * @chat: The chat.
- * @ignored: (element-type utf8): The list of ignored users.
- *
- * Sets the list of ignored users in the chat room.
- *
- * Returns: (element-type utf8) (transfer none): The list passed.
- */
-GList *purple_chat_conversation_set_ignored(PurpleChatConversation *chat, GList *ignored);
-
-/**
- * purple_chat_conversation_get_ignored:
- * @chat: The chat.
- *
- * Returns the list of ignored users in the chat room.
- *
- * Returns: (element-type utf8) (transfer none): The list of ignored users.
- */
-GList *purple_chat_conversation_get_ignored(PurpleChatConversation *chat);
-
-/**
- * purple_chat_conversation_get_ignored_user:
- * @chat: The chat.
- * @user: The user to check in the ignore list.
- *
- * Returns the actual name of the specified ignored user, if it exists in
- * the ignore list.
- *
- * If the user found contains a prefix, such as '+' or '\@', this is also
- * returned. The username passed to the function does not have to have this
- * formatting.
- *
- * Returns: The ignored user if found, complete with prefixes, or %NULL
- *          if not found.
- */
-const gchar *purple_chat_conversation_get_ignored_user(PurpleChatConversation *chat, const gchar *user);
-
-/**
- * purple_chat_conversation_is_ignored_user:
- * @chat: The chat.
- * @user: The user.
- *
- * Returns %TRUE if the specified user is ignored.
- *
- * Returns: %TRUE if the user is in the ignore list; %FALSE otherwise.
- */
-gboolean purple_chat_conversation_is_ignored_user(PurpleChatConversation *chat, const gchar *user);
-
-/**
  * purple_chat_conversation_set_topic:
  * @chat: The chat.
  * @who: The user that set the topic.
diff --git a/libpurple/purplechatconversation.c b/libpurple/purplechatconversation.c
--- a/libpurple/purplechatconversation.c
+++ b/libpurple/purplechatconversation.c
@@ -23,6 +23,7 @@
 #include <glib/gi18n-lib.h>
 
 #include "debug.h"
+#include "purplecontactmanager.h"
 #include "purpleconversationmanager.h"
 #include "purplechatconversation.h"
 #include "purpleenums.h"
@@ -32,21 +33,14 @@
 #include "server.h"
 
 typedef struct {
-	GList *ignored;     /* Ignored users.                            */
-	char  *who;         /* The person who set the topic.             */
-	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 */
 	GHashTable *users;  /* Hash table of the users in the room.      */
 } PurpleChatConversationPrivate;
 
 enum {
 	PROP_0,
-	PROP_TOPIC_WHO,
-	PROP_TOPIC,
 	PROP_CHAT_ID,
-	PROP_NICK,
 	PROP_LEFT,
 	N_PROPERTIES
 };
@@ -100,24 +94,16 @@
  *****************************************************************************/
 static void
 chat_conversation_write_message(PurpleConversation *conv, PurpleMessage *msg) {
-	PurpleChatConversation *chat_conv = PURPLE_CHAT_CONVERSATION(conv);
-	PurpleChatConversationPrivate *priv = NULL;
 	PurpleMessageFlags flags;
-	const gchar *author = NULL;
 
 	g_return_if_fail(msg != NULL);
 
-	priv = purple_chat_conversation_get_instance_private(chat_conv);
-
-	/* Don't display this if the person who wrote it is ignored. */
-	author = purple_message_get_author(msg);
-	if(purple_chat_conversation_is_ignored_user(chat_conv, author)) {
-		return;
-	}
-
 	flags = purple_message_get_flags(msg);
 	if(flags & PURPLE_MESSAGE_RECV) {
-		if(purple_utf8_has_word(purple_message_get_contents(msg), priv->nick)) {
+		const char *nickname = NULL;
+
+		nickname = purple_conversation_get_user_nickname(conv);
+		if(purple_utf8_has_word(purple_message_get_contents(msg), nickname)) {
 			flags |= PURPLE_MESSAGE_NICK;
 			purple_message_set_flags(msg, flags);
 		}
@@ -139,9 +125,6 @@
 		case PROP_CHAT_ID:
 			purple_chat_conversation_set_id(chat, g_value_get_int(value));
 			break;
-		case PROP_NICK:
-			purple_chat_conversation_set_nick(chat, g_value_get_string(value));
-			break;
 		case PROP_LEFT:
 			if(g_value_get_boolean(value)) {
 				purple_chat_conversation_leave(chat);
@@ -160,18 +143,9 @@
 	PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(obj);
 
 	switch(param_id) {
-		case PROP_TOPIC_WHO:
-			g_value_set_string(value, purple_chat_conversation_get_topic_who(chat));
-			break;
-		case PROP_TOPIC:
-			g_value_set_string(value, purple_chat_conversation_get_topic(chat));
-			break;
 		case PROP_CHAT_ID:
 			g_value_set_int(value, purple_chat_conversation_get_id(chat));
 			break;
-		case PROP_NICK:
-			g_value_set_string(value, purple_chat_conversation_get_nick(chat));
-			break;
 		case PROP_LEFT:
 			g_value_set_boolean(value, purple_chat_conversation_has_left(chat));
 			break;
@@ -262,12 +236,6 @@
 
 	g_clear_pointer(&priv->users, g_hash_table_destroy);
 
-	g_clear_list(&priv->ignored, g_free);
-
-	g_clear_pointer(&priv->who, g_free);
-	g_clear_pointer(&priv->topic, g_free);
-	g_clear_pointer(&priv->nick, g_free);
-
 	G_OBJECT_CLASS(purple_chat_conversation_parent_class)->finalize(obj);
 }
 
@@ -285,28 +253,6 @@
 	conv_class->write_message = chat_conversation_write_message;
 
 	/**
-	 * PurpleChatConversation::topic-who:
-	 *
-	 * The username who changed the topic last.
-	 */
-	properties[PROP_TOPIC_WHO] = g_param_spec_string(
-		"topic-who", "who set topic",
-		"Who set the topic of the chat.",
-		NULL,
-		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * PurpleChatConversation::topic:
-	 *
-	 * The text of the topic.
-	 */
-	properties[PROP_TOPIC] = g_param_spec_string(
-		"topic", "topic",
-		"The topic of the chat.",
-		NULL,
-		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-	/**
 	 * PurpleChatConversation::chat-id:
 	 *
 	 * The identifier of the chat.
@@ -318,17 +264,6 @@
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	/**
-	 * PurpleChatConversation::nick:
-	 *
-	 * The nickname of the user in the chat.
-	 */
-	properties[PROP_NICK] = g_param_spec_string(
-		"nick", "nick",
-		"The nickname of the user in a chat.",
-		NULL,
-		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-	/**
 	 * PurpleChatConversation::left:
 	 *
 	 * Whether the user has left the chat or not.
@@ -455,167 +390,43 @@
 }
 
 void
-purple_chat_conversation_ignore(PurpleChatConversation *chat,
-                                const gchar *name)
+purple_chat_conversation_set_topic(PurpleChatConversation *chat,
+                                   const gchar *who, const gchar *topic)
 {
-	PurpleChatConversationPrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat));
-	g_return_if_fail(name != NULL);
-
-	priv = purple_chat_conversation_get_instance_private(chat);
-
-	/* Make sure the user isn't already ignored. */
-	if(purple_chat_conversation_is_ignored_user(chat, name)) {
-		return;
-	}
-
-	priv->ignored = g_list_prepend(priv->ignored, g_strdup(name));
-}
-
-void
-purple_chat_conversation_unignore(PurpleChatConversation *chat,
-                                  const gchar *name)
-{
-	PurpleChatConversationPrivate *priv = NULL;
-	GList *item;
+	PurpleAccount *account = NULL;
+	PurpleContactManager *manager = NULL;
+	PurpleContact *contact = NULL;
 
 	g_return_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat));
-	g_return_if_fail(name != NULL);
 
-	priv = purple_chat_conversation_get_instance_private(chat);
+	account = purple_conversation_get_account(PURPLE_CONVERSATION(chat));
+	manager = purple_contact_manager_get_default();
+	contact = purple_contact_manager_find_with_username(manager, account, who);
 
-	/* Make sure the user is actually ignored. */
-	if(!purple_chat_conversation_is_ignored_user(chat, name)) {
-		return;
+	purple_conversation_set_topic(PURPLE_CONVERSATION(chat), topic);
+	if(PURPLE_IS_CONTACT_INFO(contact)) {
+		purple_conversation_set_topic_author(PURPLE_CONVERSATION(chat),
+		                                     PURPLE_CONTACT_INFO(contact));
 	}
-
-	item = g_list_find(priv->ignored,
-					   purple_chat_conversation_get_ignored_user(chat, name));
-	g_free(item->data);
-
-	priv->ignored = g_list_delete_link(priv->ignored, item);
+	g_clear_object(&contact);
 }
 
-GList *
-purple_chat_conversation_set_ignored(PurpleChatConversation *chat,
-                                     GList *ignored)
-{
-	PurpleChatConversationPrivate *priv = NULL;
-
+const char *
+purple_chat_conversation_get_topic(PurpleChatConversation *chat) {
 	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
 
-	priv = purple_chat_conversation_get_instance_private(chat);
-
-	priv->ignored = ignored;
-
-	return ignored;
+	return purple_conversation_get_topic(PURPLE_CONVERSATION(chat));
 }
 
-GList *
-purple_chat_conversation_get_ignored(PurpleChatConversation *chat) {
-	PurpleChatConversationPrivate *priv = NULL;
+const char *
+purple_chat_conversation_get_topic_who(PurpleChatConversation *chat) {
+	PurpleContactInfo *info = NULL;
 
 	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
 
-	priv = purple_chat_conversation_get_instance_private(chat);
-	return priv->ignored;
-}
-
-const gchar *
-purple_chat_conversation_get_ignored_user(PurpleChatConversation *chat,
-                                          const gchar *user)
-{
-	GList *ignored;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
-	g_return_val_if_fail(user != NULL, NULL);
-
-	ignored = purple_chat_conversation_get_ignored(chat);
-	for(; ignored != NULL; ignored = ignored->next) {
-		const gchar *ign = (const gchar *)ignored->data;
-
-		if(!purple_utf8_strcasecmp(user, ign) ||
-			((*ign == '+' || *ign == '%') &&
-			  !purple_utf8_strcasecmp(user, ign + 1)))
-		{
-			return ign;
-		}
-
-		if(*ign == '@') {
-			ign++;
-
-			if((*ign == '+' && !purple_utf8_strcasecmp(user, ign + 1)) ||
-			   (*ign != '+' && !purple_utf8_strcasecmp(user, ign)))
-			{
-				return ign;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-gboolean
-purple_chat_conversation_is_ignored_user(PurpleChatConversation *chat,
-                                         const gchar *user)
-{
-	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), FALSE);
-	g_return_val_if_fail(user != NULL, FALSE);
-
-	return (purple_chat_conversation_get_ignored_user(chat, user) != NULL);
-}
+	info = purple_conversation_get_topic_author(PURPLE_CONVERSATION(chat));
 
-void
-purple_chat_conversation_set_topic(PurpleChatConversation *chat,
-                                   const gchar *who, const gchar *topic)
-{
-	PurpleChatConversationPrivate *priv = NULL;
-	GObject *obj;
-
-	g_return_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat));
-
-	priv = purple_chat_conversation_get_instance_private(chat);
-
-	g_clear_pointer(&priv->who, g_free);
-	g_clear_pointer(&priv->topic, g_free);
-
-	priv->who = g_strdup(who);
-	priv->topic = g_strdup(topic);
-
-	obj = G_OBJECT(chat);
-	g_object_freeze_notify(obj);
-	g_object_notify_by_pspec(obj, properties[PROP_TOPIC_WHO]);
-	g_object_notify_by_pspec(obj, properties[PROP_TOPIC]);
-	g_object_thaw_notify(obj);
-
-	purple_conversation_update(PURPLE_CONVERSATION(chat),
-	                           PURPLE_CONVERSATION_UPDATE_TOPIC);
-
-	purple_signal_emit(purple_conversations_get_handle(), "chat-topic-changed",
-	                   chat, priv->who, priv->topic);
-}
-
-const gchar *
-purple_chat_conversation_get_topic(PurpleChatConversation *chat) {
-	PurpleChatConversationPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
-
-	priv = purple_chat_conversation_get_instance_private(chat);
-
-	return priv->topic;
-}
-
-const gchar *
-purple_chat_conversation_get_topic_who(PurpleChatConversation *chat) {
-	PurpleChatConversationPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
-
-	priv = purple_chat_conversation_get_instance_private(chat);
-
-	return priv->who;
+	return purple_contact_info_get_username(info);
 }
 
 void
@@ -698,7 +509,10 @@
 		const gchar *extra_msg = (extra_msgs ? extra_msgs->data : NULL);
 
 		if(!(purple_protocol_get_options(protocol) & OPT_PROTO_UNIQUE_CHATNAME)) {
-			if(purple_strequal(priv->nick, purple_normalize(account, user))) {
+			const char *nickname = NULL;
+
+			nickname = purple_conversation_get_user_nickname(conv);
+			if(purple_strequal(nickname, purple_normalize(account, user))) {
 				PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
 				const gchar *alias2 = purple_contact_info_get_alias(info);
 				if(alias2 != NULL) {
@@ -718,8 +532,7 @@
 		}
 
 		quiet = GPOINTER_TO_INT(purple_signal_emit_return_1(handle,
-		                        "chat-user-joining", chat, user, flag)) ||
-				purple_chat_conversation_is_ignored_user(chat, user);
+		                        "chat-user-joining", chat, user, flag));
 
 		chatuser = purple_chat_user_new(chat, user, alias, flag);
 
@@ -784,6 +597,7 @@
 	PurpleChatUserFlags flags;
 	PurpleChatConversationPrivate *priv;
 	const gchar *new_alias = new_user;
+	const char *nickname = NULL;
 	gchar tmp[BUF_LONG];
 	gboolean is_me = FALSE;
 
@@ -801,7 +615,8 @@
 	protocol = purple_connection_get_protocol(gc);
 	g_return_if_fail(PURPLE_IS_PROTOCOL(protocol));
 
-	if(purple_strequal(priv->nick, purple_normalize(account, old_user))) {
+	nickname = purple_conversation_get_user_nickname(conv);
+	if(purple_strequal(nickname, purple_normalize(account, old_user))) {
 		const gchar *alias;
 
 		/* Note this for later. */
@@ -840,20 +655,11 @@
 		g_hash_table_remove(priv->users, purple_chat_user_get_name(cb));
 	}
 
-	if(purple_chat_conversation_is_ignored_user(chat, old_user)) {
-		purple_chat_conversation_unignore(chat, old_user);
-		purple_chat_conversation_ignore(chat, new_user);
-	} else if(purple_chat_conversation_is_ignored_user(chat, new_user)) {
-		purple_chat_conversation_unignore(chat, new_user);
-	}
-
 	if(is_me) {
 		purple_chat_conversation_set_nick(chat, new_user);
 	}
 
-	if(purple_prefs_get_bool("/purple/conversations/chat/show_nick_change") &&
-	   !purple_chat_conversation_is_ignored_user(chat, new_user))
-	{
+	if(purple_prefs_get_bool("/purple/conversations/chat/show_nick_change")) {
 		if(is_me) {
 			gchar *escaped = g_markup_escape_text(new_user, -1);
 			g_snprintf(tmp, sizeof(tmp), _("You are now known as %s"),
@@ -933,8 +739,7 @@
 	for(l = users; l != NULL; l = l->next) {
 		const gchar *user = (const gchar *)l->data;
 		quiet = GPOINTER_TO_INT(purple_signal_emit_return_1(handle,
-		                        "chat-user-leaving", chat, user, reason)) |
-				purple_chat_conversation_is_ignored_user(chat, user);
+		                        "chat-user-leaving", chat, user, reason));
 
 		cb = purple_chat_conversation_find_user(chat, user);
 
@@ -1009,30 +814,21 @@
 purple_chat_conversation_set_nick(PurpleChatConversation *chat,
                                   const gchar *nick)
 {
-	PurpleChatConversationPrivate *priv = NULL;
 	PurpleAccount *account = NULL;
 
 	g_return_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat));
 
-	priv = purple_chat_conversation_get_instance_private(chat);
-
 	account = purple_conversation_get_account(PURPLE_CONVERSATION(chat));
 
-	g_free(priv->nick);
-	priv->nick = g_strdup(purple_normalize(account, nick));
-
-	g_object_notify_by_pspec(G_OBJECT(chat), properties[PROP_NICK]);
+	purple_conversation_set_user_nickname(PURPLE_CONVERSATION(chat),
+	                                      purple_normalize(account, nick));
 }
 
 const gchar *
 purple_chat_conversation_get_nick(PurpleChatConversation *chat) {
-	PurpleChatConversationPrivate *priv = NULL;
-
 	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
 
-	priv = purple_chat_conversation_get_instance_private(chat);
-
-	return priv->nick;
+	return purple_conversation_get_user_nickname(PURPLE_CONVERSATION(chat));
 }
 
 static void
