changeset 20957:1ec2b67e9bc1

merge of '59ab2b78429c94d5d0fc77b1b7892accb524e2a4' and 'e440d3119d6686976d657170c1fce857f4aecfc4'
author Evan Schoenberg <evan.s@dreskin.net>
date Mon, 15 Oct 2007 23:46:12 +0000
parents 37f3c1023a68 (current diff) 2101ebd66f15 (diff)
children 2002a6a32b0c
files libpurple/protocols/msn/msn.c
diffstat 10 files changed, 214 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/finch/libgnt/gntfilesel.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/finch/libgnt/gntfilesel.c	Mon Oct 15 23:46:12 2007 +0000
@@ -265,6 +265,7 @@
 		}
 		g_free(fp);
 	}
+	g_dir_close(dir);
 
 	*files = g_list_reverse(*files);
 	return TRUE;
--- a/libpurple/notify.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/libpurple/notify.c	Mon Oct 15 23:46:12 2007 +0000
@@ -688,8 +688,11 @@
 void
 purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info)
 {
-	user_info->user_info_entries = g_list_remove(user_info->user_info_entries,
-												 g_list_last(user_info->user_info_entries)->data);
+	GList *last = g_list_last(user_info->user_info_entries);
+	if (last) {
+		purple_notify_user_info_entry_destroy(last->data);
+		user_info->user_info_entries = g_list_remove_link(user_info->user_info_entries, last);
+	}
 }
 
 void *
--- a/libpurple/notify.h	Mon Oct 15 23:46:02 2007 +0000
+++ b/libpurple/notify.h	Mon Oct 15 23:46:12 2007 +0000
@@ -539,7 +539,7 @@
 void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value);
 
 /**
- * Remove a PurpleNotifyUserInfoEntry from a PurpleNotifyUserInfo object
+ * Remove a PurpleNotifyUserInfoEntry from a PurpleNotifyUserInfo object without freeing the entry.
  *
  * @param user_info          The PurpleNotifyUserInfo
  * @param user_info_entry    The PurpleNotifyUserInfoEntry
--- a/libpurple/protocols/msn/httpconn.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/libpurple/protocols/msn/httpconn.c	Mon Oct 15 23:46:12 2007 +0000
@@ -687,6 +687,17 @@
 
 	g_free(httpconn->host);
 
+	while (httpconn->queue != NULL) {
+		MsnHttpQueueData *queue_data;
+
+		queue_data = (MsnHttpQueueData *) httpconn->queue->data;
+
+		httpconn->queue = g_list_remove_link(httpconn->queue, httpconn->queue);
+
+		g_free(queue_data->body);
+		g_free(queue_data);
+	}
+
 	purple_circ_buffer_destroy(httpconn->tx_buf);
 	if (httpconn->tx_handler > 0)
 		purple_input_remove(httpconn->tx_handler);
--- a/libpurple/protocols/msn/msn.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Mon Oct 15 23:46:12 2007 +0000
@@ -1594,7 +1594,6 @@
 	gboolean sect_info = FALSE;
 	gboolean has_contact_info = FALSE;
 	char *url_buffer;
-	GString *s, *s2;
 	int stripped_len;
 #if PHOTO_SUPPORT
 	char *photo_url_text = NULL;
@@ -1679,11 +1678,6 @@
 	purple_debug_misc("msn", "stripped = %p\n", stripped);
 	purple_debug_misc("msn", "url_buffer = %p\n", url_buffer);
 
-	/* Gonna re-use the memory we've already got for url_buffer */
-	/* No we're not. */
-	s = g_string_sized_new(strlen(url_buffer));
-	s2 = g_string_sized_new(strlen(url_buffer));
-
 	/* General section header */
 	if (has_tooltip_text)
 		purple_notify_user_info_add_section_break(user_info);
@@ -2030,7 +2024,7 @@
 		purple_debug_warning("msn", "invalid connection. ignoring buddy photo info.\n");
 		g_free(stripped);
 		g_free(url_buffer);
-		g_free(user_info);
+		purple_notify_user_info_destroy(user_info);
 		g_free(info_data->name);
 		g_free(info_data);
 		g_free(photo_url_text);
--- a/libpurple/protocols/msn/slplink.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/libpurple/protocols/msn/slplink.c	Mon Oct 15 23:46:12 2007 +0000
@@ -120,6 +120,8 @@
 	while (slplink->slp_calls != NULL)
 		msn_slp_call_destroy(slplink->slp_calls->data);
 
+	g_queue_free(slplink->slp_msg_queue);
+
 	session->slplinks =
 		g_list_remove(session->slplinks, slplink);
 
--- a/libpurple/protocols/msn/switchboard.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/libpurple/protocols/msn/switchboard.c	Mon Oct 15 23:46:12 2007 +0000
@@ -108,8 +108,8 @@
 	g_free(swboard->auth_key);
 	g_free(swboard->session_id);
 
-	for (l = swboard->users; l != NULL; l = l->next)
-		g_free(l->data);
+	for (; swboard->users; swboard->users = g_list_remove_link(swboard->users, swboard->users))
+		g_free(swboard->users->data);
 
 	session = swboard->session;
 	session->switches = g_list_remove(session->switches, swboard);
--- a/pidgin/gtkblist.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/pidgin/gtkblist.c	Mon Oct 15 23:46:12 2007 +0000
@@ -3907,7 +3907,7 @@
 			convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM,
 															PIDGIN_UNSEEN_TEXT, TRUE, 1);
 			if (convs) {
-				purple_conversation_present((PurpleConversation*)convs->data);
+				pidgin_conv_present_conversation((PurpleConversation*)convs->data);
 				g_list_free(convs);
 			}
 			break;
--- a/pidgin/gtkconv.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/pidgin/gtkconv.c	Mon Oct 15 23:46:12 2007 +0000
@@ -148,6 +148,7 @@
 static void add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name);
 static gboolean tab_complete(PurpleConversation *conv);
 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type);
+static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state);
 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
 static void update_typing_icon(PidginConversation *gtkconv);
 static const char *item_factory_translate_func (const char *path, gpointer func_data);
@@ -2853,8 +2854,9 @@
 		if (gtkconv != NULL && gtkconv->active_conv != conv)
 			continue;
 		if (gtkconv == NULL) {
-			if (!hidden_only ||
-					!purple_conversation_get_data(conv, "unseen-count"))
+			if (!purple_conversation_get_data(conv, "unseen-count") ||
+				!purple_conversation_get_data(conv, "unseen-state") ||
+				GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"))<min_state)
 				continue;
 			r = g_list_prepend(r, conv);
 			c++;
@@ -3524,6 +3526,7 @@
 
 		if (b == item_buddy) {
 			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
+			g_list_free(child);
 			break;
 		}
 	}
@@ -5162,6 +5165,8 @@
 			conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
 			purple_conversation_set_ui_ops(conv, NULL);
 			ui_ops->create_conversation = pidgin_conv_new;
+		} else {
+			/* TODO: update the unseen_state data on the conv here */
 		}
 	} else {
 		/* new message for an IM */
@@ -6668,13 +6673,24 @@
 
 static void
 wrote_msg_update_unseen_cb(PurpleAccount *account, const char *who, const char *message,
-		PurpleConversation *conv, PurpleMessageFlags flag, gpointer null)
+		PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
 {
 	if (conv == NULL || PIDGIN_IS_PIDGIN_CONVERSATION(conv))
 		return;
-	if (flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) {
-		purple_conversation_set_data(conv, "unseen-count",
-				GINT_TO_POINTER(GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")) + 1));
+	if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) {
+		PidginUnseenState unseen = PIDGIN_UNSEEN_NONE;
+
+		if ((flags & PURPLE_MESSAGE_NICK) == PURPLE_MESSAGE_NICK)
+			unseen = PIDGIN_UNSEEN_NICK;
+		else if (((flags & PURPLE_MESSAGE_SYSTEM) == PURPLE_MESSAGE_SYSTEM) ||
+			  ((flags & PURPLE_MESSAGE_ERROR) == PURPLE_MESSAGE_ERROR))
+			unseen = PIDGIN_UNSEEN_EVENT;
+		else if ((flags & PURPLE_MESSAGE_NO_LOG) == PURPLE_MESSAGE_NO_LOG)
+			unseen = PIDGIN_UNSEEN_NO_LOG;
+		else
+			unseen = PIDGIN_UNSEEN_TEXT;
+
+		conv_set_unseen(conv, unseen);
 		purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
 	}
 }
@@ -7449,6 +7465,7 @@
 		return FALSE;
 
 	purple_conversation_set_data(conv, "unseen-count", NULL);
+	purple_conversation_set_data(conv, "unseen-state", NULL);
 	purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops());
 	private_gtkconv_new(conv, FALSE);
 	gtkconv = PIDGIN_CONVERSATION(conv);
@@ -7918,6 +7935,38 @@
 }
 
 static void
+conv_set_unseen(PurpleConversation *conv, PidginUnseenState state)
+{
+	int unseen_count = 0;
+	PidginUnseenState unseen_state = PIDGIN_UNSEEN_NONE;
+
+	if(purple_conversation_get_data(conv, "unseen-count"))
+		unseen_count = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"));
+
+	if(purple_conversation_get_data(conv, "unseen-state"))
+		unseen_state = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"));
+
+	if (state == PIDGIN_UNSEEN_NONE)
+	{
+		unseen_count = 0;
+		unseen_state = PIDGIN_UNSEEN_NONE;
+	}
+	else
+	{
+		if (state >= PIDGIN_UNSEEN_TEXT)
+			unseen_count++;
+
+		if (state > unseen_state)
+			unseen_state = state;
+	}
+
+	purple_conversation_set_data(conv, "unseen-count", GINT_TO_POINTER(unseen_count));
+	purple_conversation_set_data(conv, "unseen-state", GINT_TO_POINTER(unseen_state));
+
+	purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
+}
+
+static void
 gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state)
 {
 	if (state == PIDGIN_UNSEEN_NONE)
--- a/pidgin/gtkdocklet.c	Mon Oct 15 23:46:02 2007 +0000
+++ b/pidgin/gtkdocklet.c	Mon Oct 15 23:46:12 2007 +0000
@@ -38,6 +38,7 @@
 #include "gtkprefs.h"
 #include "gtksavedstatuses.h"
 #include "gtksound.h"
+#include "gtkstatusbox.h"
 #include "gtkutils.h"
 #include "pidginstock.h"
 #include "gtkdocklet.h"
@@ -144,15 +145,22 @@
 		if (ui_ops->set_tooltip) {
 			GString *tooltip_text = g_string_new("");
 			for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) {
-				if (PIDGIN_IS_PIDGIN_CONVERSATION(l->data)) {
-					PidginConversation *gtkconv = PIDGIN_CONVERSATION((PurpleConversation *)l->data);
-					if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1)
-						g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
-					else
-						g_string_append_printf(tooltip_text,
-							ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
-							gtkconv->unseen_count,
-							gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
+				PurpleConversation *conv = (PurpleConversation *)l->data;
+				PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
+
+				if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) {
+					g_string_append(tooltip_text, _("Right-click for more unread messages...\n"));
+				} else if(gtkconv) {
+					g_string_append_printf(tooltip_text,
+						ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
+						gtkconv->unseen_count,
+						gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
+				} else {
+					g_string_append_printf(tooltip_text,
+						ngettext("%d unread message from %s\n", "%d unread messages from %s\n",
+						GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))),
+						GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")),
+						purple_conversation_get_name(conv));
 				}
 			}
 
@@ -356,6 +364,10 @@
 }
 #endif
 
+/* There is a lot of code here for handling the status submenu, much of
+ * which is duplicated from the gtkstatusbox. It'd be nice to add API
+ * somewhere to simplify this (either in the statusbox, or in libpurple).
+ */
 static void
 show_custom_status_editor_cb(GtkMenuItem *menuitem, gpointer user_data)
 {
@@ -369,6 +381,70 @@
 		purple_savedstatus_is_transient(saved_status) ? saved_status : NULL);
 }
 
+static PurpleSavedStatus *
+create_transient_status(PurpleStatusPrimitive primitive, PurpleStatusType *status_type)
+{
+	PurpleSavedStatus *saved_status = purple_savedstatus_new(NULL, primitive);
+
+	if(status_type != NULL) {
+		GList *tmp, *active_accts = purple_accounts_get_all_active();
+		for (tmp = active_accts; tmp != NULL; tmp = tmp->next) {
+			purple_savedstatus_set_substatus(saved_status,
+				(PurpleAccount*) tmp->data, status_type, NULL);
+		}
+		g_list_free(active_accts);
+	}
+
+	return saved_status;
+}
+
+static void
+activate_status_account_cb(GtkMenuItem *menuitem, gpointer user_data)
+{
+	PurpleStatusType *status_type;
+	PurpleStatusPrimitive primitive;
+	PurpleSavedStatus *saved_status = NULL;
+	GList *iter = purple_savedstatuses_get_all();
+	GList *tmp, *active_accts = purple_accounts_get_all_active();
+
+	status_type = (PurpleStatusType *)user_data;
+	primitive = purple_status_type_get_primitive(status_type);
+
+	for (; iter != NULL; iter = iter->next) {
+		PurpleSavedStatus *ss = iter->data;
+		if ((purple_savedstatus_get_type(ss) == primitive) && purple_savedstatus_is_transient(ss) &&
+			purple_savedstatus_has_substatuses(ss))
+		{
+			gboolean found = FALSE;
+			/* The currently enabled accounts must have substatuses for all the active accts */
+			for(tmp = active_accts; tmp != NULL; tmp = tmp->next) {
+				PurpleAccount *acct = tmp->data;
+				PurpleSavedStatusSub *sub = purple_savedstatus_get_substatus(ss, acct);
+				if (sub) {
+					const PurpleStatusType *sub_type = purple_savedstatus_substatus_get_type(sub);
+					const char *subtype_status_id = purple_status_type_get_id(sub_type);
+					if (subtype_status_id && !strcmp(subtype_status_id,
+							purple_status_type_get_id(status_type)))
+						found = TRUE;
+				}
+			}
+			if (!found)
+				continue;
+			saved_status = ss;
+			break;
+		}
+	}
+
+	g_list_free(active_accts);
+
+	/* Create a new transient saved status if we weren't able to find one */
+	if (saved_status == NULL)
+		saved_status = create_transient_status(primitive, status_type);
+
+	/* Set the status for each account */
+	purple_savedstatus_activate(saved_status);
+}
+
 static void
 activate_status_primitive_cb(GtkMenuItem *menuitem, gpointer user_data)
 {
@@ -382,7 +458,7 @@
 
 	/* Create a new transient saved status if we weren't able to find one */
 	if (saved_status == NULL)
-		saved_status = purple_savedstatus_new(NULL, primitive);
+		saved_status = create_transient_status(primitive, NULL);
 
 	/* Set the status for each account */
 	purple_savedstatus_activate(saved_status);
@@ -425,31 +501,67 @@
 	return menuitem;
 }
 
+static void
+add_account_statuses(GtkWidget *menu, PurpleAccount *account)
+{
+	GList *l;
+
+	for (l = purple_account_get_status_types(account); l != NULL; l = l->next) {
+		PurpleStatusType *status_type = (PurpleStatusType *)l->data;
+		PurpleStatusPrimitive prim;
+
+		if (!purple_status_type_is_user_settable(status_type))
+			continue;
+
+		prim = purple_status_type_get_primitive(status_type);
+
+		new_menu_item_with_status_icon(menu,
+			purple_status_type_get_name(status_type),
+			prim, G_CALLBACK(activate_status_account_cb),
+			status_type, 0, 0, NULL);
+	}
+}
+
 static GtkWidget *
 docklet_status_submenu()
 {
 	GtkWidget *submenu, *menuitem;
 	GList *popular_statuses, *cur;
+	PidginStatusBox *statusbox = NULL;
 
 	submenu = gtk_menu_new();
 	menuitem = gtk_menu_item_new_with_label(_("Change Status"));
 	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
 
-	new_menu_item_with_status_icon(submenu, _("Available"),
-		PURPLE_STATUS_AVAILABLE, G_CALLBACK(activate_status_primitive_cb),
-		GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE), 0, 0, NULL);
+	if(pidgin_blist_get_default_gtk_blist() != NULL) {
+		statusbox = PIDGIN_STATUS_BOX(pidgin_blist_get_default_gtk_blist()->statusbox);
+	}
 
-	new_menu_item_with_status_icon(submenu, _("Away"),
-		PURPLE_STATUS_AWAY, G_CALLBACK(activate_status_primitive_cb),
-		GINT_TO_POINTER(PURPLE_STATUS_AWAY), 0, 0, NULL);
+	if(statusbox && statusbox->account != NULL) {
+		add_account_statuses(submenu, statusbox->account);
+	} else if(statusbox && statusbox->token_status_account != NULL) {
+		add_account_statuses(submenu, statusbox->token_status_account);
+	} else {
+		new_menu_item_with_status_icon(submenu, _("Available"),
+			PURPLE_STATUS_AVAILABLE, G_CALLBACK(activate_status_primitive_cb),
+			GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE), 0, 0, NULL);
 
-	new_menu_item_with_status_icon(submenu, _("Invisible"),
-		PURPLE_STATUS_INVISIBLE, G_CALLBACK(activate_status_primitive_cb),
-		GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE), 0, 0, NULL);
+		new_menu_item_with_status_icon(submenu, _("Away"),
+			PURPLE_STATUS_AWAY, G_CALLBACK(activate_status_primitive_cb),
+			GINT_TO_POINTER(PURPLE_STATUS_AWAY), 0, 0, NULL);
+
+		new_menu_item_with_status_icon(submenu, _("Do not disturb"),
+			PURPLE_STATUS_UNAVAILABLE, G_CALLBACK(activate_status_primitive_cb),
+			GINT_TO_POINTER(PURPLE_STATUS_UNAVAILABLE), 0, 0, NULL);
 
-	new_menu_item_with_status_icon(submenu, _("Offline"),
-		PURPLE_STATUS_OFFLINE, G_CALLBACK(activate_status_primitive_cb),
-		GINT_TO_POINTER(PURPLE_STATUS_OFFLINE), 0, 0, NULL);
+		new_menu_item_with_status_icon(submenu, _("Invisible"),
+			PURPLE_STATUS_INVISIBLE, G_CALLBACK(activate_status_primitive_cb),
+			GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE), 0, 0, NULL);
+
+		new_menu_item_with_status_icon(submenu, _("Offline"),
+			PURPLE_STATUS_OFFLINE, G_CALLBACK(activate_status_primitive_cb),
+			GINT_TO_POINTER(PURPLE_STATUS_OFFLINE), 0, 0, NULL);
+	}
 
 	popular_statuses = purple_savedstatuses_get_popular(6);
 	if (popular_statuses != NULL)
@@ -653,7 +765,7 @@
 			if (pending) {
 				GList *l = get_pending_list(1);
 				if (l != NULL) {
-					purple_conversation_present((PurpleConversation *)l->data);
+					pidgin_conv_present_conversation((PurpleConversation *)l->data);
 					g_list_free(l);
 				}
 			} else {