changeset 28873:3e5a37c743df

commit differences as a revision for now.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 04 Nov 2009 16:58:41 +0900
parents d7c49598cef2 (current diff) d4c28c18c20a (diff)
children 9d17b1c09193
files autogen.sh libpurple/protocols/jabber/JEPS libpurple/protocols/jabber/google.c libpurple/protocols/jabber/jabber.c libpurple/protocols/msn/msn.c libpurple/protocols/oscar/oscar.c libpurple/protocols/yahoo/libyahoo.c libpurple/protocols/yahoo/libymsg.c libpurple/protocols/yahoo/util.c libpurple/protocols/yahoo/yahoo_filexfer.c pidgin/gtkblist.c pidgin/gtkimhtml.c pidgin/gtkprefs.c
diffstat 40 files changed, 665 insertions(+), 515 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Oct 25 15:30:09 2009 +0900
+++ b/ChangeLog	Wed Nov 04 16:58:41 2009 +0900
@@ -43,6 +43,12 @@
 	* The userlist in a multiuser chat can be styled via gtkrc by using the
 	  widget name "pidgin_conv_userlist". (Heiko Schmitt)
 	* Add a hold button to the media window.
+	* Tooltips for custom smileys should work now.
+	* Users with unread messages are again bolded in the Buddy List.
+	* Minor reworking of the Preferences window's Network tab to make it need
+	  less vertical space.
+	* The global "Use remote DNS with SOCKS4 proxies" preference no longer
+	  disappears when the preference value changes in certain ways.
 
 version 2.6.3 (10/16/2009):
 	General:
--- a/autogen.sh	Sun Oct 25 15:30:09 2009 +0900
+++ b/autogen.sh	Wed Nov 04 16:58:41 2009 +0900
@@ -83,7 +83,7 @@
 
 	OUTPUT=`mktemp autogen-XXXXXX`
 
-	printf "%s" "running ${CMD} ${@}... "
+	printf "running %s %s... " ${CMD} "$*"
 	${CMD} ${@} >${OUTPUT} 2>&1
 
 	if [ $? != 0 ] ; then
@@ -99,9 +99,17 @@
 	fi
 }
 
+cleanup () {
+	rm -f autogen-??????
+	echo
+	exit 2
+}
+
 ###############################################################################
 # We really start here, yes, very sneaky!
 ###############################################################################
+trap cleanup 2
+
 FIGLET=`which figlet 2> /dev/null`
 if [ x"${FIGLET}" != x"" ] ; then
 	${FIGLET} -f small ${PACKAGE}
@@ -143,7 +151,7 @@
 run_or_die ${INTLTOOLIZE} ${INTLTOOLIZE_FLAGS:-"-c -f --automake"}
 # This call to sed is needed to work around an annoying bug in intltool 0.40.6
 # See http://developer.pidgin.im/ticket/9520 for details
-run_or_die ${SED} "s:'\^\$\$lang\$\$':\^\$\$lang\$\$:g" -i po/Makefile.in.in
+run_or_die ${SED} -i.bak -e "s:'\^\$\$lang\$\$':\^\$\$lang\$\$:g" po/Makefile.in.in
 run_or_die ${ACLOCAL} ${ACLOCAL_FLAGS:-"-I m4macros"}
 run_or_die ${AUTOHEADER} ${AUTOHEADER_FLAGS}
 run_or_die ${AUTOMAKE} ${AUTOMAKE_FLAGS:-"-a -c --gnu"}
--- a/finch/libgnt/gntentry.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/finch/libgnt/gntentry.c	Wed Nov 04 16:58:41 2009 +0900
@@ -1044,8 +1044,11 @@
 		snprintf(entry->start, len + 1, "%s", text);
 	entry->end = entry->start + len;
 
-	entry->scroll = entry->start + scroll;
-	entry->cursor = entry->end - cursor;
+	if ((entry->scroll = entry->start + scroll) > entry->end)
+		entry->scroll = entry->end;
+
+	if ((entry->cursor = entry->end - cursor) > entry->end)
+		entry->cursor = entry->end;
 
 	if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(entry), GNT_WIDGET_MAPPED))
 		entry_redraw(GNT_WIDGET(entry));
--- a/finch/libgnt/gnttextview.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/finch/libgnt/gnttextview.c	Wed Nov 04 16:58:41 2009 +0900
@@ -67,6 +67,12 @@
 
 static void reset_text_view(GntTextView *view);
 
+static gboolean
+text_view_contains(GntTextView *view, const char *str)
+{
+	return (str >= view->string->str && str < view->string->str + view->string->len);
+}
+
 static void
 gnt_text_view_draw(GntWidget *widget)
 {
@@ -109,7 +115,7 @@
 			char back = *end;
 			chtype fl = seg->flags;
 			*end = '\0';
-			if (select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) {
+			if (select_start && select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) {
 				fl |= A_REVERSE;
 				wattrset(widget->window, fl);
 				wprintw(widget->window, "%s", (view->string->str + seg->start));
@@ -326,9 +332,10 @@
 		select_start = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y);
 		g_timeout_add(500, too_slow, NULL);
 	} else if (event == GNT_MOUSE_UP) {
-		if (select_start) {
+		GntTextView *view = GNT_TEXT_VIEW(widget);
+		if (text_view_contains(view, select_start)) {
 			GString *clip;
-			select_end = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y);
+			select_end = gnt_text_view_get_p(view, x - widget->priv.x, y - widget->priv.y);
 			if (select_end < select_start) {
 				gchar *t = select_start;
 				select_start = select_end;
@@ -336,7 +343,7 @@
 			}
 			if (select_start == select_end) {
 				if (double_click) {
-					clip = select_word_text(GNT_TEXT_VIEW(widget), select_start);
+					clip = select_word_text(view, select_start);
 					double_click = FALSE;
 				} else {
 					double_click = TRUE;
--- a/libpurple/Makefile.am	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/Makefile.am	Wed Nov 04 16:58:41 2009 +0900
@@ -32,7 +32,7 @@
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = purple.pc
 
-SUBDIRS = $(GCONF_DIR) plugins protocols tests . example
+SUBDIRS = $(GCONF_DIR) plugins protocols . tests example
 
 purple_coresources = \
 	account.c \
--- a/libpurple/account.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/account.c	Wed Nov 04 16:58:41 2009 +0900
@@ -1050,6 +1050,16 @@
 	if(account->system_log)
 		purple_log_free(account->system_log);
 
+	while (account->deny) {
+		g_free(account->deny->data);
+		account->deny = g_slist_delete_link(account->deny, account->deny);
+	}
+
+	while (account->permit) {
+		g_free(account->permit->data);
+		account->permit = g_slist_delete_link(account->permit, account->permit);
+	}
+
 	priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
 	PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error);
 	if (priv->current_error) {
--- a/libpurple/cipher.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/cipher.c	Wed Nov 04 16:58:41 2009 +0900
@@ -50,10 +50,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include <glib.h>
-#include <string.h>
-#include <stdio.h>
-
 #include "internal.h"
 #include "cipher.h"
 #include "dbus-maybe.h"
--- a/libpurple/dnsquery.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/dnsquery.c	Wed Nov 04 16:58:41 2009 +0900
@@ -172,6 +172,7 @@
 	return FALSE;
 }
 
+#ifdef USE_IDN
 static gboolean
 dns_str_is_ascii(const char *name)
 {
@@ -183,6 +184,7 @@
 
 	return TRUE;
 }
+#endif
 
 #if defined(PURPLE_DNSQUERY_USE_FORK)
 
@@ -293,12 +295,11 @@
 			rc = purple_network_convert_idn_to_ascii(dns_params.hostname, &hostname);
 			if (rc != 0) {
 				write_to_parent(child_out, &rc, sizeof(rc));
-				close(child_out);
 				if (show_debug)
 					fprintf(stderr, "dns[%d] Error: IDN conversion returned "
 							"%d\n", getpid(), rc);
 				dns_params.hostname[0] = '\0';
-				continue;
+				break;
 			}
 		} else /* intentional to execute the g_strdup */
 #endif
@@ -323,14 +324,13 @@
 		rc = getaddrinfo(hostname, servname, &hints, &res);
 		write_to_parent(child_out, &rc, sizeof(rc));
 		if (rc != 0) {
-			close(child_out);
 			if (show_debug)
 				printf("dns[%d] Error: getaddrinfo returned %d\n",
 					getpid(), rc);
 			dns_params.hostname[0] = '\0';
 			g_free(hostname);
 			hostname = NULL;
-			continue;
+			break;
 		}
 		tmp = res;
 		while (res) {
--- a/libpurple/dnssrv.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/dnssrv.c	Wed Nov 04 16:58:41 2009 +0900
@@ -248,6 +248,7 @@
 	return list;
 }
 
+#ifdef USE_IDN
 static gboolean
 dns_str_is_ascii(const char *name)
 {
@@ -259,8 +260,60 @@
 
 	return TRUE;
 }
+#endif
 
 #ifndef _WIN32
+static void
+write_to_parent(int in, int out, gconstpointer data, gsize size)
+{
+	const guchar *buf = data;
+	gssize w;
+
+	do {
+		w = write(out, buf, size);
+		if (w > 0) {
+			buf += w;
+			size -= w;
+		} else if (w < 0 && errno == EINTR) {
+			/* Let's try some more; */
+			w = 1;
+		}
+	} while (size > 0 && w > 0);
+
+	if (size != 0) {
+		/* An error occurred */
+		close(out);
+		close(in);
+		_exit(0);
+	}
+}
+
+/* Read size bytes to data. Dies if an error occurs. */
+static void
+read_from_parent(int in, int out, gpointer data, gsize size)
+{
+	guchar *buf = data;
+	gssize r;
+
+	do {
+		r = read(in, data, size);
+		if (r > 0) {
+			buf += r;
+			size -= r;
+		} else if (r < 0 && errno == EINTR) {
+			/* Let's try some more; */
+			r = 1;
+		}
+	} while (size > 0 && r > 0);
+
+	if (size != 0) {
+		/* An error occurred */
+		close(out);
+		close(in);
+		_exit(0);
+	}
+}
+
 
 G_GNUC_NORETURN static void
 resolve(int in, int out)
@@ -279,16 +332,12 @@
 	purple_restore_default_signal_handlers();
 #endif
 
-	if (read(in, &query, sizeof(query)) <= 0) {
-		close(out);
-		close(in);
-		_exit(0);
-	}
+	read_from_parent(in, out, &query, sizeof(query));
 
 	size = res_query( query.query, C_IN, query.type, (u_char*)&answer, sizeof( answer));
 	if (size == -1) {
-		write(out, &(query.type), sizeof(query.type));
-		write(out, &size, sizeof(int));
+		write_to_parent(in, out, &(query.type), sizeof(query.type));
+		write_to_parent(in, out, &size, sizeof(size));
 		close(out);
 		close(in);
 		_exit(0);
@@ -353,19 +402,17 @@
 	if (query.type == T_SRV)
 		ret = purple_srv_sort(ret);
 
-	/* TODO: Check return value */
-	write(out, &(query.type), sizeof(query.type));
-	write(out, &size, sizeof(size));
+	write_to_parent(in, out, &(query.type), sizeof(query.type));
+	write_to_parent(in, out, &size, sizeof(size));
 	while (ret != NULL)
 	{
-		/* TODO: Check return value */
 		if (query.type == T_SRV)
-			write(out, ret->data, sizeof(PurpleSrvResponse));
+			write_to_parent(in, out, ret->data, sizeof(PurpleSrvResponse));
 		if (query.type == T_TXT) {
 			PurpleTxtResponse *response = ret->data;
 			gsize l = strlen(response->content) + 1 /* null byte */;
-			write(out, &l, sizeof(l));
-			write(out, response->content, l);
+			write_to_parent(in, out, &l, sizeof(l));
+			write_to_parent(in, out, response->content, l);
 		}
 
 		g_free(ret->data);
--- a/libpurple/plugins/perl/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/plugins/perl/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -7,10 +7,12 @@
 PIDGIN_TREE_TOP := ../../..
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
+
 TARGET = perl
 
 # Perl headers with /* /* */ type comments.. Turn off warnings.
-CFLAGS += -Wno-comment
+GCCWARNINGS += -Wno-comment
 
 ##
 ## INCLUDE PATHS
--- a/libpurple/plugins/perl/common/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/plugins/perl/common/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -5,9 +5,12 @@
 #
 
 PIDGIN_TREE_TOP := ../../../..
-GCCWARNINGS := -Wno-comment -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wpointer-arith -Wundef -Wno-unused
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+GCCWARNINGS += -Wno-comment -Wno-unused -Wno-nested-externs
+
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
+
 TARGET = Purple
 AUTOSPLIT = lib/auto/Purple/autosplit.ix
 EXTUTILS ?= C:/perl/lib/ExtUtils
--- a/libpurple/protocols/jabber/JEPS	Sun Oct 25 15:30:09 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-0045: IN PROGRESS
-	Multi-User Chat
-0047: IN PROGRESS
-	In-Band Bytestreams
-0060: NEED
-	Pub-Sub
-0071: AWAITING FINAL SPEC
-	XHTML-IM
-0073: NEED
-	Basic IM Protocol Suite
-0080: NEED (Do we?)
-	Geographic Location Information
-0084: NEED
-	User Avatars in Jabber
-0085: NEED
-	Chat State Notifications
-0089: WATCH
-	Generic Alerts
-0093: NEED
-	Roster Item Exchange
-0100: NEED
-	Gateway Interaction (Transports)
-0115: WATCH
-	Client Capabilities
-0117: NEED
-	Intermediate IM Protocol Suite
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/jabber/XEPS	Wed Nov 04 16:58:41 2009 +0900
@@ -0,0 +1,4 @@
+0060: NEED
+	Pub-Sub
+0080: NEED (Do we?)
+	Geographic Location Information
--- a/libpurple/protocols/jabber/caps.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/jabber/caps.c	Wed Nov 04 16:58:41 2009 +0900
@@ -975,7 +975,7 @@
 	g_free(js->caps_hash);
 	js->caps_hash = jabber_caps_calculate_hash(&info, "sha1");
 	g_list_free(info.identities);
-	g_list_free(features);
+	g_list_free(info.features);
 }
 
 const gchar* jabber_caps_get_own_hash(JabberStream *js)
--- a/libpurple/protocols/jabber/google.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/jabber/google.c	Wed Nov 04 16:58:41 2009 +0900
@@ -995,8 +995,9 @@
 
 	const char *grt = xmlnode_get_attrib_with_namespace(item, "t", "google:roster");
 	const char *subscription = xmlnode_get_attrib(item, "subscription");
+	const char *ask = xmlnode_get_attrib(item, "ask");
 
-	if (!subscription || !strcmp(subscription, "none")) {
+	if ((!subscription || !strcmp(subscription, "none")) && !ask) {
 		/* The Google Talk servers will automatically add people from your Gmail address book
 		 * with subscription=none. If we see someone with subscription=none, ignore them.
 		 */
--- a/libpurple/protocols/jabber/jabber.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/jabber/jabber.c	Wed Nov 04 16:58:41 2009 +0900
@@ -1827,7 +1827,7 @@
 		JabberFeature *feature = jabber_features->data;
 		g_free(feature->namespace);
 		g_free(feature);
-		jabber_features = g_list_remove_link(jabber_features, jabber_features);
+		jabber_features = g_list_delete_link(jabber_features, jabber_features);
 	}
 }
 
@@ -1864,7 +1864,7 @@
 		g_free(id->lang);
 		g_free(id->name);
 		g_free(id);
-		jabber_identities = g_list_remove_link(jabber_identities, jabber_identities);
+		jabber_identities = g_list_delete_link(jabber_identities, jabber_identities);
 	}
 }
 
--- a/libpurple/protocols/jabber/roster.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/jabber/roster.c	Wed Nov 04 16:58:41 2009 +0900
@@ -72,7 +72,7 @@
 		const char *alias, GSList *groups)
 {
 	GSList *buddies, *l;
-	GSList *pool = NULL;
+	PurpleAccount *account = purple_connection_get_account(js->gc);
 
 	buddies = purple_find_buddies(js->gc->account, jid);
 
@@ -117,25 +117,14 @@
 			groups = g_slist_delete_link(groups, l);
 		} else {
 			/* This buddy isn't in the group on the server anymore */
-			pool = g_slist_prepend(pool, b);
+			purple_debug_info("jabber", "jabber_roster_parse(): Removing %s "
+			                  "from group '%s' on the local list\n",
+			                  purple_buddy_get_name(b),
+			                  purple_group_get_name(g));
+			purple_blist_remove_buddy(b);
 		}
 	}
 
-	if (pool) {
-		GString *tmp = g_string_new(NULL);
-		GSList *list = pool;
-		for ( ; list; list = list->next) {
-			tmp = g_string_append(tmp,
-					purple_group_get_name(purple_buddy_get_group(list->data)));
-			if (list->next)
-				tmp = g_string_append(tmp, ", ");
-		}
-
-		purple_debug_info("jabber", "jabber_roster_parse(): Removing %s from "
-		                  "groups: %s\n", jid, tmp->str);
-		g_string_free(tmp, TRUE);
-	}
-
 	if (groups) {
 		char *tmp = roster_groups_join(groups);
 		purple_debug_info("jabber", "jabber_roster_parse(): Adding %s to "
@@ -145,17 +134,7 @@
 
 	while(groups) {
 		PurpleGroup *g = purple_find_group(groups->data);
-		PurpleBuddy *b = NULL;
-
-		/* If there are buddies we would otherwise delete, move them to
-		 * the new group (instead of deleting them below)
-		 */
-		if (pool) {
-			b = pool->data;
-			pool = g_slist_delete_link(pool, pool);
-		} else {
-			b = purple_buddy_new(js->gc->account, jid, alias);
-		}
+		PurpleBuddy *b = purple_buddy_new(account, jid, alias);
 
 		if(!g) {
 			g = purple_group_new(groups->data);
@@ -169,14 +148,6 @@
 		groups = g_slist_delete_link(groups, groups);
 	}
 
-	/* Remove this person from all the groups they're no longer in on the
-	 * server */
-	while (pool) {
-		PurpleBuddy *b = pool->data;
-		purple_blist_remove_buddy(b);
-		pool = g_slist_delete_link(pool, pool);
-	}
-
 	g_slist_free(buddies);
 }
 
--- a/libpurple/protocols/msn/msn.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/msn/msn.c	Wed Nov 04 16:58:41 2009 +0900
@@ -655,9 +655,14 @@
 		MsnSession *session = gc->proto_data;
 		if (session) {
 			MsnUser *user = msn_userlist_find_user(session->userlist, who);
-			if (user)
+			if (user) {
 				/* Include these too: MSN_CLIENT_CAP_MSNMOBILE|MSN_CLIENT_CAP_MSNDIRECT ? */
-				ret = (user->clientid & MSN_CLIENT_CAP_WEBMSGR) == 0;
+				if ((user->clientid & MSN_CLIENT_CAP_WEBMSGR) ||
+						user->networkid == MSN_NETWORK_YAHOO)
+					ret = FALSE;
+				else
+					ret = TRUE;
+			}
 		} else
 			ret = FALSE;
 	}
--- a/libpurple/protocols/msn/notification.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/msn/notification.c	Wed Nov 04 16:58:41 2009 +0900
@@ -670,7 +670,7 @@
 			                     "User %s is on both Allow and Block list; "
 			                     "removing from Allow list.\n",
 			                     user->passport);
-			msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL);
+			msn_user_unset_op(user, MSN_LIST_AL_OP);
 		}
 
 		if (user->networkid != MSN_NETWORK_UNKNOWN) {
@@ -840,17 +840,48 @@
 	MsnSession *session;
 	PurpleAccount *account;
 	PurpleConnection *gc;
-	char *adl = g_strndup(payload, len);
-	char *reason = g_strdup_printf(_("Unknown error (%d): %s"),
-		GPOINTER_TO_INT(cmd->payload_cbdata), adl);
-	g_free(adl);
+	int error = GPOINTER_TO_INT(cmd->payload_cbdata);
 
 	session = cmdproc->session;
 	account = session->account;
 	gc = purple_account_get_connection(account);
 
-	purple_notify_error(gc, NULL, _("Unable to add user"), reason);
-	g_free(reason);
+	if (error == 241) {
+		/* khc: some googling suggests that error 241 means the buddy is somehow
+		   in the local list, but not the server list, and that we should add
+		   those buddies to the addressbook. For now I will just notify the user
+		   about the raw payload, because I am lazy */
+		xmlnode *adl = xmlnode_from_str(payload, len);
+		GString *emails = g_string_new(NULL);
+
+		xmlnode *domain = xmlnode_get_child(adl, "d");
+		while (domain) {
+			const char *domain_str = xmlnode_get_attrib(domain, "n");
+			xmlnode *contact = xmlnode_get_child(domain, "c");
+			while (contact) {
+				g_string_append_printf(emails, "%s@%s\n",
+					xmlnode_get_attrib(contact, "n"), domain_str);
+				contact = xmlnode_get_next_twin(contact);
+			}
+			domain = xmlnode_get_next_twin(domain);
+		}
+
+		purple_notify_error(gc, NULL,
+			_("The following users are missing from your addressbook"),
+			emails->str);
+		g_string_free(emails, TRUE);
+		xmlnode_free(adl);
+	}
+	else
+	{
+		char *adl = g_strndup(payload, len);
+		char *reason = g_strdup_printf(_("Unknown error (%d): %s"),
+			error, adl);
+		g_free(adl);
+
+		purple_notify_error(gc, NULL, _("Unable to add user"), reason);
+		g_free(reason);
+	}
 }
 
 static void
@@ -878,50 +909,49 @@
 }
 
 static void
-adl_241_error_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
-	size_t len)
+rml_error_parse(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
 {
-	/* khc: some googling suggests that error 241 means the buddy is somehow
-	   in the local list, but not the server list, and that we should add
-	   those buddies to the addressbook. For now I will just notify the user
-	   about the raw payload, because I am lazy */
 	MsnSession *session;
 	PurpleAccount *account;
 	PurpleConnection *gc;
-	xmlnode *adl;
-	xmlnode *domain;
-	GString *emails;
+	char *adl, *reason;
+	int error = GPOINTER_TO_INT(cmd->payload_cbdata);
 
 	session = cmdproc->session;
 	account = session->account;
 	gc = purple_account_get_connection(account);
 
-	adl = xmlnode_from_str(payload, len);
-	emails = g_string_new(NULL);
+	adl = g_strndup(payload, len);
+	reason = g_strdup_printf(_("Unknown error (%d): %s"),
+		error, adl);
+	g_free(adl);
 
-	domain = xmlnode_get_child(adl, "d");
-	while (domain) {
-		const char *domain_str = xmlnode_get_attrib(domain, "n");
-		xmlnode *contact = xmlnode_get_child(domain, "c");
-		while (contact) {
-			g_string_append_printf(emails, "%s@%s\n",
-				xmlnode_get_attrib(contact, "n"), domain_str);
-			contact = xmlnode_get_next_twin(contact);
-		}
-		domain = xmlnode_get_next_twin(domain);
-	}
-
-	purple_notify_error(gc, NULL,
-		_("The following users are missing from your addressbook"), emails->str);
-	g_string_free(emails, TRUE);
-	xmlnode_free(adl);
+	purple_notify_error(gc, NULL, _("Unable to remove user"), reason);
+	g_free(reason);
 }
 
 static void
-adl_241_error_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
+rml_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
 {
-	cmdproc->last_cmd->payload_cb = adl_241_error_cmd_post;
-	cmd->payload_len = atoi(cmd->params[1]);
+	MsnSession *session;
+	PurpleAccount *account;
+	PurpleConnection *gc;
+	MsnCommand *cmd = cmdproc->last_cmd;
+
+	session = cmdproc->session;
+	account = session->account;
+	gc = purple_account_get_connection(account);
+
+	purple_debug_error("msn", "RML error\n");
+	if (cmd->param_count > 1) {
+		cmd->payload_cb = rml_error_parse;
+		cmd->payload_len = atoi(cmd->params[1]);
+		cmd->payload_cbdata = GINT_TO_POINTER(error);
+	} else {
+		char *reason = g_strdup_printf(_("Unknown error (%d)"), error);
+		purple_notify_error(gc, NULL, _("Unable to remove user"), reason);
+		g_free(reason);
+	}
 }
 
 static void
@@ -1068,7 +1098,17 @@
 		/* Where'd this come from? */
 		return;
 
-	if (cmd->param_count == 7) {
+	if (cmd->param_count == 8) {
+		/* Yahoo! Buddy, looks like */
+		networkid = atoi(cmd->params[3]);
+		friendly = g_strdup(purple_url_decode(cmd->params[4]));
+		clientid = strtoul(cmd->params[5], NULL, 10);
+
+		/* cmd->params[7] seems to be a URL to a Yahoo! icon:
+				https://sec.yimg.com/i/us/nt/b/purpley.1.0.png
+		   ... and it's purple, HAH!
+		*/
+	} else if (cmd->param_count == 7) {
 		/* MSNP14+ with Display Picture object */
 		networkid = atoi(cmd->params[3]);
 		friendly = g_strdup(purple_url_decode(cmd->params[4]));
@@ -2095,9 +2135,8 @@
 
 	msn_table_add_cmd(cbs_table, "fallback", "XFR", xfr_cmd);
 
-	msn_table_add_cmd(cbs_table, NULL, "241", adl_241_error_cmd);
-
 	msn_table_add_error(cbs_table, "ADL", adl_error);
+	msn_table_add_error(cbs_table, "RML", rml_error);
 	msn_table_add_error(cbs_table, "FQY", fqy_error);
 	msn_table_add_error(cbs_table, "USR", usr_error);
 
--- a/libpurple/protocols/oscar/oscar.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/oscar/oscar.c	Wed Nov 04 16:58:41 2009 +0900
@@ -2909,7 +2909,7 @@
 			if (text) {
 				/* Read the number of contacts that we were sent */
 				errno = 0;
-				num = strtoul(text[0], NULL, 10);
+				num = text[0] ? strtoul(text[0], NULL, 10) : 0;
 
 				if (num > 0 && errno == 0) {
 					for (i=0; i<num; i++) {
--- a/libpurple/protocols/silc/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/silc/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -7,6 +7,8 @@
 PIDGIN_TREE_TOP := ../../..
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
+
 TARGET = libsilc
 NEEDED_DLLS =		$(SILC_TOOLKIT)/bin/libsilc-1-1-2.dll \
 			$(SILC_TOOLKIT)/bin/libsilcclient-1-1-2.dll
@@ -79,7 +81,7 @@
 $(OBJECTS): $(PURPLE_CONFIG_H)
 
 $(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
-	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x64000000 -o $(TARGET).dll
+	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x74000000 -o $(TARGET).dll
 
 ##
 ## CLEAN RULES
--- a/libpurple/protocols/silc10/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/silc10/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -7,6 +7,8 @@
 PIDGIN_TREE_TOP := ../../..
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
+
 TARGET = libsilc
 NEEDED_DLLS =		$(SILC_TOOLKIT)/lib/silc.dll \
 			$(SILC_TOOLKIT)/lib/silcclient.dll
--- a/libpurple/protocols/yahoo/libyahoo.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/yahoo/libyahoo.c	Wed Nov 04 16:58:41 2009 +0900
@@ -250,7 +250,7 @@
 	yahoo_roomlist_get_list,
 	yahoo_roomlist_cancel,
 	yahoo_roomlist_expand_category,
-	NULL, /* can_receive_file */
+	yahoo_can_receive_file, /* can_receive_file */
 	yahoo_send_file,
 	yahoo_new_xfer,
 	yahoo_offline_message, /* offline_message */
--- a/libpurple/protocols/yahoo/libymsg.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/yahoo/libymsg.c	Wed Nov 04 16:58:41 2009 +0900
@@ -154,6 +154,7 @@
 	gboolean unicode = FALSE;
 	char *message = NULL;
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
+	char *fedname = NULL;
 
 	if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
 		if (!purple_account_get_remember_password(account))
@@ -194,18 +195,20 @@
 						break;
 					if (p->key == 241) {
 						fed = strtol(p->value, NULL, 10);
+						g_free(fedname);
 						switch (fed) {
 							case YAHOO_FEDERATION_MSN:
-								name = g_strconcat("msn/", name, NULL);
+								name = fedname = g_strconcat("msn/", name, NULL);
 								break;
 							case YAHOO_FEDERATION_OCS:
-								name = g_strconcat("ocs/", name, NULL);
+								name = fedname = g_strconcat("ocs/", name, NULL);
 								break;
 							case YAHOO_FEDERATION_IBM:
-								name = g_strconcat("ibm/", name, NULL);
+								name = fedname = g_strconcat("ibm/", name, NULL);
 								break;
 							case YAHOO_FEDERATION_NONE:
 							default:
+								fedname = NULL;
 								break;
 						}
 						break;
@@ -390,6 +393,7 @@
 			yahoo_update_status(gc, name, f);
 	}
 
+	g_free(fedname);
 }
 
 static void yahoo_do_group_check(PurpleAccount *account, GHashTable *ht, const char *name, const char *group)
@@ -4001,7 +4005,7 @@
 
 	}
 
-	if (f && f->status != YAHOO_STATUS_OFFLINE) {
+	if (f && f->status != YAHOO_STATUS_OFFLINE && f->fed == YAHOO_FEDERATION_NONE) {
 		if (!yd->wm) {
 			act = purple_menu_action_new(_("Join in Chat"),
 			                           PURPLE_CALLBACK(yahoo_chat_goto_menu),
@@ -4041,10 +4045,12 @@
 		                           build_presence_submenu(f, gc));
 		m = g_list_append(m, act);
 
-		act = purple_menu_action_new(_("Start Doodling"),
-		                           PURPLE_CALLBACK(yahoo_doodle_blist_node),
-		                           NULL, NULL);
-		m = g_list_append(m, act);
+		if (f->fed == YAHOO_FEDERATION_NONE) {
+			act = purple_menu_action_new(_("Start Doodling"),
+					PURPLE_CALLBACK(yahoo_doodle_blist_node),
+					NULL, NULL);
+			m = g_list_append(m, act);
+		}
 
 		act = purple_menu_action_new(_("Set User Info..."),
 		                           PURPLE_CALLBACK(yahoo_userinfo_blist_node),
@@ -4369,17 +4375,7 @@
 		}
 	}
 
-	if (who[3] == '/') {
-		if (!g_ascii_strncasecmp(who, "msn/", 4)) {
-			fed = YAHOO_FEDERATION_MSN;
-		}
-		else if (!g_ascii_strncasecmp(who, "ocs/", 4)) {
-			fed = YAHOO_FEDERATION_OCS;
-		}
-		else if (!g_ascii_strncasecmp(who, "ibm/", 4)) {
-			fed = YAHOO_FEDERATION_IBM;
-		}
-	}
+	fed = yahoo_get_federation_from_name(who);
 
 	if (who[0] == '+') {
 		/* we have an sms to be sent */
@@ -4511,17 +4507,7 @@
 	YahooFederation fed = YAHOO_FEDERATION_NONE;
 	struct yahoo_packet *pkt = NULL;
 
-	if (who[3] == '/') {
-		if (!g_ascii_strncasecmp(who, "msn/", 4)) {
-			fed = YAHOO_FEDERATION_MSN;
-		}
-		else if (!g_ascii_strncasecmp(who, "ocs/", 4)) {
-			fed = YAHOO_FEDERATION_OCS;
-		}
-		else if (!g_ascii_strncasecmp(who, "ibm/", 4)) {
-			fed = YAHOO_FEDERATION_IBM;
-		}
-	}
+	fed = yahoo_get_federation_from_name(who);
 
 	/* Don't do anything if sms is being typed */
 	if( strncmp(who, "+", 1) == 0 )
@@ -4814,18 +4800,9 @@
 		return;
 
 	f = yahoo_friend_find(gc, bname);
-	if (bname[3] == '/') {
+	fed = yahoo_get_federation_from_name(bname);
+	if (fed != YAHOO_FEDERATION_NONE)
 		fed_bname += 4;
-		if (!g_ascii_strncasecmp(bname, "msn/", 4)) {
-			fed = YAHOO_FEDERATION_MSN;
-		}
-		else if (!g_ascii_strncasecmp(bname, "ocs/", 4)) {
-			fed = YAHOO_FEDERATION_OCS;
-		}
-		else if (!g_ascii_strncasecmp(bname, "ibm/", 4)) {
-			fed = YAHOO_FEDERATION_IBM;
-		}
-	}
 
 	g = purple_buddy_get_group(buddy);
 	if (g)
@@ -4937,18 +4914,8 @@
 	if (!who || who[0] == '\0')
 		return;
 
-	if (who[3] == '/') {
-		if (!g_ascii_strncasecmp(who, "msn/", 4)) {
-			fed = YAHOO_FEDERATION_MSN;
-		}
-		else if (!g_ascii_strncasecmp(who, "ocs/", 4)) {
-			fed = YAHOO_FEDERATION_OCS;
-		}
-		else if (!g_ascii_strncasecmp(who, "ibm/", 4)) {
-			fed = YAHOO_FEDERATION_IBM;
-		}
-	}
-	
+	fed = yahoo_get_federation_from_name(who);
+
 	pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
 
 	if(fed)
@@ -4969,17 +4936,8 @@
 
 	if (!who || who[0] == '\0')
 		return;
-	if (who[3] == '/') {
-		if (!g_ascii_strncasecmp(who, "msn/", 4)) {
-			fed = YAHOO_FEDERATION_MSN;
-		}
-		else if (!g_ascii_strncasecmp(who, "ocs/", 4)) {
-			fed = YAHOO_FEDERATION_OCS;
-		}
-		else if (!g_ascii_strncasecmp(who, "ibm/", 4)) {
-			fed = YAHOO_FEDERATION_IBM;
-		}
-	}
+	fed = yahoo_get_federation_from_name(who);
+
 	pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id);
 
 	if(fed)
--- a/libpurple/protocols/yahoo/libymsg.h	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/yahoo/libymsg.h	Wed Nov 04 16:58:41 2009 +0900
@@ -346,6 +346,7 @@
 
 char *yahoo_convert_to_numeric(const char *str);
 
+YahooFederation yahoo_get_federation_from_name(const char *who);
 
 /* yahoo_profile.c */
 void yahoo_get_info(PurpleConnection *gc, const char *name);
--- a/libpurple/protocols/yahoo/util.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/yahoo/util.c	Wed Nov 04 16:58:41 2009 +0900
@@ -922,3 +922,18 @@
 
 	return g_string_free(dest, FALSE);
 }
+
+YahooFederation yahoo_get_federation_from_name(const char *who)
+{
+	YahooFederation fed = YAHOO_FEDERATION_NONE;
+	if (who[3] == '/') {
+		if (!g_ascii_strncasecmp(who, "msn", 3))
+			fed = YAHOO_FEDERATION_MSN;
+		else if (!g_ascii_strncasecmp(who, "ocs", 3))
+			fed = YAHOO_FEDERATION_OCS;
+		else if (!g_ascii_strncasecmp(who, "ibm", 3))
+			fed = YAHOO_FEDERATION_IBM;
+	}
+	return fed;
+}
+
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Wed Nov 04 16:58:41 2009 +0900
@@ -1075,6 +1075,13 @@
 	yahoo_packet_send_and_free(pkt, yd);
 }
 
+gboolean yahoo_can_receive_file(PurpleConnection *gc, const char *who)
+{
+	if (!who || yahoo_get_federation_from_name(who) != YAHOO_FEDERATION_NONE)
+		return FALSE;
+	return TRUE;
+}
+
 void yahoo_send_file(PurpleConnection *gc, const char *who, const char *file)
 {
 	struct yahoo_xfer_data *xfer_data;
--- a/libpurple/protocols/yahoo/yahoo_filexfer.h	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.h	Wed Nov 04 16:58:41 2009 +0900
@@ -43,6 +43,18 @@
 PurpleXfer *yahoo_new_xfer(PurpleConnection *gc, const char *who);
 
 /**
+ * Returns TRUE if the buddy can receive file, FALSE otherwise.
+ * Federated users cannot receive files. So this will return FALSE only
+ * for them.
+ *
+ * @param gc The connection
+ * @param who The name of the remote user
+ *
+ * @return TRUE or FALSE
+ */
+gboolean yahoo_can_receive_file(PurpleConnection *gc, const char *who);
+
+/**
  * Send a file.
  *
  * @param gc The PurpleConnection handle.
--- a/libpurple/theme-loader.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/theme-loader.c	Wed Nov 04 16:58:41 2009 +0900
@@ -100,6 +100,7 @@
 	PurpleThemeLoaderPrivate *priv = PURPLE_THEME_LOADER_GET_PRIVATE(loader);
 
 	g_free(priv->type);
+	g_free(priv);
 
 	parent_class->finalize(obj);
 }
--- a/libpurple/win32/global.mak	Sun Oct 25 15:30:09 2009 +0900
+++ b/libpurple/win32/global.mak	Wed Nov 04 16:58:41 2009 +0900
@@ -85,7 +85,7 @@
 DEFINES += -DHAVE_CYRUS_SASL
 endif
 
-DEFINES += -DHAVE_CONFIG_H
+DEFINES += -DHAVE_CONFIG_H -DWIN32_LEAN_AND_MEAN
 
 # Use -g flag when building debug version of Pidgin (including plugins).
 # Use -fnative-struct instead of -mms-bitfields when using mingw 1.1
--- a/pidgin/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -7,6 +7,8 @@
 PIDGIN_TREE_TOP := ..
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
+
 NEEDED_DLLS = $(GTKSPELL_TOP)/gtkspell/libgtkspell.dll
 
 ##
@@ -55,12 +57,12 @@
 ##
 PIDGIN_C_SRC =	\
 			gtkaccount.c \
-			gtkblist.c \
+			gtkblist-theme-loader.c \
 			gtkblist-theme.c \
-			gtkblist-theme-loader.c \
-			gtkcertmgr.c \
+			gtkblist.c \
 			gtkcellrendererexpander.c \
 			gtkcellrendererprogress.c \
+			gtkcertmgr.c \
 			gtkconn.c \
 			gtkconv.c \
 			gtkdebug.c \
@@ -70,8 +72,8 @@
 			gtkeventloop.c \
 			gtkexpander.c \
 			gtkft.c \
+			gtkicon-theme-loader.c \
 			gtkicon-theme.c \
-			gtkicon-theme-loader.c \
 			gtkidle.c \
 			gtkimhtml.c \
 			gtkimhtmltoolbar.c \
--- a/pidgin/gtkblist.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/gtkblist.c	Wed Nov 04 16:58:41 2009 +0900
@@ -4190,6 +4190,12 @@
 		}
 	}
 
+	if (hidden_conv) {
+		char *tmp = nametext;
+		nametext = g_strdup_printf("<b>%s</b>", tmp);
+		g_free(tmp);
+	}
+
 	/* Put it all together */
 	if ((!aliased || biglist) && (statustext || idletime)) {
 		/* using <span size='smaller'> breaks the status, so it must be seperated into <small><span>*/
--- a/pidgin/gtkimhtml.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/gtkimhtml.c	Wed Nov 04 16:58:41 2009 +0900
@@ -5068,7 +5068,7 @@
 		                                     It will be destroyed when 'anchor' is destroyed. */
 		anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
 		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", text, g_free);
-		g_object_set_data(G_OBJECT(anchor), "gtkimhtml_tiptext", text);
+		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_tiptext", g_strdup(text), g_free);
 		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free);
 
 		/* This catches the expose events generated by animated
@@ -5090,7 +5090,8 @@
 			gtk_container_add(GTK_CONTAINER(ebox), img);
 			gtk_widget_show(img);
 			g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", text, g_free);
-			g_object_set_data(G_OBJECT(anchor), "gtkimhtml_tiptext", text);
+			g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_tiptext",
+				g_strdup(text), g_free);
 			g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free);
 			gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor);
 		}
--- a/pidgin/gtkmain.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/gtkmain.c	Wed Nov 04 16:58:41 2009 +0900
@@ -744,7 +744,7 @@
 	}
 
 #if GLIB_CHECK_VERSION(2,2,0)
-	g_set_application_name(_("Pidgin"));
+	g_set_application_name(PIDGIN_NAME);
 #endif /* glib-2.0 >= 2.2.0 */
 
 #ifdef _WIN32
--- a/pidgin/gtkprefs.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/gtkprefs.c	Wed Nov 04 16:58:41 2009 +0900
@@ -77,6 +77,7 @@
 static GtkListStore *smiley_theme_store = NULL;
 static GtkTreeSelection *smiley_theme_sel = NULL;
 static GtkWidget *prefs_proxy_frame = NULL;
+static GtkWidget *prefs_proxy_subframe = NULL;
 
 static GtkWidget *prefs = NULL;
 static GtkWidget *debugbutton = NULL;
@@ -1890,23 +1891,27 @@
 	pidgin_prefs_checkbox(_("_Enable automatic router port forwarding"),
 			"/purple/network/map_ports", vbox);
 
-	ports_checkbox = pidgin_prefs_checkbox(_("_Manually specify range of ports to listen on"),
-			"/purple/network/ports_range_use", vbox);
-
-	spin_button = pidgin_prefs_labeled_spin_button(vbox, _("_Start port:"),
+	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+
+	ports_checkbox = pidgin_prefs_checkbox(_("_Manually specify range of ports to listen on:"),
+			"/purple/network/ports_range_use", hbox);
+
+	spin_button = pidgin_prefs_labeled_spin_button(hbox, _("_Start:"),
 			"/purple/network/ports_range_start", 0, 65535, sg);
 	if (!purple_prefs_get_bool("/purple/network/ports_range_use"))
 		gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE);
 	g_signal_connect(G_OBJECT(ports_checkbox), "clicked",
 					 G_CALLBACK(pidgin_toggle_sensitive), spin_button);
 
-	spin_button = pidgin_prefs_labeled_spin_button(vbox, _("_End port:"),
+	spin_button = pidgin_prefs_labeled_spin_button(hbox, _("_End:"),
 			"/purple/network/ports_range_end", 0, 65535, sg);
 	if (!purple_prefs_get_bool("/purple/network/ports_range_use"))
 		gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE);
 	g_signal_connect(G_OBJECT(ports_checkbox), "clicked",
 					 G_CALLBACK(pidgin_toggle_sensitive), spin_button);
 
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), NULL, NULL, hbox, TRUE, NULL);
+
 	g_object_unref(sg);
 
 	/* TURN server */
@@ -1925,9 +1930,9 @@
 
 	pidgin_prefs_labeled_spin_button(hbox, _("_Port:"),
 		"/purple/network/turn_port", 0, 65535, NULL);
-	hbox = pidgin_prefs_labeled_entry(vbox, _("_Username:"),
+	hbox = pidgin_prefs_labeled_entry(vbox, _("Use_rname:"),
 		"/purple/network/turn_username", sg);
-	pidgin_prefs_labeled_password(hbox, _("_Password:"),
+	pidgin_prefs_labeled_password(hbox, _("Pass_word:"),
 		"/purple/network/turn_password", NULL);
 
 	if (purple_running_gnome()) {
@@ -1971,9 +1976,15 @@
 		gtk_widget_show(browser_button);
 	} else {
 		vbox = pidgin_make_frame(ret, _("Proxy Server"));
-		prefs_proxy_frame = gtk_vbox_new(FALSE, 0);
-
-		pidgin_prefs_dropdown(vbox, _("Proxy _type:"), PURPLE_PREF_STRING,
+		prefs_proxy_frame = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+		prefs_proxy_subframe = gtk_vbox_new(FALSE, 0);
+
+		/* This is a global option that affects SOCKS4 usage even with account-specific proxy settings */
+		pidgin_prefs_checkbox(_("Use remote _DNS with SOCKS4 proxies"),
+							  "/purple/proxy/socks4_remotedns", prefs_proxy_frame);
+		gtk_box_pack_start(GTK_BOX(vbox), prefs_proxy_frame, 0, 0, 0);
+
+		pidgin_prefs_dropdown(prefs_proxy_frame, _("Proxy t_ype:"), PURPLE_PREF_STRING,
 					"/purple/proxy/type",
 					_("No proxy"), "none",
 					"SOCKS 4", "socks4",
@@ -1981,21 +1992,17 @@
 					"HTTP", "http",
 					_("Use Environmental Settings"), "envvar",
 					NULL);
-		gtk_box_pack_start(GTK_BOX(vbox), prefs_proxy_frame, 0, 0, 0);
+		gtk_box_pack_start(GTK_BOX(prefs_proxy_frame), prefs_proxy_subframe, 0, 0, 0);
 		proxy_info = purple_global_proxy_get_info();
 
 		purple_prefs_connect_callback(prefs, "/purple/proxy/type",
-					    proxy_changed_cb, prefs_proxy_frame);
-
-		/* This is a global option that affects SOCKS4 usage even with account-specific proxy settings */
-		pidgin_prefs_checkbox(_("Use remote DNS with SOCKS4 proxies"),
-							  "/purple/proxy/socks4_remotedns", prefs_proxy_frame);
+					    proxy_changed_cb, prefs_proxy_subframe);
 
 		table = gtk_table_new(4, 2, FALSE);
 		gtk_container_set_border_width(GTK_CONTAINER(table), 0);
 		gtk_table_set_col_spacings(GTK_TABLE(table), 5);
 		gtk_table_set_row_spacings(GTK_TABLE(table), 10);
-		gtk_container_add(GTK_CONTAINER(prefs_proxy_frame), table);
+		gtk_container_add(GTK_CONTAINER(prefs_proxy_subframe), table);
 
 
 		label = gtk_label_new_with_mnemonic(_("_Host:"));
@@ -2016,11 +2023,11 @@
 		gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 		pidgin_set_accessible_label (entry, label);
 
-		label = gtk_label_new_with_mnemonic(_("_Port:"));
+		label = gtk_label_new_with_mnemonic(_("P_ort:"));
 		gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
 		gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
 
-		entry = gtk_entry_new();
+		entry = gtk_spin_button_new_with_range(0, 65535, 1);
 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
 		gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 0, 1, GTK_FILL, 0, 0, 0);
 		g_signal_connect(G_OBJECT(entry), "changed",
@@ -2035,7 +2042,7 @@
 		}
 		pidgin_set_accessible_label (entry, label);
 
-		label = gtk_label_new_with_mnemonic(_("_User:"));
+		label = gtk_label_new_with_mnemonic(_("User_name:"));
 		gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
 		gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
 
--- a/pidgin/gtkrequest.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/gtkrequest.c	Wed Nov 04 16:58:41 2009 +0900
@@ -81,6 +81,33 @@
 } PidginRequestData;
 
 static void
+pidgin_widget_decorate_account(GtkWidget *cont, PurpleAccount *account)
+{
+	GtkWidget *image;
+	GdkPixbuf *pixbuf;
+	GtkTooltips *tips;
+
+	if (!account)
+		return;
+
+	pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
+	image = gtk_image_new_from_pixbuf(pixbuf);
+	g_object_unref(G_OBJECT(pixbuf));
+
+	tips = gtk_tooltips_new();
+	gtk_tooltips_set_tip(tips, image, purple_account_get_username(account), NULL);
+
+	if (GTK_IS_DIALOG(cont)) {
+		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cont)->action_area), image, FALSE, TRUE, 0);
+		gtk_box_reorder_child(GTK_BOX(GTK_DIALOG(cont)->action_area), image, 0);
+	} else if (GTK_IS_HBOX(cont)) {
+		gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
+		gtk_box_pack_end(GTK_BOX(cont), image, FALSE, TRUE, 0);
+	}
+	gtk_widget_show(image);
+}
+
+static void
 generic_response_start(PidginRequestData *data)
 {
 	g_return_if_fail(data != NULL);
@@ -347,6 +374,8 @@
 
 	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
 
+	pidgin_widget_decorate_account(hbox, account);
+
 	/* Descriptive label */
 	primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
 	secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL;
@@ -515,6 +544,8 @@
 	gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
 	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
 
+	pidgin_widget_decorate_account(hbox, account);
+
 	/* Vertical box */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
 	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
@@ -639,6 +670,8 @@
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
 	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
 
+	pidgin_widget_decorate_account(hbox, account);
+
 	/* Descriptive label */
 	primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
 	secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL;
@@ -1144,6 +1177,8 @@
 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
 	gtk_window_set_default(GTK_WINDOW(win), button);
 
+	pidgin_widget_decorate_account(hbox, account);
+
 	/* Setup the vbox */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
 	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
--- a/pidgin/gtkstatusbox.c	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/gtkstatusbox.c	Wed Nov 04 16:58:41 2009 +0900
@@ -79,8 +79,8 @@
 
 static void pidgin_status_box_pulse_typing(PidginStatusBox *status_box);
 static void pidgin_status_box_refresh(PidginStatusBox *status_box);
-static void status_menu_refresh_iter(PidginStatusBox *status_box);
-static void pidgin_status_box_regenerate(PidginStatusBox *status_box);
+static void status_menu_refresh_iter(PidginStatusBox *status_box, gboolean status_changed);
+static void pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed);
 static void pidgin_status_box_changed(PidginStatusBox *box);
 static void pidgin_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition);
 static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
@@ -304,7 +304,7 @@
 	if (status_box->account == account)
 		update_to_reflect_account_status(status_box, account, newstatus);
 	else if (status_box->token_status_account == account)
-		status_menu_refresh_iter(status_box);
+		status_menu_refresh_iter(status_box, TRUE);
 }
 
 static gboolean
@@ -312,6 +312,7 @@
 {
 	if (event->button == 3) {
 		GtkWidget *menu_item;
+		const char *path;
 
 		if (box->icon_box_menu)
 			gtk_widget_destroy(box->icon_box_menu);
@@ -325,7 +326,8 @@
 		menu_item = pidgin_new_item_from_stock(box->icon_box_menu, _("Remove"), GTK_STOCK_REMOVE,
 						     G_CALLBACK(remove_buddy_icon_cb),
 						     box, 0, 0, NULL);
-		if (purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon") == NULL)
+		if (!(path = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon"))
+				|| !*path)
 			gtk_widget_set_sensitive(menu_item, FALSE);
 
 		gtk_menu_popup(GTK_MENU(box->icon_box_menu), NULL, NULL, NULL, NULL,
@@ -559,7 +561,7 @@
 		else
 			statusbox->token_status_account = check_active_accounts_for_identical_statuses();
 
-		pidgin_status_box_regenerate(statusbox);
+		pidgin_status_box_regenerate(statusbox, TRUE);
 
 		break;
 	default:
@@ -821,7 +823,7 @@
  * keyboard signals instead of the changed signal?
  */
 static void
-status_menu_refresh_iter(PidginStatusBox *status_box)
+status_menu_refresh_iter(PidginStatusBox *status_box, gboolean status_changed)
 {
 	PurpleSavedStatus *saved_status;
 	PurpleStatusPrimitive primitive;
@@ -912,18 +914,15 @@
 	} else
 		status_box->active_row = NULL;
 
-	message = purple_savedstatus_get_message(saved_status);
-	if (!purple_savedstatus_is_transient(saved_status) || !message || !*message)
-	{
-		status_box->imhtml_visible = FALSE;
-		gtk_widget_hide_all(status_box->vbox);
-	}
-	else
-	{
-		status_box->imhtml_visible = TRUE;
-		gtk_widget_show_all(status_box->vbox);
+	if (status_changed) {
+		message = purple_savedstatus_get_message(saved_status);
 
 		/*
+		 * If we are going to hide the imhtml, don't retain the
+		 * message because showing the old message later is
+		 * confusing. If we are going to set the message to a pre-set,
+		 * then we need to do this anyway
+		 *
 		 * Suppress the "changed" signal because the status
 		 * was changed programmatically.
 		 */
@@ -931,12 +930,24 @@
 
 		gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml));
 		gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml));
-		gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0);
+
+		if (!purple_savedstatus_is_transient(saved_status) || !message || !*message)
+		{
+			status_box->imhtml_visible = FALSE;
+			gtk_widget_hide_all(status_box->vbox);
+		}
+		else
+		{
+			status_box->imhtml_visible = TRUE;
+			gtk_widget_show_all(status_box->vbox);
+
+			gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0);
+		}
+
 		gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), TRUE);
+		update_size(status_box);
 	}
 
-	update_size(status_box);
-
 	/* Stop suppressing the "changed" signal. */
 	gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE);
 }
@@ -996,50 +1007,50 @@
  * statuses and a token account if they do */
 static PurpleAccount* check_active_accounts_for_identical_statuses(void)
 {
-	PurpleAccount *acct = NULL, *acct2;
-	GList *tmp, *tmp2, *active_accts = purple_accounts_get_all_active();
-	GList *s, *s1, *s2;
-
-	for (tmp = active_accts; tmp; tmp = tmp->next) {
-		acct = tmp->data;
-		s = purple_account_get_status_types(acct);
-		for (tmp2 = tmp->next; tmp2; tmp2 = tmp2->next) {
-			acct2 = tmp2->data;
-
-			/* Only actually look at the statuses if the accounts use the same prpl */
-			if (strcmp(purple_account_get_protocol_id(acct), purple_account_get_protocol_id(acct2))) {
-				acct = NULL;
-				break;
-			}
-
-			s2 = purple_account_get_status_types(acct2);
-
-			s1 = s;
-			while (s1 && s2) {
-				PurpleStatusType *st1 = s1->data, *st2 = s2->data;
-				/* TODO: Are these enough to consider the statuses identical? */
-				if (purple_status_type_get_primitive(st1) != purple_status_type_get_primitive(st2)
-						|| strcmp(purple_status_type_get_id(st1), purple_status_type_get_id(st2))
-						|| strcmp(purple_status_type_get_name(st1), purple_status_type_get_name(st2))) {
-					acct = NULL;
-					break;
-				}
-
-				s1 = s1->next;
-				s2 = s2->next;
-			}
-
-			if (s1 != s2) {/* Will both be NULL if matched */
-				acct = NULL;
+	GList *iter, *active_accts = purple_accounts_get_all_active();
+	PurpleAccount *acct1 = NULL;
+	const char *prpl1 = NULL;
+
+	if (active_accts) {
+		acct1 = active_accts->data;
+		prpl1 = purple_account_get_protocol_id(acct1);
+	} else {
+		/* there's no enabled account */
+		return NULL;
+	}
+
+	/* start at the second account */
+	for (iter = active_accts->next; iter; iter = iter->next) {
+		PurpleAccount *acct2 = iter->data;
+		GList *s1, *s2;
+
+		if (!g_str_equal(prpl1, purple_account_get_protocol_id(acct2))) {
+			acct1 = NULL;
+			break;
+		}
+
+		for (s1 = purple_account_get_status_types(acct1),
+				 s2 = purple_account_get_status_types(acct2); s1 && s2;
+			 s1 = s1->next, s2 = s2->next) {
+			PurpleStatusType *st1 = s1->data, *st2 = s2->data;
+			/* TODO: Are these enough to consider the statuses identical? */
+			if (purple_status_type_get_primitive(st1) != purple_status_type_get_primitive(st2)
+				|| strcmp(purple_status_type_get_id(st1), purple_status_type_get_id(st2))
+				|| strcmp(purple_status_type_get_name(st1), purple_status_type_get_name(st2))) {
+				acct1 = NULL;
 				break;
 			}
 		}
-		if (!acct)
+
+		if (s1 != s2) {/* Will both be NULL if matched */
+			acct1 = NULL;
 			break;
+		}
 	}
+
 	g_list_free(active_accts);
 
-	return acct;
+	return acct1;
 }
 
 static void
@@ -1068,7 +1079,7 @@
 }
 
 static void
-pidgin_status_box_regenerate(PidginStatusBox *status_box)
+pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed)
 {
 	GtkIconSize icon_size;
 
@@ -1104,7 +1115,7 @@
 		pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_CUSTOM, NULL, _("New status..."), NULL, NULL);
 		pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_SAVED, NULL, _("Saved statuses..."), NULL, NULL);
 
-		status_menu_refresh_iter(status_box);
+		status_menu_refresh_iter(status_box, status_changed);
 		pidgin_status_box_refresh(status_box);
 
 	} else {
@@ -1156,7 +1167,7 @@
 			update_to_reflect_account_status(status_box, status_box->account,
 							purple_account_get_active_status(status_box->account));
 		else {
-			status_menu_refresh_iter(status_box);
+			status_menu_refresh_iter(status_box, TRUE);
 			pidgin_status_box_refresh(status_box);
 		}
 		return TRUE;
@@ -1229,7 +1240,7 @@
 
 	/* Regenerate the list if it has changed */
 	if (initial_token_acct != status_box->token_status_account) {
-		pidgin_status_box_regenerate(status_box);
+		pidgin_status_box_regenerate(status_box, TRUE);
 	}
 
 }
@@ -1238,13 +1249,14 @@
 current_savedstatus_changed_cb(PurpleSavedStatus *now, PurpleSavedStatus *old, PidginStatusBox *status_box)
 {
 	/* Make sure our current status is added to the list of popular statuses */
-	pidgin_status_box_regenerate(status_box);
+	pidgin_status_box_regenerate(status_box, TRUE);
 }
 
 static void
 saved_status_updated_cb(PurpleSavedStatus *status, PidginStatusBox *status_box)
 {
-	pidgin_status_box_regenerate(status_box);
+	pidgin_status_box_regenerate(status_box,
+		purple_savedstatus_get_current() == status);
 }
 
 static void
@@ -1919,7 +1931,7 @@
 	status_box->token_status_account = check_active_accounts_for_identical_statuses();
 
 	cache_pixbufs(status_box);
-	pidgin_status_box_regenerate(status_box);
+	pidgin_status_box_regenerate(status_box, TRUE);
 
 	purple_signal_connect(purple_savedstatuses_get_handle(), "savedstatus-changed",
 						status_box,
@@ -2324,18 +2336,6 @@
 	pidgin_status_box_refresh(status_box);
 }
 
-static gboolean
-message_changed(const char *one, const char *two)
-{
-	if (one == NULL && two == NULL)
-		return FALSE;
-
-	if (one == NULL || two == NULL)
-		return TRUE;
-
-	return (g_utf8_collate(one, two) != 0);
-}
-
 static void
 activate_currently_selected_status(PidginStatusBox *status_box)
 {
@@ -2386,6 +2386,7 @@
 
 	if (status_box->account == NULL) {
 		PurpleStatusType *acct_status_type = NULL;
+		const char *id = NULL; /* id of acct_status_type */
 		PurpleStatusPrimitive primitive = GPOINTER_TO_INT(data);
 		/* Global */
 		/* Save the newly selected status to prefs.xml and status.xml */
@@ -2394,7 +2395,6 @@
 		if (status_box->token_status_account) {
 			gint active;
 			PurpleStatus *status;
-			const char *id = NULL;
 			GtkTreePath *path = gtk_tree_row_reference_get_path(status_box->active_row);
 			active = gtk_tree_path_get_indices(path)[0];
 
@@ -2402,37 +2402,35 @@
 
 			status = purple_account_get_active_status(status_box->token_status_account);
 
-			 acct_status_type = find_status_type_by_index(status_box->token_status_account, active);
+			acct_status_type = find_status_type_by_index(status_box->token_status_account, active);
 			id = purple_status_type_get_id(acct_status_type);
 
-			if (strncmp(id, purple_status_get_id(status), strlen(id)) == 0)
+			if (g_str_equal(id, purple_status_get_id(status)) &&
+				purple_strequal(message, purple_status_get_attr_string(status, "message")))
 			{
 				/* Selected status and previous status is the same */
-				if (!message_changed(message, purple_status_get_attr_string(status, "message")))
-				{
-					PurpleSavedStatus *ss = purple_savedstatus_get_current();
-					/* Make sure that statusbox displays the correct thing.
-					 * It can get messed up if the previous selection was a
-					 * saved status that wasn't supported by this account */
-					if ((purple_savedstatus_get_type(ss) == primitive)
-							&& purple_savedstatus_is_transient(ss)
-							&& purple_savedstatus_has_substatuses(ss))
-						changed = FALSE;
-				}
+				PurpleSavedStatus *ss = purple_savedstatus_get_current();
+				/* Make sure that statusbox displays the correct thing.
+				 * It can get messed up if the previous selection was a
+				 * saved status that wasn't supported by this account */
+				if ((purple_savedstatus_get_type(ss) == primitive)
+					&& purple_savedstatus_is_transient(ss)
+					&& purple_savedstatus_has_substatuses(ss))
+					changed = FALSE;
 			}
 		} else {
 			saved_status = purple_savedstatus_get_current();
 			if (purple_savedstatus_get_type(saved_status) == primitive &&
-			    !purple_savedstatus_has_substatuses(saved_status))
+			    !purple_savedstatus_has_substatuses(saved_status) &&
+				purple_strequal(purple_savedstatus_get_message(saved_status), message))
 			{
-				if (!message_changed(purple_savedstatus_get_message(saved_status), message))
-					changed = FALSE;
+				changed = FALSE;
 			}
 		}
 
 		if (changed)
 		{
-			/* Manually find the appropriate transient acct */
+			/* Manually find the appropriate transient status */
 			if (status_box->token_status_account) {
 				GList *iter = purple_savedstatuses_get_all();
 				GList *tmp, *active_accts = purple_accounts_get_all_active();
@@ -2440,27 +2438,31 @@
 				for (; iter != NULL; iter = iter->next) {
 					PurpleSavedStatus *ss = iter->data;
 					const char *ss_msg = purple_savedstatus_get_message(ss);
+					/* find a known transient status that is the same as the
+					 * new selected one */
 					if ((purple_savedstatus_get_type(ss) == primitive) && purple_savedstatus_is_transient(ss) &&
 						purple_savedstatus_has_substatuses(ss) && /* Must have substatuses */
-						!message_changed(ss_msg, message))
+						purple_strequal(ss_msg, message))
 					{
 						gboolean found = FALSE;
-						/* The currently enabled accounts must have substatuses for all the active accts */
+						/* this status 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(acct_status_type)))
+								if (purple_strequal(subtype_status_id, id)) {
 									found = TRUE;
+									break;
+								}
 							}
 						}
-						if (!found)
-							continue;
-						saved_status = ss;
-						break;
+
+						if (found) {
+							saved_status = ss;
+							break;
+						}
 					}
 				}
 
@@ -2503,11 +2505,11 @@
 		status_type = find_status_type_by_index(status_box->account, active);
 		id = purple_status_type_get_id(status_type);
 
-		if (strncmp(id, purple_status_get_id(status), strlen(id)) == 0)
+		if (g_str_equal(id, purple_status_get_id(status)) &&
+			purple_strequal(message, purple_status_get_attr_string(status, "message")))
 		{
 			/* Selected status and previous status is the same */
-			if (!message_changed(message, purple_status_get_attr_string(status, "message")))
-				changed = FALSE;
+			changed = FALSE;
 		}
 
 		if (changed)
@@ -2597,7 +2599,7 @@
 	if (status_box->typing == 0)
 	{
 		/* Nothing has changed, so we don't need to do anything */
-		status_menu_refresh_iter(status_box);
+		status_menu_refresh_iter(status_box, FALSE);
 		return;
 	}
 
@@ -2655,14 +2657,14 @@
 			pidgin_status_editor_show(FALSE,
 				purple_savedstatus_is_transient(saved_status)
 					? saved_status : NULL);
-			status_menu_refresh_iter(status_box);
+			status_menu_refresh_iter(status_box, FALSE);
 			return;
 		}
 
 		if (type == PIDGIN_STATUS_BOX_TYPE_SAVED)
 		{
 			pidgin_status_window_show();
-			status_menu_refresh_iter(status_box);
+			status_menu_refresh_iter(status_box, FALSE);
 			return;
 		}
 	}
--- a/pidgin/plugins/perl/common/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/plugins/perl/common/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -5,9 +5,12 @@
 #
 
 PIDGIN_TREE_TOP := ../../../..
-GCCWARNINGS := -Wno-comment -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wpointer-arith -Wundef -Wno-unused
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+GCCWARNINGS += -Wno-comment -Wno-unused -Wno-nested-externs
+
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
+
 TARGET = Pidgin
 EXTUTILS ?= C:/perl/lib/ExtUtils
 
--- a/pidgin/plugins/win32/winprefs/Makefile.mingw	Sun Oct 25 15:30:09 2009 +0900
+++ b/pidgin/plugins/win32/winprefs/Makefile.mingw	Wed Nov 04 16:58:41 2009 +0900
@@ -8,6 +8,7 @@
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
 TARGET = winprefs
+DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES))
 DEFINES += -DWINVER=0x500
 
 ##
--- a/po/ca.po	Sun Oct 25 15:30:09 2009 +0900
+++ b/po/ca.po	Wed Nov 04 16:58:41 2009 +0900
@@ -33,8 +33,8 @@
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-07 18:26-0700\n"
-"PO-Revision-Date: 2009-07-26 17:23+0200\n"
+"POT-Creation-Date: 2009-10-25 17:57+0100\n"
+"PO-Revision-Date: 2009-10-26 09:20+0100\n"
 "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
 "Language-Team: Catalan <tradgnome@softcatala.net>\n"
 "MIME-Version: 1.0\n"
@@ -576,13 +576,6 @@
 msgid "Re-enable Account"
 msgstr "Rehabilita el compte"
 
-msgid ""
-"The account has disconnected and you are no longer in this chat. You will be "
-"automatically rejoined in the chat when the account reconnects."
-msgstr ""
-"El compte s'ha desconnectat i ja no sou al xat. Quan es torni a connectar el "
-"compte entrareu de nou automàticament al xat."
-
 msgid "No such command."
 msgstr "No existeix l'ordre."
 
@@ -625,6 +618,13 @@
 msgid "You have left this chat."
 msgstr "Heu sortit d'aquest xat"
 
+msgid ""
+"The account has disconnected and you are no longer in this chat. You will be "
+"automatically rejoined in the chat when the account reconnects."
+msgstr ""
+"El compte s'ha desconnectat i ja no sou al xat. Quan es torni a connectar el "
+"compte entrareu de nou automàticament al xat."
+
 msgid "Logging started. Future messages in this conversation will be logged."
 msgstr ""
 "S'ha iniciat el registre. Es registraran els propers missatges d'aquesta "
@@ -661,6 +661,9 @@
 msgid "Enable Sounds"
 msgstr "Habilita els sons"
 
+msgid "You are not connected."
+msgstr "No esteu connectat."
+
 msgid "<AUTO-REPLY> "
 msgstr "<RESPOSTA-AUTOMÀTICA> "
 
@@ -670,8 +673,8 @@
 msgstr[0] "Llista d'%d usuari:\n"
 msgstr[1] "Llista de %d usuaris:\n"
 
-msgid "Supported debug options are:  version"
-msgstr "Les opcions de depuració disponibles són:  version"
+msgid "Supported debug options are: plugins version"
+msgstr "Les opcions de depuració disponibles són:  plugins version"
 
 msgid "No such command (in this context)."
 msgstr "L'ordre no existeix (en aquest context)."
@@ -977,6 +980,9 @@
 msgid "(none)"
 msgstr "(cap)"
 
+#. XXX: The following expects that finch_notify_message gets called. This
+#. * may not always happen, e.g. when another plugin sets its own
+#. * notify_message. So tread carefully.
 msgid "URI"
 msgstr "URI"
 
@@ -1554,9 +1560,15 @@
 "\n"
 "S'està aconseguint un TinyURL..."
 
-#, fuzzy
+#, c-format
+msgid "TinyURL for above: %s"
+msgstr "Fes un TinyURL d'això d'aquí dalt: %s"
+
+msgid "Please wait while TinyURL fetches a shorter URL ..."
+msgstr "Espreu mentre TinyURL obté una URL més curta..."
+
 msgid "Only create TinyURL for URLs of this length or greater"
-msgstr "Crea TinyURL per a URL així de llargues o més"
+msgstr "Només crea TinyURL per a URL així de llargues o més"
 
 msgid "TinyURL (or other) address prefix"
 msgstr "Prefix de l'adreça TinyURL (o altra)"
@@ -1567,10 +1579,9 @@
 msgid "TinyURL plugin"
 msgstr "Connector TinyURL"
 
-#, fuzzy
 msgid "When receiving a message with URL(s), use TinyURL for easier copying"
 msgstr ""
-"Quan rebeu missagtes amb URL, feu servir TinyURL per a copiar més fàcilment"
+"En rebre missagtes amb URL, s'empra TinyURL perquè sigui més fàcil copiar"
 
 msgid "Online"
 msgstr "En línia"
@@ -1676,27 +1687,25 @@
 msgid "buddy list"
 msgstr "llista d'amics"
 
-#, fuzzy
 msgid "The certificate is self-signed and cannot be automatically checked."
-msgstr ""
-"No es pot comprovar el certificat que presenta «%s» atès que està auto-signat."
-
-#, fuzzy
-msgid "The root certificate this one claims to be issued by is unknown."
-msgstr "El Pidgin no coneix el certificat arrel d'aquest certificat."
-
-#, fuzzy
+msgstr "No es pot comprovar el certificat atès que està auto-signat."
+
+msgid ""
+"The certificate is not trusted because no certificate that can verify it is "
+"currently trusted."
+msgstr ""
+"No es pot confiar en el certificat atès que no hi hi ha cap altre certificat "
+"de confiança que el pugui verificar."
+
 msgid "The certificate is not valid yet."
-msgstr "La cadena de certificació que presenta %s no és vàlida."
-
-#, fuzzy
+msgstr "El certificat encara no és vàlid."
+
 msgid "The certificate has expired and should not be considered valid."
-msgstr "La cadena de certificació que presenta %s no és vàlida."
+msgstr "El certificat ha expirat i no s'hauria de considerar vàlid."
 
 #. Translators: "domain" refers to a DNS domain (e.g. talk.google.com)
-#, fuzzy
 msgid "The certificate presented is not issued to this domain."
-msgstr "La cadena de certificació que presenta %s no és vàlida."
+msgstr "El certificat que s'ha presentat no ha estat emès per a aquest domini."
 
 msgid ""
 "You have no database of root certificates, so this certificate cannot be "
@@ -1705,17 +1714,14 @@
 "Aquest certificat no es pot validar perquè no teniu cap base de dades de "
 "certificats arrel."
 
-#, fuzzy
 msgid "The certificate chain presented is invalid."
-msgstr "La cadena de certificació que presenta %s no és vàlida."
-
-#, fuzzy
+msgstr "La cadena de certificació que s'ha presentat no és vàlida."
+
 msgid "The certificate has been revoked."
-msgstr "Ha finalitzat la trucada."
-
-#, fuzzy
+msgstr "El certificat ha estat revocat."
+
 msgid "An unknown certificate error occurred."
-msgstr "Hi ha hagut un error de connexió desconegut: %s."
+msgstr "S'ha produït un error desconegut en el certificat."
 
 msgid "(DOES NOT MATCH)"
 msgstr "(NO COINCIDEIX)"
@@ -1760,26 +1766,25 @@
 msgid "_View Certificate..."
 msgstr "_Mostra el certificat..."
 
-#, fuzzy, c-format
+#, c-format
 msgid "The certificate for %s could not be validated."
-msgstr "La cadena de certificació que presenta %s no és vàlida."
+msgstr "No s'ha pogut validar el certificat de %s."
 
 # Títol de finestra (josep)
 #. TODO: Probably wrong.
 msgid "SSL Certificate Error"
 msgstr "Error en el certificat SSL"
 
-#, fuzzy
 msgid "Unable to validate certificate"
-msgstr "No s'ha pogut autenticar: %s"
-
-#, fuzzy, c-format
+msgstr "No s'ha pogut certificar"
+
+#, c-format
 msgid ""
 "The certificate claims to be from \"%s\" instead. This could mean that you "
 "are not connecting to the service you believe you are."
 msgstr ""
-"El certificat de «%s» sembla indicar que és de «%s». Això podria voler dir que "
-"us esteu connectant a un servei diferent del que us penseu."
+"El certificat indica que és de «%s». Això podria voler dir que us esteu "
+"connectant a un servei diferent del que us penseu."
 
 #. Make messages
 #, c-format
@@ -1927,6 +1932,10 @@
 msgstr "El procés resoledor ha acabat sense respondre la nostra sol·licitud"
 
 #, c-format
+msgid "Error converting %s to punycode: %d"
+msgstr "S'ha produït un error en convertir %s a punycode: %d"
+
+#, c-format
 msgid "Thread creation failure: %s"
 msgstr "S'ha produït un error en crear un fil: %s"
 
@@ -2020,18 +2029,18 @@
 msgid "File transfer complete"
 msgstr "S'ha completat la transferència del fitxer"
 
-#, fuzzy, c-format
+#, c-format
 msgid "You cancelled the transfer of %s"
 msgstr "Heu cancel·lat la transferència de %s"
 
 msgid "File transfer cancelled"
 msgstr "S'ha cancel·lat la transferència del fitxer"
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s cancelled the transfer of %s"
 msgstr "%s ha cancel·lat la transferència de %s"
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s cancelled the file transfer"
 msgstr "%s ha cancel·lat la transferència del fitxer"
 
@@ -2224,28 +2233,30 @@
 "No codecs found. Install some GStreamer codecs found in GStreamer plugins "
 "packages."
 msgstr ""
+"No s'ha trobat cap còdec. Instal·leu els còdecs del GStreamer que podeu "
+"trobar en els paquests de connectors del GStreamer."
 
 msgid ""
 "No codecs left. Your codec preferences in fs-codecs.conf are too strict."
 msgstr ""
-
-#, fuzzy
+"No hi ha cap més còdec. Les preferències dels còdecs al fitxer fs-codecs."
+"conf són massa estrictes."
+
 msgid "A non-recoverable Farsight2 error has occurred."
-msgstr "Hi ha hagut un error de connexió desconegut: %s."
-
-#, fuzzy
-msgid "Conference error."
-msgstr "Conferència tancada"
-
-msgid "Error with your microphone."
-msgstr ""
-
-msgid "Error with your webcam."
-msgstr ""
-
-#, fuzzy, c-format
+msgstr "S'ha produït un error no recuperable del Farsight2."
+
+msgid "Conference error"
+msgstr "Error en la conferència"
+
+msgid "Error with your microphone"
+msgstr "S'ha produït un error amb el micròfon"
+
+msgid "Error with your webcam"
+msgstr "S'ha produït un error amb la càmera web"
+
+#, c-format
 msgid "Error creating session: %s"
-msgstr "S'ha produït un error en crear la connexió"
+msgstr "S'ha produït un error en crear la sessió: %s"
 
 msgid "Error creating conference."
 msgstr "S'ha produït un error en crear la conferència."
@@ -2511,16 +2522,15 @@
 msgid "Test plugin IPC support, as a server. This registers the IPC commands."
 msgstr "Connector de proves per a servidor d'IPC, que registra les ordres IPC."
 
-#, fuzzy
 msgid "Hide Joins/Parts"
-msgstr "Oculta els errors en entrar"
+msgstr "Oculta en entrar/sortir"
 
 #. Translators: Followed by an input request a number of people
 msgid "For rooms with more than this many people"
-msgstr ""
+msgstr "Per sales amb més persones que"
 
 msgid "If user has not spoken in this many minutes"
-msgstr ""
+msgstr "Si l'usuari no ha parlat en"
 
 msgid "Apply hiding rules to buddies"
 msgstr "Aplica les normes d'ocultació als amics"
@@ -3973,11 +3983,11 @@
 msgid "Logo"
 msgstr "Logotip"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "%s will no longer be able to see your status updates.  Do you want to "
 "continue?"
-msgstr "Esteu segur que voleu suprimir %s de la llista d'amics?"
+msgstr "%s no podrà veure l'actualització del vostre estat. Voleu continuar?"
 
 msgid "Cancel Presence Notification"
 msgstr "Cancel·la la notificació de presència"
@@ -3996,6 +4006,9 @@
 msgid "Unsubscribe"
 msgstr "Cancel·la la subscripció"
 
+msgid "Initiate _Chat"
+msgstr "Inicia un _xat"
+
 msgid "Log In"
 msgstr "Connecta"
 
@@ -4580,7 +4593,7 @@
 msgid "configure:  Configure a chat room."
 msgstr "configure:  configura la sala de xat."
 
-msgid "part [room]:  Leave the room."
+msgid "part [message]:  Leave the room."
 msgstr "part [sala]:  surt de la sala."
 
 msgid "register:  Register with a chat room."
@@ -4599,13 +4612,12 @@
 "affiliate &lt;owner|admin|member|outcast|none&gt; [sobrenom1] "
 "[sobrenom2] ...: obtén els usuaris amb una afiliació, o els l'estableix."
 
-#, fuzzy
 msgid ""
 "role &lt;moderator|participant|visitor|none&gt; [nick1] [nick2] ...: Get the "
 "users with a role or set users' role with the room."
 msgstr ""
-"role &lt;usuari&gt; &lt;moderator|participant|visitor|none&gt; [sobrenom1] "
-"[sobrenom2] ...: obtén els usuaris amb el rol especificat, o els l'estableix."
+"role &lt;moderator|participant|visitor|none&gt; [sobrenom1] [sobrenom2] ...: "
+"obtén els usuaris amb el rol especificat, o els l'estableix."
 
 msgid "invite &lt;user&gt; [message]:  Invite a user to the room."
 msgstr "invite &lt;usuari&gt; [sala]:  convida un usuari a la sala."
@@ -5025,7 +5037,6 @@
 msgid "Not expected"
 msgstr "Inesperat"
 
-#, fuzzy
 msgid "Friendly name is changing too rapidly"
 msgstr "El nom amistós canvia massa de pressa"
 
@@ -5245,19 +5256,16 @@
 msgid "Send to Mobile"
 msgstr "Envia a un mòbil"
 
-msgid "Initiate _Chat"
-msgstr "Inicia un _xat"
-
 msgid "SSL support is needed for MSN. Please install a supported SSL library."
 msgstr "L'MSN necessita SSL, instal·leu alguna biblioteca d'SSL permesa."
 
 #, c-format
 msgid ""
 "Unable to add the buddy %s because the username is invalid.  Usernames must "
-"be a valid email address."
+"be valid email addresses."
 msgstr ""
 "No s'ha pogut afegir l'amic %s perquè el nom d'usuari no és vàlid. Els noms "
-"d'usuari han de ser adreces de correu vàlides."
+"d'usuari han de ser adreces de correu electròniques vàlides."
 
 msgid "Unable to Add"
 msgstr "No s'ha pogut afegir"
@@ -5597,10 +5605,10 @@
 "%s ha sol·licitat poder veure la vostra càmera web, però això encara no està "
 "implementat."
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s invited you to view his/her webcam, but this is not yet supported."
 msgstr ""
-"%s ha sol·licitat poder veure la vostra càmera web, però això encara no està "
+"%s us ha convidat a veure la seva càmera web, però això encara no està "
 "implementat."
 
 msgid "Away From Computer"
@@ -6354,9 +6362,9 @@
 msgstr "Port en el servidor"
 
 #. Note to translators: %s in this string is a URL
-#, fuzzy, c-format
+#, c-format
 msgid "Received unexpected response from %s"
-msgstr "S'ha rebut una resposta inesperada de "
+msgstr "S'ha rebut una resposta inesperada de %s"
 
 #. username connecting too frequently
 msgid ""
@@ -6369,9 +6377,9 @@
 
 #. Note to translators: The first %s is a URL, the second is an
 #. error message.
-#, fuzzy, c-format
+#, c-format
 msgid "Error requesting %s: %s"
-msgstr "S'ha produït en sol·licitar "
+msgstr "S'ha produït un error en sol·licitar %s: %s"
 
 msgid "AOL does not allow your screen name to authenticate here"
 msgstr "AOL no permet que us autentiqueu amb aquest nom d'usuari aquí"
@@ -7149,9 +7157,8 @@
 msgid "C_onnect"
 msgstr "C_onnecta"
 
-#, fuzzy
 msgid "You closed the connection."
-msgstr "El servidor ha tancat la connexió"
+msgstr "Heu tancat la connexió."
 
 msgid "Get AIM Info"
 msgstr "Obtén informació de AIM"
@@ -7163,9 +7170,8 @@
 msgid "Get Status Msg"
 msgstr "Aconsegueix el missatge d'estat"
 
-#, fuzzy
 msgid "End Direct IM Session"
-msgstr "S'ha establert una connexió directa de MI"
+msgstr "Finalitzar la sessió de MI directa"
 
 msgid "Direct IM"
 msgstr "MI directa"
@@ -8007,7 +8013,7 @@
 msgid "File Send"
 msgstr "S'ha enviat el fitxer"
 
-#, fuzzy, c-format
+#, c-format
 msgid "%d cancelled the transfer of %s"
 msgstr "%d ha cancel·lat la transferència de %s"
 
@@ -9545,7 +9551,7 @@
 msgstr "Bloca invitacions a conferències i sales de xat"
 
 msgid "Use account proxy for SSL connections"
-msgstr ""
+msgstr "Empra un compte per al servidor intermediàri per a connexions SSL"
 
 msgid "Chat room list URL"
 msgstr "URL de la llista de sales de xat"
@@ -9653,26 +9659,26 @@
 msgid "Ignore buddy?"
 msgstr "Voleu ignorar l'amic?"
 
-#, fuzzy
 msgid "Invalid username or password"
-msgstr "El sobrenom o la contrasenya no són correctes"
-
-#, fuzzy
+msgstr "El sobrenom o la contrasenya no són vàlides"
+
 msgid ""
 "Your account has been locked due to too many failed login attempts.  Please "
 "try logging into the Yahoo! website."
 msgstr ""
-"El compte està blocat perquè s'ha intentat entrar massa cops. Això es pot "
-"solucionar entrant al web de Yahoo!"
+"S'ha blocat el vostre compte perquè s'ha intentat entrar massa cops. Entreu "
+"al web de Yahoo! per solucionar això."
 
 #, c-format
 msgid "Unknown error 52.  Reconnecting should fix this."
-msgstr ""
+msgstr "Error desconegut 52. Es pot sol·lucionar connectant de nou."
 
 msgid ""
 "Error 1013: The username you have entered is invalid.  The most common cause "
 "of this error is entering your email address instead of your Yahoo! ID."
 msgstr ""
+"Error 1013: el nom d'usuari no és vàlid. Pot ser que hagueu introduït la "
+"vostra adreça de correu en lloc del nom d'usuari de Yahoo!"
 
 #, c-format
 msgid "Unknown error number %d. Logging into the Yahoo! website may fix this."
@@ -9764,6 +9770,16 @@
 msgid "Open Inbox"
 msgstr "Obre la safata d'entrada"
 
+msgid "Can't send SMS. Unable to obtain mobile carrier."
+msgstr ""
+"No es poden enviar SMS, no s'ha pogut obtenir l'operador de telefonia mòbil."
+
+msgid "Can't send SMS. Unknown mobile carrier."
+msgstr "No es poden enviar SMS, no es coneix l'operador de telefona mòbil."
+
+msgid "Getting mobile carrier to send the SMS."
+msgstr "S'està obtenint l'operador de telefonia mòbil per a poder enviar SMS."
+
 #. Write a local message to this conversation showing that a request for a
 #. * Doodle session has been made
 #.
@@ -10456,7 +10472,6 @@
 msgid "Layout"
 msgstr "Format"
 
-#, fuzzy
 msgid "The layout of icons, name, and status of the buddy list"
 msgstr "El format de les icones, el nom, i l'estat de la llista d'amics"
 
@@ -10513,9 +10528,8 @@
 
 #. Note to translators: These two strings refer to the font and color
 #. of a buddy list buddy when it is online
-#, fuzzy
 msgid "Online Text"
-msgstr "Text en línia"
+msgstr "Text en estar en línia"
 
 msgid "The text information for when a buddy is online"
 msgstr "Text informatiu per quan un amic estigui en línia"
@@ -10523,18 +10537,16 @@
 #. Note to translators: These two strings refer to the font and color
 #. of a buddy list buddy when it is away
 msgid "Away Text"
-msgstr "Text d'absència"
+msgstr "Text en estar absent"
 
 msgid "The text information for when a buddy is away"
 msgstr "Text informatiu per quan un amic estigui absent"
 
 #. Note to translators: These two strings refer to the font and color
 #. of a buddy list buddy when it is offline
-#, fuzzy
 msgid "Offline Text"
-msgstr "Text de fora de línia"
-
-#, fuzzy
+msgstr "Text fora de línia"
+
 msgid "The text information for when a buddy is offline"
 msgstr "Text informatiu per quan un amic estigui fora de línia"
 
@@ -10559,7 +10571,6 @@
 msgid "Message (Nick Said) Text"
 msgstr "Text del missatge (on s'hi ha dit el sobrenom)"
 
-#, fuzzy
 msgid ""
 "The text information for when a chat has an unread message that mentions "
 "your nickname"
@@ -11005,9 +11016,8 @@
 msgid "_Group:"
 msgstr "_Grup:"
 
-#, fuzzy
 msgid "Auto_join when account connects."
-msgstr "_Entra automàticament quant el compte estigui connectat."
+msgstr "_Entra automàticament quant es connecti el compte."
 
 msgid "_Remain in chat after window is closed."
 msgstr "Co_ntinua al xat quan la finestra es tanqui."
@@ -11121,9 +11131,8 @@
 msgid "/Conversation/New Instant _Message..."
 msgstr "/Conversa/_Missatge instantani nou..."
 
-#, fuzzy
 msgid "/Conversation/Join a _Chat..."
-msgstr "/Conversa/Con_vida..."
+msgstr "/Conversa/Entra a un _xat..."
 
 msgid "/Conversation/_Find..."
 msgstr "/Conversa/_Cerca..."
@@ -11514,7 +11523,7 @@
 msgstr "Estonià"
 
 msgid "Basque"
-msgstr ""
+msgstr "Basc"
 
 msgid "Persian"
 msgstr "Persa"
@@ -11728,6 +11737,13 @@
 "primary language is <b>English</b>.  You are welcome to post in another "
 "language, but the responses may be less helpful.<br/><br/>"
 msgstr ""
+"<font size=\"4\">Ajuda d'altres usuaris del Pidgin:</font> <a href=\"mailto:"
+"support@pidgin.im\">support@pidgin.im</a><br/>Aquesta és una llista de "
+"correu <b>pública</b>. (<a href=\"http://pidgin.im/pipermail/support/"
+"\">arxiu</a>)<br/>No us podem ajudar amb connectors d'altres proveïdors.<br/"
+">En aquesta llista s'hi empra principalment l'<b>anglès</b>.  Podeu escriure-"
+"hi en un altre idioma, però és possible que les respostes no siguin de gaire "
+"ajuda.<br/><br/>"
 
 #, c-format
 msgid ""
@@ -12299,45 +12315,48 @@
 "Usage: %s [OPTION]...\n"
 "\n"
 msgstr ""
-
-#, fuzzy
+"Forma d'ús: %s [OPCIÓ]...\n"
+"\n"
+
 msgid "DIR"
-msgstr "IRC"
+msgstr "DIR"
 
 msgid "use DIR for config files"
-msgstr ""
+msgstr "empra DIR per a fitxers de configuració"
 
 msgid "print debugging messages to stdout"
-msgstr ""
+msgstr "escriu missatges de depuració a la sortida estàndard"
 
 msgid "force online, regardless of network status"
-msgstr ""
+msgstr "força estar en línia, independentment de l'estat de la xarxa"
 
 msgid "display this help and exit"
-msgstr ""
+msgstr "mostra aquesta ajuda i surt"
 
 # FIXME: entrades/registres?
-#, fuzzy
 msgid "allow multiple instances"
-msgstr "Permet diverses entrades simultànies"
+msgstr "permet diverses instàncies"
 
 msgid "don't automatically login"
-msgstr ""
+msgstr "no entra als comptes"
 
 msgid "NAME"
-msgstr ""
+msgstr "NOM"
 
 msgid ""
 "enable specified account(s) (optional argument NAME\n"
 "                      specifies account(s) to use, separated by commas.\n"
 "                      Without this only the first account will be enabled)."
 msgstr ""
+"habilita els comptes especificats (l'argument opcional NAME especifica\n"
+"                      els comptes a emprar, separats per comes. Sense això\n"
+"                      només s'habilitarà el primer compte)."
 
 msgid "X display to use"
-msgstr ""
+msgstr "pantalla d'X a emprar"
 
 msgid "display the current version and exit"
-msgstr ""
+msgstr "mostra la versió actual i surt"
 
 # FIXME: backtrace -> traça (bug-buddy) ?
 #, c-format
@@ -12394,7 +12413,7 @@
 msgstr "%s vol iniciar una sessió de vídeo."
 
 msgid "Incoming Call"
-msgstr ""
+msgstr "Trucada entrant"
 
 msgid "_Pause"
 msgstr "_Pausa"
@@ -12576,50 +12595,54 @@
 msgid "Pounce Target"
 msgstr "Objectiu de l'avís"
 
-#, c-format
 msgid "Started typing"
 msgstr "Hagi començat a escriure"
 
-#, c-format
 msgid "Paused while typing"
 msgstr "S'aturi mentre tecleja"
 
-#, c-format
 msgid "Signed on"
 msgstr "Es connecti"
 
-#, c-format
 msgid "Returned from being idle"
 msgstr "Torna a estar actiu"
 
-#, c-format
 msgid "Returned from being away"
 msgstr "Torni a estar present"
 
-#, c-format
 msgid "Stopped typing"
 msgstr "Pari d'escriure"
 
-#, c-format
 msgid "Signed off"
 msgstr "Es desconnecti"
 
-#, c-format
 msgid "Became idle"
 msgstr "Passi a inactiu"
 
-#, c-format
 msgid "Went away"
 msgstr "En estar absent"
 
-#, c-format
 msgid "Sent a message"
 msgstr "Envia un missatge"
 
-#, c-format
 msgid "Unknown.... Please report this!"
 msgstr "Esdeveniment d'avís desconegut, informeu-nos-en."
 
+msgid "(Custom)"
+msgstr "(Personalitzat)"
+
+msgid "(Default)"
+msgstr "(Predeterminat)"
+
+msgid "The default Pidgin sound theme"
+msgstr "El tema de sons predeterminat del pidgin"
+
+msgid "The default Pidgin buddy list theme"
+msgstr "El tema per a la llista d'amics predeterminat del Pidgin"
+
+msgid "The default Pidgin status icon theme"
+msgstr "El tema de les icones d'estat predeterminat del Pidgin"
+
 msgid "Theme failed to unpack."
 msgstr "No s'ha pogut desempaquetar el tema."
 
@@ -12764,14 +12787,16 @@
 msgid "Cannot start browser configuration program."
 msgstr "No s'ha pogut iniciar el programa de configuració del navegador."
 
-#, fuzzy
 msgid "Disabled"
-msgstr "_Inhabilita"
+msgstr "Inhabilitat"
 
 #, c-format
 msgid "Use _automatically detected IP address: %s"
 msgstr "Empra l'_adreça IP detectada automàticament: %s"
 
+msgid "ST_UN server:"
+msgstr "Servidor ST_UN:"
+
 msgid "<span style=\"italic\">Example: stunserver.org</span>"
 msgstr "<span style=\"italic\">Exemple: stunserver.org</span>"
 
@@ -12797,9 +12822,8 @@
 msgid "Relay Server (TURN)"
 msgstr "Servidor repetidor (TURN)"
 
-#, fuzzy
 msgid "_TURN server:"
-msgstr "Servidor ST_UN:"
+msgstr "Servidor _TURN:"
 
 msgid "Proxy Server &amp; Browser"
 msgstr "Servidor intermediari i navegador"
@@ -14372,35 +14396,29 @@
 "Aquest connector permet a l'usuari personalitzar els formats de les marques "
 "horàries de les converses i dels registres."
 
-#, fuzzy
 msgid "Audio"
-msgstr "Auto"
-
-#, fuzzy
+msgstr "Àudio"
+
 msgid "Video"
 msgstr " Vídeo"
 
 msgid "Output"
-msgstr ""
-
-#, fuzzy
+msgstr "Sortida"
+
 msgid "_Plugin"
-msgstr "Connectors"
-
-#, fuzzy
+msgstr "_Connectors"
+
 msgid "_Device"
-msgstr "Dispositiu"
+msgstr "_Dispositiu"
 
 msgid "Input"
-msgstr ""
-
-#, fuzzy
+msgstr "Entrada"
+
 msgid "P_lugin"
-msgstr "Connectors"
-
-#, fuzzy
+msgstr "C_onnectors"
+
 msgid "D_evice"
-msgstr "Dispositiu"
+msgstr "D_ispositiu"
 
 #. *< magic
 #. *< major version
@@ -14411,18 +14429,19 @@
 #. *< dependencies
 #. *< priority
 #. *< id
-#, fuzzy
 msgid "Voice/Video Settings"
-msgstr "Edita els paràmetres"
+msgstr "Configuració del so/vídeo"
 
 #. *< name
 #. *< version
 msgid "Configure your microphone and webcam."
-msgstr ""
+msgstr "Configureu el micròfon i la càmera web."
 
 #. *< summary
 msgid "Configure microphone and webcam settings for voice/video calls."
 msgstr ""
+"Configureu els paràmetres del micròfon i la càmera web per a trucades de veu/"
+"vídeo."
 
 msgid "Opacity:"
 msgstr "Opacitat:"
@@ -14481,9 +14500,6 @@
 "\n"
 "* Nota: aquest connector requereix Windows 2000 o superior."
 
-msgid "GTK+ Runtime Version"
-msgstr "Versió del mòdul d'execució de GTK+"
-
 #. Autostart
 msgid "Startup"
 msgstr "Inicialització"
@@ -14492,6 +14508,10 @@
 msgid "_Start %s on Windows startup"
 msgstr "_Inicia el %s en iniciar Windows"
 
+# FIXME: entrades/registres?
+msgid "Allow multiple instances"
+msgstr "Permet diverses instàncies"
+
 msgid "_Dockable Buddy List"
 msgstr "Llista _d'amics acoblable"
 
@@ -14553,6 +14573,9 @@
 msgid "This plugin is useful for debbuging XMPP servers or clients."
 msgstr "Aquest connector és útil per a depurar servidors i clients XMPP."
 
+#~ msgid "GTK+ Runtime Version"
+#~ msgstr "Versió del mòdul d'execució de GTK+"
+
 #~ msgid "Calling ... "
 #~ msgstr "S'està trucant..."
 
@@ -14796,9 +14819,6 @@
 #~ msgid "Could not write"
 #~ msgstr "No s'ha pogut escriure"
 
-#~ msgid "Could not connect"
-#~ msgstr "No s'ha pogut connectar"
-
 #~ msgid "Could not create listen socket"
 #~ msgstr "No s'ha pogut crear el sòcol per a escoltar"