changeset 30383:2a19f7385ba5

merged from im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 18 May 2010 02:29:24 +0900
parents 46275cca345e (current diff) fb2bf8986524 (diff)
children 9623db527d1e
files configure.ac libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/protocols/yahoo/libymsg.c libpurple/util.c pidgin/gtkblist.c pidgin/gtkimhtml.c
diffstat 22 files changed, 255 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri May 14 17:24:16 2010 +0900
+++ b/COPYRIGHT	Tue May 18 02:29:24 2010 +0900
@@ -250,6 +250,7 @@
 Krzysztof Klinikowski
 Akuke Kok
 Kir Kolyshkin
+Ivan Komarov
 F.W. Kong
 Konstantin Korikov
 Cole Kowalski
--- a/ChangeLog	Fri May 14 17:24:16 2010 +0900
+++ b/ChangeLog	Tue May 18 02:29:24 2010 +0900
@@ -1,9 +1,18 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
 version 2.7.1 (??/??/????):
+	General:
+	* Build fixes on OpenSolaris.  (Brian Lu)
+
+	Pidgin:
+	* Restore the tray icon's blinking functionality.
+
 	Bonjour:
 	* Fix a crash on disconnect.
 
+	ICQ:
+	* Fix bug that caused HTML to be displayed in incoming messages.
+
 	MSN:
 	* Fix unnecessary bandwidth consumption for buddy icon requests when
 	  buddies have capital letters in their passport addresses.
--- a/configure.ac	Fri May 14 17:24:16 2010 +0900
+++ b/configure.ac	Tue May 18 02:29:24 2010 +0900
@@ -115,6 +115,9 @@
 PKG_PROG_PKG_CONFIG
 AC_FUNC_ALLOCA
 
+dnl Check for Sun compiler
+AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
@@ -1337,6 +1340,10 @@
 	DEBUG_CFLAGS="-Wall $DEBUG_CFLAGS"
 	CFLAGS="-g $CFLAGS"
 fi
+
+if test "x$SUNCC" = "xyes"; then
+        CFLAGS="-features=extensions" 
+fi
 AC_SUBST(CFLAGS)
 
 AC_PATH_PROG(pidginpath, pidgin)
--- a/doc/funniest_home_convos.txt	Fri May 14 17:24:16 2010 +0900
+++ b/doc/funniest_home_convos.txt	Tue May 18 02:29:24 2010 +0900
@@ -530,6 +530,17 @@
 
 --
 
+(14:30:09) linux_user: i have a ?
+(14:31:03) linux_user: when i install this on wine and run it it come up as
+           boxes on the screen
+(14:31:26) nosnilmot: why on earth would you install Pidgin under wine?
+(14:31:41) Err: heh
+(14:31:48) Err: I think my brain just segfaulted on that
+(14:31:58) linux_user: well i am on linux
+(14:32:10) linux_user: linux mint and thay is the only way i can run it
+
+--
+
 14:39 <rrobbertt> Does anyone know a way to get text to speech with pidgin?
 14:41 <elb> do you want to be rooted sooner, or later?
 14:42 <seanegan> good question"; rm -rf ~
--- a/libpurple/protocols/bonjour/jabber.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/bonjour/jabber.c	Tue May 18 02:29:24 2010 +0900
@@ -386,7 +386,7 @@
 	BonjourBuddy *bb = NULL;
 	const gchar *name = bconv->pb ? purple_buddy_get_name(bconv->pb) : "(unknown)";
 
-	purple_debug_info("bonjour", "Recieved conversation close notification from %s.\n", name);
+	purple_debug_info("bonjour", "Received conversation close notification from %s.\n", name);
 
 	if(bconv->pb != NULL)
 		bb = purple_buddy_get_protocol_data(bconv->pb);
@@ -582,7 +582,7 @@
 }
 
 /* This gets called when we've successfully sent our <stream:stream />
- * AND when we've recieved a <stream:stream /> */
+ * AND when we've received a <stream:stream /> */
 void bonjour_jabber_stream_started(BonjourJabberConversation *bconv) {
 
 	if (bconv->sent_stream_start == NOT_SENT && !bonjour_jabber_send_stream_init(bconv, bconv->socket)) {
--- a/libpurple/protocols/gg/lib/libgadu.h	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/gg/lib/libgadu.h	Tue May 18 02:29:24 2010 +0900
@@ -117,7 +117,7 @@
 typedef unsigned short uint16_t;
 typedef unsigned int   uint32_t;
 
-#ifndef __CYGWIN__
+#if !defined(__CYGWIN__) && !defined(__SunOS)
 #define __int8_t_defined
 typedef   signed char    int8_t;
 typedef   signed short  int16_t;
--- a/libpurple/protocols/irc/msgs.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/irc/msgs.c	Tue May 18 02:29:24 2010 +0900
@@ -851,7 +851,7 @@
 	}
 
 	if (!convo) {
-		purple_debug(PURPLE_DEBUG_ERROR, "irc", "Recieved a KICK for unknown channel %s\n", args[0]);
+		purple_debug(PURPLE_DEBUG_ERROR, "irc", "Received a KICK for unknown channel %s\n", args[0]);
 		g_free(nick);
 		return;
 	}
--- a/libpurple/protocols/mxit/chunk.h	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/mxit/chunk.h	Tue May 18 02:29:24 2010 +0900
@@ -42,7 +42,7 @@
 #define		CP_CHUNK_OFFER				0x06		/* (6) offer file */
 #define		CP_CHUNK_REJECT				0x07		/* (7) reject file */
 #define		CP_CHUNK_GET				0x08		/* (8) get file */
-#define		CP_CHUNK_RECIEVED			0x09		/* (9) received file */
+#define		CP_CHUNK_RECEIVED			0x09		/* (9) received file */
 #define		CP_CHUNK_DIRECT_SND			0x0A		/* (10) send file direct */
 #define		CP_CHUNK_DIRECT_FWD			0x0B		/* (11) forward file direct */
 #define		CP_CHUNK_SKIN				0x0C		/* (12) MXit client skin */
--- a/libpurple/protocols/mxit/protocol.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/mxit/protocol.c	Tue May 18 02:29:24 2010 +0900
@@ -1183,7 +1183,7 @@
 		return;
 	}
 
-	set_chunk_type( chunk, CP_CHUNK_RECIEVED );
+	set_chunk_type( chunk, CP_CHUNK_RECEIVED );
 	set_chunk_length( chunk, size );
 	datalen += MXIT_CHUNK_HEADER_SIZE + size;
 
@@ -1783,7 +1783,7 @@
 			/* this is a ack for a file send. no action is required */
 			break;
 
-		case CP_CHUNK_RECIEVED :
+		case CP_CHUNK_RECEIVED :
 			/* this is a ack for a file received. no action is required */
 			break;
 
--- a/libpurple/protocols/oscar/family_icbm.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/oscar/family_icbm.c	Tue May 18 02:29:24 2010 +0900
@@ -1356,7 +1356,7 @@
 	channel = byte_stream_get16(bs);
 
 	if (channel != 0x01) {
-		purple_debug_misc("oscar", "icbm: ICBM recieved on unsupported channel.  Ignoring. (chan = %04x)\n", channel);
+		purple_debug_misc("oscar", "icbm: ICBM received on unsupported channel.  Ignoring. (chan = %04x)\n", channel);
 		return 0;
 	}
 
--- a/libpurple/protocols/oscar/oscar.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.c	Tue May 18 02:29:24 2010 +0900
@@ -2516,32 +2516,6 @@
 	tmp = g_string_free(message, FALSE);
 
 	/*
-	 * If the message is from an ICQ user and to an ICQ user then escape any HTML,
-	 * because HTML is not sent over ICQ as a means to format a message.
-	 * So any HTML we receive is intended to be displayed.  Also, \r\n must be
-	 * replaced with <br>
-	 *
-	 * Note: There *may* be some clients which send messages as HTML formatted -
-	 *       they need to be special-cased somehow.
-	 *
-	 * Update: Newer ICQ clients have started sending IMs as HTML.  We can
-	 * distinguish HTML IMs from non-HTML IMs by looking at the features.  If
-	 * the features are "0x 01 06" then the message is plain text.  If the
-	 * features are "0x 01" then the message is HTML.
-	 */
-	if (od->icq && oscar_util_valid_name_icq(userinfo->bn)
-			&& (args->featureslen != 1 || args->features[0] != 0x01))
-	{
-		/* being recevied by ICQ from ICQ - escape HTML so it is displayed as sent */
-		gchar *tmp2 = g_markup_escape_text(tmp, -1);
-		g_free(tmp);
-		tmp = tmp2;
-		tmp2 = purple_strreplace(tmp, "\r\n", "<br>");
-		g_free(tmp);
-		tmp = tmp2;
-	}
-
-	/*
 	 * Convert iChat color tags to normal font tags.
 	 */
 	if (purple_markup_find_tag("body", tmp, &start, &end, &attribs))
--- a/libpurple/protocols/oscar/oscar.h	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.h	Tue May 18 02:29:24 2010 +0900
@@ -757,8 +757,7 @@
  * HTML messages, then the oscar servers will merrily strip the HTML
  * for us.
  *
- * When we receive an IM we look at the features on the ICBM to
- * determine if the message is HTML or plaintext.
+ * All incoming IMs are treated as HTML.
  */
 #define AIM_IMPARAM_FLAG_USE_HTML_FOR_ICQ       0x00000400
 
--- a/libpurple/protocols/oscar/snac.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/oscar/snac.c	Tue May 18 02:29:24 2010 +0900
@@ -56,11 +56,9 @@
 	snac.type = type;
 	snac.flags = flags;
 
-	if (datalen) {
-		if (!(snac.data = g_malloc(datalen)))
-			return 0; /* er... */
-		memcpy(snac.data, data, datalen);
-	} else
+	if (datalen)
+		snac.data = g_memdup(data, datalen);
+	else
 		snac.data = NULL;
 
 	return aim_newsnac(od, &snac);
@@ -78,9 +76,7 @@
 	if (!newsnac)
 		return 0;
 
-	if (!(snac = g_malloc(sizeof(aim_snac_t))))
-		return 0;
-	memcpy(snac, newsnac, sizeof(aim_snac_t));
+	snac = g_memdup(newsnac, sizeof(aim_snac_t));
 	snac->issuetime = time(NULL);
 
 	index = snac->id % FAIM_SNAC_HASH_SIZE;
--- a/libpurple/protocols/yahoo/libymsg.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/protocols/yahoo/libymsg.c	Tue May 18 02:29:24 2010 +0900
@@ -1793,23 +1793,17 @@
 	return tmp2;
 }
 
-static void yahoo_auth16_stage2(PurpleUtilFetchUrlData *unused, gpointer user_data, const gchar *ret_data, size_t len, const gchar *error_message)
+static void yahoo_auth16_stage2(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *ret_data, size_t len, const gchar *error_message)
 {
 	struct yahoo_auth_data *auth_data = user_data;
 	PurpleConnection *gc = auth_data->gc;
-	YahooData *yd;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	gboolean try_login_on_error = FALSE;
 
 	purple_debug_info("yahoo","Authentication: In yahoo_auth16_stage2\n");
 
-	if (!PURPLE_CONNECTION_IS_VALID(gc)) {
-		g_free(auth_data->seed);
-		g_free(auth_data);
-		g_return_if_reached();
-	}
-
-	yd = (YahooData *)gc->proto_data;
-
+	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
+	
 	if (error_message != NULL) {
 		purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message);
 		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
@@ -1916,18 +1910,15 @@
 	g_free(auth_data);
 }
 
-static void yahoo_auth16_stage1_cb(PurpleUtilFetchUrlData *unused, gpointer user_data, const gchar *ret_data, size_t len, const gchar *error_message)
+static void yahoo_auth16_stage1_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *ret_data, size_t len, const gchar *error_message)
 {
 	struct yahoo_auth_data *auth_data = user_data;
 	PurpleConnection *gc = auth_data->gc;
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 
 	purple_debug_info("yahoo","Authentication: In yahoo_auth16_stage1_cb\n");
 
-	if (!PURPLE_CONNECTION_IS_VALID(gc)) {
-		g_free(auth_data->seed);
-		g_free(auth_data);
-		g_return_if_reached();
-	}
+	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
 	if (error_message != NULL) {
 		purple_debug_error("yahoo", "Login Failed, unable to retrieve login url: %s\n", error_message);
@@ -2029,6 +2020,8 @@
 			url_data = purple_util_fetch_url_request_len_with_account(
 					proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT,
 					TRUE, NULL, TRUE, -1, yahoo_auth16_stage2, auth_data);
+			if (url_data)
+				yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
 			g_free(url);
 			g_free(token);
 		}
@@ -2037,6 +2030,7 @@
 
 static void yahoo_auth16_stage1(PurpleConnection *gc, const char *seed)
 {
+	YahooData *yd = purple_connection_get_protocol_data(gc);
 	PurpleAccount *account = purple_connection_get_account(gc);
 	PurpleUtilFetchUrlData *url_data = NULL;
 	struct yahoo_auth_data *auth_data = NULL;
@@ -2068,6 +2062,8 @@
 			proxy_ssl ? account : NULL, url, TRUE,
 			YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
 			yahoo_auth16_stage1_cb, auth_data);
+	if (url_data)
+		yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
 
 	g_free(url);
 }
@@ -3606,6 +3602,8 @@
 	gchar **strings = NULL, *cs_server = NULL;
 	int port = 0, stringslen = 0;
 
+	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
+
 	if(error_message != NULL || len == 0) {
 		purple_debug_error("yahoo", "Unable to retrieve server info. %"
 				G_GSIZE_FORMAT " bytes retrieved with error message: %s\n", len,
@@ -3652,6 +3650,7 @@
 	YahooData *yd = gc->proto_data = g_new0(YahooData, 1);
 	PurpleStatus *status = purple_account_get_active_status(account);
 	gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
+	PurpleUtilFetchUrlData *url_data;
 
 	gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;
 
@@ -3684,12 +3683,14 @@
 
 	/* Get the pager server.  Actually start connecting in the callback since we
 	 * must have the contents of the HTTP response to proceed. */
-	purple_util_fetch_url_request_len_with_account(
+	url_data = purple_util_fetch_url_request_len_with_account(
 			purple_connection_get_account(gc),
 			yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL,
 			use_whole_url ? TRUE : FALSE,
 			YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1,
 			yahoo_got_pager_server, yd);
+	if (url_data)
+		yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
 
 	return;
 }
@@ -4379,6 +4380,8 @@
 	PurpleAccount *account = purple_connection_get_account(gc);
 	PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, sms_cb_data->who, account);
 
+	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
+
 	if (error_message != NULL) {
 		purple_conversation_write(conv, NULL, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
 
@@ -4472,7 +4475,9 @@
 	g_free(request);
 	g_free(validate_request_str);
 
-	if (!url_data) {
+	if (url_data)
+		yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
+	else {
 		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, _("Can't send SMS. Unable to obtain mobile carrier."), PURPLE_MESSAGE_SYSTEM, time(NULL));
--- a/libpurple/util.c	Fri May 14 17:24:16 2010 +0900
+++ b/libpurple/util.c	Tue May 18 02:29:24 2010 +0900
@@ -1310,12 +1310,17 @@
 #define ALLOW_TAG_ALT(x, y) if(!g_ascii_strncasecmp(c, "<" x " ", strlen("<" x " "))) { \
 						const char *o = c + strlen("<" x); \
 						const char *p = NULL, *q = NULL, *r = NULL; \
+						/* o = iterating over full tag \
+						 * p = > (end of tag) \
+						 * q = start of quoted bit \
+						 * r = < inside tag \
+						 */ \
 						GString *innards = g_string_new(""); \
 						while(o && *o) { \
 							if(!q && (*o == '\"' || *o == '\'') ) { \
 								q = o; \
 							} else if(q) { \
-								if(*o == *q) { \
+								if(*o == *q) { /* end of quoted bit */ \
 									char *unescaped = g_strndup(q+1, o-q-1); \
 									char *escaped = g_markup_escape_text(unescaped, -1); \
 									g_string_append_printf(innards, "%c%s%c", *q, escaped, *q); \
@@ -1335,7 +1340,7 @@
 							} \
 							o++; \
 						} \
-						if(p && !r) { \
+						if(p && !r) { /* got an end of tag and no other < earlier */\
 							if(*(p-1) != '/') { \
 								struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
 								pt->src_tag = x; \
@@ -1348,7 +1353,7 @@
 								xhtml = g_string_append_c(xhtml, '>'); \
 							} \
 							c = p + 1; \
-						} else { \
+						} else { /* got end of tag with earlier < *or* didn't get anything */ \
 							if(xhtml) \
 								xhtml = g_string_append(xhtml, "&lt;"); \
 							if(plain) \
--- a/pidgin/gtkblist.c	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/gtkblist.c	Tue May 18 02:29:24 2010 +0900
@@ -947,6 +947,9 @@
 	PurpleConnection *gc = purple_account_get_connection(account);
 	PurplePluginProtocolInfo *prpl_info = NULL;
 
+	if (gc == NULL)
+		return FALSE;
+
 	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
 
 	return (prpl_info->chat_info != NULL);
--- a/pidgin/gtkdocklet-gtk.c	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/gtkdocklet-gtk.c	Tue May 18 02:29:24 2010 +0900
@@ -75,6 +75,12 @@
 	if (icon_name) {
 		gtk_status_icon_set_from_icon_name(docklet, icon_name);
 	}
+
+	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/docklet/blink")) {
+		gtk_status_icon_set_blinking(docklet, (pending && !connecting));
+	} else if (gtk_status_icon_get_blinking(docklet)) {
+		gtk_status_icon_set_blinking(docklet, FALSE);
+	}
 }
 
 static void
@@ -101,7 +107,8 @@
 	g_return_if_fail(docklet != NULL);
 
 	pidgin_docklet_remove();
-	
+
+	gtk_status_icon_set_visible(docklet, FALSE);
 	g_object_unref(G_OBJECT(docklet));
 	docklet = NULL;
 
--- a/pidgin/gtkimhtml.c	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/gtkimhtml.c	Tue May 18 02:29:24 2010 +0900
@@ -1276,7 +1276,7 @@
 #ifdef _WIN32
 	/* If we're on windows, let's see if we can get data from the HTML Format
 	   clipboard before we try to paste from the GTK buffer */
-	if (!clipboard_paste_html_win32(imhtml)) {
+	if (!clipboard_paste_html_win32(imhtml) && gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) {
 		GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD);
 		gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
 
--- a/pidgin/gtksession.c	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/gtksession.c	Tue May 18 02:29:24 2010 +0900
@@ -346,7 +346,7 @@
 	purple_debug(PURPLE_DEBUG_INFO, "Session Management",
 			   "Connected to manager (%s) with client ID %s\n",
 			   tmp, client_id);
-	g_free(tmp);
+	free(tmp);
 
 	session_managed = TRUE;
 	gdk_set_sm_client_id(client_id);
--- a/pidgin/win32/nsis/langmacros.nsh	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/win32/nsis/langmacros.nsh	Tue May 18 02:29:24 2010 +0900
@@ -71,6 +71,8 @@
   !insertmacro PIDGIN_MACRO_LANGSTRING_INSERT PIDGIN_DEBUGSYMBOLS_ERROR		${CUR_LANG}
   !insertmacro PIDGIN_MACRO_LANGSTRING_INSERT PIDGIN_GTK_DOWNLOAD_ERROR		${CUR_LANG}
 
+  !insertmacro PIDGIN_MACRO_LANGSTRING_INSERT PIDGIN_PROMPT_FORCE_NO_GTK 	${CUR_LANG}
+
   !undef CUR_LANG
 !macroend
 
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Tue May 18 02:29:24 2010 +0900
@@ -8,9 +8,9 @@
 ;--------------------------------
 ;Global Variables
 Var name
-Var ISSILENT
 Var STARTUP_RUN_KEY
-Var SPELLCHECK_SEL
+Var CURRENT_GTK_STATE
+Var WARNED_GTK_STATE
 
 ;--------------------------------
 ;Configuration
@@ -352,7 +352,7 @@
   Pop $R0
   StrCmp $R0 "cancel" done
   StrCmp $R0 "success" +2
-    MessageBox MB_RETRYCANCEL "$(PIDGIN_GTK_DOWNLOAD_ERROR) : $R2" /SD IDCANCEL IDRETRY retry IDCANCEL done
+    MessageBox MB_RETRYCANCEL "$(PIDGIN_GTK_DOWNLOAD_ERROR)" /SD IDCANCEL IDRETRY retry IDCANCEL done
 
 !endif
 
@@ -549,7 +549,7 @@
   Pop $R0
   StrCmp $R0 "cancel" done
   StrCmp $R0 "success" +2
-    MessageBox MB_RETRYCANCEL "$(PIDGIN_DEBUGSYMBOLS_ERROR) : $R2" /SD IDCANCEL IDRETRY retry IDCANCEL done
+    MessageBox MB_RETRYCANCEL "$(PIDGIN_DEBUGSYMBOLS_ERROR)" /SD IDCANCEL IDRETRY retry IDCANCEL done
 
 !endif
 
@@ -595,7 +595,7 @@
     DeleteRegValue HKCU "${STARTUP_RUN_KEY}" "Pidgin"
     DeleteRegValue HKLM "${STARTUP_RUN_KEY}" "Pidgin"
     ; Remove Language preference info
-    DeleteRegValue HKCU "${PIDGIN_REG_KEY}" "Installer Language"
+    DeleteRegValue HKCU "${PIDGIN_REG_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}"
 
     ; Remove any URI handlers
     ; I can't think of an easy way to maintain a list in a single place
@@ -1109,18 +1109,17 @@
   Call RunCheck
 
   StrCpy $name "Pidgin ${PIDGIN_VERSION}"
-  StrCpy $SPELLCHECK_SEL ""
 
   ;Try to copy the old Gaim installer Lang Reg. key
   ;(remove it after we're done to prevent this being done more than once)
   ClearErrors
-  ReadRegStr $R0 HKCU "${PIDGIN_REG_KEY}" "Installer Language"
+  ReadRegStr $R0 HKCU "${PIDGIN_REG_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}"
   IfErrors 0 +5
   ClearErrors
-  ReadRegStr $R0 HKCU "${OLD_GAIM_REG_KEY}" "Installer Language"
+  ReadRegStr $R0 HKCU "${OLD_GAIM_REG_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}"
   IfErrors +3
-  DeleteRegValue HKCU "${OLD_GAIM_REG_KEY}" "Installer Language"
-  WriteRegStr HKCU "${PIDGIN_REG_KEY}" "Installer Language" "$R0"
+  DeleteRegValue HKCU "${OLD_GAIM_REG_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}"
+  WriteRegStr HKCU "${PIDGIN_REG_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}" "$R0"
 
   ${MementoSectionRestore}
 
@@ -1130,7 +1129,7 @@
   ;Preselect the "shortcuts" checkboxes according to the previous installation
   ClearErrors
   ;Make sure that there was a previous installation
-  ReadRegStr $R0 HKCU "${PIDGIN_REG_KEY}" "Installer Language"
+  ReadRegStr $R0 HKCU "${PIDGIN_REG_KEY}" "${MUI_LANGDLL_REGISTRY_VALUENAME}"
   IfErrors done_preselecting_shortcuts
     ;Does the Desktop shortcut exist?
     GetFileTime "$DESKTOP\Pidgin.lnk" $R0 $R0
@@ -1156,12 +1155,6 @@
   ;Reset ShellVarContext because we may have changed it
   SetShellVarContext "current"
 
-  StrCpy $ISSILENT "/S"
-  ; GTK installer has two silent states - one with Message boxes, one without
-  ; If pidgin installer was run silently, we want to supress gtk installer msg boxes.
-  IfSilent 0 +2
-    StrCpy $ISSILENT "/NOUI"
-
   ClearErrors
   ${GetOptions} "$R3" "/L=" $R1
   IfErrors +3
@@ -1222,11 +1215,14 @@
     StrCpy $INSTDIR "$R2\Pidgin"
 
   instdir_done:
+;LogSet on
+
+  ; Try to select a translation and a dictionary for the currently selected Language
+  Call SelectTranslationForCurrentLanguage
 
   ;Mark the dictionaries that are already installed as readonly
   Call SelectAndDisableInstalledDictionaries
 
-;LogSet on
   Pop $R3
   Pop $R2
   Pop $R1
@@ -1262,9 +1258,11 @@
 !endif
 
   Call DoWeNeedGtk
-  Pop $R0
-  IntCmp $R0 1 done gtk_not_mandatory
-    ; Make the GTK+ Section RO if it is required.
+  Pop $CURRENT_GTK_STATE
+  StrCpy $WARNED_GTK_STATE "0"
+  IntCmp $CURRENT_GTK_STATE 1 done gtk_not_mandatory
+    ; Make the GTK+ Section RO if it is required. (it is required only if you have an existing version that is too old)
+    StrCmp $CURRENT_GTK_STATE "2" 0 done
     !insertmacro SetSectionFlag ${SecGtk} ${SF_RO}
     Goto done
   gtk_not_mandatory:
@@ -1276,13 +1274,147 @@
   Pop $R0
 FunctionEnd
 
+; If the GTK+ Section has been unselected and there isn't a compatible GTK+ already, confirm
+Function .onSelChange
+  Push $R0
+
+  SectionGetFlags ${SecGtk} $R0
+  IntOp $R0 $R0 & ${SF_SELECTED}
+  ; If the Gtk Section is currently selected, reset the "Warned" flag
+  StrCmp $R0 "${SF_SELECTED}" 0 +3
+  StrCpy $WARNED_GTK_STATE "0"
+  Goto done
+
+  ; If we've already warned the user, don't warn them again
+  StrCmp $WARNED_GTK_STATE "1" done
+  IntCmp $CURRENT_GTK_STATE 1 done done 0
+  StrCpy $WARNED_GTK_STATE "1"
+  MessageBox MB_YESNO $(PIDGIN_PROMPT_FORCE_NO_GTK) /SD IDNO IDYES done
+  !insertmacro SelectSection ${SecGtk}
+
+  done:
+  Pop $R0
+FunctionEnd
+
+
+; Convert the current $LANGUAGE to a language code that we can use for translation mo selection
+; If there's a better way to do this, I'd love to know it
+Function SelectTranslationForCurrentLanguage
+
+  StrCmp "$LANGUAGE" "1078" 0 sq
+  !insertmacro SelectSection ${SecLang_af}
+  Goto done
+  sq: StrCmp "$LANGUAGE" "1052" 0 ar
+  !insertmacro SelectSection ${SecLang_sq}
+  Goto done
+  ar: StrCmp "$LANGUAGE" "1025" 0 eu
+  !insertmacro SelectSection ${SecLang_ar}
+  Goto done
+  eu: StrCmp "$LANGUAGE" "1069" 0 bg
+  !insertmacro SelectSection ${SecLang_eu}
+  Goto done
+  bg: StrCmp "$LANGUAGE" "1026" 0 ca 
+  !insertmacro SelectSection ${SecLang_bg}
+  Goto done
+  ca: StrCmp "$LANGUAGE" "1027" 0 cs
+  !insertmacro SelectSection ${SecLang_ca}
+  Goto done
+  cs: StrCmp "$LANGUAGE" "1029" 0 da 
+  !insertmacro SelectSection ${SecLang_cs}
+  Goto done
+  da: StrCmp "$LANGUAGE" "1030" 0 nl
+  !insertmacro SelectSection ${SecLang_da}
+  Goto done
+  nl: StrCmp "$LANGUAGE" "1043" 0 fa
+  !insertmacro SelectSection ${SecLang_nl}
+  Goto done
+  ;We have several English translations, but we don't have a way of guessing, so we don't choose one
+  ;en: StrCmp "$LANGUAGE" "1033" 0 +3
+  ;!insertmacro SelectSection ${SecLang_en_??}
+  ;Goto done
+  fa: StrCmp "$LANGUAGE" "1065" 0 fi
+  !insertmacro SelectSection ${SecLang_fa}
+  Goto done
+  fi: StrCmp "$LANGUAGE" "1035" 0 fr
+  !insertmacro SelectSection ${SecLang_fi}
+  Goto done
+  fr: StrCmp "$LANGUAGE" "1036" 0 de
+  !insertmacro SelectSection ${SecLang_fr}
+  Goto done
+  de: StrCmp "$LANGUAGE" "1031" 0 he
+  !insertmacro SelectSection ${SecLang_de}
+  Goto done
+  he: StrCmp "$LANGUAGE" "1037" 0 hu
+  !insertmacro SelectSection ${SecLang_he}
+  Goto done
+  hu: StrCmp "$LANGUAGE" "1038" 0 it
+  !insertmacro SelectSection ${SecLang_hu}
+  Goto done
+  it: StrCmp "$LANGUAGE" "1040" 0 ja
+  !insertmacro SelectSection ${SecLang_it}
+  Goto done
+  ja: StrCmp "$LANGUAGE" "1041" 0 ko
+  !insertmacro SelectSection ${SecLang_ja}
+  Goto done
+  ko: StrCmp "$LANGUAGE" "1042" 0 ku
+  !insertmacro SelectSection ${SecLang_ko}
+  Goto done
+  ku: StrCmp "$LANGUAGE" "9999" 0 lt
+  !insertmacro SelectSection ${SecLang_ku}
+  Goto done
+  lt: StrCmp "$LANGUAGE" "1063" 0 nb
+  !insertmacro SelectSection ${SecLang_lt}
+  Goto done
+  nb: StrCmp "$LANGUAGE" "1044" 0 nn
+  !insertmacro SelectSection ${SecLang_nb}
+  Goto done
+  nn: StrCmp "$LANGUAGE" "2068" 0 pl
+  !insertmacro SelectSection ${SecLang_nn}
+  Goto done
+  pl: StrCmp "$LANGUAGE" "1045" 0 pt
+  !insertmacro SelectSection ${SecLang_pl}
+  Goto done
+  pt: StrCmp "$LANGUAGE" "2070" 0 pt_BR
+  !insertmacro SelectSection ${SecLang_pt}
+  Goto done
+  pt_BR: StrCmp "$LANGUAGE" "1046" 0 ro
+  !insertmacro SelectSection ${SecLang_pt_BR}
+  Goto done
+  ro: StrCmp "$LANGUAGE" "1048" 0 ru
+  !insertmacro SelectSection ${SecLang_ro}
+  Goto done
+  ru: StrCmp "$LANGUAGE" "1049" 0 sr
+  !insertmacro SelectSection ${SecLang_ru}
+  Goto done
+  sr: StrCmp "$LANGUAGE" "3098" 0 zh_CN
+  !insertmacro SelectSection ${SecLang_sr}
+  Goto done
+  zh_CN: StrCmp "$LANGUAGE" "2052" 0 sk
+  !insertmacro SelectSection ${SecLang_zh_CN}
+  Goto done
+  sk: StrCmp "$LANGUAGE" "1051" 0 sl
+  !insertmacro SelectSection ${SecLang_sk}
+  Goto done
+  sl: StrCmp "$LANGUAGE" "1060" 0 es
+  !insertmacro SelectSection ${SecLang_sl}
+  Goto done
+  es: StrCmp "$LANGUAGE" "1034" 0 sv
+  !insertmacro SelectSection ${SecLang_es}
+  Goto done
+  sv: StrCmp "$LANGUAGE" "1053" 0 zh_TW
+  !insertmacro SelectSection ${SecLang_sv}
+  Goto done
+  zh_TW: StrCmp "$LANGUAGE" "1028" 0 done
+  !insertmacro SelectSection ${SecLang_zh_TW}
+  Goto done
+
+  done:
+FunctionEnd
+
+
 ; SpellChecker Related Functions
 ;-------------------------------
 
-; Convert the a Section index to the language code
-; Push the section index onto the stack and pop off the language code after the call
-; This will set the error code, if no match is found
-
 ; Select and Disable any Sections that have currently installed dictionaries
 !macro CHECK_SPELLCHECK_SECTION lang
   ;Advance to the next (correct) section index
@@ -1317,6 +1449,7 @@
   Pop $R1 ;This is the language file
   Push $R2
   Push $R3
+  Push $R4
 
   ClearErrors
   IfFileExists "$INSTDIR\spellcheck\share\enchant\myspell\$R0.dic" installed
@@ -1329,10 +1462,10 @@
   DetailPrint "Downloading the $R0 Dictionary... ($R3)"
   retry:
   NSISdl::download /TIMEOUT=10000 "$R3" "$R2"
-  Pop $R3
-  StrCmp $R3 "cancel" done
-  StrCmp $R3 "success" +3
-    MessageBox MB_RETRYCANCEL "$(PIDGIN_SPELLCHECK_ERROR) : $R3" /SD IDCANCEL IDRETRY retry IDCANCEL done
+  Pop $R4
+  StrCmp $R4 "cancel" done
+  StrCmp $R4 "success" +3
+    MessageBox MB_RETRYCANCEL "$(PIDGIN_SPELLCHECK_ERROR)" /SD IDCANCEL IDRETRY retry IDCANCEL done
     Goto done
   SetOutPath "$INSTDIR\spellcheck\share\enchant\myspell"
   nsisunz::UnzipToLog "$R2" "$OUTDIR"
@@ -1346,6 +1479,7 @@
     DetailPrint "$R0 Dictionary is installed"
 
   done:
+  Pop $R4
   Pop $R3
   Pop $R2
   Pop $R0
--- a/pidgin/win32/nsis/translations/english.nsh	Fri May 14 17:24:16 2010 +0900
+++ b/pidgin/win32/nsis/translations/english.nsh	Tue May 18 02:29:24 2010 +0900
@@ -44,6 +44,8 @@
 
 ; GTK+ Section Prompts
 
+!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_PROMPT_FORCE_NO_GTK		"Pidgin requires a compatible GTK+ Runtime (which doesn't appear to be already present).$\rAre you sure you want to skip installing the GTK+ Runtime?"
+
 ; URL Handler section
 !insertmacro PIDGIN_MACRO_DEFAULT_STRING URI_HANDLERS_SECTION_TITLE		"URI Handlers"
 
@@ -53,10 +55,10 @@
 
 ; Spellcheck Section Prompts
 !insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_SPELLCHECK_SECTION_TITLE	"Spellchecking Support"
-!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_SPELLCHECK_ERROR		"Error Installing Spellchecking"
+!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_SPELLCHECK_ERROR		"Error Installing Spellchecking ($R3).$\rIf retrying fails, manual installation instructions are at: http://d.pidgin.im/wiki/Installing%20Pidgin#manual_win32_spellcheck_installation"
 !insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_SPELLCHECK_SECTION_DESCRIPTION	"Support for Spellchecking.  (Internet connection required for installation)"
 
-!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_DEBUGSYMBOLS_ERROR		"Error Installing Debug Symbols"
+!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_DEBUGSYMBOLS_ERROR		"Error Installing Debug Symbols ($R2)"
 
-!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_GTK_DOWNLOAD_ERROR		"Error Downloading the GTK+ Runtime"
+!insertmacro PIDGIN_MACRO_DEFAULT_STRING PIDGIN_GTK_DOWNLOAD_ERROR		"Error Downloading the GTK+ Runtime ($R2).$\rThis is required for Pidgin to function; if retrying fails, you may need to use the 'Offline Installer' from http://pidgin.im/download/windows/ ."