changeset 28003:268f58ce1289

merge of '53b02d9c3c8aa71b13cea90eea22a0b60155dc8c' and '7c150a3616a42da59174d4b392caadb4df5f0d2c'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Wed, 19 Aug 2009 00:41:20 +0000
parents 901476dc70b9 (diff) a195ce8eb805 (current diff)
children 5479ffb6ec6c d83ee160ffb6 e9b4440718fe
files
diffstat 18 files changed, 226 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Aug 19 00:41:06 2009 +0000
+++ b/ChangeLog	Wed Aug 19 00:41:20 2009 +0000
@@ -1,5 +1,9 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
+version 2.6.1 (??/??/2009):
+	XMPP:
+	* Prompt the user before cancelling a presence subscription.
+
 version 2.6.0 (08/18/2009):
 	libpurple:
 	* Theme support in libpurple thanks to Justin Rodriguez's summer of code
--- a/finch/gntmedia.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/finch/gntmedia.c	Wed Aug 19 00:41:20 2009 +0000
@@ -156,7 +156,7 @@
 {
 	media->priv = FINCH_MEDIA_GET_PRIVATE(media);
 
-	media->priv->calling = gnt_label_new(_("Calling ... "));
+	media->priv->calling = gnt_label_new(_("Calling..."));
 	media->priv->hangup = gnt_button_new(_("Hangup"));
 	media->priv->accept = gnt_button_new(_("Accept"));
 	media->priv->reject = gnt_button_new(_("Reject"));
--- a/finch/plugins/gnttinyurl.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/finch/plugins/gnttinyurl.c	Wed Aug 19 00:41:20 2009 +0000
@@ -354,7 +354,7 @@
   frame = purple_plugin_pref_frame_new();
 
   pref = purple_plugin_pref_new_with_name(PREF_LENGTH);
-  purple_plugin_pref_set_label(pref, _("Only create TinyURL for urls"
+  purple_plugin_pref_set_label(pref, _("Only create TinyURL for URLs"
 				     " of this length or greater"));
   purple_plugin_pref_frame_add(frame, pref);
   pref = purple_plugin_pref_new_with_name(PREF_URL);
@@ -390,7 +390,7 @@
 	N_("TinyURL"),
 	DISPLAY_VERSION,
 	N_("TinyURL plugin"),
-	N_("When receiving a message with URL(s), TinyURL for easier copying"),
+	N_("When receiving a message with URL(s), use TinyURL for easier copying"),
 	"Richard Nelson <wabz@whatsbeef.net>",
 	PURPLE_WEBSITE,
 	plugin_load,
--- a/libpurple/certificate.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/certificate.c	Wed Aug 19 00:41:20 2009 +0000
@@ -1635,33 +1635,35 @@
 	if (!ret || now > expiration || now < activation) {
 		gchar *secondary;
 
-		if (!ret)
+		if (!ret) {
 			purple_debug_error("certificate/x509/tls_cached",
 					"Failed to get validity times for certificate %s\n",
 					vrq->subject_name);
-		else if (now > expiration)
+			secondary = g_strdup_printf(_("Failed to validate expiration time "
+					"for %s"), vrq->subject_name);
+		} else if (now > expiration) {
 			purple_debug_error("certificate/x509/tls_cached",
 					"Certificate %s expired at %s\n",
 					vrq->subject_name, ctime(&expiration));
-		else
+			secondary = g_strdup_printf(_("The certificate for %s is expired."),
+					vrq->subject_name);
+		} else {
 			purple_debug_error("certificate/x509/tls_cached",
 					"Certificate %s is not yet valid, will be at %s\n",
 					vrq->subject_name, ctime(&activation));
-
-		/* FIXME 2.6.1 */
-		secondary = g_strdup_printf(_("The certificate chain presented"
-					" for %s is not valid."),
-					vrq->subject_name);
+			secondary = g_strdup_printf(_("The certificate for %s should not "
+					"yet be in use."), vrq->subject_name);
+		}
 
 		purple_notify_error(NULL, /* TODO: Probably wrong. */
-					_("SSL Certificate Error"),
-					_("Invalid certificate chain"),
-					secondary );
+				_("SSL Certificate Error"),
+				_("Invalid certificate chain"),
+				secondary );
 		g_free(secondary);
 
 		/* Okay, we're done here */
 		purple_certificate_verify_complete(vrq,
-						    PURPLE_CERTIFICATE_INVALID);
+				PURPLE_CERTIFICATE_INVALID);
 		return;
 	}
 
--- a/libpurple/ft.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/ft.c	Wed Aug 19 00:41:20 2009 +0000
@@ -1313,7 +1313,7 @@
 
 	if (purple_xfer_get_filename(xfer) != NULL)
 	{
-		msg = g_strdup_printf(_("You canceled the transfer of %s"),
+		msg = g_strdup_printf(_("You cancelled the transfer of %s"),
 							  purple_xfer_get_filename(xfer));
 	}
 	else
@@ -1376,12 +1376,12 @@
 
 	if (purple_xfer_get_filename(xfer) != NULL)
 	{
-		msg = g_strdup_printf(_("%s canceled the transfer of %s"),
+		msg = g_strdup_printf(_("%s cancelled the transfer of %s"),
 				buddy ? purple_buddy_get_alias(buddy) : xfer->who, purple_xfer_get_filename(xfer));
 	}
 	else
 	{
-		msg = g_strdup_printf(_("%s canceled the file transfer"),
+		msg = g_strdup_printf(_("%s cancelled the file transfer"),
 				buddy ? purple_buddy_get_alias(buddy) : xfer->who);
 	}
 	purple_xfer_conversation_write(xfer, msg, TRUE);
--- a/libpurple/plugins/joinpart.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/plugins/joinpart.c	Wed Aug 19 00:41:20 2009 +0000
@@ -229,16 +229,17 @@
 
 	frame = purple_plugin_pref_frame_new();
 
-	ppref = purple_plugin_pref_new_with_label(_("Join/Part Hiding Configuration"));
+	ppref = purple_plugin_pref_new_with_label(_("Hide Joins/Parts"));
 	purple_plugin_pref_frame_add(frame, ppref);
 
 	ppref = purple_plugin_pref_new_with_name_and_label(THRESHOLD_PREF,
-	                                                 _("Minimum Room Size"));
+	                                                 /* Translators: Followed by an input request a number of people */
+	                                                 _("For rooms with more than this many people"));
 	purple_plugin_pref_set_bounds(ppref, 0, 1000);
 	purple_plugin_pref_frame_add(frame, ppref);
 
 	ppref = purple_plugin_pref_new_with_name_and_label(DELAY_PREF,
-	                                                 _("User Inactivity Timeout (in minutes)"));
+	                                                 _("If user has not spoken in this many minutes"));
 	purple_plugin_pref_set_bounds(ppref, 0, 8 * 60); /* 8 Hours */
 	purple_plugin_pref_frame_add(frame, ppref);
 
--- a/libpurple/protocols/jabber/buddy.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Wed Aug 19 00:41:20 2009 +0000
@@ -1675,21 +1675,42 @@
 	jabber_buddy_set_invisibility(js, purple_buddy_get_name(buddy), FALSE);
 }
 
-static void jabber_buddy_cancel_presence_notification(PurpleBlistNode *node,
-		gpointer data)
+static void cancel_presence_notification(gpointer data)
 {
 	PurpleBuddy *buddy;
 	PurpleConnection *gc;
 	JabberStream *js;
 
+	buddy = data;
+	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
+	js = purple_connection_get_protocol_data(gc);
+
+	jabber_presence_subscription_set(js, purple_buddy_get_name(buddy), "unsubscribed");
+}
+
+static void
+jabber_buddy_cancel_presence_notification(PurpleBlistNode *node,
+                                          gpointer data)
+{
+	PurpleBuddy *buddy;
+	PurpleAccount *account;
+	PurpleConnection *gc;
+	const gchar *name;
+	char *msg;
+
 	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
 
 	buddy = (PurpleBuddy *) node;
-	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
-	js = purple_connection_get_protocol_data(gc);
+	name = purple_buddy_get_name(buddy);
+	account = purple_buddy_get_account(buddy);
+	gc = purple_account_get_connection(account);
 
-	/* I wonder if we should prompt the user before doing this */
-	jabber_presence_subscription_set(js, purple_buddy_get_name(buddy), "unsubscribed");
+	msg = g_strdup_printf(_("%s will no longer be able to see your status "
+	                        "updates.  Do you want to continue?"), name);
+	purple_request_yes_no(gc, NULL, _("Cancel Presence Notification"),
+	                      msg, 0 /* Yes */, account, name, NULL, buddy,
+	                      cancel_presence_notification, NULL /* Do nothing */);
+	g_free(msg);
 }
 
 static void jabber_buddy_rerequest_auth(PurpleBlistNode *node, gpointer data)
--- a/libpurple/protocols/jabber/jabber.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Wed Aug 19 00:41:20 2009 +0000
@@ -3302,7 +3302,7 @@
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_role,
-	                  _("role &lt;moderator|participant|visitor|none&gt; [nick1] [nick2] ...: Get the users with an role or set users' role with the room."),
+	                  _("role &lt;moderator|participant|visitor|none&gt; [nick1] [nick2] ...: Get the users with a role or set users' role with the room."),
 	                  NULL);
 	jabber_cmds = g_slist_prepend(jabber_cmds, GUINT_TO_POINTER(id));
 
--- a/libpurple/protocols/msn/error.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/msn/error.c	Wed Aug 19 00:41:20 2009 +0000
@@ -198,7 +198,7 @@
 			break;
 
 		case 800:
-			result = _("Friendly name changes too rapidly");
+			result = _("Friendly name is changing too rapidly");
 			break;
 
 		case 910:
--- a/libpurple/protocols/oscar/clientlogin.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/oscar/clientlogin.c	Wed Aug 19 00:41:20 2009 +0000
@@ -156,11 +156,15 @@
 	response_node = xmlnode_from_str(response, response_len);
 	if (response_node == NULL)
 	{
+		char *msg;
 		purple_debug_error("oscar", "startOSCARSession could not parse "
 				"response as XML: %s\n", response);
+		/* Note to translators: %s in this string is a URL */
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_START_OSCAR_SESSION);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_START_OSCAR_SESSION));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		return FALSE;
 	}
 
@@ -175,11 +179,14 @@
 
 	/* Make sure we have a status code */
 	if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) {
+		char *msg;
 		purple_debug_error("oscar", "startOSCARSession response was "
 				"missing statusCode: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_START_OSCAR_SESSION);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_START_OSCAR_SESSION));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		xmlnode_free(response_node);
 		return FALSE;
 	}
@@ -197,10 +204,14 @@
 					  "frequently. Wait ten minutes and try again. If "
 					  "you continue to try, you will need to wait even "
 					  "longer."));
-		else
+		else {
+			char *msg;
+			msg = g_strdup_printf(_("Received unexpected response from %s"),
+					URL_START_OSCAR_SESSION);
 			purple_connection_error_reason(gc,
-					PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-					_("Received unexpected response from " URL_START_OSCAR_SESSION));
+					PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg);
+			g_free(msg);
+		}
 
 		g_free(tmp);
 		xmlnode_free(response_node);
@@ -212,11 +223,14 @@
 	if (data_node == NULL || host_node == NULL ||
 		port_node == NULL || cookie_node == NULL)
 	{
+		char *msg;
 		purple_debug_error("oscar", "startOSCARSession response was missing "
 				"something: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_START_OSCAR_SESSION);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_START_OSCAR_SESSION));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		xmlnode_free(response_node);
 		return FALSE;
 	}
@@ -227,11 +241,14 @@
 	*cookie = xmlnode_get_data_unescaped(cookie_node);
 	if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || cookie == NULL || *cookie == '\0')
 	{
+		char *msg;
 		purple_debug_error("oscar", "startOSCARSession response was missing "
 				"something: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_START_OSCAR_SESSION);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_START_OSCAR_SESSION));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		g_free(*host);
 		g_free(tmp);
 		g_free(*cookie);
@@ -261,8 +278,10 @@
 
 	if (error_message != NULL || len == 0) {
 		gchar *tmp;
-		tmp = g_strdup_printf(_("Error requesting " URL_START_OSCAR_SESSION
-				": %s"), error_message);
+		/* Note to translators: The first %s is a URL, the second is an
+		   error message. */
+		tmp = g_strdup_printf(_("Error requesting %s: %s"),
+				URL_START_OSCAR_SESSION, error_message);
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
@@ -339,11 +358,14 @@
 	response_node = xmlnode_from_str(response, response_len);
 	if (response_node == NULL)
 	{
+		char *msg;
 		purple_debug_error("oscar", "clientLogin could not parse "
 				"response as XML: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_CLIENT_LOGIN);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_CLIENT_LOGIN));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		return FALSE;
 	}
 
@@ -360,11 +382,14 @@
 
 	/* Make sure we have a status code */
 	if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) {
+		char *msg;
 		purple_debug_error("oscar", "clientLogin response was "
 				"missing statusCode: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_CLIENT_LOGIN);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_CLIENT_LOGIN));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		xmlnode_free(response_node);
 		return FALSE;
 	}
@@ -393,10 +418,14 @@
 			purple_connection_error_reason(gc,
 					PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 					_("AOL does not allow your screen name to authenticate here"));
-		} else
+		} else {
+			char *msg;
+			msg = g_strdup_printf(_("Received unexpected response from %s"),
+					URL_CLIENT_LOGIN);
 			purple_connection_error_reason(gc,
-					PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-					_("Received unexpected response from " URL_CLIENT_LOGIN));
+					PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg);
+			g_free(msg);
+		}
 
 		xmlnode_free(response_node);
 		return FALSE;
@@ -407,11 +436,14 @@
 	if (data_node == NULL || secret_node == NULL ||
 		token_node == NULL || tokena_node == NULL)
 	{
+		char *msg;
 		purple_debug_error("oscar", "clientLogin response was missing "
 				"something: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_CLIENT_LOGIN);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_CLIENT_LOGIN));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		xmlnode_free(response_node);
 		return FALSE;
 	}
@@ -422,11 +454,14 @@
 	tmp = xmlnode_get_data_unescaped(hosttime_node);
 	if (*token == NULL || **token == '\0' || *secret == NULL || **secret == '\0' || tmp == NULL || *tmp == '\0')
 	{
+		char *msg;
 		purple_debug_error("oscar", "clientLogin response was missing "
 				"something: %s\n", response);
+		msg = g_strdup_printf(_("Received unexpected response from %s"),
+				URL_CLIENT_LOGIN);
 		purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
-				_("Received unexpected response from " URL_CLIENT_LOGIN));
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg);
+		g_free(msg);
 		g_free(*token);
 		g_free(*secret);
 		g_free(tmp);
@@ -458,8 +493,8 @@
 
 	if (error_message != NULL || len == 0) {
 		gchar *tmp;
-		tmp = g_strdup_printf(_("Error requesting " URL_CLIENT_LOGIN
-				": %s"), error_message);
+		tmp = g_strdup_printf(_("Error requesting %s: %s"),
+				URL_CLIENT_LOGIN, error_message);
 		purple_connection_error_reason(gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
 		g_free(tmp);
--- a/libpurple/protocols/oscar/oscar.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Aug 19 00:41:20 2009 +0000
@@ -6303,6 +6303,44 @@
 }
 
 static void
+oscar_close_directim(gpointer object, gpointer ignored)
+{
+	PurpleBlistNode *node;
+	PurpleBuddy *buddy;
+	PurpleAccount *account;
+	PurpleConnection *gc;
+	PurpleConversation *conv;
+	OscarData *od;
+	PeerConnection *conn;
+	const char *name;
+
+	node = object;
+
+	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
+
+	buddy = (PurpleBuddy*)node;
+	name = purple_buddy_get_name(buddy);
+	account = purple_buddy_get_account(buddy);
+	gc = purple_account_get_connection(account);
+	od = gc->proto_data;
+	conn = peer_connection_find_by_type(od, name, OSCAR_CAPABILITY_DIRECTIM);
+
+	if (conn != NULL)
+	{
+		if (!conn->ready)
+			aim_im_sendch2_cancel(conn);
+
+		peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL);
+
+		/* OSCAR_DISCONNECT_LOCAL_CLOSED doesn't write anything to the convo
+		 * window. Let the user know that we canceled the Direct IM. */
+		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
+		purple_conversation_write(conv, NULL, _("You closed the connection."),
+		                          PURPLE_MESSAGE_SYSTEM, time(NULL));
+	}
+}
+
+static void
 oscar_get_aim_info_cb(PurpleBlistNode *node, gpointer ignore)
 {
 	PurpleBuddy *buddy;
@@ -6365,11 +6403,23 @@
 		oscar_util_name_compare(purple_account_get_username(account), bname) &&
 		PURPLE_BUDDY_IS_ONLINE(buddy))
 	{
+		PeerConnection *conn;
+		conn = peer_connection_find_by_type(od, bname, OSCAR_CAPABILITY_DIRECTIM);
+
 		if (userinfo->capabilities & OSCAR_CAPABILITY_DIRECTIM)
 		{
-			act = purple_menu_action_new(_("Direct IM"),
-			                           PURPLE_CALLBACK(oscar_ask_directim),
-			                           NULL, NULL);
+			if (conn)
+			{
+				act = purple_menu_action_new(_("Cancel Direct IM"),
+				                          PURPLE_CALLBACK(oscar_close_directim),
+				                          NULL, NULL);
+			}
+			else
+			{
+				act = purple_menu_action_new(_("Direct IM"),
+				                          PURPLE_CALLBACK(oscar_ask_directim),
+				                          NULL, NULL);
+			}
 			menu = g_list_prepend(menu, act);
 		}
 #if 0
--- a/libpurple/protocols/qq/send_file.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/qq/send_file.c	Wed Aug 19 00:41:20 2009 +0000
@@ -730,7 +730,7 @@
 	*/
 	filename = g_path_get_basename(purple_xfer_get_local_filename(qd->xfer));
 	msg = g_strdup_printf
-		(_("%d canceled the transfer of %s"),
+		(_("%d cancelled the transfer of %s"),
 		 sender_uid, filename);
 
 	purple_notify_warning (gc, _("File Send"), msg, NULL);
--- a/libpurple/protocols/yahoo/libymsg.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/libpurple/protocols/yahoo/libymsg.c	Wed Aug 19 00:41:20 2009 +0000
@@ -2077,21 +2077,24 @@
 		if (!purple_account_get_remember_password(account))
 			purple_account_set_password(account, NULL);
 
-		msg = g_strdup(_("Incorrect password"));
+		msg = g_strdup(_("Invalid username or password"));
 		reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
 		break;
 	case 14:
-		msg = g_strdup(_("Your account is locked, please log in to the Yahoo! website."));
+		msg = g_strdup(_("Your account has been locked due to too many failed login attempts."
+					"  Please try logging into the Yahoo! website."));
 		reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
 		break;
 	case 52:
 		/* See #9660. As much as we know, reconnecting shouldn't hurt */
 		purple_debug_info("yahoo", "Got error 52, Set to autoreconnect\n");
-		msg = g_strdup_printf(_("Unknown error"));
+		msg = g_strdup_printf(_("Unknown error 52.  Reconnecting should fix this."));
 		reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
 		break;
 	case 1013:
-		msg = g_strdup(_("Invalid username"));
+		msg = g_strdup(_("Error 1013: The username you have entered is invalid."
+					"  The most common cause of this error is entering your e-mail"
+					" address instead of your Yahoo! ID."));
 		reason = PURPLE_CONNECTION_ERROR_INVALID_USERNAME;
 		break;
 	default:
--- a/pidgin/gtkblist-theme.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/pidgin/gtkblist-theme.c	Wed Aug 19 00:41:20 2009 +0000
@@ -373,7 +373,7 @@
 	g_object_class_install_property(obj_class, PROP_BACKGROUND_COLOR, pspec);
 
 	pspec = g_param_spec_pointer("layout", _("Layout"),
-			_("The layout of icons, name, and status of the blist"),
+			_("The layout of icons, name, and status of the buddy list"),
 			G_PARAM_READWRITE);
 
 	g_object_class_install_property(obj_class, PROP_LAYOUT, pspec);
--- a/pidgin/gtkblist.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/pidgin/gtkblist.c	Wed Aug 19 00:41:20 2009 +0000
@@ -7137,7 +7137,7 @@
 	                          data->chat_data.rq_data.sg, data->group_combo,
 	                          TRUE, NULL);
 
-	data->autojoin = gtk_check_button_new_with_mnemonic(_("Auto_join when account becomes online."));
+	data->autojoin = gtk_check_button_new_with_mnemonic(_("Auto_join when account connects."));
 	data->persistent = gtk_check_button_new_with_mnemonic(_("_Remain in chat after window is closed."));
 	gtk_box_pack_start(GTK_BOX(vbox), data->autojoin, FALSE, FALSE, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), data->persistent, FALSE, FALSE, 0);
--- a/pidgin/gtkconv.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/pidgin/gtkconv.c	Wed Aug 19 00:41:20 2009 +0000
@@ -959,6 +959,12 @@
 }
 
 static void
+menu_join_chat_cb(gpointer data, guint action, GtkWidget *widget)
+{
+	pidgin_blist_joinchat_show();
+}
+
+static void
 savelog_writefile_cb(void *user_data, const char *filename)
 {
 	PurpleConversation *conv = (PurpleConversation *)user_data;
@@ -3133,6 +3139,8 @@
 
 	{ N_("/Conversation/New Instant _Message..."), "<CTL>M", menu_new_conv_cb,
 			0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
+	{ N_("/Conversation/Join a _Chat..."), "<CTL>C", menu_join_chat_cb,
+			0, "<StockItem>", PIDGIN_STOCK_CHAT },
 
 	{ "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
 
--- a/pidgin/gtkdialogs.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/pidgin/gtkdialogs.c	Wed Aug 19 00:41:20 2009 +0000
@@ -170,9 +170,7 @@
 	{N_("Esperanto"),           "eo", "Stéphane Fillod", "fillods@users.sourceforge.net"},
 	{N_("Spanish"),             "es", "Javier Fernández-Sanguino Peña", "jfs@debian.org"},
 	{N_("Estonian"),            "et", "Ivar Smolin", "okul@linux.ee"},
-	{N_("Euskera(Basque)"),     "eu", "Mikel Pascual Aldabaldetreku", "mikel.paskual@gmail.com"},
-	{N_("Euskera(Basque)"),     "eu", "Iñaki Larrañaga Murgoitio", "dooteo@zundan.com"},
-	{N_("Euskera(Basque)"),     "eu", "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"},
+	{N_("Basque"),              "eu", "Mikel Pascual Aldabaldetreku", "mikel.paskual@gmail.com"},
 	{N_("Persian"),             "fa", "Elnaz Sarbar", "elnaz@farsiweb.info"},
 	{N_("Persian"),             "fa", "Meelad Zakaria", "meelad@farsiweb.info"},
 	{N_("Persian"),             "fa", "Roozbeh Pournader ", "roozbeh@farsiweb.info"},
@@ -257,6 +255,8 @@
 	{N_("Spanish"),             "es", "Nicolás Lichtmaier", NULL},
 	{N_("Spanish"),             "es", "Amaya Rodrigo", NULL},
 	{N_("Spanish"),             "es", "Alejandro G Villar", NULL},
+	{N_("Basque"),              "eu", "Iñaki Larrañaga Murgoitio", "dooteo@zundan.com"},
+	{N_("Basque"),              "eu", "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"},
 	{N_("Finnish"),             "fi", "Arto Alakulju", NULL},
 	{N_("Finnish"),             "fi", "Tero Kuusela", NULL},
 	{N_("French"),              "fr", "Sébastien François", NULL},
@@ -472,7 +472,13 @@
 				"http://developer.pidgin.im/wiki/FAQ</A><BR/><BR/>"));
 	g_string_append_printf(str, _("<FONT SIZE=\"4\">Help via e-mail:</FONT>"
 				" <A HREF=\"mailto:support@pidgin.im\">support@pidgin.im</A>"
-				"<BR/><BR/>"));
+				" (This is a"
+				" <A HREF=\"http://pidgin.im/cgi-bin/mailman/listinfo/support\">"
+				"mailing list</A>, and messages sent here are"
+				" <A HREF=\"http://pidgin.im/pipermail/support/\">publicly"
+				" archived!</A>  Furthermore, we do <I><B>not</B></I> support"
+				" MXit, Facebook, Skype, or any other third-party plugins on"
+				" this list.<BR/><BR/>"));
 	g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC Channel:</FONT> "
 				"#pidgin on irc.freenode.net<BR><BR>"));
 	g_string_append_printf(str, _("<FONT SIZE=\"4\">XMPP MUC:</FONT> "
--- a/pidgin/gtkmain.c	Wed Aug 19 00:41:06 2009 +0000
+++ b/pidgin/gtkmain.c	Wed Aug 19 00:41:20 2009 +0000
@@ -406,34 +406,34 @@
 	if (terse) {
 		text = g_strdup_printf(_("%s %s. Try `%s -h' for more information.\n"), PIDGIN_NAME, DISPLAY_VERSION, name);
 	} else {
+		GString *str = g_string_new(NULL);
+		g_string_append_printf(str, "%s %s\n", PIDGIN_NAME, DISPLAY_VERSION);
+		g_string_append_printf(str, _("Usage: %s [OPTION]...\n\n"), name);
+		g_string_append_printf(str, "  -c, --config=DIR    %s\n",
+				_("use DIR for config files"));
+		g_string_append_printf(str, "  -d, --debug         %s\n",
+				_("print debugging messages to stdout"));
+		g_string_append_printf(str, "  -f, --force-online  %s\n",
+				_("force online, regardless of network status"));
+		g_string_append_printf(str, "  -h, --help          %s\n",
+				_("display this help and exit"));
+		g_string_append_printf(str, "  -m, --multiple      %s\n",
+				_("allow multiple instances"));
+		g_string_append_printf(str, "  -n, --nologin       %s\n",
+				_("don't automatically login"));
+		g_string_append_printf(str, "  -l, --login[=NAME]  %s\n",
+				_("enable specified account(s) (optional argument NAME\n"
+				  "                      "
+				  "specifies account(s) to use, separated by commas."));
+		g_string_append_printf(str, "                      %s\n",
+				_("Without this only the first account will be enabled)."));
 #ifndef WIN32
-		text = g_strdup_printf(_("%s %s\n"
-		       "Usage: %s [OPTION]...\n\n"
-		       "  -c, --config=DIR    use DIR for config files\n"
-		       "  -d, --debug         print debugging messages to stdout\n"
-		       "  -f, --force-online  force online, regardless of network status\n"
-		       "  -h, --help          display this help and exit\n"
-		       "  -m, --multiple      do not ensure single instance\n"
-		       "  -n, --nologin       don't automatically login\n"
-		       "  -l, --login[=NAME]  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).\n"
-		       "  --display=DISPLAY   X display to use\n"
-		       "  -v, --version       display the current version and exit\n"), PIDGIN_NAME, DISPLAY_VERSION, name);
-#else
-		text = g_strdup_printf(_("%s %s\n"
-		       "Usage: %s [OPTION]...\n\n"
-		       "  -c, --config=DIR    use DIR for config files\n"
-		       "  -d, --debug         print debugging messages to stdout\n"
-		       "  -f, --force-online  force online, regardless of network status\n"
-		       "  -h, --help          display this help and exit\n"
-		       "  -m, --multiple      do not ensure single instance\n"
-		       "  -n, --nologin       don't automatically login\n"
-		       "  -l, --login[=NAME]  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).\n"
-		       "  -v, --version       display the current version and exit\n"), PIDGIN_NAME, DISPLAY_VERSION, name);
-#endif
+		g_string_append_printf(str, "  --display=DISPLAY   %s\n",
+				_("X display to use"));
+#endif /* !WIN32 */
+		g_string_append_printf(str, "  -v, --version       %s\n",
+				_("display the current version and exit"));
+		text = g_string_free(str, FALSE);
 	}
 
 	purple_print_utf8_to_console(stdout, text);