changeset 29504:057372f5c319

propagate from branch 'im.pidgin.pidgin' (head bd59b6d44034a232a0414586f78d8f559d9705f8) to branch 'im.pidgin.pidgin.next.minor' (head e3b29e5b831c5e0c79521e61160af19f21dae099)
author John Bailey <rekkanoryo@rekkanoryo.org>
date Sun, 27 Sep 2009 22:22:36 +0000
parents 60e4ef6801ff (diff) 7525698499e3 (current diff)
children 2cc15ca3c26d
files ChangeLog libpurple/dnsquery.c libpurple/protocols/yahoo/libymsg.c libpurple/util.c pidgin/gtkcelllayout.c pidgin/gtkcelllayout.h pidgin/gtkcellrendererprogress.c pidgin/gtkcellrendererprogress.h pidgin/gtkcellview.c pidgin/gtkcellview.h pidgin/gtkcellviewmenuitem.c pidgin/gtkcellviewmenuitem.h pidgin/gtkexpander.c pidgin/gtkexpander.h pidgin/gtkprefs.c pidgin/pidgincombobox.c pidgin/pidgincombobox.h pidgin/win32/nsis/pidgin-installer.nsi
diffstat 25 files changed, 461 insertions(+), 437 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Wed Sep 16 16:26:55 2009 +0000
+++ b/COPYRIGHT	Sun Sep 27 22:22:36 2009 +0000
@@ -275,6 +275,7 @@
 Lokheed
 Norberto Lopes
 Shlomi Loubaton
+Brian Lu
 Uli Luckas
 Matthew Luckie
 Marcus Lundblad
--- a/ChangeLog	Wed Sep 16 16:26:55 2009 +0000
+++ b/ChangeLog	Sun Sep 27 22:22:36 2009 +0000
@@ -5,10 +5,15 @@
 version 2.6.3 (??/??/20??):
 	XMPP:
 	* Fix a crash when attempting to validate an invalid JID.
+	* Resolve an issue when connecting to iChat Server when no resource
+	  is specified.
+	* Fix a crash when adding a buddy without an '@'.
 
 	General:
 	* New 'plugins' sub-command to 'debug' command (i.e. '/debug plugins')
 	  to announce the list of loaded plugins (in both Finch and Pidgin).
+	* Fix a crash when performing DNS queries on Unixes that use the
+	  blocking DNS lookups.  (Brian Lu)
 
 version 2.6.2 (09/05/2009):
 	libpurple:
--- a/doc/finch.1.in	Wed Sep 16 16:26:55 2009 +0000
+++ b/doc/finch.1.in	Sun Sep 27 22:22:36 2009 +0000
@@ -40,14 +40,14 @@
 The following options are provided by \fBfinch\fR using the standard GNU
 command line syntax:
 .TP
+.B \-c, \-\-config=\fIDIR\fB
+Use \fIDIR\fR as the directory for config files instead of \fI~/.purple\fR.
+.TP
 .B \-d, \-\-debug
 Print debugging messages to stderr and start with the \fBDebug\fR window. The
 messages shown in the \fBDebug\fR window are the same as the ones printed in
 stderr.
 .TP
-.B \-c, \-\-config=\fIDIR\fB
-Use \fIDIR\fR as the directory for config files instead of \fI~/.purple\fR.
-.TP
 .B \-h, \-\-help
 Print this help and exit.
 .TP
--- a/doc/pidgin.1.in	Wed Sep 16 16:26:55 2009 +0000
+++ b/doc/pidgin.1.in	Sun Sep 27 22:22:36 2009 +0000
@@ -49,6 +49,10 @@
 Print debugging messages to stdout.  These are the same debugging messages
 that are displayed in the \fBDebug Window\fR.
 .TP
+.B \-f, \-\-force-online
+Try to be online even if the network is reported (by Windows, or NetworkManager
+on Linux) to be unavailable.
+.TP
 .B \-h, \-\-help
 Print a summary of command line options and exit.
 .TP
--- a/finch/gntaccount.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/finch/gntaccount.c	Sun Sep 27 22:22:36 2009 +0000
@@ -166,8 +166,7 @@
 
 	/* Alias */
 	value = gnt_entry_get_text(GNT_ENTRY(dialog->alias));
-	if (value && *value)
-		purple_account_set_alias(account, value);
+	purple_account_set_alias(account, value);
 
 	/* Remember password and password */
 	purple_account_set_remember_password(account,
--- a/libpurple/connection.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/connection.c	Sun Sep 27 22:22:36 2009 +0000
@@ -52,10 +52,7 @@
 send_keepalive(gpointer data)
 {
 	PurpleConnection *gc = data;
-	PurplePluginProtocolInfo *prpl_info = NULL;
-
-	if (gc == NULL)
-		return TRUE;
+	PurplePluginProtocolInfo *prpl_info;
 
 	/* Only send keep-alives if we haven't heard from the
 	 * server in a while.
@@ -63,12 +60,8 @@
 	if ((time(NULL) - gc->last_received) < KEEPALIVE_INTERVAL)
 		return TRUE;
 
-	if (gc->prpl == NULL)
-		return TRUE;
-
 	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
-	if (prpl_info && prpl_info->keepalive)
+	if (prpl_info->keepalive)
 		prpl_info->keepalive(gc);
 
 	return TRUE;
--- a/libpurple/dbus-server.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/dbus-server.c	Sun Sep 27 22:22:36 2009 +0000
@@ -126,8 +126,10 @@
 	gint id = GPOINTER_TO_INT(g_hash_table_lookup(map_node_id, node));
 	if ((id == 0) && (node != NULL))
 	{
-		purple_debug_warning("dbus",
-				"Need to register an object with the dbus subsystem. (If you are not a developer, please ignore this message.)\n");
+		if (purple_debug_is_verbose())
+			purple_debug_warning("dbus",
+				"Need to register an object with the dbus subsystem."
+				" (If you are not a developer, please ignore this message.)\n");
 		return 0;
 	}
 	return id;
@@ -795,7 +797,11 @@
 	dbus_message_iter_init_append(signal, &iter);
 
 	if (purple_dbus_message_append_purple_values(&iter, num_values, values, vargs))
-		purple_debug_warning("dbus", "The signal \"%s\" caused some dbus error. (If you are not a developer, please ignore this message.)\n", name);
+		if (purple_debug_is_verbose())
+			purple_debug_warning("dbus",
+				"The signal \"%s\" caused some dbus error."
+				" (If you are not a developer, please ignore this message.)\n",
+				name);
 
 	dbus_connection_send(purple_dbus_connection, signal, NULL);
 
--- a/libpurple/dnsquery.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/dnsquery.c	Sun Sep 27 22:22:36 2009 +0000
@@ -920,7 +920,6 @@
 	PurpleDnsQueryData *query_data;
 	struct sockaddr_in sin;
 	GSList *hosts = NULL;
-	char *hostname;
 
 	query_data = data;
 	query_data->timeout = 0;
@@ -933,6 +932,7 @@
 
 	if (!inet_aton(query_data->hostname, &sin.sin_addr)) {
 		struct hostent *hp;
+		gchar *hostname;
 #ifdef USE_IDN
 		if (!dns_str_is_ascii(query_data->hostname)) {
 			int ret = purple_network_convert_idn_to_ascii(query_data->hostname,
@@ -958,11 +958,11 @@
 		memset(&sin, 0, sizeof(struct sockaddr_in));
 		memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
 		sin.sin_family = hp->h_addrtype;
+		g_free(hostname);
 	} else
 		sin.sin_family = AF_INET;
 	sin.sin_port = htons(query_data->port);
 
-	g_free(hostname);
 	hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin)));
 	hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin)));
 
--- a/libpurple/protocols/jabber/auth.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/jabber/auth.c	Sun Sep 27 22:22:36 2009 +0000
@@ -692,7 +692,8 @@
 	JabberIq *iq;
 	xmlnode *query, *username;
 
-	/* We can end up here without encryption if the server doesn't support
+	/*
+	 * We can end up here without encryption if the server doesn't support
 	 * <stream:features/> and we're not using old-style SSL.  If the user
 	 * is requiring SSL/TLS, we need to enforce it.
 	 */
@@ -704,6 +705,16 @@
 		return;
 	}
 
+	/*
+	 * IQ Auth doesn't have support for resource binding, so we need to pick a
+	 * default resource so it will work properly.  jabberd14 throws an error and
+	 * iChat server just fails silently.
+	 */
+	if (!js->user->resource || *js->user->resource == '\0') {
+		g_free(js->user->resource);
+		js->user->resource = g_strdup("Home");
+	}
+
 #ifdef HAVE_CYRUS_SASL
 	/* If we have Cyrus SASL, then passwords will have been set
 	 * to OPTIONAL for this protocol. So, we need to do our own
--- a/libpurple/protocols/jabber/chat.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/jabber/chat.c	Sun Sep 27 22:22:36 2009 +0000
@@ -99,6 +99,9 @@
 {
 	JabberChat *chat = NULL;
 
+	g_return_val_if_fail(room != NULL, NULL);
+	g_return_val_if_fail(server != NULL, NULL);
+
 	if(NULL != js->chats)
 	{
 		char *room_jid = g_strdup_printf("%s@%s", room, server);
--- a/libpurple/protocols/jabber/jabber.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sun Sep 27 22:22:36 2009 +0000
@@ -1593,15 +1593,6 @@
 			if(js->protocol_version == JABBER_PROTO_0_9 && js->registration) {
 				jabber_register_start(js);
 			} else if(js->auth_type == JABBER_AUTH_IQ_AUTH) {
-				/* with dreamhost's xmpp server at least, you have to
-				   specify a resource or you will get a "406: Not
-				   Acceptable"
-				*/
-				if(!js->user->resource || *js->user->resource == '\0') {
-					g_free(js->user->resource);
-					js->user->resource = g_strdup("Home");
-				}
-
 				jabber_auth_start_old(js);
 			}
 			break;
@@ -3465,15 +3456,16 @@
 
 	/* Jingle features! */
 	jabber_add_feature(JINGLE, 0);
-	jabber_add_feature(JINGLE_TRANSPORT_RAWUDP, 0);
 
 #ifdef USE_VV
 	jabber_add_feature("http://www.google.com/xmpp/protocol/session", jabber_audio_enabled);
 	jabber_add_feature("http://www.google.com/xmpp/protocol/voice/v1", jabber_audio_enabled);
 	jabber_add_feature("http://www.google.com/xmpp/protocol/video/v1", jabber_video_enabled);
 	jabber_add_feature("http://www.google.com/xmpp/protocol/camera/v1", jabber_video_enabled);
+	jabber_add_feature(JINGLE_APP_RTP, 0);
 	jabber_add_feature(JINGLE_APP_RTP_SUPPORT_AUDIO, jabber_audio_enabled);
 	jabber_add_feature(JINGLE_APP_RTP_SUPPORT_VIDEO, jabber_video_enabled);
+	jabber_add_feature(JINGLE_TRANSPORT_RAWUDP, 0);
 	jabber_add_feature(JINGLE_TRANSPORT_ICEUDP, 0);
 #endif
 
--- a/libpurple/protocols/jabber/jingle/jingle.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/jabber/jingle/jingle.c	Sun Sep 27 22:22:36 2009 +0000
@@ -115,7 +115,7 @@
 		const gchar *creator = xmlnode_get_attrib(content, "creator");
 		JingleContent *local_content = jingle_session_find_content(session, name, creator);
 
-		if (content != NULL) {
+		if (local_content != NULL) {
 			const gchar *senders = xmlnode_get_attrib(content, "senders");
 			gchar *local_senders = jingle_content_get_senders(local_content);
 			if (strcmp(senders, local_senders))
--- a/libpurple/protocols/jabber/roster.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/jabber/roster.c	Sun Sep 27 22:22:36 2009 +0000
@@ -354,7 +354,7 @@
 	}
 
 	/* Adding a chat room or a chat buddy to the roster is *not* supported. */
-	if (jabber_chat_find(js, jid->node, jid->domain) != NULL) {
+	if (jid->node && jabber_chat_find(js, jid->node, jid->domain) != NULL) {
 		/*
 		 * This is the same thing Bonjour does. If it causes problems, move
 		 * it to an idle callback.
--- a/libpurple/protocols/msn/msn.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/msn/msn.c	Sun Sep 27 22:22:36 2009 +0000
@@ -1423,7 +1423,7 @@
 	{
 		PurpleBuddy * buddy = purple_find_buddy(session->account, who);
 		gchar *buf;
-		buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid.  Usernames must be a valid email address."), who);
+		buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid.  Usernames must be valid email addresses."), who);
 		if (!purple_conv_present_error(who, session->account, buf))
 			purple_notify_error(purple_account_get_connection(session->account), NULL, _("Unable to Add"), buf);
 		g_free(buf);
@@ -1513,7 +1513,7 @@
 
 	if (!purple_email_is_valid(bname)) {
 		gchar *buf;
-		buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid.  Usernames must be a valid email address."), bname);
+		buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid.  Usernames must be valid email addresses."), bname);
 		if (!purple_conv_present_error(bname, purple_connection_get_account(gc), buf))
 			purple_notify_error(gc, NULL, _("Unable to Add"), buf);
 		g_free(buf);
--- a/libpurple/protocols/oscar/family_feedbag.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/oscar/family_feedbag.c	Sun Sep 27 22:22:36 2009 +0000
@@ -135,13 +135,18 @@
 					}
 			} while (exists);
 		}
-	} else if (type == AIM_SSI_TYPE_ICONINFO) {
+	} else if (new->gid == 0x0000) {
+		/*
+		 * This is weird, but apparently items in the root group can't
+		 * have a buddy ID equal to any group ID.  You'll get error
+		 * 0x0003 when trying to add, which is "item already exists"
+		 */
 		if (new->bid == 0xFFFF) {
 			do {
 				new->bid += 0x0001;
 				exists = FALSE;
 				for (cur = *list; cur != NULL; cur = cur->next)
-					if ((cur->bid >= new->bid) || (cur->gid >= new->bid)) {
+					if (cur->bid == new->bid || cur->gid == new->bid) {
 						exists = TRUE;
 						break;
 					}
@@ -153,7 +158,7 @@
 				new->bid += 0x0001;
 				exists = FALSE;
 				for (cur = *list; cur != NULL; cur = cur->next)
-					if ((cur->bid == new->bid) && (cur->gid == new->gid)) {
+					if (cur->bid == new->bid && cur->gid == new->gid) {
 						exists = TRUE;
 						break;
 					}
@@ -687,10 +692,6 @@
 		cur = cur->next;
 	}
 
-	/* Check if the master group is empty */
-	if ((cur = aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000)) && (!cur->data))
-		aim_ssi_itemlist_del(&od->ssi.local, cur);
-
 	/* If we've made any changes then sync our list with the server's */
 	return aim_ssi_sync(od);
 }
--- a/libpurple/protocols/oscar/oscarcommon.h	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/oscar/oscarcommon.h	Sun Sep 27 22:22:36 2009 +0000
@@ -44,8 +44,8 @@
 #define OSCAR_DEFAULT_WEB_AWARE FALSE
 #define OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY FALSE
 #define OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS TRUE
-#define OSCAR_DEFAULT_USE_SSL FALSE
-#define OSCAR_DEFAULT_USE_CLIENTLOGIN FALSE
+#define OSCAR_DEFAULT_USE_SSL TRUE
+#define OSCAR_DEFAULT_USE_CLIENTLOGIN TRUE
 
 #ifdef _WIN32
 const char *oscar_get_locale_charset(void);
--- a/libpurple/protocols/yahoo/libymsg.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/yahoo/libymsg.c	Sun Sep 27 22:22:36 2009 +0000
@@ -4143,14 +4143,13 @@
 	struct yahoo_sms_carrier_cb_data *sms_cb_data = user_data;
 	PurpleConnection *gc = sms_cb_data->gc;
 	YahooData *yd = gc->proto_data;
-	char *mobile_no = NULL;
 	char *status = NULL;
 	char *carrier = NULL;
 	PurpleAccount *account = purple_connection_get_account(gc);
 	PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account);
 
 	if (error_message != NULL) {
-		purple_conversation_write(conv, NULL, "Cant send SMS, Unable to obtain mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL));
+		purple_conversation_write(conv, NULL, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
 
 		g_free(sms_cb_data->who);
 		g_free(sms_cb_data->what);
@@ -4160,7 +4159,7 @@
 	else if (len > 0 && webdata && *webdata) {
 		xmlnode *validate_data_root = xmlnode_from_str(webdata, -1);
 		xmlnode *validate_data_child = xmlnode_get_child(validate_data_root, "mobile_no");
-		mobile_no = (char *)xmlnode_get_attrib(validate_data_child, "msisdn");
+		const char *mobile_no = xmlnode_get_attrib(validate_data_child, "msisdn");
 
 		validate_data_root = xmlnode_copy(validate_data_child);
 		validate_data_child = xmlnode_get_child(validate_data_root, "status");
@@ -4177,7 +4176,7 @@
 		}
 		else	{
 			g_hash_table_insert(yd->sms_carrier, g_strdup_printf("+%s", mobile_no), g_strdup("Unknown"));
-			purple_conversation_write(conv, NULL, "Cant send SMS, Unknown mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL));
+			purple_conversation_write(conv, NULL, _("Can't send SMS. Unknown mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
 		}
 
 		xmlnode_free(validate_data_child);
@@ -4185,7 +4184,6 @@
 		g_free(sms_cb_data->who);
 		g_free(sms_cb_data->what);
 		g_free(sms_cb_data);
-		g_free(mobile_no);
 		g_free(status);
 		g_free(carrier);
 	}
@@ -4242,7 +4240,7 @@
 	if (!url_data) {
 		PurpleAccount *account = purple_connection_get_account(gc);
 		PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account);
-		purple_conversation_write(conv, NULL, "Cant send SMS, Unable to obtain mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL));
+		purple_conversation_write(conv, NULL, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
 		g_free(sms_cb_data->who);
 		g_free(sms_cb_data->what);
 		g_free(sms_cb_data);
@@ -4282,7 +4280,7 @@
 
 	msn = !g_ascii_strncasecmp(who, "msn/", 4);
 
-	if( strncmp(who, "+", 1) == 0 ) {
+	if (who[0] == '+') {
 		/* we have an sms to be sent */
 		gchar *carrier = NULL;
 		const char *alias = NULL;
@@ -4297,7 +4295,7 @@
 			sms_cb_data->who = g_strdup(who);
 			sms_cb_data->what = g_strdup(what);
 
-			purple_conversation_write(conv, NULL, "Getting mobile carrier to send the sms", PURPLE_MESSAGE_SYSTEM, time(NULL));
+			purple_conversation_write(conv, NULL, _("Getting mobile carrier to send the SMS."), PURPLE_MESSAGE_SYSTEM, time(NULL));
 
 			yahoo_get_sms_carrier(gc, sms_cb_data);
 
@@ -4306,7 +4304,7 @@
 			return ret;
 		}
 		else if( strcmp(carrier,"Unknown") == 0 ) {
-			purple_conversation_write(conv, NULL, "Cant send SMS, Unknown mobile carrier", PURPLE_MESSAGE_SYSTEM, time(NULL));
+			purple_conversation_write(conv, NULL, _("Can't send SMS. Unknown mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
 
 			g_free(msg);
 			g_free(msg2);
@@ -4539,7 +4537,7 @@
 		yd->current_status = get_yahoo_status_from_purple_status(status);
 	}
 
-	invisible = !( purple_presence_is_available(purple_account_get_presence(purple_connection_get_account(gc))) );
+	invisible = (yd->current_status == YAHOO_STATUS_INVISIBLE);
 
 	pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
 
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Sun Sep 27 22:22:36 2009 +0000
@@ -1363,7 +1363,6 @@
 
 	xfer = data;
 	if (!(xd = xfer->data))	{
-		purple_input_remove(xd->input_event);
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -1387,7 +1386,6 @@
 
 	xfer = data;
 	if (!(xd = xfer->data))	{
-		purple_input_remove(xd->input_event);
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
@@ -1491,7 +1489,7 @@
 	char *filename_without_spaces = NULL;
 
 	xfer = data;
-	if ( !( (xd = xfer->data) || (listenfd != -1) ) )	{
+	if (!(xd = xfer->data) || (listenfd == -1))	{
 		purple_debug_warning("yahoo","p2p: error starting server for p2p file transfer\n");
 		purple_xfer_cancel_remote(xfer);
 		return;
--- a/libpurple/server.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/server.c	Sun Sep 27 22:22:36 2009 +0000
@@ -44,17 +44,16 @@
 unsigned int
 serv_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->send_typing)
-		return prpl_info->send_typing(gc, name, state);
+		if (prpl_info->send_typing)
+			return prpl_info->send_typing(gc, name, state);
+	}
 
 	return 0;
 }
@@ -142,7 +141,7 @@
 
 	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, name, account);
 
-	if(prpl_info && prpl_info->send_im)
+	if (prpl_info->send_im)
 		val = prpl_info->send_im(gc, name, message, flags);
 
 	/*
@@ -167,43 +166,40 @@
 
 void serv_get_info(PurpleConnection *gc, const char *name)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(gc && prpl_info && prpl_info->get_info)
-		prpl_info->get_info(gc, name);
+		if (prpl_info->get_info)
+			prpl_info->get_info(gc, name);
+	}
 }
 
 void serv_set_info(PurpleConnection *gc, const char *info)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
-	PurpleAccount *account = NULL;;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
+	PurpleAccount *account;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->set_info) {
-
-		account = purple_connection_get_account(gc);
+		if (prpl_info->set_info) {
+			account = purple_connection_get_account(gc);
 
-		if(purple_signal_emit_return_1(purple_accounts_get_handle(),
-									  "account-setting-info", account, info))
-			return;
+			if (purple_signal_emit_return_1(purple_accounts_get_handle(),
+					"account-setting-info", account, info))
+				return;
 
-		prpl_info->set_info(gc, info);
+			prpl_info->set_info(gc, info);
 
-		purple_signal_emit(purple_accounts_get_handle(),
-						 "account-set-info", account, info);
+			purple_signal_emit(purple_accounts_get_handle(),
+					"account-set-info", account, info);
+		}
 	}
 }
 
@@ -212,25 +208,27 @@
  */
 void serv_alias_buddy(PurpleBuddy *b)
 {
-	PurpleAccount *account = NULL;
-	PurpleConnection *gc = NULL;
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurpleAccount *account;
+	PurpleConnection *gc;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(b)
+	if (b) {
 		account = purple_buddy_get_account(b);
 
-	if(account)
-		gc = purple_account_get_connection(account);
+		if (account) {
+			gc = purple_account_get_connection(account);
 
-	if(gc)
-		prpl = purple_connection_get_prpl(gc);
+			if (gc) {
+				prpl = purple_connection_get_prpl(gc);
+				prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl)
-		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
-	if(b && prpl_info && prpl_info->alias_buddy) {
-		prpl_info->alias_buddy(gc, purple_buddy_get_name(b), purple_buddy_get_local_buddy_alias(b));
+				if (prpl_info->alias_buddy)
+					prpl_info->alias_buddy(gc,
+							purple_buddy_get_name(b),
+							purple_buddy_get_local_buddy_alias(b));
+			}
+		}
 	}
 }
 
@@ -349,10 +347,10 @@
  */
 void serv_move_buddy(PurpleBuddy *b, PurpleGroup *og, PurpleGroup *ng)
 {
-	PurpleAccount *account = NULL;
-	PurpleConnection *gc = NULL;
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurpleAccount *account;
+	PurpleConnection *gc;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
 	g_return_if_fail(b != NULL);
 	g_return_if_fail(og != NULL);
@@ -361,131 +359,120 @@
 	account = purple_buddy_get_account(b);
 	gc = purple_account_get_connection(account);
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(gc && og && ng) {
-		if (prpl_info && prpl_info->group_buddy) {
+		if (prpl_info->group_buddy)
 			prpl_info->group_buddy(gc, purple_buddy_get_name(b),
-			                       purple_group_get_name(og),
-								   purple_group_get_name(ng));
-		}
+					purple_group_get_name(og),
+					purple_group_get_name(ng));
 	}
 }
 
 void serv_add_permit(PurpleConnection *gc, const char *name)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->add_permit)
-		prpl_info->add_permit(gc, name);
+		if (prpl_info->add_permit)
+			prpl_info->add_permit(gc, name);
+	}
 }
 
 void serv_add_deny(PurpleConnection *gc, const char *name)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->add_deny)
-		prpl_info->add_deny(gc, name);
+		if (prpl_info->add_deny)
+			prpl_info->add_deny(gc, name);
+	}
 }
 
 void serv_rem_permit(PurpleConnection *gc, const char *name)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->rem_permit)
-		prpl_info->rem_permit(gc, name);
+		if (prpl_info->rem_permit)
+			prpl_info->rem_permit(gc, name);
+	}
 }
 
 void serv_rem_deny(PurpleConnection *gc, const char *name)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->rem_deny)
-		prpl_info->rem_deny(gc, name);
+		if (prpl_info->rem_deny)
+			prpl_info->rem_deny(gc, name);
+	}
 }
 
 void serv_set_permit_deny(PurpleConnection *gc)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	/*
-	 * this is called when either you import a buddy list, and make lots
-	 * of changes that way, or when the user toggles the permit/deny mode
-	 * in the prefs. In either case you should probably be resetting and
-	 * resending the permit/deny info when you get this.
-	 */
-	if(prpl_info && prpl_info->set_permit_deny)
-		prpl_info->set_permit_deny(gc);
+		/*
+		 * this is called when either you import a buddy list, and make lots
+		 * of changes that way, or when the user toggles the permit/deny mode
+		 * in the prefs. In either case you should probably be resetting and
+		 * resending the permit/deny info when you get this.
+		 */
+		if (prpl_info->set_permit_deny)
+			prpl_info->set_permit_deny(gc);
+	}
 }
 
 void serv_join_chat(PurpleConnection *gc, GHashTable *data)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->join_chat)
-		prpl_info->join_chat(gc, data);
+		if (prpl_info->join_chat)
+			prpl_info->join_chat(gc, data);
+	}
 }
 
 
 void serv_reject_chat(PurpleConnection *gc, GHashTable *data)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->reject_chat)
-		prpl_info->reject_chat(gc, data);
+		if (prpl_info->reject_chat)
+			prpl_info->reject_chat(gc, data);
+	}
 }
 
 void serv_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name)
@@ -523,51 +510,44 @@
  * Then again, something might want to use this, from outside prpl-land
  * to leave a chat without destroying the conversation.
  */
-
 void serv_chat_leave(PurpleConnection *gc, int id)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
 	prpl = purple_connection_get_prpl(gc);
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl)
-		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
-
-	if(prpl_info && prpl_info->chat_leave)
+	if (prpl_info->chat_leave)
 		prpl_info->chat_leave(gc, id);
 }
 
 void serv_chat_whisper(PurpleConnection *gc, int id, const char *who, const char *message)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->chat_whisper)
-		prpl_info->chat_whisper(gc, id, who, message);
+		if (prpl_info->chat_whisper)
+			prpl_info->chat_whisper(gc, id, who, message);
+	}
 }
 
 int serv_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
 {
-	int val = -EINVAL;
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
 	prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
-		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if(prpl_info && prpl_info->chat_send)
-		val = prpl_info->chat_send(gc, id, message, flags);
+	if (prpl_info->chat_send)
+		return prpl_info->chat_send(gc, id, message, flags);
 
-	return val;
+	return -EINVAL;
 }
 
 /*
@@ -980,18 +960,16 @@
 
 void serv_send_file(PurpleConnection *gc, const char *who, const char *file)
 {
-	PurplePlugin *prpl = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurplePlugin *prpl;
+	PurplePluginProtocolInfo *prpl_info;
 
-	if(gc)
+	if (gc) {
 		prpl = purple_connection_get_prpl(gc);
-
-	if(prpl)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-	if (prpl_info && prpl_info->send_file) {
-		if (!prpl_info->can_receive_file || prpl_info->can_receive_file(gc, who)) {
+		if (prpl_info->send_file &&
+				(!prpl_info->can_receive_file
+						|| prpl_info->can_receive_file(gc, who)))
 			prpl_info->send_file(gc, who, file);
-		}
 	}
 }
--- a/libpurple/tests/test_jabber_jutil.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/tests/test_jabber_jutil.c	Sun Sep 27 22:22:36 2009 +0000
@@ -142,13 +142,20 @@
 
 	/* Cyrillic capital EF (U+0424) maps to lowercase EF (U+0444) */
 	assert_jid_parts("ф", "darkrain42.org", "Ф@darkrain42.org");
+
+#ifdef USE_IDN
 	/*
 	 * These character (U+A664 and U+A665) are not mapped to anything in
 	 * RFC3454 B.2. This first test *fails* when not using IDN because glib's
-	 * case-folding/utf8_strdown improperly lowercases the character.
+	 * case-folding/utf8_strdown improperly (for XMPP) lowercases the character.
+	 *
+	 * This is known, but not (very?) likely to actually cause a problem, so
+	 * this test is commented out when using glib's functions.
 	 */
 	assert_jid_parts("Ꙥ", "darkrain42.org", "Ꙥ@darkrain42.org");
 	assert_jid_parts("ꙥ", "darkrain42.org", "ꙥ@darkrain42.org");
+#endif
+
 	/* U+04E9 to U+04E9 */
 	assert_jid_parts("paul", "өarkrain42.org", "paul@Өarkrain42.org");
 }
--- a/libpurple/util.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/libpurple/util.c	Sun Sep 27 22:22:36 2009 +0000
@@ -2990,7 +2990,7 @@
 		{
 			PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 
-			if(prpl_info && prpl_info->normalize)
+			if (prpl_info->normalize)
 				ret = prpl_info->normalize(account, str);
 		}
 	}
--- a/pidgin/gtkprefs.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/pidgin/gtkprefs.c	Sun Sep 27 22:22:36 2009 +0000
@@ -459,13 +459,24 @@
 	return row_ref;
 }
 
+static gchar *
+get_theme_markup(const char *name, gboolean custom, const char *author,
+				 const char *description)
+{
+
+	return g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
+						   name, custom ? " " : "", custom ? _("(Custom)") : "",
+						   author != NULL ? " - " : "", author != NULL ? author : "",
+						   description != NULL ? description : "");
+}
+
 /* Rebuild the markup for the sound theme selection for "(Custom)" themes */
 static void
 pref_sound_generate_markup(void)
 {
 	gboolean print_custom, customized;
-	const gchar *name, *author, *description, *current_theme;
-	gchar *markup;
+	const gchar *author, *description, *current_theme;
+	gchar *name, *markup;
 	PurpleSoundTheme *theme;
 	GtkTreeIter iter;
 
@@ -476,23 +487,24 @@
 		do {
 			gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1);
 
-			print_custom = customized && g_str_equal(current_theme, name);
-
-			if (!name || *name == '\0')
-				markup = g_strdup_printf("<b>(Default)</b>%s%s - None\n<span foreground='dim grey'>The default Pidgin sound theme</span>",
-							 print_custom ? " " : "", print_custom ? "(Custom)" : "");
-			else {
+			print_custom = customized && name && g_str_equal(current_theme, name);
+
+			if (!name || *name == '\0') {
+				g_free(name);
+				name = g_strdup(_("(Default)"));
+				author = _("None");
+				description = _("The default Pidgin sound theme");
+			} else {
 				theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound"));
 				author = purple_theme_get_author(PURPLE_THEME(theme));
 				description = purple_theme_get_description(PURPLE_THEME(theme));
-
-				markup = g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
-							 name, print_custom ? " " : "", print_custom ? "(Custom)" : "",
-							 author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : "");
 			}
 
+			markup = get_theme_markup(name, print_custom, author, description);
+
 			gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1);
 
+			g_free(name);
 			g_free(markup);
 
 		} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter));
@@ -514,7 +526,8 @@
 		if (image_full != NULL){
 			pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
 			g_free(image_full);
-		} else pixbuf = NULL;
+		} else
+			pixbuf = NULL;
 
 		gtk_list_store_append(prefs_sound_themes, &iter);
 		gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1);
@@ -527,20 +540,21 @@
 
 		if (PIDGIN_IS_BLIST_THEME(theme))
 			store = prefs_blist_themes;
-		else store = prefs_status_icon_themes;
+		else
+			store = prefs_status_icon_themes;
 
 		image_full = purple_theme_get_image_full(theme);
 		if (image_full != NULL){
 			pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
 			g_free(image_full);
-		} else pixbuf = NULL;
+		} else
+			pixbuf = NULL;
 
 		name = purple_theme_get_name(theme);
 		author = purple_theme_get_author(theme);
 		description = purple_theme_get_description(theme);
 
-		markup = g_strdup_printf("<b>%s</b>%s%s\n<span foreground='dim grey'>%s</span>", name, author != NULL ? " - " : "",
-					 author != NULL ? author : "", description != NULL ? description : "");
+		markup = get_theme_markup(name, FALSE, author, description);
 
 		gtk_list_store_append(store, &iter);
 		gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1);
@@ -579,16 +593,16 @@
 prefs_themes_refresh(void)
 {
 	GdkPixbuf *pixbuf = NULL;
-	gchar *filename;
+	gchar *tmp;
 	GtkTreeIter iter;
 
 	prefs_sound_themes_loading = TRUE;
 	/* refresh the list of themes in the manager */
 	purple_theme_manager_refresh();
 
-	filename = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
-	pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
-	g_free(filename);
+	tmp = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
+	pixbuf = gdk_pixbuf_new_from_file_at_scale(tmp, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
+	g_free(tmp);
 
 	/* sound themes */
 	gtk_list_store_clear(prefs_sound_themes);
@@ -598,16 +612,18 @@
 	/* blist themes */
 	gtk_list_store_clear(prefs_blist_themes);
 	gtk_list_store_append(prefs_blist_themes, &iter);
-	gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1,
-	                   "<b>(Default)</b> - None\n<span color='dim grey'>"
-	                   "The default Pidgin buddy list theme</span>", 2, "", -1);
+	tmp = get_theme_markup(_("(Default)"), FALSE, _("None"),
+		_("The default Pidgin buddy list theme"));
+	gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
+	g_free(tmp);
 
 	/* status icon themes */
 	gtk_list_store_clear(prefs_status_icon_themes);
 	gtk_list_store_append(prefs_status_icon_themes, &iter);
-	gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1,
-	                   "<b>(Default)</b> - None\n<span color='dim grey'>"
-	                   "The default Pidgin status icon theme</span>", 2, "", -1);
+	tmp = get_theme_markup(_("(Default)"), FALSE, _("None"),
+		_("The default Pidgin status icon theme"));
+	gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
+	g_free(tmp);
 	g_object_unref(G_OBJECT(pixbuf));
 
 	purple_theme_manager_for_each_theme(prefs_themes_sort);
@@ -676,6 +692,17 @@
 	return TRUE;
 }
 
+static void
+free_theme_info(struct theme_info *info)
+{
+	if (info != NULL) {
+		g_free(info->type);
+		g_free(info->extension);
+		g_free(info->original_name);
+		g_free(info);
+	}
+}
+
 /* installs a theme, info is freed by function */
 static void
 theme_install_theme(char *path, struct theme_info *info)
@@ -683,7 +710,8 @@
 #ifndef _WIN32
 	gchar *command;
 #endif
-	gchar *destdir, *tail, *type, *original_name;
+	gchar *destdir;
+	const char *tail;
 	GtkTreeRowReference *theme_rowref;
 	gboolean is_smiley_theme, is_archive;
 	PurpleTheme *theme = NULL;
@@ -691,30 +719,23 @@
 	if (info == NULL)
 		return;
 
-	original_name = info->original_name;
-	type = info->type;
-
 	/* check the extension */
-	tail = info->extension ? info->extension : g_strdup(strrchr(path, '.'));
+	tail = info->extension ? info->extension : strrchr(path, '.');
 
 	if (!tail) {
-		g_free(type);
-		g_free(original_name);
-		g_free(info);
+		free_theme_info(info);
 		return;
-	} else
-		g_free(info);
+	}
 
 	is_archive = !g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz");
 
-	g_free(tail);
-
 	/* Just to be safe */
 	g_strchomp(path);
 
-	if ((is_smiley_theme = g_str_equal(type, "smiley")))
+	if ((is_smiley_theme = g_str_equal(info->type, "smiley")))
 		destdir = g_build_filename(purple_user_dir(), "smileys", NULL);
-	else destdir = g_build_filename(purple_user_dir(), "themes", "temp", NULL);
+	else
+		destdir = g_build_filename(purple_user_dir(), "themes", "temp", NULL);
 
 	/* We'll check this just to make sure. This also lets us do something different on
 	 * other platforms, if need be */
@@ -735,15 +756,14 @@
 			purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL);
 			g_free(command);
 			g_free(destdir);
-			g_free(type);
-			g_free(original_name);
+			free_theme_info(info);
 			return;
 		}
 #else
-		if(!winpidgin_gz_untar(path, destdir)) {
+		if (!winpidgin_gz_untar(path, destdir)) {
+			purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL);
 			g_free(destdir);
-			g_free(type);
-			g_free(original_name);
+			free_theme_info(info);
 			return;
 		}
 #endif
@@ -763,13 +783,13 @@
 		}
 
 	} else if (is_archive) {
-		theme = prefs_theme_find_theme(destdir, type);
+		theme = prefs_theme_find_theme(destdir, info->type);
 
 		if (PURPLE_IS_THEME(theme)) {
 			/* create the location for the theme */
 			gchar *theme_dest = g_build_filename(purple_user_dir(), "themes",
 						 purple_theme_get_name(theme),
-						 "purple", type, NULL);
+						 "purple", info->type, NULL);
 
 			if (!g_file_test(theme_dest, G_FILE_TEST_IS_DIR))
 				purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR);
@@ -777,7 +797,7 @@
 			g_free(theme_dest);
 			theme_dest = g_build_filename(purple_user_dir(), "themes",
 						 purple_theme_get_name(theme),
-						 "purple", type, NULL);
+						 "purple", info->type, NULL);
 
 			/* move the entire directory to new location */
 			g_rename(purple_theme_get_dir(theme), theme_dest);
@@ -799,9 +819,9 @@
 
 		temp_path = g_build_filename(purple_user_dir(), "themes", "temp", "sub_folder", NULL);
 
-		if (original_name != NULL) {
+		if (info->original_name != NULL) {
 			/* name was changed from the original (probably a dnd) change it back before loading */
-			temp_file = g_build_filename(temp_path, original_name, NULL);
+			temp_file = g_build_filename(temp_path, info->original_name, NULL);
 
 		} else {
 			gchar *source_name = g_path_get_basename(path);
@@ -814,12 +834,12 @@
 
 		if (purple_theme_file_copy(path, temp_file)) {
 			/* find the theme, could be in subfolder */
-			theme = prefs_theme_find_theme(temp_path, type);
+			theme = prefs_theme_find_theme(temp_path, info->type);
 
 			if (PURPLE_IS_THEME(theme)) {
 				gchar *theme_dest = g_build_filename(purple_user_dir(), "themes",
 							 purple_theme_get_name(theme),
-							 "purple", type, NULL);
+							 "purple", info->type, NULL);
 
 				if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR))
 					purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR);
@@ -842,9 +862,8 @@
 		g_free(temp_path);
 	}
 
-	g_free(type);
-	g_free(original_name);
 	g_free(destdir);
+	free_theme_info(info);
 }
 
 static void
@@ -855,8 +874,10 @@
 	gchar *path;
 	size_t wc;
 
-	if ((error_message != NULL) || (len == 0))
+	if ((error_message != NULL) || (len == 0)) {
+		free_theme_info(user_data);
 		return;
+	}
 
 	f = purple_mkstemp(&path, TRUE);
 	wc = fwrite(themedata, len, 1, f);
@@ -865,6 +886,7 @@
 		fclose(f);
 		g_unlink(path);
 		g_free(path);
+		free_theme_info(user_data);
 		return;
 	}
 	fclose(f);
@@ -900,6 +922,7 @@
 				purple_debug(PURPLE_DEBUG_ERROR, "theme dnd", "%s\n",
 						   (converr ? converr->message :
 							"g_filename_from_uri error"));
+				free_theme_info(info);
 				return;
 			}
 			theme_install_theme(tmp, info);
@@ -920,7 +943,8 @@
 
 			purple_util_fetch_url(tmp, TRUE, NULL, FALSE, theme_got_url, info);
 			g_free(tmp);
-		}
+		} else
+			free_theme_info(info);
 
 		gtk_drag_finish(dc, TRUE, FALSE, t);
 	}
@@ -930,7 +954,7 @@
 
 /* builds a theme combo box from a list store with colums: icon preview, markup, theme name */
 static GtkWidget *
-prefs_build_theme_combo_box(GtkListStore *store, const gchar *current_theme, gchar *type)
+prefs_build_theme_combo_box(GtkListStore *store, const char *current_theme, const char *type)
 {
 	GtkCellRenderer *cell_rend;
 	GtkWidget *combo_box;
@@ -959,7 +983,7 @@
 	gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te,
 					sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE);
 
-	g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), type);
+	g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), (gpointer) type);
 
 	return combo_box;
 }
@@ -980,7 +1004,7 @@
 		purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme);
 
 		/* New theme removes all customization */
-		for(i=0; i <  PURPLE_NUM_SOUNDS; i++){
+		for(i = 0; i < PURPLE_NUM_SOUNDS; i++){
 			pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s",
 						pidgin_sound_get_event_option(i));
 			purple_prefs_set_path(pref, "");
@@ -1037,8 +1061,6 @@
 {
 	struct theme_info *info = g_new0(struct theme_info, 1);
 	info->type = g_strdup("smiley");
-	info->extension = NULL;
-	info->original_name = NULL;
 
 	theme_install_theme(theme_file_name, info);
 }
--- a/pidgin/plugins/win32/winprefs/winprefs.c	Wed Sep 16 16:26:55 2009 +0000
+++ b/pidgin/plugins/win32/winprefs/winprefs.c	Sun Sep 27 22:22:36 2009 +0000
@@ -101,10 +101,7 @@
 			blist_set_ontop(TRUE);
 	} else {
 		purple_debug_info(WINPREFS_PLUGIN_ID, "Blist Undocking...\n");
-		if(purple_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS)
-			blist_set_ontop(TRUE);
-		else
-			blist_set_ontop(FALSE);
+		blist_set_ontop(purple_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS);
 	}
 }
 
@@ -120,10 +117,7 @@
 			blist_ab = NULL;
 		}
 
-		if(purple_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS)
-			blist_set_ontop(TRUE);
-		else
-			blist_set_ontop(FALSE);
+		blist_set_ontop(purple_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS);
 	}
 }
 
@@ -210,6 +204,12 @@
 }
 
 static void
+winprefs_set_multiple_instances(GtkWidget *w) {
+	wpurple_write_reg_string(HKEY_CURRENT_USER, "Environment", "PIDGIN_MULTI_INST",
+			gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)) ? "1" : NULL);
+}
+
+static void
 winprefs_set_blist_dockable(const char *pref, PurplePrefType type,
 		gconstpointer value, gpointer user_data)
 {
@@ -270,34 +270,18 @@
 	GtkWidget *ret;
 	GtkWidget *vbox;
 	GtkWidget *button;
-	char *gtk_version = NULL;
 	char *run_key_val;
 	char *tmp;
 
 	ret = gtk_vbox_new(FALSE, 18);
 	gtk_container_set_border_width(GTK_CONTAINER(ret), 12);
 
-	gtk_version = g_strdup_printf("GTK+\t%u.%u.%u\nGlib\t%u.%u.%u",
-		gtk_major_version, gtk_minor_version, gtk_micro_version,
-		glib_major_version, glib_minor_version, glib_micro_version);
-
-	/* Display Installed GTK+ Runtime Version */
-	if(gtk_version) {
-		GtkWidget *label;
-		vbox = pidgin_make_frame(ret, _("GTK+ Runtime Version"));
-		label = gtk_label_new(gtk_version);
-		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-		gtk_widget_show(label);
-		g_free(gtk_version);
-	}
-
 	/* Autostart */
 	vbox = pidgin_make_frame(ret, _("Startup"));
 	tmp = g_strdup_printf(_("_Start %s on Windows startup"), PIDGIN_NAME);
 	button = gtk_check_button_new_with_mnemonic(tmp);
 	g_free(tmp);
 	gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-
 	if ((run_key_val = wpurple_read_reg_string(HKEY_CURRENT_USER, RUNKEY, "Pidgin"))
 			|| (run_key_val = wpurple_read_reg_string(HKEY_LOCAL_MACHINE, RUNKEY, "Pidgin"))) {
 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@@ -306,6 +290,15 @@
 	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(winprefs_set_autostart), NULL);
 	gtk_widget_show(button);
 
+	button = gtk_check_button_new_with_mnemonic(_("Allow multiple instances"));
+	gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+	if ((run_key_val = wpurple_read_reg_string(HKEY_CURRENT_USER, "Environment", "PIDGIN_MULTI_INST"))) {
+		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+		g_free(run_key_val);
+	}
+	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(winprefs_set_multiple_instances), NULL);
+	gtk_widget_show(button);
+
 	/* Buddy List */
 	vbox = pidgin_make_frame(ret, _("Buddy List"));
 	pidgin_prefs_checkbox(_("_Dockable Buddy List"),
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Wed Sep 16 16:26:55 2009 +0000
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Sun Sep 27 22:22:36 2009 +0000
@@ -1343,12 +1343,13 @@
 
   ClearErrors
   ${GetOptions} "$R3" "/L=" $R1
-  IfErrors +3
+  IfErrors +4
   StrCpy $LANGUAGE $R1
   Goto skip_lang
 
   ; Select Language
     ; Display Language selection dialog
+    !define MUI_LANGDLL_ALWAYSSHOW
     !insertmacro MUI_LANGDLL_DISPLAY
     skip_lang:
 
--- a/po/sv.po	Wed Sep 16 16:26:55 2009 +0000
+++ b/po/sv.po	Sun Sep 27 22:22:36 2009 +0000
@@ -9,8 +9,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-15 18:36+0100\n"
+"POT-Creation-Date: 2009-09-24 22:37+0200\n"
+"PO-Revision-Date: 2009-09-24 22:37+0100\n"
 "Last-Translator: Peter Hjalmarsson <xake@rymdraket.net>\n"
 "Language-Team: \n"
 "MIME-Version: 1.0\n"
@@ -365,7 +365,7 @@
 msgstr "OK"
 
 msgid "New Instant Message"
-msgstr "Nytt snabbmeddelanden"
+msgstr "Nytt snabbmeddelande"
 
 msgid "Please enter the username or alias of the person you would like to IM."
 msgstr ""
@@ -636,8 +636,8 @@
 msgstr[0] "Lista över %d användare:\n"
 msgstr[1] "Lista över %d användare:\n"
 
-msgid "Supported debug options are:  version"
-msgstr "De felsökningsalternativ som stöds är:  version"
+msgid "Supported debug options are: plugins version"
+msgstr "De felsökningsalternativ som stöds är: moduler version"
 
 msgid "No such command (in this context)."
 msgstr "Det finns inget sådant kommando (i denna kontext)."
@@ -1300,10 +1300,10 @@
 msgstr "Alltid"
 
 msgid "Only when available"
-msgstr "Endast vid tillgänglig"
+msgstr "Endast när \"Tillgänglig\""
 
 msgid "Only when not available"
-msgstr "Endast vid Ej tillgänglig"
+msgstr "Endast när \"Ej tillgänglig\""
 
 msgid "Volume(0-100):"
 msgstr "Volym(0-100):"
@@ -1510,9 +1510,8 @@
 "\n"
 "Hämtar TinyURL..."
 
-#, fuzzy
 msgid "Only create TinyURL for URLs of this length or greater"
-msgstr "Skapa enbart TinyURL om url:en är av denna längd eller större"
+msgstr "Skapa enbart TinyURL om url:en är av denna längd eller längre"
 
 msgid "TinyURL (or other) address prefix"
 msgstr "TinyURL (eller annan) adressprefix"
@@ -1523,9 +1522,10 @@
 msgid "TinyURL plugin"
 msgstr "TinyURL modul"
 
-#, fuzzy
 msgid "When receiving a message with URL(s), use TinyURL for easier copying"
-msgstr "När du får en/flera URL/URLer, TinyURL för att lättare hantering"
+msgstr ""
+"När du får meddelande med en/flera URL/URLer, använd TinyURL för att lättare "
+"hantering"
 
 msgid "Online"
 msgstr "Ansluten"
@@ -1631,28 +1631,22 @@
 msgid "buddy list"
 msgstr "kompislista"
 
-#, fuzzy
 msgid "The certificate is self-signed and cannot be automatically checked."
 msgstr ""
-"Certifikatet uppvisat av \"%s\" är självsignerat. Det kan inte kontrolleras "
-"automatiskt."
-
-#, fuzzy
+"Detta certifikatet är självsignerat och kan inte kontrolleras automatiskt."
+
 msgid "The root certificate this one claims to be issued by is unknown."
-msgstr "Rootcertifikatet som denna påstås använda är okänd för Pidgin."
-
-#, fuzzy
+msgstr "Rootcertifikatet som denna påstås använda är okänd."
+
 msgid "The certificate is not valid yet."
-msgstr "Certifikatskedjan uppvisad för %s är inte giltig."
-
-#, fuzzy
+msgstr "Certifikatet är inte giltigt än."
+
 msgid "The certificate has expired and should not be considered valid."
-msgstr "Certifikatskedjan uppvisad för %s är inte giltig."
+msgstr "Certifikatet är för gammalt och bör inte anses giltigt."
 
 #. Translators: "domain" refers to a DNS domain (e.g. talk.google.com)
-#, fuzzy
 msgid "The certificate presented is not issued to this domain."
-msgstr "Certifikatskedjan uppvisad för %s är inte giltig."
+msgstr "Certifikatet är inte utfärdat för denna domän."
 
 msgid ""
 "You have no database of root certificates, so this certificate cannot be "
@@ -1661,17 +1655,14 @@
 "Du har ingen databas över rootcertifikat, så detta certifikat kan inte bli "
 "verifierat."
 
-#, fuzzy
 msgid "The certificate chain presented is invalid."
-msgstr "Certifikatskedjan uppvisad för %s är inte giltig."
-
-#, fuzzy
+msgstr "Certifikatskedjan som uppvisades är ogiltig."
+
 msgid "The certificate has been revoked."
-msgstr "Samtalet avslutat."
-
-#, fuzzy
+msgstr "Certifikatet är taget tillbaka."
+
 msgid "An unknown certificate error occurred."
-msgstr "Ett okänt inloggningsfel har inträffat: %s."
+msgstr "Ett okänt certifikatsfel har inträffat."
 
 msgid "(DOES NOT MATCH)"
 msgstr "(MATCHAR INTE)"
@@ -1717,25 +1708,24 @@
 msgid "_View Certificate..."
 msgstr "_Visa Certifikat..."
 
-#, fuzzy, c-format
+#, c-format
 msgid "The certificate for %s could not be validated."
-msgstr "Certifikatskedjan uppvisad för %s är inte giltig."
+msgstr "Certifikatet för %s kunde inte valideras."
 
 #. TODO: Probably wrong.
 msgid "SSL Certificate Error"
 msgstr "SSL Certifikatsfel"
 
-#, fuzzy
 msgid "Unable to validate certificate"
-msgstr "Kan inte autentisera: %s"
-
-#, fuzzy, c-format
+msgstr "Kan inte validera certifikat."
+
+#, 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 ""
-"Certifikatet uppvisat av \"%s\" påstår sig istället vara för \"%s\". Detta "
-"kan betyda att du inte ansluter till den tjänst du tror du ansluter till."
+"Certifikatet påstår sig vara för \"%s\" istället. Detta kan betyda att du "
+"inte ansluter till den tjänst du tror du ansluter till."
 
 #. Make messages
 #, c-format
@@ -1973,18 +1963,18 @@
 msgid "File transfer complete"
 msgstr "Filöverföringen slutfördes"
 
-#, fuzzy, c-format
+#, c-format
 msgid "You cancelled the transfer of %s"
 msgstr "Du avbröt överföringen av %s"
 
 msgid "File transfer cancelled"
 msgstr "Filöverföringen avbröts"
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s cancelled the transfer of %s"
 msgstr "%s avbröt överföringen av %s"
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s cancelled the file transfer"
 msgstr "%s avbröt filöverföringen"
 
@@ -2167,28 +2157,29 @@
 "No codecs found. Install some GStreamer codecs found in GStreamer plugins "
 "packages."
 msgstr ""
+"Hittade inga codecs. Installera några GStreamer codecs vilka finns i "
+"GStreamers pluginpaket."
 
 msgid ""
 "No codecs left. Your codec preferences in fs-codecs.conf are too strict."
 msgstr ""
-
-#, fuzzy
+"Ingen codec kvar. Dina codec-inställningar i fs-codecs.conf är för strikta."
+
 msgid "A non-recoverable Farsight2 error has occurred."
-msgstr "Ett okänt inloggningsfel har inträffat: %s."
-
-#, fuzzy
-msgid "Conference error."
-msgstr "Konferansen är stängd"
-
-msgid "Error with your microphone."
-msgstr ""
-
-msgid "Error with your webcam."
-msgstr ""
-
-#, fuzzy, c-format
+msgstr "Ett okänt Farsight2-fel har inträffat."
+
+msgid "Conference error"
+msgstr "Konferensfel"
+
+msgid "Error with your microphone"
+msgstr "Problem med din mikrofon"
+
+msgid "Error with your webcam"
+msgstr "Problem med din webbkamera"
+
+#, c-format
 msgid "Error creating session: %s"
-msgstr "Fel vid skapandet av anslutning"
+msgstr "Problem att skapa session: %s"
 
 msgid "Error creating conference."
 msgstr "Fel vid skapandet av konferens."
@@ -2397,7 +2388,7 @@
 msgstr "_Ta bort"
 
 msgid "Set Idle Time for All Accounts"
-msgstr "Ange Inaktivitetstiden för alla konton"
+msgstr "Ange inaktivitetstiden för alla konton"
 
 msgid "Unset Idle Time for All Idled Accounts"
 msgstr "Tar bort inaktivitetstiden för alla inaktiva konton"
@@ -2450,14 +2441,14 @@
 "kommandona."
 
 msgid "Hide Joins/Parts"
-msgstr ""
+msgstr "Göm gå med/lämna"
 
 #. Translators: Followed by an input request a number of people
 msgid "For rooms with more than this many people"
-msgstr ""
+msgstr "För rum med fler än detta antalet personer"
 
 msgid "If user has not spoken in this many minutes"
-msgstr ""
+msgstr "Om användaren inte pratat på så här många minuter"
 
 msgid "Apply hiding rules to buddies"
 msgstr "Verkställ döljningsregler för kompisar"
@@ -3921,11 +3912,12 @@
 msgid "Logo"
 msgstr "Logotyp"
 
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "%s will no longer be able to see your status updates.  Do you want to "
 "continue?"
-msgstr "Du håller på att ta bort %s från din kompislista. Vill du fortsätta?"
+msgstr ""
+"%s kommer inte längre kunna se dina statusuppdateringar. Vill du fortsätta?"
 
 msgid "Cancel Presence Notification"
 msgstr "Avbryt närvarorapportering"
@@ -4275,7 +4267,7 @@
 
 #. if (js->protocol_options & CHANGE_PASSWORD) {
 msgid "Change Password..."
-msgstr "Byt lösenor..."
+msgstr "Byt lösenord..."
 
 #. }
 msgid "Search for Users..."
@@ -4540,12 +4532,11 @@
 "affiliate &lt;ägare|admin|medlem|utstött|ingen&gt;: [nick1] [nick2] ...: "
 "Hämta eller ange användarnas anknytning till rummet."
 
-#, 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;moderator|deltagare|besökare|inget&gt;: [nick1] [nick2] ...: Hämta "
+"role &lt;moderator|participant|visitor|none&gt;: [nick1] [nick2] ...: Hämta "
 "eller ange användarnas roll i rummet."
 
 msgid "invite &lt;user&gt; [message]:  Invite a user to the room."
@@ -4969,7 +4960,6 @@
 msgid "Not expected"
 msgstr "Ej väntat"
 
-#, fuzzy
 msgid "Friendly name is changing too rapidly"
 msgstr "Smeknamn ändras för ofta"
 
@@ -5197,7 +5187,7 @@
 #, 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 ""
 "Kunde inte lägga till kompisen %s eftersom användarnamnet är ogiltigt. "
 "Användarnamnet måste vara en giltig epost-adress."
@@ -5536,10 +5526,10 @@
 "%s har frågar efter att få se fin webbkamera, men denna förfrågan stöds inte "
 "än."
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s invited you to view his/her webcam, but this is not yet supported."
 msgstr ""
-"%s har frågar efter att få se fin webbkamera, men denna förfrågan stöds inte "
+"%s har gett dig en inbjudan att se dennes webbkamera, men detta stöds inte "
 "än."
 
 msgid "Away From Computer"
@@ -6274,9 +6264,9 @@
 msgstr "Serverport"
 
 #. Note to translators: %s in this string is a URL
-#, fuzzy, c-format
+#, c-format
 msgid "Received unexpected response from %s"
-msgstr "Mottog oväntat svar från"
+msgstr "Mottog oväntat svar från %s"
 
 #. username connecting too frequently
 msgid ""
@@ -6288,9 +6278,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 "Fel vid efterfrågan av"
+msgstr "Fel vid efterfrågan av %s: %s"
 
 msgid "AOL does not allow your screen name to authenticate here"
 msgstr "AOL tillåter inte ditt skärmnamn att autentisera här"
@@ -7077,9 +7067,8 @@
 msgid "C_onnect"
 msgstr "_Anslut"
 
-#, fuzzy
 msgid "You closed the connection."
-msgstr "Servern stängde anslutningen"
+msgstr "Du stängde anslutningen."
 
 msgid "Get AIM Info"
 msgstr "Hämta AIM-info"
@@ -7091,9 +7080,8 @@
 msgid "Get Status Msg"
 msgstr "Hämta statusmeddelande"
 
-#, fuzzy
 msgid "End Direct IM Session"
-msgstr "Direktmeddelande har etablerats"
+msgstr "Avsluta direkt-IM session"
 
 msgid "Direct IM"
 msgstr "Direktmeddelande"
@@ -7925,7 +7913,7 @@
 msgid "File Send"
 msgstr "Filsändning"
 
-#, fuzzy, c-format
+#, c-format
 msgid "%d cancelled the transfer of %s"
 msgstr "%d avbröt överföringen av %s"
 
@@ -9455,7 +9443,7 @@
 msgstr "Ignorera inbjudningar till konferenser och chatrum"
 
 msgid "Use account proxy for SSL connections"
-msgstr ""
+msgstr "Använd kontoproxy för SSL-anslutningar"
 
 msgid "Chat room list URL"
 msgstr "URL för chattrumlista"
@@ -9560,26 +9548,27 @@
 msgid "Ignore buddy?"
 msgstr "Ignorera kompis?"
 
-#, fuzzy
 msgid "Invalid username or password"
 msgstr "Felaktigt användarnamn eller lösenord"
 
-#, fuzzy
 msgid ""
 "Your account has been locked due to too many failed login attempts.  Please "
 "try logging into the Yahoo! website."
 msgstr ""
-"Kontot låst: För många inloggningsförsök.  Logga in på Yahoo!s hemsida kan "
-"fixa detta."
+"Ditt kontot har låsts på grund av för många inloggningsförsök.  Försök att "
+"logga in på Yahoo!s hemsida."
 
 #, c-format
 msgid "Unknown error 52.  Reconnecting should fix this."
-msgstr ""
+msgstr "Okänt fel 52. En återanslutning borde fixa detta."
 
 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 ""
+"Fel 1013: Användarnamnet du har angivit är ogiltigt.  Den vanligaste "
+"anledningen till detta är att du angett din epost-adress istället flr ditt "
+"Yahoo! ID."
 
 #, c-format
 msgid "Unknown error number %d. Logging into the Yahoo! website may fix this."
@@ -9667,6 +9656,15 @@
 msgid "Open Inbox"
 msgstr "Öppna Inkorg"
 
+msgid "Can't send SMS. Unable to obtain mobile carrier."
+msgstr ""
+
+msgid "Can't send SMS. Unknown mobile carrier."
+msgstr ""
+
+msgid "Getting mobile carrier to send the SMS."
+msgstr ""
+
 #. Write a local message to this conversation showing that a request for a
 #. * Doodle session has been made
 #.
@@ -9749,9 +9747,9 @@
 msgid "The user's profile is empty."
 msgstr "Användarens profil är tom."
 
-#, fuzzy, c-format
+#, c-format
 msgid "%s has declined to join."
-msgstr "%s har loggat in."
+msgstr "%s har nekat att ansluta."
 
 msgid "Failed to join chat"
 msgstr "Kunde inte ansluta till chatt"
@@ -10022,7 +10020,7 @@
 msgstr "SSL_handskakning misslyckades"
 
 msgid "SSL peer presented an invalid certificate"
-msgstr "SSL-motparten uppvisade ett ogiltig certifikat"
+msgstr "SSL-motparten uppvisade ett ogiltigt certifikat"
 
 msgid "Unknown SSL error"
 msgstr "Okänt SSL-fel"
@@ -10343,7 +10341,6 @@
 msgid "Layout"
 msgstr "Utseende"
 
-#, fuzzy
 msgid "The layout of icons, name, and status of the buddy list"
 msgstr "Utseendet på ikoner, namn och status i kompislistan"
 
@@ -10399,7 +10396,6 @@
 
 #. 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 "Ansluten-text"
 
@@ -10416,11 +10412,9 @@
 
 #. 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 "Frånkopplad-text"
 
-#, fuzzy
 msgid "The text information for when a buddy is offline"
 msgstr "Textinformationen för när en kompis är frånkopplad"
 
@@ -10445,7 +10439,6 @@
 msgid "Message (Nick Said) Text"
 msgstr "Meddelande (Smeknamn nämnt) Text"
 
-#, fuzzy
 msgid ""
 "The text information for when a chat has an unread message that mentions "
 "your nickname"
@@ -10651,7 +10644,7 @@
 msgstr "/Verktyg/_Certifikat"
 
 msgid "/Tools/Custom Smile_ys"
-msgstr "/Verktyg/Egna Smile_ys"
+msgstr "/Verktyg/Egna smile_ys"
 
 msgid "/Tools/Plu_gins"
 msgstr "/Verktyg/Insticksmodu_ler"
@@ -10891,9 +10884,8 @@
 msgid "_Group:"
 msgstr "_Grupp:"
 
-#, fuzzy
 msgid "Auto_join when account connects."
-msgstr "_Gå med automatiskt då kontot är anslutet."
+msgstr "_Gå med automatiskt då kontot ansluter."
 
 msgid "_Remain in chat after window is closed."
 msgstr "Va_r kvar i chattfönster efter att det stängts."
@@ -11009,9 +11001,8 @@
 msgid "/Conversation/New Instant _Message..."
 msgstr "/Konversation/Nytt snabb_meddelande..."
 
-#, fuzzy
 msgid "/Conversation/Join a _Chat..."
-msgstr "/Konversation/_Bjud in..."
+msgstr "/Konversation/Anslut till en _chatt..."
 
 msgid "/Conversation/_Find..."
 msgstr "/Konversation/_Sök..."
@@ -11403,7 +11394,7 @@
 msgstr "Estniska"
 
 msgid "Basque"
-msgstr ""
+msgstr "Baskiska"
 
 msgid "Persian"
 msgstr "Persiska"
@@ -11612,6 +11603,12 @@
 "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\">Hjälp från andra Pidgin-användare:</font> <a href=\"mailto:"
+"support@pidgin.im\">support@pidgin.im</a><br/>Detta är en <b>publik</b> "
+"epostlista! (<a href=\"http://pidgin.im/pipermail/support/\">arkiv</a>)<br/"
+">Vi kan inte hjälpa dig med 3:djepartsmoduler och protokoll!<br/>Listans "
+"huvudspråk är <b>Engelska</b>.  Du är välkommen att skriva i ett annat "
+"språk, men svaren kan vara mindre hjälpsamma.<br/><br/>"
 
 #, c-format
 msgid ""
@@ -12173,43 +12170,48 @@
 "Usage: %s [OPTION]...\n"
 "\n"
 msgstr ""
+"Användning: %s [FLAGGOR]...\n"
+"\n"
 
 msgid "DIR"
-msgstr ""
+msgstr "KATALOG"
 
 msgid "use DIR for config files"
-msgstr ""
+msgstr "Använd KATALOG för konfigurationsfiler"
 
 msgid "print debugging messages to stdout"
-msgstr ""
+msgstr "skriv ut felsökningsmeddelanden till stdout"
 
 msgid "force online, regardless of network status"
-msgstr ""
+msgstr "tvinga ansluten, oavsätt nätverkets status"
 
 msgid "display this help and exit"
-msgstr ""
-
-#, fuzzy
+msgstr "visa denna hjältexten och avsluta"
+
 msgid "allow multiple instances"
-msgstr "Tillåt många samtidiga inloggningar"
+msgstr "tillåt flera instanser"
 
 msgid "don't automatically login"
-msgstr ""
+msgstr "anslut inte automatiskt"
 
 msgid "NAME"
-msgstr ""
+msgstr "NAMN"
 
 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 ""
+"aktivera valda konton (det ej obligatoriska argumentet NAMN\n"
+"                      specificerar en kommaseparerad lista av konton.\n"
+"                      Utan denna lista kommer enbart det första kontot "
+"aktiveras)."
 
 msgid "X display to use"
-msgstr ""
+msgstr "X displayen att använda"
 
 msgid "display the current version and exit"
-msgstr ""
+msgstr "Visar nuvarande version och avslutar"
 
 #, c-format
 msgid ""
@@ -12263,7 +12265,7 @@
 msgstr "%s önskar påbörja en videosession med dig."
 
 msgid "Incoming Call"
-msgstr ""
+msgstr "Inkommande samtal"
 
 msgid "_Pause"
 msgstr "_Pausa"
@@ -12481,6 +12483,21 @@
 msgid "Unknown.... Please report this!"
 msgstr "Okänd... Var snäll och rapportera detta!"
 
+msgid "(Custom)"
+msgstr "(Egen)"
+
+msgid "(Default)"
+msgstr "(Förvald)"
+
+msgid "The default Pidgin sound theme"
+msgstr "Pidgins förvalda ljudtema"
+
+msgid "The default Pidgin buddy list theme"
+msgstr "Pidgins förvalda tema för kompislistan"
+
+msgid "The default Pidgin status icon theme"
+msgstr "Pidgins förvalda statusikon-tema"
+
 msgid "Theme failed to unpack."
 msgstr "Temat kunde inte packas upp."
 
@@ -12511,7 +12528,7 @@
 
 #. Buddy List Themes
 msgid "Buddy List Theme"
-msgstr "Tema för Kompislista"
+msgstr "Tema för kompislista"
 
 #. System Tray
 msgid "System Tray Icon"
@@ -12624,9 +12641,8 @@
 msgid "Cannot start browser configuration program."
 msgstr "Kan inte starta konfigurationsprogrammet för webbläsaren"
 
-#, fuzzy
 msgid "Disabled"
-msgstr "A_vaktivera"
+msgstr "Avaktiverad"
 
 #, c-format
 msgid "Use _automatically detected IP address: %s"
@@ -12657,9 +12673,8 @@
 msgid "Relay Server (TURN)"
 msgstr "Återsändningsserver (TURN)"
 
-#, fuzzy
 msgid "_TURN server:"
-msgstr "ST_UN-server:"
+msgstr "_TURN-server:"
 
 msgid "Proxy Server &amp; Browser"
 msgstr "Proxyserver &amp; Webbläsare"
@@ -12674,7 +12689,7 @@
 "Proxy & Browser preferences are configured\n"
 "in GNOME Preferences"
 msgstr ""
-"Proxy- & Webbläsar-inställningarna konfigureras i\n"
+"Proxy- & webbläsar-inställningarna konfigureras i\n"
 "GNOMEs inställningar"
 
 msgid "Configure _Proxy"
@@ -12839,7 +12854,7 @@
 msgstr "_Rapportera inaktivitetstid:"
 
 msgid "Based on keyboard or mouse use"
-msgstr "Baserat på tangetbord eller musanvändning"
+msgstr "Baserat på tangentbord eller musanvändning"
 
 msgid "_Auto-reply:"
 msgstr "_Automatiskt svar:"
@@ -13038,7 +13053,7 @@
 msgstr "Genvägstext"
 
 msgid "Custom Smiley Manager"
-msgstr "Hanterare för egna Smileys"
+msgstr "Hanterare för egna smileys"
 
 msgid "Select Buddy Icon"
 msgstr "Välj kompisikon"
@@ -13233,7 +13248,7 @@
 msgstr "Liten"
 
 msgid "Smaller versions of the default smilies"
-msgstr "Mindre versioner av de förvadla smiliesarna."
+msgstr "Mindre versioner av de förvalda smiliesarna."
 
 msgid "Response Probability:"
 msgstr "Trolighet för svar:"
@@ -14215,35 +14230,29 @@
 "Denna modul tillåter användaren att personifiera konversationernas och "
 "loggarnas tidsstämpelformat."
 
-#, fuzzy
 msgid "Audio"
-msgstr "Auto"
-
-#, fuzzy
+msgstr "Ljud"
+
 msgid "Video"
-msgstr " Video"
+msgstr "Video"
 
 msgid "Output"
-msgstr ""
-
-#, fuzzy
+msgstr "Utmatning"
+
 msgid "_Plugin"
-msgstr "Insticksmoduler"
-
-#, fuzzy
+msgstr "_Insticksmoduler"
+
 msgid "_Device"
-msgstr "Enhet"
+msgstr "_Enhet"
 
 msgid "Input"
-msgstr ""
-
-#, fuzzy
+msgstr "Inmatning"
+
 msgid "P_lugin"
-msgstr "Insticksmoduler"
-
-#, fuzzy
+msgstr "Insticksmodu_ler"
+
 msgid "D_evice"
-msgstr "Enhet"
+msgstr "_Enhet"
 
 #. *< magic
 #. *< major version
@@ -14254,18 +14263,18 @@
 #. *< dependencies
 #. *< priority
 #. *< id
-#, fuzzy
 msgid "Voice/Video Settings"
-msgstr "Ändra inställningar"
+msgstr "Röst/videoinställningar"
 
 #. *< name
 #. *< version
 msgid "Configure your microphone and webcam."
-msgstr ""
+msgstr "Konfigurerar din mikrofon och kamera."
 
 #. *< summary
 msgid "Configure microphone and webcam settings for voice/video calls."
 msgstr ""
+"Konfigurera mikrofon och webbkamera-inställningar för röst/videosamtal."
 
 msgid "Opacity:"
 msgstr "Ogenomskinlighet:"
@@ -14323,9 +14332,6 @@
 "\n"
 "* Observera: Denna insticksmodul kräver Win2000 eller senare."
 
-msgid "GTK+ Runtime Version"
-msgstr "GTK+ Runtime-version"
-
 #. Autostart
 msgid "Startup"
 msgstr "Uppstart"
@@ -14334,6 +14340,9 @@
 msgid "_Start %s on Windows startup"
 msgstr "_Starta %s när Windows startar"
 
+msgid "Allow multiple instances"
+msgstr "Tillåt flera instanser"
+
 msgid "_Dockable Buddy List"
 msgstr "_Dockningsbar kompislista"
 
@@ -14394,11 +14403,14 @@
 msgid "This plugin is useful for debbuging XMPP servers or clients."
 msgstr "Denna modul är användbar vid felsökning av XMPP serverar och klienter."
 
+#~ msgid "GTK+ Runtime Version"
+#~ msgstr "GTK+ Runtime-version"
+
 #~ msgid "Calling ... "
 #~ msgstr "Ringer..."
 
 #~ msgid "Invalid certificate chain"
-#~ msgstr "Ogiltigt certifikatskedja"
+#~ msgstr "Ogiltig certifikatskedja"
 
 #~ msgid ""
 #~ "The certificate chain presented by %s does not have a valid digital "