changeset 27819:030185a59a1a

propagate from branch 'im.pidgin.pidgin' (head 0525a14734461b19a7561e49645fb0df3ebaeea9) to branch 'im.pidgin.pidgin.yaz' (head 71571b132edb3a8ab3619647d3a6c46f5ae0ae49)
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sun, 13 Apr 2008 22:46:58 +0000
parents 5624eec4da24 (diff) bc6cc2c04476 (current diff)
children e0a04ba10ae1
files configure.ac libpurple/conversation.c libpurple/protocols/irc/parse.c libpurple/protocols/oscar/oscar.c libpurple/server.c pidgin/gtkconv.c pidgin/gtkimhtml.c pidgin/gtkutils.c
diffstat 37 files changed, 492 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Tue Apr 08 06:17:41 2008 +0000
+++ b/COPYRIGHT	Sun Apr 13 22:46:58 2008 +0000
@@ -52,6 +52,7 @@
 Matt Brenneke
 Jeremy Brooks
 Jonathan Brossard
+Jeffery Brown
 Philip Brown
 Norbert Buchmuller
 Sean Burke
@@ -232,6 +233,7 @@
 Matthew Luckie
 Mike Lundy
 Jason Lynch
+Iain MacDonnell
 Lucio Maciel
 Brian Macke
 Paolo Maggi
--- a/ChangeLog	Tue Apr 08 06:17:41 2008 +0000
+++ b/ChangeLog	Sun Apr 13 22:46:58 2008 +0000
@@ -3,11 +3,24 @@
 version 2.x.x:
 	libpurple:
 	* In MySpaceIM, messages from spambots are discarded (Justin Williams)
-
+	* Strip mIRC formatting codes from quit and part messages.
+	* IRC now displays ban lists in-channel for joined channels.
+	
 	Pidgin:
 	* The typing notification in the conversation history can be disabled or
 	  customized (font, color etc.) in .gtkrc-2.0.
 
+	General:
+	* The configure script now dies on more absent dependencies.  The
+	  --disable-xxx arguments to configure can be used to bypass unneeded
+	  dependencies.  This will also cause the configure script to die if an
+	  --enable-xxx option is used and the dependencies it requires are
+	  missing.
+	* The Evolution integration plugin must now be explicitly enabled.  Use
+	  the --enable-gevolution argument to configure to enable it.
+	* The Contact Availability Prediction plugin must now be explicitly
+	  enabled.  Use the --enable-cap argument to configure to enable it.
+
 version 2.4.1 (03/31/2008):
 	http://developer.pidgin.im/query?status=closed&milestone=2.4.1
 
--- a/configure.ac	Tue Apr 08 06:17:41 2008 +0000
+++ b/configure.ac	Sun Apr 13 22:46:58 2008 +0000
@@ -64,6 +64,14 @@
 
 AC_INIT([pidgin], [purple_display_version], [devel@pidgin.im])
 
+if test `pwd | wc -w` -ne 1; then
+	AC_MSG_ERROR([
+You are attempting to build in a path that contains spaces.  This
+will fail.  Relocate this source tree to a path that does not contain
+spaces and run configure again.
+])
+fi
+
 AC_CANONICAL_SYSTEM
 AM_CONFIG_HEADER(config.h)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
@@ -350,13 +358,13 @@
 		[compile without GtkSpell automatic spell checking])],
 	enable_gtkspell="$enableval", enable_gtkspell="yes")
 AC_ARG_ENABLE(gevolution,
-	[AC_HELP_STRING([--disable-gevolution],
-		[compile without the Evolution plugin])],
-	enable_gevolution="$enableval", enable_gevolution="yes")
+	[AC_HELP_STRING([--enable-gevolution],
+		[compile with the Evolution plugin])],
+	enable_gevolution="$enableval", enable_gevolution="no")
 AC_ARG_ENABLE(cap,
-	[AC_HELP_STRING([--disable-cap],
-		[compile without Contact Availability Prediction plugin])],
-	enable_cap="$enableval", enable_cap="yes")
+	[AC_HELP_STRING([--enable-cap],
+		[compile with Contact Availability Prediction plugin])],
+	enable_cap="$enableval", enable_cap="no")
 AC_ARG_ENABLE(gestures,
 	[AC_HELP_STRING([--disable-gestures],
 		[compile without the gestures plugin])],
--- a/finch/gntft.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/finch/gntft.c	Sun Apr 13 22:46:58 2008 +0000
@@ -403,6 +403,7 @@
 	double kbps = 0.0;
 	time_t elapsed, now;
 	char *kbsec;
+	gboolean send;
 
 	if ((now = purple_xfer_get_end_time(xfer)) == 0)
 		now = time(NULL);
@@ -429,6 +430,7 @@
 	}
 	data->last_updated_time = current_time;
 
+	send = (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND);
 	size_str      = purple_str_size_to_units(purple_xfer_get_size(xfer));
 	remaining_str = purple_str_size_to_units(purple_xfer_get_bytes_remaining(xfer));
 	kbsec = g_strdup_printf(_("%.2f KiB/s"), kbps);
@@ -442,14 +444,17 @@
 	g_free(remaining_str);
 	g_free(kbsec);
 	if (purple_xfer_is_completed(xfer)) {
-		char *msg = g_strdup_printf(_("The file was saved as %s."), purple_xfer_get_local_filename(xfer));
-		gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_STATUS, _("Finished"));
+		gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_STATUS, send ? _("Sent") : _("Received"));
 		gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_REMAINING, _("Finished"));
-		purple_xfer_conversation_write(xfer, msg, FALSE);
-		g_free(msg);
+		if (!send) {
+			char *msg = g_strdup_printf(_("The file was saved as %s."), purple_xfer_get_local_filename(xfer));
+			purple_xfer_conversation_write(xfer, msg, FALSE);
+			g_free(msg);
+		}
 		data->notified = TRUE;
 	} else {
-		gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_STATUS, _("Transferring"));
+		gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_STATUS,
+				send ? _("Sending") : _("Receiving"));
 	}
 
 	update_title_progress();
--- a/libpurple/conversation.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/conversation.c	Sun Apr 13 22:46:58 2008 +0000
@@ -866,7 +866,7 @@
 		gc = purple_account_get_connection(account);
 
 	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
-		(gc == NULL || !g_slist_find(gc->buddy_chats, conv)))
+		(gc != NULL && !g_slist_find(gc->buddy_chats, conv)))
 		return;
 
 	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
--- a/libpurple/protocols/irc/irc.h	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/irc/irc.h	Sun Apr 13 22:46:58 2008 +0000
@@ -118,6 +118,7 @@
 void irc_msg_away(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_badmode(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_badnick(struct irc_conn *irc, const char *name, const char *from, char **args);
+void irc_msg_ban(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_banfull(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_banned(struct irc_conn *irc, const char *name, const char *from, char **args);
 void irc_msg_chanmode(struct irc_conn *irc, const char *name, const char *from, char **args);
--- a/libpurple/protocols/irc/msgs.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/irc/msgs.c	Sun Apr 13 22:46:58 2008 +0000
@@ -30,6 +30,7 @@
 #include "irc.h"
 
 #include <stdio.h>
+#include <stdlib.h>
 
 static char *irc_mask_nick(const char *mask);
 static char *irc_mask_userhost(const char *mask);
@@ -61,9 +62,11 @@
 
 static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2])
 {
-	char *message;
+	char *message, *stripped;
 
-	message = g_strdup_printf("quit: %s", data[1]);
+	stripped = data[1] ? irc_mirc2txt(data[1]) : NULL;
+	message = g_strdup_printf("quit: %s", stripped);
+	g_free(stripped);
 
 	if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(convo), data[0]))
 		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), data[0], message);
@@ -189,6 +192,49 @@
 	purple_notify_error(gc, NULL, _("Bad mode"), args[1]);
 }
 
+void irc_msg_ban(struct irc_conn *irc, const char *name, const char *from, char **args)
+{
+	PurpleConversation *convo;
+
+	if (!args || !args[0] || !args[1])
+		return;
+
+	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
+						      args[1], irc->account);
+
+	if (!strcmp(name, "367")) {
+		char *msg = NULL;
+		/* Ban list entry */
+		if (!args[2])
+			return;
+		if (args[3] && args[4]) {
+			/* This is an extended syntax, not in RFC 1459 */
+			int t1 = atoi(args[4]);
+			time_t t2 = time(NULL);
+			msg = g_strdup_printf(_("Ban on %s by %s, set %ld seconds ago"),
+			                      args[2], args[3], t2 - t1);
+		} else {
+			msg = g_strdup_printf(_("Ban on %s"), args[2]);
+		}
+		if (convo) {
+			purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg,
+			                       PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG,
+			                       time(NULL));
+		} else {
+			purple_debug_info("irc", "%s\n", msg);
+		}
+		g_free(msg);
+	} else if (!strcmp(name, "368")) {
+		if (!convo)
+			return;
+		/* End of ban list */
+		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "",
+		                       _("End of ban list"),
+		                       PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG,
+		                       time(NULL));
+	}
+}
+
 void irc_msg_banned(struct irc_conn *irc, const char *name, const char *from, char **args)
 {
 	PurpleConnection *gc = purple_account_get_connection(irc->account);
@@ -991,7 +1037,9 @@
 		g_free(msg);
 		serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
 	} else {
-		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nick, args[1]);
+		msg = args[1] ? irc_mirc2txt(args[1]) : NULL;
+		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nick, msg);
+		g_free(msg);
 	}
 	g_free(nick);
 }
--- a/libpurple/protocols/irc/parse.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/irc/parse.c	Sun Apr 13 22:46:58 2008 +0000
@@ -75,6 +75,8 @@
 	{ "333", "*", irc_msg_ignore },		/* Topic setter stuff		*/
 	{ "353", "nvc:", irc_msg_names },	/* Names list			*/
 	{ "366", "nc:", irc_msg_names },	/* End of names			*/
+	{ "367", "ncnnv", irc_msg_ban },	/* Ban list			*/
+	{ "368", "nc:", irc_msg_ban },		/* End of ban list		*/
 	{ "372", "n:", irc_msg_motd },		/* MOTD				*/
 	{ "375", "n:", irc_msg_motd },		/* Start MOTD			*/
 	{ "376", "n:", irc_msg_motd },		/* End of MOTD			*/
--- a/libpurple/protocols/jabber/auth.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/jabber/auth.c	Sun Apr 13 22:46:58 2008 +0000
@@ -264,7 +264,7 @@
 
 static void jabber_auth_start_cyrus(JabberStream *js)
 {
-	const char *clientout = NULL, *mech = NULL;
+	const char *clientout = NULL;
 	char *enc_out;
 	unsigned coutlen = 0;
 	xmlnode *auth;
@@ -297,7 +297,7 @@
 		if (js->sasl_state==SASL_OK) {
 			sasl_setprop(js->sasl, SASL_SEC_PROPS, &secprops);
 			purple_debug_info("sasl", "Mechs found: %s\n", js->sasl_mechs->str);
-			js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &mech);
+			js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &js->current_mech);
 		}
 		switch (js->sasl_state) {
 			/* Success */
@@ -372,10 +372,10 @@
 				 * due to mechanism specific issues, so we want to try one of the other
 				 * supported mechanisms. This code handles that case
 				 */
-				if (mech && strlen(mech) > 0) {
+				if (js->current_mech && strlen(js->current_mech) > 0) {
 					char *pos;
-					if ((pos = strstr(js->sasl_mechs->str, mech))) {
-						g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(mech));
+					if ((pos = strstr(js->sasl_mechs->str, js->current_mech))) {
+						g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(js->current_mech));
 					}
 					again = TRUE;
 				}
@@ -387,7 +387,7 @@
 	if (js->sasl_state == SASL_CONTINUE || js->sasl_state == SASL_OK) {
 		auth = xmlnode_new("auth");
 		xmlnode_set_namespace(auth, "urn:ietf:params:xml:ns:xmpp-sasl");
-		xmlnode_set_attrib(auth, "mechanism", mech);
+		xmlnode_set_attrib(auth, "mechanism", js->current_mech);
 		if (clientout) {
 			if (coutlen == 0) {
 				xmlnode_insert_data(auth, "=", -1);
@@ -1101,8 +1101,24 @@
 void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet)
 {
 	PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
-	char *msg = jabber_parse_error(js, packet, &reason);
+	char *msg;
 
+#ifdef HAVE_CYRUS_SASL
+	if(js->auth_fail_count++ < 5) {
+		if (js->current_mech && strlen(js->current_mech) > 0) {
+			char *pos;
+			if ((pos = strstr(js->sasl_mechs->str, js->current_mech))) {
+				g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(js->current_mech));
+			}
+		}
+
+		sasl_dispose(&js->sasl);
+
+		jabber_auth_start_cyrus(js);
+		return;
+	}
+#endif
+	msg = jabber_parse_error(js, packet, &reason);
 	if(!msg) {
 		purple_connection_error_reason (js->gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
--- a/libpurple/protocols/jabber/chat.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/jabber/chat.c	Sun Apr 13 22:46:58 2008 +0000
@@ -137,9 +137,12 @@
 {
 	PurpleAccount *account = purple_conversation_get_account(conv);
 	PurpleConnection *gc = purple_account_get_connection(account);
-	JabberStream *js = gc->proto_data;
-	int id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
-
+	JabberStream *js;
+	int id;
+	if (!gc)
+		return NULL;
+	js = gc->proto_data;
+	id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
 	return jabber_chat_find_by_id(js, id);
 }
 
--- a/libpurple/protocols/jabber/jabber.h	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Sun Apr 13 22:46:58 2008 +0000
@@ -158,6 +158,11 @@
 	void *sasl;
 	void *sasl_cb;
 #endif
+	/* did someone say something about the end of the struct? */
+#ifdef HAVE_CYRUS_SASL
+	const char *current_mech;
+	int auth_fail_count;
+#endif
 
 	int sasl_state;
 	int sasl_maxbuf;
--- a/libpurple/protocols/oscar/oscar.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sun Apr 13 22:46:58 2008 +0000
@@ -5330,7 +5330,7 @@
 	else
 		nombre = g_strdup(sn);
 
-	dialog_msg = g_strdup_printf(_("The user %s has given you permission to add you to their buddy list.  Do you want to add them?"), nombre);
+	dialog_msg = g_strdup_printf(_("The user %s has given you permission to add him or her to your buddy list.  Do you want to add this user?"), nombre);
 	g_free(nombre);
 
 	data = g_new(struct name_data, 1);
--- a/libpurple/server.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/server.c	Sun Apr 13 22:46:58 2008 +0000
@@ -717,7 +717,7 @@
 	if (conv == NULL)
 		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name);
 
-	purple_conv_im_write(PURPLE_CONV_IM(conv), NULL, message, flags, mtime);
+	purple_conv_im_write(PURPLE_CONV_IM(conv), name, message, flags, mtime);
 	g_free(message);
 
 	/*
--- a/libpurple/status.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/status.c	Sun Apr 13 22:46:58 2008 +0000
@@ -130,14 +130,15 @@
 	-100,   /* away                     */
 	-200,   /* extended away            */
 	-400,   /* mobile                   */
+	0,      /* tune                     */
 	-10,    /* idle, special case.      */
 	-5,     /* idle time, special case. */
 	10      /* Offline messageable      */
 };
 
-#define SCORE_IDLE      8
-#define SCORE_IDLE_TIME 9
-#define SCORE_OFFLINE_MESSAGE 10
+#define SCORE_IDLE      9
+#define SCORE_IDLE_TIME 10
+#define SCORE_OFFLINE_MESSAGE 11
 
 /**************************************************************************
  * PurpleStatusPrimitive API
--- a/libpurple/status.h	Tue Apr 08 06:17:41 2008 +0000
+++ b/libpurple/status.h	Sun Apr 13 22:46:58 2008 +0000
@@ -96,7 +96,8 @@
  */
 /*
  * If you add a value to this enum, make sure you update
- * the status_primitive_map array in status.c.
+ * the status_primitive_map array in status.c and the special-cases for idle
+ * and offline-messagable just below it.
  */
 typedef enum
 {
@@ -110,7 +111,6 @@
 	PURPLE_STATUS_MOBILE,
 	PURPLE_STATUS_TUNE,
 	PURPLE_STATUS_NUM_PRIMITIVES
-
 } PurpleStatusPrimitive;
 
 #include "account.h"
--- a/pidgin/gtkblist.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/gtkblist.c	Sun Apr 13 22:46:58 2008 +0000
@@ -1033,6 +1033,7 @@
 		g_free(title);
 
 		purple_blist_node_set_bool(node, "collapsed", FALSE);
+		pidgin_blist_tooltip_destroy();
 	}
 }
 
@@ -1070,7 +1071,7 @@
 				pidgin_blist_update_contact(NULL, cnode);
 			}
 		}
-
+		pidgin_blist_tooltip_destroy();
 	} else if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
 		pidgin_blist_collapse_contact_cb(NULL, node);
 	}
--- a/pidgin/gtkconv.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/gtkconv.c	Sun Apr 13 22:46:58 2008 +0000
@@ -1869,6 +1869,22 @@
 }
 
 static void
+activate_list_cb(GtkTreeView *list, GtkTreePath *path, GtkTreeViewColumn *column, PidginConversation *gtkconv)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	gchar *who;
+	
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
+
+	gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
+	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
+	chat_do_im(gtkconv, who);
+
+	g_free(who);
+}
+
+static void
 move_to_next_unread_tab(PidginConversation *gtkconv, gboolean forward)
 {
 	PidginConversation *next_gtkconv = NULL, *most_active = NULL;
@@ -4597,6 +4613,8 @@
 
 	g_signal_connect(G_OBJECT(list), "button_press_event",
 					 G_CALLBACK(right_click_chat_cb), gtkconv);
+	g_signal_connect(G_OBJECT(list), "row-activated",
+					 G_CALLBACK(activate_list_cb), gtkconv);
 	g_signal_connect(G_OBJECT(list), "popup-menu",
 			 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv);
 	g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv);
@@ -5502,7 +5520,7 @@
 	account = purple_conversation_get_account(conv);
 	g_return_if_fail(account != NULL);
 	gc = purple_account_get_connection(account);
-	g_return_if_fail(gc != NULL);
+	g_return_if_fail(gc != NULL || !(flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)));
 
 	/* Make sure URLs are clickable */
 	if(flags & PURPLE_MESSAGE_NO_LINKIFY)
@@ -5535,7 +5553,7 @@
 	}
 
 	win = gtkconv->win;
-	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+	prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
 
 	line_count = gtk_text_buffer_get_line_count(
 			gtk_text_view_get_buffer(GTK_TEXT_VIEW(
@@ -5774,7 +5792,7 @@
 		g_free(alias_escaped);
 
 		/* Are we in a chat where we can tell which users are buddies? */
-		if  (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) &&
+		if  (prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) &&
 		     purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 
 			/* Bold buddies to make them stand out from non-buddies. */
@@ -6613,7 +6631,9 @@
 				markup = title;
 			}
 		} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
-			const char *topic = gtkconv->u.chat->topic_text ? gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text)) : NULL;
+			const char *topic = gtkconv->u.chat->topic_text
+				? gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text))
+				: NULL;
 			char *esc = NULL, *tmp;
 #if GTK_CHECK_VERSION(2,6,0)
 			esc = topic ? g_markup_escape_text(topic, -1) : NULL;
@@ -6623,20 +6643,22 @@
 			int len = 0;
 			char *c;
 
-			tmp = g_strdup(topic);
-			c = tmp;
-			while(*c && len < 72) {
-				c = g_utf8_next_char(c);
-				len++;
+			if (topic != NULL) {
+				tmp = g_strdup(topic);
+				c = tmp;
+				while(*c && len < 72) {
+					c = g_utf8_next_char(c);
+					len++;
+				}
+				if (len == 72) {
+					*c = '\0';
+					c = g_strdup_printf("%s...", tmp);
+					g_free(tmp);
+					tmp = c;
+				}
+				esc = g_markup_escape_text(tmp, -1);
+				g_free(tmp);
 			}
-			if (len == 72) {
-				*c = '\0';
-				c = g_strdup_printf("%s...", tmp);
-				g_free(tmp);
-				tmp = c;
-			}
-			esc = tmp ? g_markup_escape_text(tmp, -1) : NULL;
-			g_free(tmp);
 #endif
 			tmp = g_markup_escape_text(purple_conversation_get_title(conv), -1);
 			markup = g_strdup_printf("%s%s<span color='%s' size='smaller'>%s</span>",
--- a/pidgin/gtkimhtml.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/gtkimhtml.c	Sun Apr 13 22:46:58 2008 +0000
@@ -363,17 +363,17 @@
 	GtkTextIter iter;
 	gboolean scroll = TRUE;
 
-        gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter);
+	gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter);
 
 	gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &rect);
-        gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height);
-
-	if(((y + height) - (rect.y + rect.height)) > height
-           && gtk_text_buffer_get_char_count(imhtml->text_buffer)){
-                scroll = FALSE;
-        }
-
-	if(imhtml->old_rect.width != rect.width || imhtml->old_rect.height != rect.height){
+	gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height);
+
+	if (((y + height) - (rect.y + rect.height)) > height &&
+			gtk_text_buffer_get_char_count(imhtml->text_buffer)) {
+		scroll = FALSE;
+	}
+
+	if(imhtml->old_rect.width != rect.width || imhtml->old_rect.height != rect.height) {
 		GList *iter = GTK_IMHTML(widget)->scalables;
 
 		xminus = gtk_text_view_get_left_margin(GTK_TEXT_VIEW(widget)) +
@@ -390,11 +390,11 @@
 
 	imhtml->old_rect = rect;
 	parent_size_allocate(widget, alloc);
-	
+
 	/* Don't scroll here if we're in the middle of a smooth scroll */
 	if (scroll && imhtml->scroll_time == NULL &&
- 	    GTK_WIDGET_REALIZED(imhtml)) 
-		gtk_imhtml_scroll_to_end(imhtml, FALSE);	
+	    GTK_WIDGET_REALIZED(imhtml))
+		gtk_imhtml_scroll_to_end(imhtml, FALSE);
 }
 
 static gint
@@ -583,12 +583,12 @@
 	/* If we don't have a tip from a URL, let's see if we have a tip from a smiley */
 	anchor = gtk_text_iter_get_child_anchor(&iter);
 	if (anchor) {
-		tip = g_object_get_data(G_OBJECT(anchor), "gtkimhtml_plaintext");
+		tip = g_object_get_data(G_OBJECT(anchor), "gtkimhtml_tiptext");
 		hand = FALSE;
 	}
 //yaz here bomb explodes
 #if 1
-	if (tip){
+	if (tip && *tip) {
 		if (!GTK_IMHTML(imhtml)->editable && hand)
 			gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->hand_cursor);
 		GTK_IMHTML(imhtml)->tip_timer = g_timeout_add (TOOLTIP_TIMEOUT,
@@ -2276,8 +2276,7 @@
 					 GSList *unused)
 {
 	GtkTextIter iter, ins, sel;
-	GdkRectangle rect;
-	int y, height, ins_offset = 0, sel_offset = 0;
+	int ins_offset = 0, sel_offset = 0;
 	gboolean fixins = FALSE, fixsel = FALSE;
 
 	g_return_if_fail (imhtml != NULL);
@@ -2298,13 +2297,17 @@
 		sel_offset = gtk_text_iter_get_offset(&sel);
 	}
 
-	gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect);
-	gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height);
-
-
-	if(((y + height) - (rect.y + rect.height)) > height
-	   && gtk_text_buffer_get_char_count(imhtml->text_buffer)){
-		options |= GTK_IMHTML_NO_SCROLL;
+	if (!(options & GTK_IMHTML_NO_SCROLL)) {
+		GdkRectangle rect;
+		int y, height;
+
+		gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect);
+		gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height);
+
+		if (((y + height) - (rect.y + rect.height)) > height &&
+				gtk_text_buffer_get_char_count(imhtml->text_buffer)) {
+			options |= GTK_IMHTML_NO_SCROLL;
+		}
 	}
 
 	gtk_imhtml_insert_html_at_iter(imhtml, text, options, &iter);
@@ -4721,8 +4724,11 @@
 	}
 
 	if (icon) {
+		char *text = g_strdup(unescaped); /* Do not g_free 'text'.
+		                                     It will be destroyed when 'anchor' is destroyed. */
 		anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
-		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free);
+		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", text, g_free);
+		g_object_set_data(G_OBJECT(anchor), "gtkimhtml_tiptext", text);
 		g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free);
 
 		/* This catches the expose events generated by animated
@@ -4740,9 +4746,11 @@
 		imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor);
 		if (ebox) {
 			GtkWidget *img = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU);
+			char *text = g_strdup(unescaped);
 			gtk_container_add(GTK_CONTAINER(ebox), img);
 			gtk_widget_show(img);
-			g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free);
+			g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", text, g_free);
+			g_object_set_data(G_OBJECT(anchor), "gtkimhtml_tiptext", text);
 			gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor);
 		}
 	} else {
--- a/pidgin/gtkmain.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/gtkmain.c	Sun Apr 13 22:46:58 2008 +0000
@@ -299,7 +299,7 @@
 	purple_sound_set_ui_ops(pidgin_sound_get_ui_ops());
 	purple_connections_set_ui_ops(pidgin_connections_get_ui_ops());
 	purple_whiteboard_set_ui_ops(pidgin_whiteboard_get_ui_ops());
-#ifdef USE_SCREENSAVER
+#if defined(USE_SCREENSAVER) || defined(HAVE_IOKIT)
 	purple_idle_set_ui_ops(pidgin_idle_get_ui_ops());
 #endif
 
--- a/pidgin/gtkplugin.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/gtkplugin.c	Sun Apr 13 22:46:58 2008 +0000
@@ -42,7 +42,15 @@
 
 static GtkWidget *expander = NULL;
 static GtkWidget *plugin_dialog = NULL;
-static GtkWidget *plugin_details = NULL;
+
+static GtkLabel *plugin_name = NULL;
+static GtkTextBuffer *plugin_desc = NULL;
+static GtkLabel *plugin_error = NULL;
+static GtkLabel *plugin_author = NULL;
+static GtkLabel *plugin_website = NULL;
+static gchar *plugin_website_uri = NULL;
+static GtkLabel *plugin_filename = NULL;
+
 static GtkWidget *pref_button = NULL;
 static GHashTable *plugin_pref_dialogs = NULL;
 
@@ -301,9 +309,6 @@
 
 static void plugin_toggled_stage_two(PurplePlugin *plug, GtkTreeModel *model, GtkTreeIter *iter, gboolean unload)
 {
-	gchar *name = NULL;
-	gchar *description = NULL;
-
 	if (unload)
 	{
 		pidgin_set_cursor(plugin_dialog, GDK_WATCH);
@@ -337,30 +342,30 @@
 		 || (plug->info->prefs_info
 			&& plug->info->prefs_info->get_plugin_pref_frame)));
 
-	name = g_markup_escape_text(_(plug->info->name), -1);
-	description = g_markup_escape_text(_(plug->info->description), -1);
+	if (plug->error != NULL)
+	{
+		gchar *name = g_markup_escape_text(_(plug->info->name), -1);
 
-	if (plug->error != NULL) {
 		gchar *error = g_markup_escape_text(plug->error, -1);
-		gchar *desc;
-		gchar *text = g_strdup_printf(
-				   "<span size=\"larger\">%s %s</span>\n\n"
-				   "<span weight=\"bold\" color=\"red\">%s</span>\n\n"
-				   "%s",
-				   name, plug->info->version, error, description);
-		desc = g_strdup_printf("<b>%s</b> %s\n<span weight=\"bold\" color=\"red\"%s</span>",
-			       plug->info->name, plug->info->version, error);
+		gchar *text;
+
+		text = g_strdup_printf(
+			"<b>%s</b> %s\n<span weight=\"bold\" color=\"red\"%s</span>",
+			plug->info->name, plug->info->version, error);
 		gtk_list_store_set(GTK_LIST_STORE (model), iter,
-				   1, desc,
+				   1, text,
 				   -1);
-		g_free(desc);
+		g_free(text);
+
+		text = g_strdup_printf(
+			"<span weight=\"bold\" color=\"red\">%s</span>",
+			error);
+		gtk_label_set_markup(plugin_error, text);
+		g_free(text);
+
 		g_free(error);
-		gtk_label_set_markup(GTK_LABEL(plugin_details), text);
-		g_free(text);
+		g_free(name);
 	}
-	g_free(name);
-	g_free(description);
-
 
 	gtk_list_store_set(GTK_LIST_STORE (model), iter,
 	                   0, purple_plugin_is_loaded(plug),
@@ -387,15 +392,13 @@
 
 static void prefs_plugin_sel (GtkTreeSelection *sel, GtkTreeModel *model)
 {
-	gchar *buf, *pname, *pdesc, *pauth, *pweb;
+	gchar *buf, *tmp, *name, *version;
 	GtkTreeIter  iter;
 	GValue val;
 	PurplePlugin *plug;
 
 	if (!gtk_tree_selection_get_selected (sel, &model, &iter))
 	{
-		/* Clear the old plugin details */
-		gtk_label_set_markup(GTK_LABEL(plugin_details), "");
 		gtk_widget_set_sensitive(pref_button, FALSE);
 
 		/* Collapse and disable the expander widget */
@@ -411,32 +414,51 @@
 	gtk_tree_model_get_value (model, &iter, 2, &val);
 	plug = g_value_get_pointer(&val);
 
-	pname = g_markup_escape_text(_(plug->info->name), -1);
-	pdesc = (plug->info->description) ?
-			g_markup_escape_text(_(plug->info->description), -1) : NULL;
-	pauth = (plug->info->author) ?
-			g_markup_escape_text(_(plug->info->author), -1) : NULL;
-	pweb = (plug->info->homepage) ?
-		   g_markup_escape_text(_(plug->info->homepage), -1) : NULL;
+	name = g_markup_escape_text(_(plug->info->name), -1);
+	version = g_markup_escape_text(plug->info->version, -1);
 	buf = g_strdup_printf(
-		   _("%s%s"
-		     "<span weight=\"bold\">Written by:</span>\t%s\n"
-		     "<span weight=\"bold\">Website:</span>\t\t%s\n"
-		     "<span weight=\"bold\">Filename:</span>\t\t%s"),
-		   pdesc ? pdesc : "", pdesc ? "\n\n" : "",
-		   pauth ? pauth : "", pweb ? pweb : "", plug->path);
+		"<span size=\"larger\" weight=\"bold\">%s</span> "
+		"<span size=\"smaller\">%s</span>",
+		name, version);
+	gtk_label_set_markup(plugin_name, buf);
+	g_free(buf);
+
+	gtk_text_buffer_set_text(plugin_desc, plug->info->description, -1);
+	gtk_label_set_text(plugin_author, plug->info->author);
+	gtk_label_set_text(plugin_filename, plug->path);
 
-	if (plug->error != NULL)
+	g_free(plugin_website_uri);
+	plugin_website_uri = g_strdup(plug->info->homepage);
+	if (plugin_website_uri)
+	{
+		tmp = g_markup_escape_text(plugin_website_uri, -1);
+		buf = g_strdup_printf("<span underline=\"single\" "
+			"foreground=\"blue\">%s</span>", tmp);
+		gtk_label_set_markup(plugin_website, buf);
+		g_free(tmp);
+		g_free(buf);
+	}
+	else
 	{
-		char *tmp = g_strdup_printf(
-			_("%s\n"
-			  "<span foreground=\"#ff0000\" weight=\"bold\">"
+		gtk_label_set_text(plugin_website, NULL);
+	}
+
+	if (plug->error == NULL)
+	{
+		gtk_label_set_text(plugin_error, NULL);
+	}
+	else
+	{
+		tmp = g_markup_escape_text(plug->error, -1);
+		buf = g_strdup_printf(
+			_("<span foreground=\"red\" weight=\"bold\">"
 			  "Error: %s\n"
 			  "Check the plugin website for an update."
 			  "</span>"),
-			buf, plug->error);
+			tmp);
+		gtk_label_set_markup(plugin_error, buf);
 		g_free(buf);
-		buf = tmp;
+		g_free(tmp);
 	}
 
 	gtk_widget_set_sensitive(pref_button,
@@ -446,18 +468,10 @@
 		 || (plug->info->prefs_info
 			&& plug->info->prefs_info->get_plugin_pref_frame)));
 
-	gtk_label_set_markup(GTK_LABEL(plugin_details), buf);
-
 	/* Make sure the selected plugin is still visible */
 	g_idle_add(ensure_plugin_visible, sel);
 
-
 	g_value_unset(&val);
-	g_free(buf);
-	g_free(pname);
-	g_free(pdesc);
-	g_free(pauth);
-	g_free(pweb);
 }
 
 static void plugin_dialog_response_cb(GtkWidget *d, int response, GtkTreeSelection *sel)
@@ -588,6 +602,102 @@
 	return TRUE;
 }
 
+static gboolean
+website_button_motion_cb(GtkWidget *button, GdkEventCrossing *event,
+                          gpointer unused)
+{
+	if (plugin_website_uri) {
+		pidgin_set_cursor(button, GDK_HAND2);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+website_button_clicked_cb(GtkButton *button, GdkEventButton *event,
+                          gpointer unused)
+{
+	if (plugin_website_uri) {
+		purple_notify_uri(NULL, plugin_website_uri);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static GtkWidget *
+create_details()
+{
+	GtkBox *vbox = GTK_BOX(gtk_vbox_new(FALSE, 3));
+	GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+	GtkWidget *label, *view, *website_button;
+
+	plugin_name = GTK_LABEL(gtk_label_new(NULL));
+	gtk_misc_set_alignment(GTK_MISC(plugin_name), 0, 0);
+	gtk_label_set_line_wrap(plugin_name, FALSE);
+	gtk_label_set_selectable(plugin_name, TRUE);
+	gtk_box_pack_start(vbox, GTK_WIDGET(plugin_name), FALSE, FALSE, 0);
+
+	view = gtk_text_view_new();
+	plugin_desc = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
+	g_object_set(view, "wrap-mode", GTK_WRAP_WORD,
+	                   "editable",  FALSE,
+	                   "left-margin",  PIDGIN_HIG_CAT_SPACE,
+	                   "right-margin", PIDGIN_HIG_CAT_SPACE,
+	                   NULL);
+	gtk_box_pack_start(vbox, view, TRUE, TRUE, 0);
+
+	plugin_error = GTK_LABEL(gtk_label_new(NULL));
+	gtk_misc_set_alignment(GTK_MISC(plugin_error), 0, 0);
+	gtk_label_set_line_wrap(plugin_error, FALSE);
+	gtk_label_set_selectable(plugin_error, TRUE);
+	gtk_box_pack_start(vbox, GTK_WIDGET(plugin_error), FALSE, FALSE, 0);
+
+	plugin_author = GTK_LABEL(gtk_label_new(NULL));
+	gtk_label_set_line_wrap(plugin_author, FALSE);
+	gtk_misc_set_alignment(GTK_MISC(plugin_author), 0, 0);
+	gtk_label_set_selectable(plugin_author, TRUE);
+	pidgin_add_widget_to_vbox(vbox, "", sg,
+		GTK_WIDGET(plugin_author), TRUE, &label);
+	gtk_label_set_markup(GTK_LABEL(label), _("<b>Written by:</b>"));
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+
+	website_button = gtk_event_box_new();
+#if GTK_CHECK_VERSION(2,4,0)
+	gtk_event_box_set_visible_window(GTK_EVENT_BOX(website_button), FALSE);
+#endif
+
+	plugin_website = GTK_LABEL(gtk_label_new(NULL));
+#if GTK_CHECK_VERSION(2,6,0)
+	g_object_set(G_OBJECT(plugin_website),
+		"ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
+#endif
+	gtk_misc_set_alignment(GTK_MISC(plugin_website), 0, 0);
+	gtk_container_add(GTK_CONTAINER(website_button),
+		GTK_WIDGET(plugin_website));
+	g_signal_connect(website_button, "button-release-event",
+		G_CALLBACK(website_button_clicked_cb), NULL);
+	g_signal_connect(website_button, "enter-notify-event",
+		G_CALLBACK(website_button_motion_cb), NULL);
+	g_signal_connect(website_button, "leave-notify-event",
+		G_CALLBACK(pidgin_clear_cursor), NULL);
+
+	pidgin_add_widget_to_vbox(vbox, "", sg, website_button, TRUE, &label);
+	gtk_label_set_markup(GTK_LABEL(label), _("<b>Web site:</b>"));
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+	plugin_filename = GTK_LABEL(gtk_label_new(NULL));
+	gtk_label_set_line_wrap(plugin_filename, FALSE);
+	gtk_misc_set_alignment(GTK_MISC(plugin_filename), 0, 0);
+	gtk_label_set_selectable(plugin_filename, TRUE);
+	pidgin_add_widget_to_vbox(vbox, "", sg,
+		GTK_WIDGET(plugin_filename), TRUE, &label);
+	gtk_label_set_markup(GTK_LABEL(label), _("<b>Filename:</b>"));
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+
+	return GTK_WIDGET(vbox);
+}
+
+
 void pidgin_plugin_dialog_show()
 {
 	GtkWidget *sw;
@@ -674,16 +784,17 @@
 			pidgin_plugins_create_tooltip,
 			pidgin_plugins_paint_tooltip);
 
+
 	expander = gtk_expander_new(_("<b>Plugin Details</b>"));
 	gtk_expander_set_use_markup(GTK_EXPANDER(expander), TRUE);
-	plugin_details = gtk_label_new(NULL);
-	gtk_label_set_line_wrap(GTK_LABEL(plugin_details), TRUE);
-	gtk_container_add(GTK_CONTAINER(expander), plugin_details);
 	gtk_widget_set_sensitive(expander, FALSE);
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), expander, FALSE, FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(expander), create_details());
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), expander,
+		FALSE, FALSE, 0);
+
 
 	g_signal_connect (G_OBJECT (sel), "changed", G_CALLBACK (prefs_plugin_sel), NULL);
 	g_signal_connect(G_OBJECT(plugin_dialog), "response", G_CALLBACK(plugin_dialog_response_cb), sel);
-	gtk_window_set_default_size(GTK_WINDOW(plugin_dialog), 430, 430);
+	gtk_window_set_default_size(GTK_WINDOW(plugin_dialog), 430, 530);
 	gtk_widget_show_all(plugin_dialog);
 }
--- a/pidgin/gtkutils.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/gtkutils.c	Sun Apr 13 22:46:58 2008 +0000
@@ -2262,7 +2262,7 @@
 	if (widget->window == NULL)
 		return;
 
-	cursor = gdk_cursor_new(GDK_WATCH);
+	cursor = gdk_cursor_new(cursor_type);
 	gdk_window_set_cursor(widget->window, cursor);
 	gdk_cursor_unref(cursor);
 
--- a/pidgin/pixmaps/Makefile.am	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/pixmaps/Makefile.am	Sun Apr 13 22:46:58 2008 +0000
@@ -538,7 +538,9 @@
 		status/48/person.png
 
 STATUS_48_RTL = \
-		status/48/rtl/extended-away.png
+		status/48/rtl/extended-away.png \
+		status/48/rtl/login.png \
+		status/48/rtl/logout.png
 
 TOOLBAR_11 = \
 		toolbar/11/message-new.png
--- a/pidgin/pixmaps/emotes/default/24/scalable/shock.svg	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/pixmaps/emotes/default/24/scalable/shock.svg	Sun Apr 13 22:46:58 2008 +0000
@@ -2,7 +2,7 @@
 <!-- Created with Inkscape (http://www.inkscape.org/) -->
 <svg
    xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:cc="http://creativecommons.org/ns#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
@@ -13,16 +13,23 @@
    height="24"
    id="svg2"
    sodipodi:version="0.32"
-   inkscape:version="0.45.1"
+   inkscape:version="0.46"
    version="1.0"
    sodipodi:docbase="/home/hbons/Desktop"
-   sodipodi:docname="new-style-shock.svg"
+   sodipodi:docname="shock.svg"
    inkscape:export-filename="/home/hbons/Desktop/newstyle.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90"
    inkscape:output_extension="org.inkscape.output.svg.inkscape">
   <defs
      id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 12 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="24 : 12 : 1"
+       inkscape:persp3d-origin="12 : 8 : 1"
+       id="perspective29" />
     <linearGradient
        inkscape:collect="always"
        id="linearGradient3263">
@@ -88,16 +95,26 @@
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
      inkscape:zoom="22.4"
-     inkscape:cx="26.558313"
-     inkscape:cy="10.870659"
+     inkscape:cx="13.477956"
+     inkscape:cy="11.67423"
      inkscape:document-units="px"
      inkscape:current-layer="layer1"
      showgrid="true"
      fill="#fce94f"
      inkscape:window-width="1440"
-     inkscape:window-height="845"
+     inkscape:window-height="846"
      inkscape:window-x="0"
-     inkscape:window-y="0" />
+     inkscape:window-y="25"
+     inkscape:snap-bbox="true"
+     inkscape:snap-nodes="false"
+     objecttolerance="9"
+     gridtolerance="9">
+    <inkscape:grid
+       type="xygrid"
+       visible="true"
+       enabled="true"
+       id="grid2402" />
+  </sodipodi:namedview>
   <metadata
      id="metadata7">
     <rdf:RDF>
@@ -155,7 +172,7 @@
        transform="matrix(0.852176,0,0,0.852216,1.93909,2.639626)" />
     <path
        style="fill:#eeeeec;fill-opacity:1;stroke:#fea523;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1"
-       d="M 11.499998,9.5 C 11.499998,11.156 10.156,12.5 8.4999995,12.5 C 6.844,12.5 5.5000002,11.156 5.5000002,9.5 C 5.5000002,7.844 6.844,6.5 8.4999995,6.5 C 10.156,6.5 11.499998,7.844 11.499998,9.5 z "
+       d="M 11.499998,9.0000003 C 11.499998,10.932 10.156,12.5 8.4999995,12.5 C 6.844,12.5 5.5000002,10.932 5.5000002,9.0000003 C 5.5000002,7.0680003 6.844,5.5000002 8.4999995,5.5000002 C 10.156,5.5000002 11.499998,7.0680003 11.499998,9.0000003 z"
        id="path3154" />
     <path
        sodipodi:type="arc"
@@ -169,14 +186,14 @@
        transform="matrix(0.9747196,0,0,0.7726436,0.5384595,3.0419202)" />
     <path
        sodipodi:type="arc"
-       style="opacity:1;fill:#eeeeec;fill-opacity:1;stroke:#fea523;stroke-width:0.47042996;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="opacity:1;fill:#eeeeec;fill-opacity:1;stroke:#fea523;stroke-width:0.43553349;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="path3152"
        sodipodi:cx="9.7069349"
        sodipodi:cy="9.6526775"
        sodipodi:rx="1.0259361"
        sodipodi:ry="1.9413869"
-       d="M 10.732871 9.6526775 A 1.0259361 1.9413869 0 1 1  8.6809988,9.6526775 A 1.0259361 1.9413869 0 1 1  10.732871 9.6526775 z"
-       transform="matrix(2.9241589,0,0,1.5452871,-12.884621,-5.4161575)" />
+       d="M 10.732871,9.6526775 A 1.0259361,1.9413869 0 1 1 8.6809988,9.6526775 A 1.0259361,1.9413869 0 1 1 10.732871,9.6526775 z"
+       transform="matrix(2.9241589,0,0,1.802835,-12.884621,-8.4021847)" />
     <path
        sodipodi:type="arc"
        style="opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.98640186;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
@@ -196,7 +213,7 @@
        sodipodi:rx="1.2276785"
        sodipodi:ry="1.7410715"
        d="M 7.2133909,8.4869402 A 1.2276785,1.7410715 0 0 1 9.288462,8.1425499"
-       transform="matrix(1.8690368,0.3494647,-0.353133,0.9196421,3.0149257,-5.2342213)"
+       transform="matrix(1.8690368,0.3494647,-0.353133,0.9196421,3.0149257,-6.2342213)"
        sodipodi:start="3.5782199"
        sodipodi:end="5.6135639"
        sodipodi:open="true" />
@@ -209,7 +226,7 @@
        sodipodi:rx="1.2276785"
        sodipodi:ry="1.7410715"
        d="M 7.2133909,8.4869402 A 1.2276785,1.7410715 0 0 1 9.288462,8.1425499"
-       transform="matrix(-1.8690368,0.3494647,0.353133,0.9196421,20.985074,-5.2342213)"
+       transform="matrix(-1.8690368,0.3494647,0.353133,0.9196421,20.985074,-6.2342213)"
        sodipodi:start="3.5782199"
        sodipodi:end="5.6135639"
        sodipodi:open="true" />
@@ -221,17 +238,17 @@
        sodipodi:cy="15.741072"
        sodipodi:rx="2.0982144"
        sodipodi:ry="1.7857143"
-       d="M 13.928572 15.741072 A 2.0982144 1.7857143 0 1 1  9.7321432,15.741072 A 2.0982144 1.7857143 0 1 1  13.928572 15.741072 z"
-       transform="matrix(1.4297873,0,0,1.3999999,-4.9148951,-5.5374984)" />
+       d="M 13.928572,15.741072 A 2.0982144,1.7857143 0 1 1 9.7321432,15.741072 A 2.0982144,1.7857143 0 1 1 13.928572,15.741072 z"
+       transform="matrix(1.4297873,0,0,1.3999998,-4.9148951,-5.5374976)" />
     <path
        sodipodi:type="arc"
-       style="opacity:1;fill:url(#linearGradient3269);fill-opacity:1.0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="opacity:1;fill:url(#linearGradient3269);fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="path3261"
        sodipodi:cx="11.830358"
        sodipodi:cy="15.741072"
        sodipodi:rx="2.0982144"
        sodipodi:ry="1.7857143"
-       d="M 13.928572 15.741072 A 2.0982144 1.7857143 0 1 1  9.7321432,15.741072 A 2.0982144 1.7857143 0 1 1  13.928572 15.741072 z"
-       transform="matrix(1.4297873,0,0,1.3999999,-4.9148951,-5.5374984)" />
+       d="M 13.928572,15.741072 A 2.0982144,1.7857143 0 1 1 9.7321432,15.741072 A 2.0982144,1.7857143 0 1 1 13.928572,15.741072 z"
+       transform="matrix(1.4297873,0,0,1.3999998,-4.9148951,-5.5374976)" />
   </g>
 </svg>
Binary file pidgin/pixmaps/emotes/default/24/shock.png has changed
Binary file pidgin/pixmaps/status/11/away.png has changed
Binary file pidgin/pixmaps/status/48/available.png has changed
Binary file pidgin/pixmaps/status/48/away.png has changed
Binary file pidgin/pixmaps/status/48/busy.png has changed
Binary file pidgin/pixmaps/status/48/chat.png has changed
Binary file pidgin/pixmaps/status/48/extended-away.png has changed
Binary file pidgin/pixmaps/status/48/offline.png has changed
Binary file pidgin/pixmaps/status/48/rtl/login.png has changed
Binary file pidgin/pixmaps/status/48/rtl/logout.png has changed
--- a/pidgin/plugins/cap/cap.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/plugins/cap/cap.c	Sun Apr 13 22:46:58 2008 +0000
@@ -894,7 +894,7 @@
 	N_("Contact Availability Prediction"),				/**< name		*/
 	DISPLAY_VERSION,									/**< version		*/
 	N_("Contact Availability Prediction plugin."),	/**  summary		*/
-	N_("The contact availability plugin (cap) is used to display statistical information about buddies in a users contact list."),
+	N_("Displays statistical information about your buddies' availability"),
 	/**  description	*/
 	"Geoffrey Foster <geoffrey.foster@gmail.com>",	/**< author		*/
 	PURPLE_WEBSITE,									/**< homepage		*/
--- a/pidgin/plugins/gestures/gestures.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/plugins/gestures/gestures.c	Sun Apr 13 22:46:58 2008 +0000
@@ -297,12 +297,12 @@
 	                                                  /**  summary        */
 	N_("Provides support for mouse gestures"),
 	                                                  /**  description    */
-	N_("Allows support for mouse gestures in conversation windows.\n"
-	   "Drag the middle mouse button to perform certain actions:\n\n"
-	   "Drag down and then to the right to close a conversation.\n"
-	   "Drag up and then to the left to switch to the previous "
+	N_("Allows support for mouse gestures in conversation windows. "
+	   "Drag the middle mouse button to perform certain actions:\n"
+	   " • Drag down and then to the right to close a conversation.\n"
+	   " • Drag up and then to the left to switch to the previous "
 	   "conversation.\n"
-	   "Drag up and then to the right to switch to the next "
+	   " • Drag up and then to the right to switch to the next "
 	   "conversation."),
 	"Christian Hammond <chipx86@gnupdate.org>",       /**< author         */
 	PURPLE_WEBSITE,                                     /**< homepage       */
--- a/pidgin/plugins/notify.c	Tue Apr 08 06:17:41 2008 +0000
+++ b/pidgin/plugins/notify.c	Sun Apr 13 22:46:58 2008 +0000
@@ -909,7 +909,7 @@
 	                                                  /**  description    */
 	N_("Provides a variety of ways of notifying you of unread messages."),
 	                                                  /**< author         */
-	"Etan Reisner <deryni@eden.rutgers.edu>\n\t\t\tBrian Tarricone <bjt23@cornell.edu>",
+	"Etan Reisner <deryni@eden.rutgers.edu>,\nBrian Tarricone <bjt23@cornell.edu>",
 	PURPLE_WEBSITE,                                     /**< homepage       */
 
 	plugin_load,                                      /**< load           */
--- a/po/de.po	Tue Apr 08 06:17:41 2008 +0000
+++ b/po/de.po	Sun Apr 13 22:46:58 2008 +0000
@@ -11,8 +11,8 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-04-05 13:11+0200\n"
-"PO-Revision-Date: 2008-04-05 13:11+0200\n"
+"POT-Creation-Date: 2008-04-12 10:45+0200\n"
+"PO-Revision-Date: 2008-04-12 10:45+0200\n"
 "Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -611,7 +611,7 @@
 msgstr "Buddy-Alarm hinzufügen..."
 
 msgid "View Log..."
-msgstr "Mitschnitt anzeigen.."
+msgstr "Mitschnitt anzeigen..."
 
 msgid "Enable Logging"
 msgstr "Mitschnitt einschalten"
@@ -752,17 +752,26 @@
 
 #, c-format
 msgid "%.2f KiB/s"
-msgstr "%.2f KB/s"
+msgstr "%.2f KiB/s"
+
+msgid "Sent"
+msgstr "Gesendet"
+
+msgid "Received"
+msgstr "Empfangen"
+
+msgid "Finished"
+msgstr "Fertig"
 
 #, c-format
 msgid "The file was saved as %s."
 msgstr "Die Datei wurde unter %s gespeichert."
 
-msgid "Finished"
-msgstr "Fertig"
-
-msgid "Transferring"
-msgstr "Übertragung"
+msgid "Sending"
+msgstr "Sende"
+
+msgid "Receiving"
+msgstr "Empfange"
 
 #, c-format
 msgid "Conversation in %s on %s"
@@ -5212,7 +5221,10 @@
 "versuchen Sie es später nochmal."
 
 msgid "Handshaking"
-msgstr "Händedruck"
+msgstr "Abgleich"
+
+msgid "Transferring"
+msgstr "Übertrage"
 
 msgid "Starting authentication"
 msgstr "Starte Authentifizierung"
@@ -11312,6 +11324,23 @@
 msgid "Color to draw the name of an action message."
 msgstr "Farbe, mit der der Name in einer Aktions-Nachricht dargestellt wird."
 
+msgid "Typing notification color"
+msgstr "Farbe der Tipp-Benachrichtigung"
+
+msgid "The color to use for the typing notification font"
+msgstr ""
+"Die Farbe, die für die Tipp-Benachrichtigungsmeldung benutzt werden soll"
+
+msgid "Typing notification font"
+msgstr "Tipp-Benachrichtigungs-Schriftart"
+
+msgid "The font to use for the typing notification"
+msgstr ""
+"Die Schriftart, die für die Tipp-Benachrichtigungsmeldung benutzt werden soll"
+
+msgid "Enable typing notification"
+msgstr "Tipp-Benachrichtigung aktivieren"
+
 msgid "_Copy E-Mail Address"
 msgstr "Kopiere _E-Mail-Adresse"
 
@@ -11710,27 +11739,24 @@
 
 #, c-format
 msgid ""
-"%s%s<span weight=\"bold\">Written by:</span>\t%s\n"
-"<span weight=\"bold\">Website:</span>\t\t%s\n"
-"<span weight=\"bold\">Filename:</span>\t\t%s"
-msgstr ""
-"%s%s<span weight=\"bold\">Geschrieben von:</span>\t%s\n"
-"<span weight=\"bold\">Webseite: </span>\t\t%s\n"
-"<span weight=\"bold\">Dateiname:</span>\t\t%s"
-
-#, c-format
-msgid ""
-"%s\n"
-"<span foreground=\"#ff0000\" weight=\"bold\">Error: %s\n"
+"<span foreground=\"red\" weight=\"bold\">Error: %s\n"
 "Check the plugin website for an update.</span>"
 msgstr ""
-"%s\n"
-"<span foreground=\"#ff0000\" weight=\"bold\">Fehler: %s\n"
+"<span foreground=\"red\" weight=\"bold\">Fehler: %s\n"
 "Überprüfen Sie die Website des Plugins auf eine neue Version.</span>"
 
 msgid "Author"
 msgstr "Autor"
 
+msgid "<b>Written by:</b>"
+msgstr "<b>Geschrieben von:</b>"
+
+msgid "<b>Web site:</b>"
+msgstr "<b>Webseite:</b>"
+
+msgid "<b>Filename:</b>"
+msgstr "<b>Dateiname:</b>"
+
 msgid "Configure Pl_ugin"
 msgstr "Pl_ugin konfigurieren"
 
@@ -12481,12 +12507,8 @@
 msgstr "Kontakt-Verfügbarkeits-Vorhersage-Plugin."
 
 #. *  summary
-msgid ""
-"The contact availability plugin (cap) is used to display statistical "
-"information about buddies in a users contact list."
-msgstr ""
-"Das Kontakt-Verfügbarkeits-Plugin (cap) wird benutzt um statistische "
-"Informationen über Buddys anzuzeigen."
+msgid "Displays statistical information about your buddies' availability"
+msgstr "Statistische Informationen über die Verfügbarkeit Ihrer Buddys zeigen"
 
 msgid "Buddy is idle"
 msgstr "Buddy ist untätig"
@@ -12636,7 +12658,7 @@
 
 #. "Visual gesture display" checkbox
 msgid "_Visual gesture display"
-msgstr "_Gestiken anzeigen"
+msgstr "_Gesten anzeigen"
 
 #. *< type
 #. *< ui_requirement
@@ -12645,29 +12667,27 @@
 #. *< priority
 #. *< id
 msgid "Mouse Gestures"
-msgstr "Maus-Gestiken"
+msgstr "Maus-Gesten"
 
 #. *< name
 #. *< version
 #. *  summary
 msgid "Provides support for mouse gestures"
-msgstr "Ermöglicht die Bedienung mit Maus-Gestiken"
+msgstr "Ermöglicht die Bedienung mit Maus-Gesten"
 
 #. *  description
 msgid ""
-"Allows support for mouse gestures in conversation windows.\n"
-"Drag the middle mouse button to perform certain actions:\n"
-"\n"
-"Drag down and then to the right to close a conversation.\n"
-"Drag up and then to the left to switch to the previous conversation.\n"
-"Drag up and then to the right to switch to the next conversation."
-msgstr ""
-"Ermöglicht das Benutzen von Maus-Gestiken im Gesprächsfenster. Halten Sie "
-"die mittlere Maustaste gedrückt um folgende Aktionen auszuführen:\n"
-"\n"
-"Herunterziehen und dann nach rechts, um ein Gespräch zu beenden. Hochziehen "
-"und dann nach links, um auf ein voriges Gespräch zu wechseln. Hochziehen und "
-"dann nach rechts, um zum nächsten Gespräche zu wechseln."
+"Allows support for mouse gestures in conversation windows. Drag the middle "
+"mouse button to perform certain actions:\n"
+" • Drag down and then to the right to close a conversation.\n"
+" • Drag up and then to the left to switch to the previous conversation.\n"
+" • Drag up and then to the right to switch to the next conversation."
+msgstr ""
+"Ermöglicht das Benutzen von Maus-Gesten in Gesprächsfenstern. Halten Sie die "
+"mittlere Maustaste gedrückt um folgende Aktionen auszuführen:\n"
+" • Herunterziehen und dann nach rechts, um ein Gespräch zu beenden.\n"
+" • Hochziehen und dann nach links, um auf ein voriges Gespräch zu wechseln.\n"
+" • Hochziehen und dann nach rechts, um zum nächsten Gespräche zu wechseln."
 
 msgid "Instant Messaging"
 msgstr "Sofortnachrichten"