changeset 29778:cece09dbb119

merge of 'e9d34ab5e47f22b35fd2d69d61a2c943cc0653db' and 'fc3d5c2a3920e0875ac235415cea9fc7f5ed780c'
author Mark Doliner <mark@kingant.net>
date Thu, 18 Feb 2010 08:10:58 +0000
parents 46abe1203e0b (diff) 4e42f18df200 (current diff)
children 4c266d9c17eb
files ChangeLog
diffstat 15 files changed, 457 insertions(+), 466 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Feb 16 09:14:54 2010 +0000
+++ b/ChangeLog	Thu Feb 18 08:10:58 2010 +0000
@@ -44,23 +44,24 @@
 	* Less likely to send messages to a contact's idle/inactive resource.
 	  Previously, if a message was received from a specific resource,
 	  responses would be sent to that resource until either it went offline
-	  or a message is received from another resource.  Now, messages are sent
-	  to the bare JID upon receipt of any presence change from the contact.
+	  or a message is received from another resource.  Now, messages are
+	  sent to the bare JID upon receipt of any presence change from the
+	  contact.
 	* Added support for the SCRAM-SHA-1 SASL mechanism.  This is only
 	  available when built without Cyrus SASL support.
 	* When getting info on a domain-only (server) JID, show uptime
-	  (when given by the result of the "last query") and don't show status as
-	  offline.
+	  (when given by the result of the "last query") and don't show status
+	  as offline.
 	* Fix getting info on your own JID.
-	* Wrap XHTML messages in <p>, as described in XEP-0071, for compatibility
-	  with some clients.
+	* Wrap XHTML messages in <p>, as described in XEP-0071, for
+	  compatibility with some clients.
 	* Don't do an SRV lookup for a STUN server associated with the account
 	  if one is already set globally in prefs.
-	* Don't send custom smileys larger than the recommended maximum object size
-	  specified in the BoB XEP.   This prevents a client from being
+	* Don't send custom smileys larger than the recommended maximum object
+	  size specified in the BoB XEP.   This prevents a client from being
 	  disconnected by servers that dislike overly-large stanzas.
-	* Fix receiving messages without markup over an Openfire BOSH connection
-	  (forcibly put the stanzas in the jabber:client namespace).
+	* Fix receiving messages without markup over an Openfire BOSH
+	  connection (forcibly put the stanzas in the jabber:client namespace).
 	* The default value for the file transfer proxies is automatically
 	  updated when an account connects, if it is still the old (broken)
 	  default (from 'proxy.jabber.org' to 'proxy.eu.jabber.org').
@@ -99,7 +100,8 @@
 	  tooltips will show for all tabs.
 	* The File Transfers and Debug Window windows are no longer created as
 	  dialogs.  These windows should now have minimize buttons in many
-	  environments in which they were previously missing (including Windows).
+	  environments in which they were previously missing
+	  (including Windows).
 	* Smiley themes with Windows line endings no longer cause theme
 	  descriptions not to be displayed in the theme selector.
 
@@ -137,11 +139,11 @@
 	* Actually emit the hold signal for media calls.
 	* Fix building the GnuTLS plugin with older versions of GnuTLS.
 	* Fix DNS TXT query resolution.
-	* Don't send Proxy-Authorization headers to HTTP proxy servers until we've
-	  received a "407 Proxy Authentication Required" response from the server.
-	  (thecrux)
-	* Added "MXit" protocol plugin, supported and maintained by the MXit folks
-	  themselves (MXit Lifestyle (Pty) Ltd.)
+	* Don't send Proxy-Authorization headers to HTTP proxy servers until
+	  we've received a "407 Proxy Authentication Required" response from
+	  the server.  (thecrux)
+	* Added "MXit" protocol plugin, supported and maintained by the MXit
+	  folks themselves (MXit Lifestyle (Pty) Ltd.)
 
 	General:
 	* New 'plugins' sub-command to 'debug' command (i.e. '/debug plugins')
@@ -172,14 +174,14 @@
 	  as it has probably been reset.
 
 	XMPP:
-	* Users connecting to Google Talk now have an "Initiate Chat" context menu
-	  option for their buddies.  (Eion Robb)
+	* Users connecting to Google Talk now have an "Initiate Chat" context
+	  menu option for their buddies.  (Eion Robb)
 	* Fix a crash when attempting to validate an invalid JID.
 	* Resolve an issue when connecting to iChat Server when no resource
 	  is specified.
 	* Try to automatically find a STUN server by using an SRV lookup on the
-	  account's domain, and use that for voice and video if found and the user
-	  didn't set one manually in prefs.
+	  account's domain, and use that for voice and video if found and the
+	  user didn't set one manually in prefs.
 	* Fix a crash when adding a buddy without an '@'.
 	* Don't show the option to send a file to a buddy if we know for certain
 	  they don't support any file transfer method supported by libpurple.
@@ -203,23 +205,23 @@
 	* The userlist in a multiuser chat can be styled via gtkrc by using the
 	  widget name "pidgin_conv_userlist". (Heiko Schmitt)
 	* Add a hold button to the media window.
-	* Fix a bug where the conversation backlog stops scrolling in a very busy
-	  chat room.
+	* Fix a bug where the conversation backlog stops scrolling in a very
+	  busy chat room.
 	* In the Conversation "Send To" menu, offline buddies appear grayed
 	  out (but are still selectable).  Previously, only offline buddies on
 	  accounts that do not support offline messaging appeared grayed out.
 
 	Pidgin Preference and Preference Window Changes:
 	* Removed the "Use font from theme" and "Conversation Font" preferences
-	  for everyone except Windows users.  The font can be controlled from the
-	  Pidgin GTK+ Theme Control plugin.
+	  for everyone except Windows users.  The font can be controlled from
+	  the Pidgin GTK+ Theme Control plugin.
 	* Tabs in the Preferences window are now on the left side.
 	* The Browser tab is now visible for GNOME users.
 	* Added a Proxy tab shown no matter what environment Pidgin runs in.
-	* The Browser and Proxy tabs show appropriate GNOME-specific messages and
-	  allow launching the correct applications to change the relevant GNOME
-	  preferences if found.  These were previously together on the Network
-	  tab.
+	* The Browser and Proxy tabs show appropriate GNOME-specific messages
+	  and allow launching the correct applications to change the relevant
+	  GNOME preferences if found.  These were previously together on the
+	  Network tab.
 	* Moved the port range spin buttons on the Network tab to be beside the
 	  checkbox that enables/disables them.
 	* Reorganized preferences on the Status/Idle tab to have one less
@@ -229,10 +231,10 @@
 	* Moved Buddy List Theme and Status Icon Theme selectors from Interface
 	  tab to Themes tab.
 	* Moved Sound Theme selector from Sounds tab to Themes tab.
-	* Changed the Smiley Theme selector to be consistent with the other theme
-	  selectors.
-	* Rearranged tabs such that Interface is first and all remaining tabs are
-	  alphabetized in English.
+	* Changed the Smiley Theme selector to be consistent with the other
+	  theme selectors.
+	* Rearranged tabs such that Interface is first and all remaining tabs
+	  are alphabetized in English.
 
 version 2.6.3 (10/16/2009):
 	General:
@@ -272,16 +274,17 @@
 	  properly.  In addition, it is no longer possible to add buddies of
 	  the form "room@conference.example.net/User", where
 	  room@conference.example.net is a MUC.
-	* Don't crash when receiving "smileyfied" XHTML-IM from clients that don't
-	  support bits of binary (ie. when getting an empty <data/> in return)
+	* Don't crash when receiving "smileyfied" XHTML-IM from clients that
+	  don't support bits of binary (ie. when getting an empty <data/> in
+	  return)
 	* Fix bug where SSL/TLS was not required even though the
 	  "require SSL/TLS" preference checked when connecting to servers
 	  that use the older iq-based authentication.  (CVE-2009-3026)
 
 	Yahoo!/Yahoo! JAPAN:
-	* Accounts now have "Use account proxy for SSL connections" option.  This
-	  option force-overrides the account specific proxy settings for SSL
-	  connections only and instead uses the global proxy configuration.
+	* Accounts now have "Use account proxy for SSL connections" option.
+	  This option force-overrides the account specific proxy settings for
+	  SSL connections only and instead uses the global proxy configuration.
 
 	Finch:
 	* Properly detect libpanel on OpenBSD.  (Brad Smith)
@@ -323,8 +326,8 @@
 	* Various memory leaks fixed as reported by Josh Mueller.
 	* Properly handle an IRC buddy appearing in multiple groups.
 	* Escape HTML entities in usernames when written with the HTML logger.
-	* Do not display MySpace status changes as incoming IMs.  (Mark Doliner and
-	  Justin Williams)
+	* Do not display MySpace status changes as incoming IMs.  (Mark Doliner
+	  and Justin Williams)
 
 	DNS:
 	* DNS servers are re-read when DNS queries fail in case the system has
@@ -335,32 +338,34 @@
 	  address configured.
 	* Fix a leak when the UI provides its own DNS resolving UI op.
 	  (Aman Gupta)
-	* Don't fork a DNS resolver process to resolve IP addresses.  (Aman Gupta)
-	* Internationalized Domain Names are supported when libpurple is compiled
-	  against the GNU IDN library.
+	* Don't fork a DNS resolver process to resolve IP addresses.
+	  (Aman Gupta)
+	* Internationalized Domain Names are supported when libpurple is
+	  compiled against the GNU IDN library.
 
 	Environment Variables:
 	* GnuTLS logging (disabled by default) can be controlled through the
 	  PURPLE_GNUTLS_DEBUG environment variable, which is an integer between
 	  0 and 9 (higher is more verbose). Higher values may reveal sensitive
 	  information.
-	* PURPLE_VERBOSE_DEBUG environment variable.  Currently, this is an "on" or
-	  "off" variable.  Set it to any value to turn it on and unset it to turn
-	  it off.  This will optionally be used to only show less useful debug
-	  information on an as-needed basis.
-	* PURPLE_LEAKCHECK_HELP environment variable.  Currently, this is an "on"
+	* PURPLE_VERBOSE_DEBUG environment variable.  Currently, this is an "on"
 	  or "off" variable.  Set it to any value to turn it on and unset it to
-	  turn it off.  This will be used to perform various actions that are
-	  useful when running libpurple inside of Valgrind or similar programs.
-	  Currently, it keeps plugins in memory, allowing Valgrind to perform
-	  symbol resolution of leak traces at shutdown.
+	  turn it off.  This will optionally be used to only show less useful
+	  debug information on an as-needed basis.
+	* PURPLE_LEAKCHECK_HELP environment variable.  Currently, this is an
+	  "on" or "off" variable.  Set it to any value to turn it on and unset
+	  it to turn it off.  This will be used to perform various actions
+	  that are useful when running libpurple inside of Valgrind or similar
+	  programs.  Currently, it keeps plugins in memory, allowing Valgrind
+	  to perform symbol resolution of leak traces at shutdown.
 
 	AIM and ICQ:
 	* Preliminary support for a new authentication scheme called
 	  "clientLogin."
 	* Fixed a bug where your away message sometimes would not get set when
 	  you first sign on.
-	* Make sure links in your away messages show up as links to other people.
+	* Make sure links in your away messages show up as links to other
+	  people.
 	* For ICQ, Never change the privacy setting specified by the user.
 
 	Gadu-Gadu:
@@ -379,15 +384,16 @@
 	  Topper, and Elliott Sales de Andrade)
 	* Show the invite message for buddies that requested authorization
 	  from you on MSN.
-	* Support sending an invite message to buddies when requesting authorization
-	  from them on MSN.
+	* Support sending an invite message to buddies when requesting
+	  authorization from them on MSN.
 	* Timeout switchboard connections aggressively (60 seconds).
 
 	XMPP:
-	* Voice & Video support with Jingle (XEP-0166, 0167, 0176, & 0177), voice
-	  support with GTalk and voice and video support with the GMail web
-	  client. (Mike "Maiku" Ruprecht)
-	* Added a Service Discovery Browser plugin for Pidgin. (Andrei Mozzhuhin)
+	* Voice & Video support with Jingle (XEP-0166, 0167, 0176, & 0177),
+	  voice support with GTalk and voice and video support with the GMail
+	  web client. (Mike "Maiku" Ruprecht)
+	* Added a Service Discovery Browser plugin for Pidgin.
+	  (Andrei Mozzhuhin)
 	* Support for in-band bytestreams for file transfers (XEP-0047). (Marcus
 	  Lundblad)
 	* Support for sending and receiving attentions (equivalent to "buzz"
@@ -404,28 +410,30 @@
 	* Better support for receiving remote users' nicknames.
 	* /affiliate and /role will now list the room members with the specified
 	  affiliation/role if possible. (Andrei Mozzhuhin)
-	* Put section breaks between resources in "Get Info" to improve readability.
-	* Silently remove invalid XML 1.0 entities (e.g. ASCII control characters)
-	  from sent messages.
+	* Put section breaks between resources in "Get Info" to improve
+	  readability.
+	* Silently remove invalid XML 1.0 entities (e.g. ASCII control
+	  characters) from sent messages.
 	* XHTML markup is only included in outgoing messages when the message
 	  contains formatting.
-	* Show when the user was last logged in when doing "Get Info" on an offline
-	  buddy, provided the server supports it.
+	* Show when the user was last logged in when doing "Get Info" on an
+	  offline buddy, provided the server supports it.
 	* Support custom smileys in MUCs (only when all participants support the
-	  "Bits of Binary" extension, and a maximum of 10 participants are in the
-	  chat to avoid getting too many fetch requests).
+	  "Bits of Binary" extension, and a maximum of 10 participants are in
+	  the chat to avoid getting too many fetch requests).
 	* Fix an issue with Jabber (pre-XMPP) servers and the user's preference
 	  to require SSL not being respected.
 	* Fix an issue where Cyrus SASL DIGEST MD5 authentication might fail if
 	  the username, password, or realm (the JID domain) contain non-ASCII
 	  characters.
-	* Show emblem for mobile, handheld, and web clients and bots (if the other
-	  client supports it).
-	* Google Talk mail notifications should now work for people for whom they
-	  inexplicably did not.  (Thanks to yukam for determining the reason)
+	* Show emblem for mobile, handheld, and web clients and bots (if the
+	  other client supports it).
+	* Google Talk mail notifications should now work for people for whom
+	  they inexplicably did not.  (Thanks to yukam for determining the
+	  reason)
 	* New XMPP and Google Talk accounts require SSL by default.
-	* Display kicks (and the reasons given) in chat rooms when an occupant is
-	  kicked.
+	* Display kicks (and the reasons given) in chat rooms when an occupant
+	  is kicked.
 	* Fix issues with case-sensitivity of XMPP roster and case-insensitive
 	  Purple groups.
 	* For contacts who advertise Entity Capabilities, only send rich text
--- a/libpurple/certificate.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/certificate.c	Thu Feb 18 08:10:58 2010 +0000
@@ -874,7 +874,6 @@
 #else
 # ifdef SSL_CERTIFICATES_DIR
 		x509_ca_paths = g_list_append(NULL, g_strdup(SSL_CERTIFICATES_DIR));
-# else
 # endif
 		x509_ca_paths = g_list_append(x509_ca_paths,
 			g_build_filename(DATADIR, "purple", "ca-certs", NULL));
--- a/libpurple/protocols/jabber/buddy.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Thu Feb 18 08:10:58 2010 +0000
@@ -57,6 +57,36 @@
 	gchar *last_message;
 } JabberBuddyInfo;
 
+static void
+jabber_buddy_resource_free(JabberBuddyResource *jbr)
+{
+	g_return_if_fail(jbr != NULL);
+
+	jbr->jb->resources = g_list_remove(jbr->jb->resources, jbr);
+
+	while(jbr->commands) {
+		JabberAdHocCommands *cmd = jbr->commands->data;
+		g_free(cmd->jid);
+		g_free(cmd->node);
+		g_free(cmd->name);
+		g_free(cmd);
+		jbr->commands = g_list_delete_link(jbr->commands, jbr->commands);
+	}
+
+	while (jbr->caps.exts) {
+		g_free(jbr->caps.exts->data);
+		jbr->caps.exts = g_list_delete_link(jbr->caps.exts, jbr->caps.exts);
+	}
+
+	g_free(jbr->name);
+	g_free(jbr->status);
+	g_free(jbr->thread_id);
+	g_free(jbr->client.name);
+	g_free(jbr->client.version);
+	g_free(jbr->client.os);
+	g_free(jbr);
+}
+
 void jabber_buddy_free(JabberBuddy *jb)
 {
 	g_return_if_fail(jb != NULL);
@@ -91,6 +121,10 @@
 	return jb;
 }
 
+/* Returns -1 if a is a higher priority resource than b, or is
+ * "more available" than b.  0 if they're the same, and 1 if b is
+ * higher priority/more available than a.
+ */
 static gint resource_compare_cb(gconstpointer a, gconstpointer b)
 {
 	const JabberBuddyResource *jbra = a;
@@ -98,9 +132,10 @@
 	JabberBuddyState state_a, state_b;
 
 	if (jbra->priority != jbrb->priority)
-		return jbra->priority > jbrb->priority ? 1 : -1;
+		return jbra->priority > jbrb->priority ? -1 : 1;
 
 	/* Fold the states for easier comparison */
+	/* TODO: Differentiate online/chat and away/dnd? */
 	switch (jbra->state) {
 		case JABBER_BUDDY_STATE_ONLINE:
 		case JABBER_BUDDY_STATE_CHAT:
@@ -146,105 +181,74 @@
 			return 0;
 		else if ((jbra->idle && !jbrb->idle) ||
 				(jbra->idle && jbrb->idle && jbra->idle < jbrb->idle))
-			return -1;
+			return 1;
 		else
-			return 1;
+			return -1;
 	}
 
 	if (state_a == JABBER_BUDDY_STATE_ONLINE)
-		return 1;
+		return -1;
 	else if (state_a == JABBER_BUDDY_STATE_AWAY &&
 				(state_b == JABBER_BUDDY_STATE_XA ||
 				 state_b == JABBER_BUDDY_STATE_UNAVAILABLE ||
 				 state_b == JABBER_BUDDY_STATE_UNKNOWN))
-		return 1;
+		return -1;
 	else if (state_a == JABBER_BUDDY_STATE_XA &&
 				(state_b == JABBER_BUDDY_STATE_UNAVAILABLE ||
 				 state_b == JABBER_BUDDY_STATE_UNKNOWN))
-		return 1;
+		return -1;
 	else if (state_a == JABBER_BUDDY_STATE_UNAVAILABLE &&
 				state_b == JABBER_BUDDY_STATE_UNKNOWN)
-		return 1;
+		return -1;
 
-	return -1;
+	return 1;
 }
 
 JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb,
 		const char *resource)
 {
-	JabberBuddyResource *jbr = NULL;
 	GList *l;
 
-	if(!jb)
+	if (!jb)
 		return NULL;
 
-	for(l = jb->resources; l; l = l->next)
+	if (resource == NULL)
+		return jb->resources ? jb->resources->data : NULL;
+
+	for (l = jb->resources; l; l = l->next)
 	{
-		JabberBuddyResource *tmp = (JabberBuddyResource *) l->data;
-		if (!jbr && !resource) {
-			jbr = tmp;
-		} else if (!resource) {
-			if (resource_compare_cb(tmp, jbr) > 0)
-				jbr = tmp;
-		} else if(tmp->name) {
-			if(!strcmp(tmp->name, resource)) {
-				jbr = tmp;
-				break;
-			}
-		}
+		JabberBuddyResource *jbr = l->data;
+		if (g_str_equal(resource, jbr->name))
+			return jbr;
 	}
 
-	return jbr;
+	return NULL;
 }
 
 JabberBuddyResource *jabber_buddy_track_resource(JabberBuddy *jb, const char *resource,
 		int priority, JabberBuddyState state, const char *status)
 {
+	/* TODO: Optimization: Only reinsert if priority+state changed */
 	JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, resource);
-	if(!jbr) {
+	if (jbr) {
+		jb->resources = g_list_remove(jb->resources, jbr);
+	} else {
 		jbr = g_new0(JabberBuddyResource, 1);
 		jbr->jb = jb;
 		jbr->name = g_strdup(resource);
 		jbr->capabilities = JABBER_CAP_NONE;
 		jbr->tz_off = PURPLE_NO_TZ_OFF;
-		jb->resources = g_list_append(jb->resources, jbr);
 	}
 	jbr->priority = priority;
 	jbr->state = state;
 	g_free(jbr->status);
 	jbr->status = g_strdup(status);
 
+	jb->resources = g_list_insert_sorted(jb->resources, jbr,
+	                                     resource_compare_cb);
 	return jbr;
 }
 
-void jabber_buddy_resource_free(JabberBuddyResource *jbr)
-{
-	g_return_if_fail(jbr != NULL);
-
-	jbr->jb->resources = g_list_remove(jbr->jb->resources, jbr);
-
-	while(jbr->commands) {
-		JabberAdHocCommands *cmd = jbr->commands->data;
-		g_free(cmd->jid);
-		g_free(cmd->node);
-		g_free(cmd->name);
-		g_free(cmd);
-		jbr->commands = g_list_delete_link(jbr->commands, jbr->commands);
-	}
-
-	if (jbr->caps.exts) {
-		g_list_foreach(jbr->caps.exts, (GFunc)g_free, NULL);
-		g_list_free(jbr->caps.exts);
-	}
-	g_free(jbr->name);
-	g_free(jbr->status);
-	g_free(jbr->thread_id);
-	g_free(jbr->client.name);
-	g_free(jbr->client.version);
-	g_free(jbr->client.os);
-	g_free(jbr);
-}
-
 void jabber_buddy_remove_resource(JabberBuddy *jb, const char *resource)
 {
 	JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, resource);
@@ -797,6 +801,8 @@
 		jbr = jabber_buddy_find_resource(jbi->jb, resource_name);
 		add_jbr_info(jbi, resource_name, jbr);
 	} else {
+		/* TODO: This is in priority-ascending order (lowest prio first), because
+		 * everything is prepended.  Is that ok? */
 		for (resources = jbi->jb->resources; resources; resources = resources->next) {
 			jbr = resources->data;
 
@@ -1909,116 +1915,6 @@
 }
 
 
-const char *
-jabber_buddy_state_get_name(JabberBuddyState state)
-{
-	switch(state) {
-		case JABBER_BUDDY_STATE_UNKNOWN:
-			return _("Unknown");
-		case JABBER_BUDDY_STATE_ERROR:
-			return _("Error");
-		case JABBER_BUDDY_STATE_UNAVAILABLE:
-			return _("Offline");
-		case JABBER_BUDDY_STATE_ONLINE:
-			return _("Available");
-		case JABBER_BUDDY_STATE_CHAT:
-			return _("Chatty");
-		case JABBER_BUDDY_STATE_AWAY:
-			return _("Away");
-		case JABBER_BUDDY_STATE_XA:
-			return _("Extended Away");
-		case JABBER_BUDDY_STATE_DND:
-			return _("Do Not Disturb");
-	}
-
-	return _("Unknown");
-}
-
-JabberBuddyState jabber_buddy_status_id_get_state(const char *id) {
-	if(!id)
-		return JABBER_BUDDY_STATE_UNKNOWN;
-	if(!strcmp(id, "available"))
-		return JABBER_BUDDY_STATE_ONLINE;
-	if(!strcmp(id, "freeforchat"))
-		return JABBER_BUDDY_STATE_CHAT;
-	if(!strcmp(id, "away"))
-		return JABBER_BUDDY_STATE_AWAY;
-	if(!strcmp(id, "extended_away"))
-		return JABBER_BUDDY_STATE_XA;
-	if(!strcmp(id, "dnd"))
-		return JABBER_BUDDY_STATE_DND;
-	if(!strcmp(id, "offline"))
-		return JABBER_BUDDY_STATE_UNAVAILABLE;
-	if(!strcmp(id, "error"))
-		return JABBER_BUDDY_STATE_ERROR;
-
-	return JABBER_BUDDY_STATE_UNKNOWN;
-}
-
-const struct {
-	const char *name;
-	JabberBuddyState state;
-} show_state_pairs[] = {
-	{ "available", JABBER_BUDDY_STATE_ONLINE },
-	{ "chat",      JABBER_BUDDY_STATE_CHAT },
-	{ "away",      JABBER_BUDDY_STATE_AWAY },
-	{ "xa",        JABBER_BUDDY_STATE_XA },
-	{ "dnd",       JABBER_BUDDY_STATE_DND },
-	{ "offline",   JABBER_BUDDY_STATE_UNAVAILABLE },
-	{ "error",     JABBER_BUDDY_STATE_ERROR },
-	{ NULL,        JABBER_BUDDY_STATE_UNKNOWN }
-};
-
-JabberBuddyState jabber_buddy_show_get_state(const char *id)
-{
-	int i;
-
-	g_return_val_if_fail(id != NULL, JABBER_BUDDY_STATE_UNKNOWN);
-
-	for (i = 0; show_state_pairs[i].name; ++i)
-		if (g_str_equal(id, show_state_pairs[i].name))
-			return show_state_pairs[i].state;
-
-	purple_debug_warning("jabber", "Invalid value of presence <show/> "
-	                     "attribute: %s\n", id);
-	return JABBER_BUDDY_STATE_UNKNOWN;
-}
-
-const char *
-jabber_buddy_state_get_show(JabberBuddyState state)
-{
-	int i;
-
-	for (i = 0; show_state_pairs[i].name; ++i)
-		if (state == show_state_pairs[i].state)
-			return show_state_pairs[i].name;
-
-/*	purple_debug_warning("jabber", "Unknown buddy state: %d\n", state); */
-	return NULL;
-}
-
-const char *jabber_buddy_state_get_status_id(JabberBuddyState state) {
-	switch(state) {
-		case JABBER_BUDDY_STATE_CHAT:
-			return "freeforchat";
-		case JABBER_BUDDY_STATE_AWAY:
-			return "away";
-		case JABBER_BUDDY_STATE_XA:
-			return "extended_away";
-		case JABBER_BUDDY_STATE_DND:
-			return "dnd";
-		case JABBER_BUDDY_STATE_ONLINE:
-			return "available";
-		case JABBER_BUDDY_STATE_UNKNOWN:
-			return "available";
-		case JABBER_BUDDY_STATE_ERROR:
-			return "error";
-		case JABBER_BUDDY_STATE_UNAVAILABLE:
-			return "offline";
-	}
-	return NULL;
-}
-
 static void user_search_result_add_buddy_cb(PurpleConnection *gc, GList *row, void *user_data)
 {
 	/* XXX find out the jid */
--- a/libpurple/protocols/jabber/buddy.h	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/buddy.h	Thu Feb 18 08:10:58 2010 +0000
@@ -24,23 +24,20 @@
 #ifndef PURPLE_JABBER_BUDDY_H_
 #define PURPLE_JABBER_BUDDY_H_
 
-typedef enum {
-	JABBER_BUDDY_STATE_UNKNOWN = -2,
-	JABBER_BUDDY_STATE_ERROR = -1,
-	JABBER_BUDDY_STATE_UNAVAILABLE = 0,
-	JABBER_BUDDY_STATE_ONLINE,
-	JABBER_BUDDY_STATE_CHAT,
-	JABBER_BUDDY_STATE_AWAY,
-	JABBER_BUDDY_STATE_XA,
-	JABBER_BUDDY_STATE_DND
-} JabberBuddyState;
-
 typedef struct _JabberBuddy JabberBuddy;
 
 #include "jabber.h"
 #include "caps.h"
+#include "jutil.h"
 
 struct _JabberBuddy {
+	/**
+	 * A sorted list of resources in priority descending order.
+	 * This means that the first resource in the list is the
+	 * "most available" (see resource_compare_cb in buddy.c for
+	 * details).  Don't play with this yourself, let
+	 * jabber_buddy_track_resource and jabber_buddy_remove_resource do it.
+	 */
 	GList *resources;
 	char *error_msg;
 	enum {
@@ -100,7 +97,6 @@
 		const char *resource);
 JabberBuddyResource *jabber_buddy_track_resource(JabberBuddy *jb, const char *resource,
 		int priority, JabberBuddyState state, const char *status);
-void jabber_buddy_resource_free(JabberBuddyResource *jbr);
 void jabber_buddy_remove_resource(JabberBuddy *jb, const char *resource);
 void jabber_buddy_get_info(PurpleConnection *gc, const char *who);
 
@@ -110,12 +106,6 @@
 void jabber_setup_set_info(PurplePluginAction *action);
 void jabber_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img);
 
-const char *jabber_buddy_state_get_name(JabberBuddyState state);
-const char *jabber_buddy_state_get_status_id(JabberBuddyState state);
-const char *jabber_buddy_state_get_show(JabberBuddyState state);
-JabberBuddyState jabber_buddy_status_id_get_state(const char *id);
-JabberBuddyState jabber_buddy_show_get_state(const char *id);
-
 void jabber_user_search(JabberStream *js, const char *directory);
 void jabber_user_search_begin(PurplePluginAction *);
 
--- a/libpurple/protocols/jabber/chat.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/chat.c	Thu Feb 18 08:10:58 2010 +0000
@@ -1048,7 +1048,8 @@
 	return TRUE;
 }
 
-gboolean jabber_chat_role_user(JabberChat *chat, const char *who, const char *role)
+gboolean jabber_chat_role_user(JabberChat *chat, const char *who,
+                               const char *role, const char *why)
 {
 	char *to;
 	JabberIq *iq;
@@ -1071,6 +1072,10 @@
 	item = xmlnode_new_child(query, "item");
 	xmlnode_set_attrib(item, "nick", jcm->handle);
 	xmlnode_set_attrib(item, "role", role);
+	if (why) {
+		xmlnode *reason = xmlnode_new_child(item, "reason");
+		xmlnode_insert_data(reason, why, -1);
+	}
 
 	jabber_iq_send(iq);
 
@@ -1138,37 +1143,6 @@
 	return TRUE;
 }
 
-gboolean jabber_chat_kick_user(JabberChat *chat, const char *who, const char *why)
-{
-	JabberIq *iq;
-	JabberChatMember *jcm = g_hash_table_lookup(chat->members, who);
-	char *to;
-	xmlnode *query, *item, *reason;
-
-	if(!jcm || !jcm->jid)
-		return FALSE;
-
-	iq = jabber_iq_new_query(chat->js, JABBER_IQ_SET,
-			"http://jabber.org/protocol/muc#admin");
-
-	to = g_strdup_printf("%s@%s", chat->room, chat->server);
-	xmlnode_set_attrib(iq->node, "to", to);
-	g_free(to);
-
-	query = xmlnode_get_child(iq->node, "query");
-	item = xmlnode_new_child(query, "item");
-	xmlnode_set_attrib(item, "jid", jcm->jid);
-	xmlnode_set_attrib(item, "role", "none");
-	if(why) {
-		reason = xmlnode_new_child(item, "reason");
-		xmlnode_insert_data(reason, why, -1);
-	}
-
-	jabber_iq_send(iq);
-
-	return TRUE;
-}
-
 static void jabber_chat_disco_traffic_cb(JabberStream *js, const char *from,
                                          JabberIqType type, const char *id,
                                          xmlnode *packet, gpointer data)
--- a/libpurple/protocols/jabber/chat.h	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/chat.h	Thu Feb 18 08:10:58 2010 +0000
@@ -100,7 +100,7 @@
 		const char *affiliation);
 gboolean jabber_chat_affiliation_list(JabberChat *chat, const char *affiliation);
 gboolean jabber_chat_role_user(JabberChat *chat, const char *who,
-		const char *role);
+		const char *role, const char *why);
 gboolean jabber_chat_role_list(JabberChat *chat, const char *role);
 gboolean jabber_chat_kick_user(JabberChat *chat, const char *who,
 		const char *why);
--- a/libpurple/protocols/jabber/iq.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/iq.c	Thu Feb 18 08:10:58 2010 +0000
@@ -43,8 +43,8 @@
 #include "utsname.h"
 #endif
 
-GHashTable *iq_handlers = NULL;
-GHashTable *signal_iq_handlers = NULL;
+static GHashTable *iq_handlers = NULL;
+static GHashTable *signal_iq_handlers = NULL;
 
 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
 {
--- a/libpurple/protocols/jabber/jabber.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Thu Feb 18 08:10:58 2010 +0000
@@ -2721,9 +2721,10 @@
 		char **nicks = g_strsplit(args[1], " ", -1);
 
 		for (i = 0; nicks[i]; i++)
-			if (!jabber_chat_role_user(chat, nicks[i], args[0])) {
+			if (!jabber_chat_role_user(chat, nicks[i], args[0], NULL)) {
 				*error = g_strdup_printf(_("Unable to set role \"%s\" for user: %s"),
 										 args[0], nicks[i]);
+				g_strfreev(nicks);
 				return PURPLE_CMD_RET_FAILED;
 			}
 
@@ -2778,7 +2779,7 @@
 	if(!chat || !args || !args[0])
 		return PURPLE_CMD_RET_FAILED;
 
-	if(!jabber_chat_kick_user(chat, args[0], args[1])) {
+	if(!jabber_chat_role_user(chat, args[0], "none", args[1])) {
 		*error = g_strdup_printf(_("Unable to kick user %s"), args[0]);
 		return PURPLE_CMD_RET_FAILED;
 	}
--- a/libpurple/protocols/jabber/jutil.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/jutil.c	Thu Feb 18 08:10:58 2010 +0000
@@ -651,6 +651,83 @@
 	return equal;
 }
 
+static const struct {
+		const char *status_id; /* link to core */
+		const char *show; /* The show child's cdata in a presence stanza */
+		const char *readable; /* readable representation */
+		JabberBuddyState state;
+} jabber_statuses[] = {
+	{ "offline",       NULL,   N_("Offline"),        JABBER_BUDDY_STATE_UNAVAILABLE },
+	{ "available",     NULL,   N_("Available"),      JABBER_BUDDY_STATE_ONLINE},
+	{ "freeforchat",   "chat", N_("Chatty"),         JABBER_BUDDY_STATE_CHAT },
+	{ "away",          "away", N_("Away"),           JABBER_BUDDY_STATE_AWAY },
+	{ "extended_away", "xa",   N_("Extended Away"),  JABBER_BUDDY_STATE_XA },
+	{ "dnd",           "dnd",  N_("Do Not Disturb"), JABBER_BUDDY_STATE_DND },
+	{ "error",         NULL,   N_("Error"),          JABBER_BUDDY_STATE_ERROR }
+};
+
+const char *
+jabber_buddy_state_get_name(const JabberBuddyState state)
+{
+	int i;
+	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
+		if (jabber_statuses[i].state == state)
+			return _(jabber_statuses[i].readable);
+
+	return _("Unknown");
+}
+
+JabberBuddyState
+jabber_buddy_status_id_get_state(const char *id)
+{
+	int i;
+	if (!id)
+		return JABBER_BUDDY_STATE_UNKNOWN;
+
+	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
+		if (g_str_equal(id, jabber_statuses[i].status_id))
+			return jabber_statuses[i].state;
+
+	return JABBER_BUDDY_STATE_UNKNOWN;
+}
+
+JabberBuddyState jabber_buddy_show_get_state(const char *id)
+{
+	int i;
+
+	g_return_val_if_fail(id != NULL, JABBER_BUDDY_STATE_UNKNOWN);
+
+	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
+		if (jabber_statuses[i].show && g_str_equal(id, jabber_statuses[i].show))
+			return jabber_statuses[i].state;
+
+	purple_debug_warning("jabber", "Invalid value of presence <show/> "
+	                     "attribute: %s\n", id);
+	return JABBER_BUDDY_STATE_UNKNOWN;
+}
+
+const char *
+jabber_buddy_state_get_show(JabberBuddyState state)
+{
+	int i;
+	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
+		if (state == jabber_statuses[i].state)
+			return jabber_statuses[i].show;
+
+	return NULL;
+}
+
+const char *
+jabber_buddy_state_get_status_id(JabberBuddyState state)
+{
+	int i;
+	for (i = 0; i < G_N_ELEMENTS(jabber_statuses); ++i)
+		if (state == jabber_statuses[i].state)
+			return jabber_statuses[i].status_id;
+
+	return NULL;
+}
+
 /* The same as purple_util_get_image_checksum, but guaranteed to remain SHA1 */
 char *
 jabber_calculate_data_sha1sum(gconstpointer data, size_t len)
--- a/libpurple/protocols/jabber/jutil.h	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/jabber/jutil.h	Thu Feb 18 08:10:58 2010 +0000
@@ -30,6 +30,17 @@
 	char *resource;
 } JabberID;
 
+typedef enum {
+	JABBER_BUDDY_STATE_UNKNOWN = -2,
+	JABBER_BUDDY_STATE_ERROR = -1,
+	JABBER_BUDDY_STATE_UNAVAILABLE = 0,
+	JABBER_BUDDY_STATE_ONLINE,
+	JABBER_BUDDY_STATE_CHAT,
+	JABBER_BUDDY_STATE_AWAY,
+	JABBER_BUDDY_STATE_XA,
+	JABBER_BUDDY_STATE_DND
+} JabberBuddyState;
+
 #include "jabber.h"
 
 JabberID* jabber_id_new(const char *str);
@@ -63,5 +74,16 @@
  */
 char *jabber_saslprep(const char *);
 
+/* state -> readable name */
+const char *jabber_buddy_state_get_name(JabberBuddyState state);
+/* state -> core id */
+const char *jabber_buddy_state_get_status_id(JabberBuddyState state);
+/* state -> show attr (for presence stanza) */
+const char *jabber_buddy_state_get_show(JabberBuddyState state);
+/* core id -> state */
+JabberBuddyState jabber_buddy_status_id_get_state(const char *id);
+/* show attr (presence stanza) -> state */
+JabberBuddyState jabber_buddy_show_get_state(const char *id);
+
 char *jabber_calculate_data_sha1sum(gconstpointer data, size_t len);
 #endif /* PURPLE_JABBER_JUTIL_H_ */
--- a/libpurple/protocols/msn/notification.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/libpurple/protocols/msn/notification.c	Thu Feb 18 08:10:58 2010 +0000
@@ -361,81 +361,6 @@
 	msn_cmdproc_send_trans(cmdproc, trans);
 }
 
-#if 0
-static void
-ubm_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
-			 size_t len)
-{
-	MsnMessage *msg;
-	PurpleConnection *gc;
-	const char *passport;
-	const char *content_type;
-
-	purple_debug_info("msn", "Process UBM payload:%.*s\n", (guint)len, payload);
-	msg = msn_message_new_from_cmd(cmdproc->session, cmd);
-
-	msn_message_parse_payload(msg, payload, len,MSG_LINE_DEM,MSG_BODY_DEM);
-	if (purple_debug_is_verbose())
-		msn_message_show_readable(msg, "Notification", TRUE);
-
-	gc = cmdproc->session->account->gc;
-	passport = msg->remote_user;
-
-	content_type = msn_message_get_content_type(msg);
-	purple_debug_info("msn", "type:%s\n", content_type);
-	if(!strcmp(content_type,"text/plain")){
-		const char *value;
-		const char *body;
-		char *body_enc;
-		char *body_final = NULL;
-		size_t body_len;
-
-		body = msn_message_get_bin_data(msg, &body_len);
-		body_enc = g_markup_escape_text(body, body_len);
-
-		if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL)	{
-			char *pre, *post;
-
-			msn_parse_format(value, &pre, &post);
-			body_final = g_strdup_printf("%s%s%s", pre ? pre : "",
-							body_enc ? body_enc : "", post ? post : "");
-			g_free(pre);
-			g_free(post);
-		}
-		g_free(body_enc);
-		serv_got_im(gc, passport, body_final, 0, time(NULL));
-		g_free(body_final);
-	}
-	if(!strcmp(content_type,"text/x-msmsgscontrol")){
-		if(msn_message_get_attr(msg, "TypingUser") != NULL){
-			serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT,
-						PURPLE_TYPING);
-		}
-	}
-	if(!strcmp(content_type,"text/x-msnmsgr-datacast")){
-		char *username, *str;
-		PurpleAccount *account;
-		PurpleBuddy *buddy;
-		const char *user;
-
-		account = cmdproc->session->account;
-		user = msg->remote_user;
-
-		if ((buddy = purple_find_buddy(account, user)) != NULL){
-			username = g_markup_escape_text(purple_buddy_get_alias(buddy), -1);
-		}else{
-			username = g_markup_escape_text(user, -1);
-		}
-
-		str = g_strdup_printf(_("%s just sent you a Nudge!"), username);
-		g_free(username);
-		msn_session_report_user(cmdproc->session,user,str,PURPLE_MESSAGE_SYSTEM);
-		g_free(str);
-	}
-	msn_message_destroy(msg);
-}
-#endif
-
 /*Yahoo msg process*/
 static void
 ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
--- a/pidgin/Makefile.am	Tue Feb 16 09:14:54 2010 +0000
+++ b/pidgin/Makefile.am	Thu Feb 18 08:10:58 2010 +0000
@@ -48,6 +48,7 @@
 		win32/nsis/translations/kurdish.nsh \
 		win32/nsis/translations/lithuanian.nsh \
 		win32/nsis/translations/norwegian.nsh \
+		win32/nsis/translations/norwegian_nynorsk.nsh \
 		win32/nsis/translations/persian.nsh \
 		win32/nsis/translations/polish.nsh \
 		win32/nsis/translations/portuguese.nsh \
--- a/pidgin/gtkprefs.c	Tue Feb 16 09:14:54 2010 +0000
+++ b/pidgin/gtkprefs.c	Thu Feb 18 08:10:58 2010 +0000
@@ -223,16 +223,8 @@
 
 	g_return_val_if_fail(menuitems != NULL, NULL);
 
-#if 0 /* GTK_CHECK_VERSION(2,4,0) */
-	if(type == PURPLE_PREF_INT)
-		model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
-	else if(type == PURPLE_PREF_STRING)
-		model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-	dropdown = gtk_combo_box_new_with_model(model);
-#else
 	dropdown = gtk_option_menu_new();
 	menu = gtk_menu_new();
-#endif
 
 	if (type == PURPLE_PREF_INT)
 		stored_int = purple_prefs_get_int(key);
@@ -908,11 +900,11 @@
 	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "pixbuf", 0, NULL);
 
 	cell_rend = gtk_cell_renderer_text_new();
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE);
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, TRUE);
 	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL);
-/*#if GTK_CHECK_VERSION(2,6,0)
-			g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-#endif*/
+#if GTK_CHECK_VERSION(2,6,0)
+	g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+#endif
 
 	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);
@@ -1090,7 +1082,7 @@
 	g_signal_connect(G_OBJECT(prefs_blist_themes_combo_box), "changed",
 						(GCallback)prefs_set_blist_theme_cb, NULL);
 	gtk_size_group_add_widget(combo_sg, prefs_blist_themes_combo_box);
-	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_blist_themes_combo_box, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_blist_themes_combo_box, TRUE, TRUE, 0);
 
 	gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
 
@@ -1108,7 +1100,7 @@
 	g_signal_connect(G_OBJECT(prefs_status_themes_combo_box), "changed",
 						(GCallback)prefs_set_status_icon_theme_cb, NULL);
 	gtk_size_group_add_widget(combo_sg, prefs_status_themes_combo_box);
-	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_status_themes_combo_box, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_status_themes_combo_box, TRUE, TRUE, 0);
 
 	gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
 
@@ -1126,7 +1118,7 @@
 	g_signal_connect(G_OBJECT(prefs_sound_themes_combo_box), "changed",
 						(GCallback)prefs_set_sound_theme_cb, NULL);
 	gtk_size_group_add_widget(combo_sg, prefs_sound_themes_combo_box);
-	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_sound_themes_combo_box, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_sound_themes_combo_box, TRUE, TRUE, 0);
 
 	gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
 
@@ -1144,7 +1136,7 @@
 	g_signal_connect(G_OBJECT(prefs_smiley_themes_combo_box), "changed",
 						(GCallback)prefs_set_smiley_theme_cb, NULL);
 	gtk_size_group_add_widget(combo_sg, prefs_smiley_themes_combo_box);
-	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_smiley_themes_combo_box, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(themesel_hbox), prefs_smiley_themes_combo_box, TRUE, TRUE, 0);
 
 	gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
 
--- a/po/ca.po	Tue Feb 16 09:14:54 2010 +0000
+++ b/po/ca.po	Thu Feb 18 08:10:58 2010 +0000
@@ -33,8 +33,8 @@
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-11-29 22:28+0100\n"
-"PO-Revision-Date: 2009-11-29 22:39+0100\n"
+"POT-Creation-Date: 2010-02-16 09:18+0100\n"
+"PO-Revision-Date: 2010-02-16 23:08+0100\n"
 "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
 "Language-Team: Catalan <tradgnome@softcatala.net>\n"
 "MIME-Version: 1.0\n"
@@ -1987,6 +1987,9 @@
 msgid "%s is not a regular file. Cowardly refusing to overwrite it.\n"
 msgstr "%s no és un fitxer normal, no se sobreescriurà.\n"
 
+msgid "File is not readable."
+msgstr "No ha estat possible llegir el fitxer."
+
 #, c-format
 msgid "%s wants to send you %s (%s)"
 msgstr "%s us vol enviar %s (%s)"
@@ -3845,6 +3848,13 @@
 msgid "Server requires plaintext authentication over an unencrypted stream"
 msgstr "El servidor requereix autenticació de text sobre un flux no xifrat"
 
+#. This should never happen!
+msgid "Invalid response from server"
+msgstr "La resposta del servidor no és vàlida"
+
+msgid "Server does not use any supported authentication method"
+msgstr "No hi ha cap mètode d'autenticació compatible amb aquest servidor"
+
 #, c-format
 msgid ""
 "%s requires plaintext authentication over an unencrypted connection.  Allow "
@@ -3856,25 +3866,35 @@
 msgid "Plaintext Authentication"
 msgstr "Autenticació de text"
 
-msgid "SASL authentication failed"
-msgstr "Ha fallat l'autenticació SASL"
-
-msgid "Invalid response from server"
-msgstr "La resposta del servidor no és vàlida"
-
-msgid "Server does not use any supported authentication method"
-msgstr "No hi ha cap mètode d'autenticació compatible amb aquest servidor"
-
 msgid "You require encryption, but it is not available on this server."
 msgstr "Requeriu xifratge, però no està disponible en aquest servidor."
 
 msgid "Invalid challenge from server"
 msgstr "Repte del servidor invàlid"
 
+msgid "Server thinks authentication is complete, but client does not"
+msgstr "El servidor creu que s'ha completat l'autenticació, però el client no"
+
+msgid "SASL authentication failed"
+msgstr "Ha fallat l'autenticació SASL"
+
 #, c-format
 msgid "SASL error: %s"
 msgstr "Error SASL: %s"
 
+# FIXME: canonicalize -> normalitzar (josep)
+msgid "Unable to canonicalize username"
+msgstr "No s'ha pogut normalitzar el nom d'usuari"
+
+msgid "Unable to canonicalize password"
+msgstr "No s'ha pogut normalitzar la contrasenya"
+
+msgid "Malicious challenge from server"
+msgstr "Desafiament malició del servidor"
+
+msgid "Unexpected response from server"
+msgstr "S'ha rebut una resposta inesperada del servidor"
+
 msgid "The BOSH connection manager terminated your session."
 msgstr "El gestor de connexions BOSH ha tancat la connexió."
 
@@ -3975,13 +3995,17 @@
 msgid "Resource"
 msgstr "Recurs"
 
+# FIXME
+msgid "Uptime"
+msgstr "Temps connectat"
+
+msgid "Logged Off"
+msgstr "Desconnectat"
+
 #, c-format
 msgid "%s ago"
 msgstr "fa %s"
 
-msgid "Logged Off"
-msgstr "Desconnectat"
-
 # Segons la viquipèdia
 msgid "Middle Name"
 msgstr "Nom del mig"
@@ -4172,13 +4196,6 @@
 msgid "Ping timed out"
 msgstr "S'ha esgitat el temps d'espera (ping)"
 
-msgid ""
-"Unable to find alternative XMPP connection methods after failing to connect "
-"directly."
-msgstr ""
-"No s'ha pogut trobar cap mètode alternatiu de connexió XMPP després de no "
-"haver pogut connectar directament."
-
 msgid "Invalid XMPP ID"
 msgstr "ID de l'XMPP invàlid"
 
@@ -4734,6 +4751,11 @@
 msgid "(Code %s)"
 msgstr "(Codi %s)"
 
+msgid "A custom smiley in the message is too large to send."
+msgstr ""
+"No es pot enviar una de les emoticones personalitzades del missatge atès que "
+"és massa llarga."
+
 msgid "XML Parse error"
 msgstr "Error en l'anàlisi de l'XML"
 
@@ -4776,13 +4798,13 @@
 msgstr "Us han fet fora (%s)"
 
 msgid "An error occurred on the in-band bytestream transfer\n"
-msgstr ""
+msgstr "S'ha produit un error en el fluxe de transferència de dades en banda\n"
 
 msgid "Transfer was closed."
 msgstr "La transferència s'ha tancat."
 
 msgid "Failed to open in-band bytestream"
-msgstr ""
+msgstr "No s'ha pogut obrir el fluxe de transferència de dades en banda"
 
 #, c-format
 msgid "Unable to send file to %s, user does not support file transfers"
@@ -5149,6 +5171,10 @@
 msgid "Your new MSN friendly name is too long."
 msgstr "El vostre nom amistós nou d'MSN és massa llarg."
 
+#, c-format
+msgid "Set friendly name for %s."
+msgstr "Establiu el nom amistós de %s."
+
 msgid "Set your friendly name."
 msgstr "Establiu el vostre nom amistós."
 
@@ -6771,7 +6797,10 @@
 msgid "Server port"
 msgstr "Port en el servidor"
 
-#. Note to translators: %s in this string is a URL
+#, c-format
+msgid "Received unexpected response from %s: %s"
+msgstr "S'ha rebut una resposta inesperada de %s: %s"
+
 #, c-format
 msgid "Received unexpected response from %s"
 msgstr "S'ha rebut una resposta inesperada de %s"
@@ -6790,6 +6819,13 @@
 msgid "Error requesting %s: %s"
 msgstr "S'ha produït un error en sol·licitar %s: %s"
 
+msgid ""
+"Server requested that you fill out a CAPTCHA in order to sign in, but this "
+"client does not currently support CAPTCHAs."
+msgstr ""
+"El servidor requereix que ompliu el CAPTCHA per poder entrar, però aquest "
+"client encara no permet l'ús de CAPTCHA."
+
 msgid "AOL does not allow your screen name to authenticate here"
 msgstr "AOL no permet que us autentiqueu amb aquest nom d'usuari aquí"
 
@@ -7352,13 +7388,6 @@
 "[No s'ha pogut mostrar el missatge d'aquest usuari perquè contenia caràcters "
 "invàlids.]"
 
-msgid ""
-"The last action you attempted could not be performed because you are over "
-"the rate limit. Please wait 10 seconds and try again.\n"
-msgstr ""
-"No s'ha pogut realitzar la darrera acció que havíeu intentat perquè esteu "
-"per sobre del límit. Espereu 10 segons i torneu-ho a provar.\n"
-
 #, c-format
 msgid "You have been disconnected from chat room %s."
 msgstr "Se us ha desconnectat de la conversa %s."
@@ -12040,15 +12069,15 @@
 msgid "Lao"
 msgstr "Lasià"
 
-msgid "Lithuanian"
-msgstr "Lituà"
-
 msgid "Macedonian"
 msgstr "Macedoni"
 
 msgid "Mongolian"
 msgstr "Mongol"
 
+msgid "Marathi"
+msgstr "Marathi"
+
 msgid "Malay"
 msgstr "Malai"
 
@@ -12067,6 +12096,9 @@
 msgid "Occitan"
 msgstr "Occità"
 
+msgid "Oriya"
+msgstr "Oriya"
+
 msgid "Punjabi"
 msgstr "Punjabi"
 
@@ -12148,6 +12180,9 @@
 msgid "Amharic"
 msgstr "Amhàric"
 
+msgid "Lithuanian"
+msgstr "Lituà"
+
 #, c-format
 msgid "About %s"
 msgstr "Quant al %s"
@@ -13816,6 +13851,10 @@
 msgid "_Save File"
 msgstr "_Desa el fitxer"
 
+# Nota: com que és una pissarra, fem servir esborrar.
+msgid "Do you really want to clear?"
+msgstr "Esteu segur que voleu esborrar-ho?"
+
 msgid "Select color"
 msgstr "Seleccioneu un color"
 
@@ -15036,6 +15075,20 @@
 msgid "This plugin is useful for debbuging XMPP servers or clients."
 msgstr "Aquest connector és útil per a depurar servidors i clients XMPP."
 
+#~ msgid ""
+#~ "Unable to find alternative XMPP connection methods after failing to "
+#~ "connect directly."
+#~ msgstr ""
+#~ "No s'ha pogut trobar cap mètode alternatiu de connexió XMPP després de no "
+#~ "haver pogut connectar directament."
+
+#~ msgid ""
+#~ "The last action you attempted could not be performed because you are over "
+#~ "the rate limit. Please wait 10 seconds and try again.\n"
+#~ msgstr ""
+#~ "No s'ha pogut realitzar la darrera acció que havíeu intentat perquè esteu "
+#~ "per sobre del límit. Espereu 10 segons i torneu-ho a provar.\n"
+
 #~ msgid "(Default)"
 #~ msgstr "(Predeterminat)"
 
--- a/po/ca@valencia.po	Tue Feb 16 09:14:54 2010 +0000
+++ b/po/ca@valencia.po	Thu Feb 18 08:10:58 2010 +0000
@@ -3,7 +3,7 @@
 # Copyright (C) unknown, Robert Millan <zeratul2@wanadoo.es>
 # Copyright (C) December 2003 (from 2003-12-12 until 2003-12-18),
 #               January (2004-01-07,12), Xan <dxpublica@telefonica.net>
-# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009
+# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010
 #               Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>
 #
 # This file is distributed under the same license as the Pidgin package.
@@ -33,8 +33,8 @@
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-11-28 18:48+0100\n"
-"PO-Revision-Date: 2009-11-28 21:57+0100\n"
+"POT-Creation-Date: 2010-02-16 09:18+0100\n"
+"PO-Revision-Date: 2010-02-16 23:08+0100\n"
 "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
 "Language-Team: Catalan <tradgnome@softcatala.net>\n"
 "MIME-Version: 1.0\n"
@@ -66,7 +66,7 @@
 "Forma d'ús: %s [OPCIÓ]...\n"
 "\n"
 "  -c, --config=DIR    utilitza DIR per als fitxers de configuració\n"
-"  -d, --debug         mostra missatges de depuració a la eixida d'error\n"
+"  -d, --debug         mostra missatges de depuració a l'eixida d'error\n"
 "                      estàndard \n"
 "  -h, --help          mostra esta ajuda i ix\n"
 "  -n, --nologin       no entra automàticament\n"
@@ -1987,6 +1987,9 @@
 msgid "%s is not a regular file. Cowardly refusing to overwrite it.\n"
 msgstr "%s no és un fitxer normal, no se sobreescriurà.\n"
 
+msgid "File is not readable."
+msgstr "No ha estat possible llegir el fitxer."
+
 #, c-format
 msgid "%s wants to send you %s (%s)"
 msgstr "%s vos vol enviar %s (%s)"
@@ -2337,7 +2340,7 @@
 msgstr "Estableix el paràmetre d'acceptació automàtica"
 
 msgid "_Save"
-msgstr "De_sa"
+msgstr "Al_ça"
 
 msgid "_Cancel"
 msgstr "_Cancel·la"
@@ -2680,11 +2683,11 @@
 "WARNING: This plugin is still alpha code and may crash frequently.  Use it "
 "at your own risk!"
 msgstr ""
-"Quan es visualitzin els registres, este connector inclourà registres "
+"Quan es visualitzen els registres, este connector inclourà registres "
 "d'altres clients de MI. De moment, es poden incloure els d'Adium, MSN "
 "Messenger, aMSN, i Trillian.\n"
 "\n"
-"Avís: este connector encara està en desenvolupament i pot ser que es pengi."
+"Avís: este connector encara està en desenvolupament i pot ser que es penge."
 
 msgid "Mono Plugin Loader"
 msgstr "Carregador de connectors Mono"
@@ -3845,6 +3848,13 @@
 msgid "Server requires plaintext authentication over an unencrypted stream"
 msgstr "El servidor requereix autenticació de text sobre un flux no xifrat"
 
+#. This should never happen!
+msgid "Invalid response from server"
+msgstr "La resposta del servidor no és vàlida"
+
+msgid "Server does not use any supported authentication method"
+msgstr "No hi ha cap mètode d'autenticació compatible amb este servidor"
+
 #, c-format
 msgid ""
 "%s requires plaintext authentication over an unencrypted connection.  Allow "
@@ -3856,25 +3866,35 @@
 msgid "Plaintext Authentication"
 msgstr "Autenticació de text"
 
-msgid "SASL authentication failed"
-msgstr "Ha fallat l'autenticació SASL"
-
-msgid "Invalid response from server"
-msgstr "La resposta del servidor no és vàlida"
-
-msgid "Server does not use any supported authentication method"
-msgstr "No hi ha cap mètode d'autenticació compatible amb este servidor"
-
 msgid "You require encryption, but it is not available on this server."
 msgstr "Requeriu xifratge, però no està disponible en este servidor."
 
 msgid "Invalid challenge from server"
 msgstr "Repte del servidor invàlid"
 
+msgid "Server thinks authentication is complete, but client does not"
+msgstr "El servidor creu que s'ha completat l'autenticació, però el client no"
+
+msgid "SASL authentication failed"
+msgstr "Ha fallat l'autenticació SASL"
+
 #, c-format
 msgid "SASL error: %s"
 msgstr "Error SASL: %s"
 
+# FIXME: canonicalize -> normalitzar (josep)
+msgid "Unable to canonicalize username"
+msgstr "No s'ha pogut normalitzar el nom d'usuari"
+
+msgid "Unable to canonicalize password"
+msgstr "No s'ha pogut normalitzar la contrasenya"
+
+msgid "Malicious challenge from server"
+msgstr "Desafiament malició del servidor"
+
+msgid "Unexpected response from server"
+msgstr "S'ha rebut una resposta inesperada del servidor"
+
 msgid "The BOSH connection manager terminated your session."
 msgstr "El gestor de connexions BOSH ha tancat la connexió."
 
@@ -3975,13 +3995,17 @@
 msgid "Resource"
 msgstr "Recurs"
 
+# FIXME
+msgid "Uptime"
+msgstr "Temps connectat"
+
+msgid "Logged Off"
+msgstr "Desconnectat"
+
 #, c-format
 msgid "%s ago"
 msgstr "fa %s"
 
-msgid "Logged Off"
-msgstr "Desconnectat"
-
 # Segons la viquipèdia
 msgid "Middle Name"
 msgstr "Nom del mig"
@@ -4172,13 +4196,6 @@
 msgid "Ping timed out"
 msgstr "S'ha esgitat el temps d'espera (ping)"
 
-msgid ""
-"Unable to find alternative XMPP connection methods after failing to connect "
-"directly."
-msgstr ""
-"No s'ha pogut trobar cap mètode alternatiu de connexió XMPP després de no "
-"haver pogut connectar directament."
-
 msgid "Invalid XMPP ID"
 msgstr "ID de l'XMPP invàlid"
 
@@ -4734,6 +4751,11 @@
 msgid "(Code %s)"
 msgstr "(Codi %s)"
 
+msgid "A custom smiley in the message is too large to send."
+msgstr ""
+"No es pot enviar una de les emoticones personalitzades del missatge atès que "
+"és massa llarga."
+
 msgid "XML Parse error"
 msgstr "Error en l'anàlisi de l'XML"
 
@@ -4776,13 +4798,13 @@
 msgstr "Vos han fet fora (%s)"
 
 msgid "An error occurred on the in-band bytestream transfer\n"
-msgstr ""
+msgstr "S'ha produit un error en el fluxe de transferència de dades en banda\n"
 
 msgid "Transfer was closed."
 msgstr "La transferència s'ha tancat."
 
 msgid "Failed to open in-band bytestream"
-msgstr ""
+msgstr "No s'ha pogut obrir el fluxe de transferència de dades en banda"
 
 #, c-format
 msgid "Unable to send file to %s, user does not support file transfers"
@@ -5133,15 +5155,15 @@
 "no està implementat."
 
 msgid "Nudge"
-msgstr "Donar un colp de colze"
+msgstr "Donar un cop de colze"
 
 #, c-format
 msgid "%s has nudged you!"
-msgstr "%s vos ha donat un colp de colze!"
+msgstr "%s vos ha donat un cop de colze!"
 
 #, c-format
 msgid "Nudging %s..."
-msgstr "S'està donant un colp de colze a %s..."
+msgstr "S'està donant un cop de colze a %s..."
 
 msgid "Email Address..."
 msgstr "Correu electrònic..."
@@ -5149,6 +5171,10 @@
 msgid "Your new MSN friendly name is too long."
 msgstr "El vostre nom amistós nou d'MSN és massa llarg."
 
+#, c-format
+msgid "Set friendly name for %s."
+msgstr "Establiu el nom amistós de %s."
+
 msgid "Set your friendly name."
 msgstr "Establiu el vostre nom amistós."
 
@@ -5483,7 +5509,7 @@
 msgstr "Mostra emoticones personalitzades"
 
 msgid "nudge: nudge a user to get their attention"
-msgstr "nudge: doneu un colp de colze a un usuari perquè vos pare atenció"
+msgstr "nudge: doneu un cop de colze a un usuari perquè vos pare atenció"
 
 msgid "Windows Live ID authentication:Unable to connect"
 msgstr "Autenticació amb el Windows Live ID: no s'ha pogut connectar"
@@ -5493,7 +5519,7 @@
 
 #, c-format
 msgid "%s just sent you a Nudge!"
-msgstr "%s vos ha donat un colp de colze!"
+msgstr "%s vos ha donat un cop de colze!"
 
 msgid "The following users are missing from your addressbook"
 msgstr "Manquen estos usuaris a la vostra llista d'amics"
@@ -6346,7 +6372,7 @@
 msgstr "Este nom d'usuari està disponible. Voleu fer-lo servir?"
 
 msgid "ONCE SET, THIS CANNOT BE CHANGED!"
-msgstr "Una vegada l'hagueu establit no el podreu canviar!"
+msgstr "Un cop l'hagueu establit no el podreu canviar!"
 
 msgid "MySpaceIM - Please Set a Username"
 msgstr "MySpaceIM - Establiu un nom d'usuari"
@@ -6771,7 +6797,10 @@
 msgid "Server port"
 msgstr "Port en el servidor"
 
-#. Note to translators: %s in this string is a URL
+#, c-format
+msgid "Received unexpected response from %s: %s"
+msgstr "S'ha rebut una resposta inesperada de %s: %s"
+
 #, c-format
 msgid "Received unexpected response from %s"
 msgstr "S'ha rebut una resposta inesperada de %s"
@@ -6790,6 +6819,13 @@
 msgid "Error requesting %s: %s"
 msgstr "S'ha produït un error en sol·licitar %s: %s"
 
+msgid ""
+"Server requested that you fill out a CAPTCHA in order to sign in, but this "
+"client does not currently support CAPTCHAs."
+msgstr ""
+"El servidor requereix que ompliu el CAPTCHA per poder entrar, però este "
+"client encara no permet l'ús de CAPTCHA."
+
 msgid "AOL does not allow your screen name to authenticate here"
 msgstr "AOL no permet que vos autentiqueu amb este nom d'usuari ací"
 
@@ -7352,13 +7388,6 @@
 "[No s'ha pogut mostrar el missatge d'este usuari perquè contenia caràcters "
 "invàlids.]"
 
-msgid ""
-"The last action you attempted could not be performed because you are over "
-"the rate limit. Please wait 10 seconds and try again.\n"
-msgstr ""
-"No s'ha pogut realitzar la darrera acció que havíeu intentat perquè esteu "
-"per sobre del límit. Espereu 10 segons i torneu-ho a provar.\n"
-
 #, c-format
 msgid "You have been disconnected from chat room %s."
 msgstr "Se vos ha desconnectat de la conversa %s."
@@ -9495,10 +9524,10 @@
 msgstr "Serveis en línia"
 
 msgid "Let others see what services you are using"
-msgstr "Permet que els altres vegin quins serveis feu servir"
+msgstr "Permet que els altres vegen quins serveis feu servir"
 
 msgid "Let others see what computer you are using"
-msgstr "Permet que els altres vegin quin ordinador feu servir"
+msgstr "Permet que els altres vegen quin ordinador feu servir"
 
 msgid "Your VCard File"
 msgstr "El fitxer de la vostra VCard"
@@ -9514,7 +9543,7 @@
 "information. Please fill the information you would like other users to see "
 "about yourself."
 msgstr ""
-"Podeu permetre que altres usuaris vegin informació sobre el vostre estat en "
+"Podeu permetre que altres usuaris vegen informació sobre el vostre estat en "
 "línia, així com informació personal. Empleneu la informació que vulgueu que "
 "altres usuaris puguen veure."
 
@@ -10877,7 +10906,7 @@
 msgstr "_Bàsic"
 
 msgid "Create _this new account on the server"
-msgstr "Crea _aquest compte nou al servidor"
+msgstr "Crea _este compte nou al servidor"
 
 msgid "P_roxy"
 msgstr "Servidor _intermediari"
@@ -12040,15 +12069,15 @@
 msgid "Lao"
 msgstr "Lasià"
 
-msgid "Lithuanian"
-msgstr "Lituà"
-
 msgid "Macedonian"
 msgstr "Macedoni"
 
 msgid "Mongolian"
 msgstr "Mongol"
 
+msgid "Marathi"
+msgstr "Marathi"
+
 msgid "Malay"
 msgstr "Malai"
 
@@ -12067,6 +12096,9 @@
 msgid "Occitan"
 msgstr "Occità"
 
+msgid "Oriya"
+msgstr "Oriya"
+
 msgid "Punjabi"
 msgstr "Punjabi"
 
@@ -12148,6 +12180,9 @@
 msgid "Amharic"
 msgstr "Amhàric"
 
+msgid "Lithuanian"
+msgstr "Lituà"
+
 #, c-format
 msgid "About %s"
 msgstr "Quant al %s"
@@ -12780,7 +12815,7 @@
 msgstr "empra DIR per a fitxers de configuració"
 
 msgid "print debugging messages to stdout"
-msgstr "escriu missatges de depuració a la eixida estàndard"
+msgstr "escriu missatges de depuració a l'eixida estàndard"
 
 msgid "force online, regardless of network status"
 msgstr "força estar en línia, independentment de l'estat de la xarxa"
@@ -13816,6 +13851,10 @@
 msgid "_Save File"
 msgstr "Al_ça el fitxer"
 
+# Nota: com que és una pissarra, fem servir esborrar.
+msgid "Do you really want to clear?"
+msgstr "Esteu segur que voleu esborrar-ho?"
+
 msgid "Select color"
 msgstr "Seleccioneu un color"
 
@@ -15036,6 +15075,20 @@
 msgid "This plugin is useful for debbuging XMPP servers or clients."
 msgstr "Este connector és útil per a depurar servidors i clients XMPP."
 
+#~ msgid ""
+#~ "Unable to find alternative XMPP connection methods after failing to "
+#~ "connect directly."
+#~ msgstr ""
+#~ "No s'ha pogut trobar cap mètode alternatiu de connexió XMPP després de no "
+#~ "haver pogut connectar directament."
+
+#~ msgid ""
+#~ "The last action you attempted could not be performed because you are over "
+#~ "the rate limit. Please wait 10 seconds and try again.\n"
+#~ msgstr ""
+#~ "No s'ha pogut realitzar la darrera acció que havíeu intentat perquè esteu "
+#~ "per sobre del límit. Espereu 10 segons i torneu-ho a provar.\n"
+
 #~ msgid "(Default)"
 #~ msgstr "(Predeterminat)"