changeset 17781:78b2d9f6c7c1

merge of '5cdcf39e21d4c670562fa2acfe8520f8ee140262' and '7aef540f0fc83c1f0c8dcaec723c7d8caaacfb72'
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 07 Jun 2007 14:20:56 +0000
parents 496d007a8912 (current diff) 68d034c6e65d (diff)
children 5eebb9b24e30
files
diffstat 20 files changed, 305 insertions(+), 249 deletions(-) [+]
line wrap: on
line diff
--- a/config.h.mingw	Wed Jun 06 04:22:15 2007 +0000
+++ b/config.h.mingw	Thu Jun 07 14:20:56 2007 +0000
@@ -344,9 +344,6 @@
 /* Define to the version of this package. */
 /* #define PACKAGE_VERSION "2.0.0dev" */
 
-/* Define to make assertions fatal (useful for debugging). */
-/* #define PURPLE_FATAL_ASSERTS 1 */
-
 /* Define if plugins are enabled. */
 #define PURPLE_PLUGINS 1
 
--- a/configure.ac	Wed Jun 06 04:22:15 2007 +0000
+++ b/configure.ac	Thu Jun 07 14:20:56 2007 +0000
@@ -569,14 +569,15 @@
 AC_ARG_ENABLE(gstreamer,
 	[AC_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])],
 	enable_gst="$enableval", enable_gst="yes")
-PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], , [
-	AC_MSG_RESULT(no)
-	enable_gst="no"
-])
 if test "x$enable_gst" != "xno"; then
-	AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
-	AC_SUBST(GSTREAMER_CFLAGS)
-	AC_SUBST(GSTREAMER_LIBS)
+	PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
+		AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
+		AC_SUBST(GSTREAMER_CFLAGS)
+		AC_SUBST(GSTREAMER_LIBS)
+	], [
+		AC_MSG_RESULT(no)
+		enable_gst="no"
+	])
 fi
 
 dnl #######################################################################
--- a/libpurple/network.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/network.c	Thu Jun 07 14:20:56 2007 +0000
@@ -598,8 +598,6 @@
 void
 nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data)
 {
-	GList *l;
-	PurpleAccount *account;
 	static libnm_glib_state prev = LIBNM_NO_DBUS;
 	libnm_glib_state current;
 	PurpleConnectionUiOps *ui_ops = purple_connections_get_ui_ops();
--- a/libpurple/plugins/log_reader.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/plugins/log_reader.c	Thu Jun 07 14:20:56 2007 +0000
@@ -1425,7 +1425,7 @@
 	char *escaped;
 	GString *formatted;
 	char *c;
-	char *line;
+	const char *line;
 
 	g_return_val_if_fail(log != NULL, g_strdup(""));
 
@@ -1460,240 +1460,234 @@
 	read = escaped;
 
 	/* Apply formatting... */
-	formatted = g_string_new("");
+	formatted = g_string_sized_new(strlen(read));
 	c = read;
 	line = read;
-	while (*c)
+	while (c)
 	{
-		if (*c == '\n')
-		{
-			char *link_temp_line;
-			char *link;
-			char *timestamp;
-			char *footer = NULL;
-			*c = '\0';
+		const char *link;
+		const char *footer = NULL;
+		GString *temp = NULL;
 
-			/* Convert links.
-			 *
-			 * The format is (Link: URL)URL
-			 * So, I want to find each occurance of "(Link: " and replace that chunk with:
-			 * <a href="
-			 * Then, replace the next ")" with:
-			 * ">
-			 * Then, replace the next " " (or add this if the end-of-line is reached) with:
-			 * </a>
-			 * 
-			 * As implemented, this isn't perfect, but it should cover common cases.
-			 */
-			link_temp_line = NULL;
-			while ((link = strstr(line, "(Link: ")))
-			{
-				char *tmp = link;
-
-				link += 7;
-				if (*link)
-				{
-					char *end_paren;
-					char *space;
-					GString *temp;
-
-					if (!(end_paren = strstr(link, ")")))
-					{
-						/* Something is not as we expect.  Bail out. */
-						break;
-					}
-
-					*tmp = '\0';
-					temp = g_string_new(line);
-
-					/* Start an <a> tag. */
-					g_string_append(temp, "<a href=\"");
-
-					/* Append up to the ) */
-					g_string_append_len(temp, link, end_paren - link);
+		if ((c = strstr(c, "\n")))
+		{
+			*c = '\0';
+			c++;
+		}
 
-					/* Finish the <a> tag. */
-					g_string_append(temp, "\">");
-
-					/* The \r is a bit of a hack to keep there from being a \r in
-					 * the link text, which may not matter. */
-					if ((space = strstr(end_paren, " ")) || (space = strstr(end_paren, "\r")))
-					{
-						g_string_append_len(temp, end_paren + 1, space - end_paren - 1);
-
-						/* Close the <a> tag. */
-						g_string_append(temp, "</a>");
+		/* Convert links.
+		 *
+		 * The format is (Link: URL)URL
+		 * So, I want to find each occurance of "(Link: " and replace that chunk with:
+		 * <a href="
+		 * Then, replace the next ")" with:
+		 * ">
+		 * Then, replace the next " " (or add this if the end-of-line is reached) with:
+		 * </a>
+		 * 
+		 * As implemented, this isn't perfect, but it should cover common cases.
+		 */
+		while (line && (link = strstr(line, "(Link: ")))
+		{
+			const char *tmp = link;
 
-						space++;
-						if (*space)
-						{
-							g_string_append_c(temp, ' ');
-							/* Keep the rest of the line. */
-							g_string_append(temp, space);
-						}
-					}
-					else
-					{
-						/* There is no space before the end of the line. */
-						g_string_append(temp, end_paren + 1);
-						/* Close the <a> tag. */
-						g_string_append(temp, "</a>");
-					}
-
-					g_free(link_temp_line);
-					line = g_string_free(temp, FALSE);
+			link += 7;
+			if (*link)
+			{
+				char *end_paren;
+				char *space;
 
-					/* Save this memory location so we can free it later. */
-					link_temp_line = line;
-				}
-			}
-
-			timestamp = "";
-			if (*line == '[') {
-				timestamp = line;
-				while (*timestamp && *timestamp != ']')
-					timestamp++;
-				if (*timestamp == ']') {
-					*timestamp = '\0';
-					line++;
-					/* TODO: Parse the timestamp and convert it to Purple's format. */
-					g_string_append_printf(formatted,
-						"<font size=\"2\">(%s)</font> ", line);
-					line = timestamp;
-					if (line[1] && line[2])
-						line += 2;
+				if (!(end_paren = strstr(link, ")")))
+				{
+					/* Something is not as we expect.  Bail out. */
+					break;
 				}
 
-				if (purple_str_has_prefix(line, "*** ")) {
-					line += (sizeof("*** ") - 1);
-					g_string_append(formatted, "<b>");
-					footer = "</b>";
-					if (purple_str_has_prefix(line, "NOTE: This user is offline.")) {
-						line = _("User is offline.");
-					} else if (purple_str_has_prefix(line,
-							"NOTE: Your status is currently set to ")) {
+				if (!temp)
+					temp = g_string_sized_new(c ? (c - 1 - line) : strlen(line));
+
+				g_string_append_len(temp, line, (tmp - line));
+
+				/* Start an <a> tag. */
+				g_string_append(temp, "<a href=\"");
+
+				/* Append up to the ) */
+				g_string_append_len(temp, link, end_paren - link);
+
+				/* Finish the <a> tag. */
+				g_string_append(temp, "\">");
+
+				/* The \r is a bit of a hack to keep there from being a \r in
+				 * the link text, which may not matter. */
+				if ((space = strstr(end_paren, " ")) || (space = strstr(end_paren, "\r")))
+				{
+					g_string_append_len(temp, end_paren + 1, space - end_paren - 1);
+
+					/* Close the <a> tag. */
+					g_string_append(temp, "</a>");
+
+					space++;
+				}
+				else
+				{
+					/* There is no space before the end of the line. */
+					g_string_append(temp, end_paren + 1);
+					/* Close the <a> tag. */
+					g_string_append(temp, "</a>");
+				}
+				line = space;
+			}
+			else
+			{
+				/* Something is not as we expect.  Bail out. */
+				break;
+			}
+		}
+
+		if (temp)
+		{
+			if (line)
+				g_string_append(temp, line);
+			line = temp->str;
+		}
+
+		if (*line == '[') {
+			const char *timestamp;
+
+			if ((timestamp = strstr(line, "]"))) {
+				line++;
+				/* TODO: Parse the timestamp and convert it to Purple's format. */
+				g_string_append(formatted, "<font size=\"2\">(");
+				g_string_append_len(formatted, line, (timestamp - line));
+				g_string_append(formatted,")</font> ");
+				line = timestamp + 1;
+				if (line[0] && line[1])
+					line++;
+			}
 
-						line += (sizeof("NOTE: ") - 1);
-					} else if (purple_str_has_prefix(line, "Auto-response sent to ")) {
-						g_string_append(formatted, _("Auto-response sent:"));
-						while (*line && *line != ':')
-							line++;
-						if (*line)
-							line++;
-						g_string_append(formatted, "</b>");
-						footer = NULL;
-					} else if (strstr(line, " signed off ")) {
-						if (buddy != NULL && buddy->alias)
-							g_string_append_printf(formatted,
-								_("%s has signed off."), buddy->alias);
-						else
-							g_string_append_printf(formatted,
-								_("%s has signed off."), log->name);
-						line = "";
-					} else if (strstr(line, " signed on ")) {
-						if (buddy != NULL && buddy->alias)
-							g_string_append(formatted, buddy->alias);
-						else
-							g_string_append(formatted, log->name);
-						line = " logged in.";
-					} else if (purple_str_has_prefix(line,
-						"One or more messages may have been undeliverable.")) {
+			if (purple_str_has_prefix(line, "*** ")) {
+				line += (sizeof("*** ") - 1);
+				g_string_append(formatted, "<b>");
+				footer = "</b>";
+				if (purple_str_has_prefix(line, "NOTE: This user is offline.")) {
+					line = _("User is offline.");
+				} else if (purple_str_has_prefix(line,
+						"NOTE: Your status is currently set to ")) {
+
+					line += (sizeof("NOTE: ") - 1);
+				} else if (purple_str_has_prefix(line, "Auto-response sent to ")) {
+					g_string_append(formatted, _("Auto-response sent:"));
+					while (*line && *line != ':')
+						line++;
+					if (*line)
+						line++;
+					g_string_append(formatted, "</b>");
+					footer = NULL;
+				} else if (strstr(line, " signed off ")) {
+					if (buddy != NULL && buddy->alias)
+						g_string_append_printf(formatted,
+							_("%s has signed off."), buddy->alias);
+					else
+						g_string_append_printf(formatted,
+							_("%s has signed off."), log->name);
+					line = "";
+				} else if (strstr(line, " signed on ")) {
+					if (buddy != NULL && buddy->alias)
+						g_string_append(formatted, buddy->alias);
+					else
+						g_string_append(formatted, log->name);
+					line = " logged in.";
+				} else if (purple_str_has_prefix(line,
+					"One or more messages may have been undeliverable.")) {
 
-						g_string_append(formatted,
-							"<span style=\"color: #ff0000;\">");
-						g_string_append(formatted,
-							_("One or more messages may have been "
-							  "undeliverable."));
-						line = "";
-						footer = "</span></b>";
-					} else if (purple_str_has_prefix(line,
-							"You have been disconnected.")) {
+					g_string_append(formatted,
+						"<span style=\"color: #ff0000;\">");
+					g_string_append(formatted,
+						_("One or more messages may have been "
+						  "undeliverable."));
+					line = "";
+					footer = "</span></b>";
+				} else if (purple_str_has_prefix(line,
+						"You have been disconnected.")) {
 
-						g_string_append(formatted,
-							"<span style=\"color: #ff0000;\">");
-						g_string_append(formatted,
-							_("You were disconnected from the server."));
-						line = "";
-						footer = "</span></b>";
-					} else if (purple_str_has_prefix(line,
-							"You are currently disconnected.")) {
+					g_string_append(formatted,
+						"<span style=\"color: #ff0000;\">");
+					g_string_append(formatted,
+						_("You were disconnected from the server."));
+					line = "";
+					footer = "</span></b>";
+				} else if (purple_str_has_prefix(line,
+						"You are currently disconnected.")) {
+
+					g_string_append(formatted,
+						"<span style=\"color: #ff0000;\">");
+					line = _("You are currently disconnected. Messages "
+					         "will not be received unless you are "
+					         "logged in.");
+					footer = "</span></b>";
+				} else if (purple_str_has_prefix(line,
+						"Your previous message has not been sent.")) {
+
+					g_string_append(formatted,
+						"<span style=\"color: #ff0000;\">");
+
+					if (purple_str_has_prefix(line,
+						"Your previous message has not been sent.  "
+						"Reason: Maximum length exceeded.")) {
 
 						g_string_append(formatted,
-							"<span style=\"color: #ff0000;\">");
-						line = _("You are currently disconnected. Messages "
-						         "will not be received unless you are "
-						         "logged in.");
-						footer = "</span></b>";
-					} else if (purple_str_has_prefix(line,
-							"Your previous message has not been sent.")) {
-
+							_("Message could not be sent because "
+							  "the maximum length was exceeded."));
+						line = "";
+					} else {
 						g_string_append(formatted,
-							"<span style=\"color: #ff0000;\">");
-
-						if (purple_str_has_prefix(line,
-							"Your previous message has not been sent.  "
-							"Reason: Maximum length exceeded.")) {
+							_("Message could not be sent."));
+						line += (sizeof(
+							"Your previous message "
+							"has not been sent. ") - 1);
+					}
 
-							g_string_append(formatted,
-								_("Message could not be sent because "
-								  "the maximum length was exceeded."));
-							line = "";
-						} else {
-							g_string_append(formatted,
-								_("Message could not be sent."));
-							line += (sizeof(
-								"Your previous message "
-								"has not been sent. ") - 1);
-						}
+					footer = "</span></b>";
+				}
+			} else if (purple_str_has_prefix(line, data->their_nickname)) {
+				if (buddy != NULL && buddy->alias) {
+					line += strlen(data->their_nickname) + 2;
+					g_string_append_printf(formatted,
+						"<span style=\"color: #A82F2F;\">"
+						"<b>%s</b></span>: ", buddy->alias);
+				}
+			} else {
+				const char *line2 = strstr(line, ":");
+				if (line2) {
+					const char *acct_name;
+					line2++;
+					line = line2;
+					acct_name = purple_account_get_alias(log->account);
+					if (!acct_name)
+						acct_name = purple_account_get_username(log->account);
 
-						footer = "</span></b>";
-					}
-				} else if (purple_str_has_prefix(line, data->their_nickname)) {
-					if (buddy != NULL && buddy->alias) {
-						line += strlen(data->their_nickname) + 2;
-						g_string_append_printf(formatted,
-							"<span style=\"color: #A82F2F;\">"
-							"<b>%s</b></span>: ", buddy->alias);
-					}
-				} else {
-					char *line2 = line;
-					while (*line2 && *line2 != ':')
-						line2++;
-					if (*line2 == ':') {
-						const char *acct_name;
-						line2++;
-						line = line2;
-						acct_name = purple_account_get_alias(log->account);
-						if (!acct_name)
-							acct_name = purple_account_get_username(log->account);
-
-						g_string_append_printf(formatted,
-							"<span style=\"color: #16569E;\">"
-							"<b>%s</b></span>:", acct_name);
-					}
+					g_string_append_printf(formatted,
+						"<span style=\"color: #16569E;\">"
+						"<b>%s</b></span>:", acct_name);
 				}
 			}
-
-			g_string_append(formatted, line);
+		}
 
-			if (footer)
-				g_string_append(formatted, footer);
+		g_string_append(formatted, line);
 
-			g_string_append_c(formatted, '\n');
-
-			g_free(link_temp_line);
+		line = c;
+		if (temp)
+			g_string_free(temp, TRUE);
 
-			c++;
-			line = c;
-		} else
-			c++;
+		if (footer)
+			g_string_append(formatted, footer);
+
+		g_string_append_c(formatted, '\n');
 	}
 
 	g_free(read);
-	read = formatted->str;
-	g_string_free(formatted, FALSE);
-
-	return read;
+	/* XXX: TODO: Avoid this g_strchomp() */
+	return g_strchomp(g_string_free(formatted, FALSE));
 }
 
 static int trillian_logger_size (PurpleLog *log)
--- a/libpurple/protocols/jabber/.todo	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/jabber/.todo	Thu Jun 07 14:20:56 2007 +0000
@@ -38,7 +38,7 @@
             formatted. enhancement-request so that the birthday field in the setinfo form would split up into relevant fields allowing for a strict syntax (like year--month--day or so, perhaps even dropdown menus)
         </note>
         <note priority="low" time="1037890968">
-            have set info pre-fill values from the server when no local vcard exists. this will help people migrating to gaim
+            have set info pre-fill values from the server when no local vcard exists. this will help people migrating to libpurple-based clients
         </note>
     </note>
     <note priority="verylow" time="1036044192">
--- a/libpurple/protocols/jabber/jabber.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Thu Jun 07 14:20:56 2007 +0000
@@ -463,7 +463,11 @@
 	JabberStream *js = gc->proto_data;
 
 	if (source < 0) {
-		purple_connection_error(gc, _("Couldn't connect to host"));
+		gchar *tmp;
+		tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),
+				error);
+		purple_connection_error(gc, tmp);
+		g_free(tmp);
 		return;
 	}
 
--- a/libpurple/protocols/jabber/si.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/jabber/si.c	Thu Jun 07 14:20:56 2007 +0000
@@ -105,6 +105,9 @@
 	jsx->connect_data = NULL;
 
 	if(source < 0) {
+		purple_debug_warning("jabber",
+				"si connection failed, jid was %s, host was %s, error was %s\n",
+				streamhost->jid, streamhost->host, error_message);
 		jsx->streamhosts = g_list_remove(jsx->streamhosts, streamhost);
 		g_free(streamhost->jid);
 		g_free(streamhost->host);
--- a/libpurple/protocols/msn/servconn.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/msn/servconn.c	Thu Jun 07 14:20:56 2007 +0000
@@ -195,6 +195,7 @@
 	}
 	else
 	{
+		purple_debug_error("msn", "Connection error: %s\n", error_message);
 		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT);
 	}
 }
--- a/libpurple/protocols/oscar/.todo	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/oscar/.todo	Thu Jun 07 14:20:56 2007 +0000
@@ -15,16 +15,10 @@
             <note priority="veryhigh" time="1036040919">
                 some way to close direct connect w/out closing convo.
             </note>
-            <note priority="low" time="1036040970">
-                canceled direct im should still allow new attempt
-            </note>
             <note priority="low" time="1036041084">
                 failed direct im attempt should allow new attempt some way to cancel an attempt that isn't happening
             </note>
         </note>
-        <note priority="low" time="1036041105">
-            Colors in Chat room are wrong (using Gold too much)
-        </note>
         <note priority="verylow" time="1036041121">
             Voice Chat
         </note>
@@ -44,7 +38,7 @@
             color support
         </note>
         <note priority="high" time="1036041251">
-            set status message and of course when gaim can set them, it needs to be able to get the ones it sets. (yes this is redundant. its a reflection of my current mood)
+            set status message and of course when libpurple can set them, it needs to be able to get the ones it sets. (yes this is redundant. its a reflection of my current mood)
         </note>
         <note priority="medium" time="1036041165">
             Chat (this is different from aim chat)
@@ -66,6 +60,6 @@
         </note>
     </note>
     <note priority="medium" time="1036040870">
-        The order of groups and buddies in the server list is not updated when groups and buddies are re-arranged locally in Gaim.
+        The order of groups and buddies in the server list is not updated when groups and buddies are re-arranged locally in libpurple.
     </note>
 </todo>
--- a/libpurple/protocols/oscar/AUTHORS	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/oscar/AUTHORS	Thu Jun 07 14:20:56 2007 +0000
@@ -35,7 +35,7 @@
 N: Eric Warmenhoven
 T: 1998-2001
 E: warmenhoven a.t linux d.o.t com
-D: Some OFT info, author of the faim interface for gaim
+D: Some OFT info, initial author of the libpurple-side of the oscar protocol plugin
 
 N: Brock Wilcox
 T: 1998-2001
--- a/libpurple/protocols/qq/AUTHORS	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/qq/AUTHORS	Thu Jun 07 14:20:56 2007 +0000
@@ -1,7 +1,7 @@
 Code Contributors
 =====
 puzzlebird  : original author
-gfhuang     : patches for gaim 2.0.0beta2, maintainer
+gfhuang     : patches for libpurple 2.0.0beta2, maintainer
 henryouly   : file transfer, udp sock5 proxy and qq_show, maintainer
 hzhr        : maintainer
 joymarquis  : maintainer
@@ -10,7 +10,7 @@
 yyw         : improved performance on PPC linux
 lvxiang     : provided ip to location original code
 csyfek      : faces
-markhuetsch : OpenQ merge into gaim, maintainer 2006-2007
+markhuetsch : OpenQ merge into libpurple, maintainer 2006-2007
 
 Acknowledgement
 =====
--- a/libpurple/protocols/toc/PROTOCOL	Wed Jun 06 04:22:15 2007 +0000
+++ b/libpurple/protocols/toc/PROTOCOL	Thu Jun 07 14:20:56 2007 +0000
@@ -14,10 +14,10 @@
 #   along with this program; if not, write to the Free Software
 #   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-# Note from Jim Duchek, gaim maintainer -- this may not be the latest
-# version of this document, I provide it as a service.  Download a copy
-# of TiK (http://www.aim.aol.com/tik/) for the latest version of this
-# doc.
+# Note from Jim Duchek, former libpurple maintainer -- this may not be
+# the latest version of this document, I provide it as a service.
+# Download a copy of TiK (http://www.aim.aol.com/tik/) for the latest
+# version of this doc.
 
 # Note from Eric Warmenhoven, random guy -- this appears to be the last
 # published version of the protocol, and AOL has stopped hosting the TiK
--- a/pidgin/gtkconv.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/gtkconv.c	Thu Jun 07 14:20:56 2007 +0000
@@ -1247,6 +1247,37 @@
 }
 
 static void
+menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget)
+{
+	PidginWindow *win = data;
+	PidginConversation *gtkconv;
+	GtkIMHtmlToolbar *toolbar;
+
+	gtkconv = pidgin_conv_window_get_active_gtkconv(win);
+	toolbar = GTK_IMHTMLTOOLBAR(gtkconv->toolbar);
+
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link),
+			!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link)));
+}
+
+static void
+menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget)
+{
+	PidginWindow *win = data;
+	PurpleConversation *conv;
+	PidginConversation *gtkconv;
+	GtkIMHtmlToolbar *toolbar;
+
+	gtkconv = pidgin_conv_window_get_active_gtkconv(win);
+	conv    = gtkconv->active_conv;
+	toolbar = GTK_IMHTMLTOOLBAR(gtkconv->toolbar);
+
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->image),
+			!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image)));
+}
+
+
+static void
 menu_alias_cb(gpointer data, guint action, GtkWidget *widget)
 {
 	PidginWindow *win = data;
@@ -2818,6 +2849,14 @@
 
 	{ "/Conversation/sep3", NULL, NULL, 0, "<Separator>", NULL },
 
+	{ N_("/Conversation/Insert Lin_k..."), NULL, menu_insert_link_cb, 0,
+		"<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_LINK },
+	{ N_("/Conversation/Insert Imag_e..."), NULL, menu_insert_image_cb, 0,
+		"<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE },
+
+	{ "/Conversation/sep4", NULL, NULL, 0, "<Separator>", NULL },
+
+
 	{ N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0,
 			"<StockItem>", GTK_STOCK_CLOSE },
 
@@ -3042,6 +3081,18 @@
 		gtk_item_factory_get_widget(win->menu.item_factory,
 		                            N_("/Conversation/Remove..."));
 
+	/* --- */
+
+	win->menu.insert_link =
+		gtk_item_factory_get_widget(win->menu.item_factory,
+				N_("/Conversation/Insert Link..."));
+
+	win->menu.insert_image =
+		gtk_item_factory_get_widget(win->menu.item_factory,
+				N_("/Conversation/Insert Image..."));
+
+	/* --- */
+
 	win->menu.logging =
 		gtk_item_factory_get_widget(win->menu.item_factory,
 		                            N_("/Options/Enable Logging"));
@@ -5907,6 +5958,8 @@
 			gtk_widget_hide(win->menu.add);
 		}
 
+		gtk_widget_show(win->menu.insert_link);
+		gtk_widget_show(win->menu.insert_image);
 		gtk_widget_show(win->menu.show_icon);
 	} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
 		/* Show stuff that applies to Chats, hide stuff that applies to IMs */
@@ -5932,6 +5985,8 @@
 			gtk_widget_show(win->menu.remove);
 		}
 
+		gtk_widget_show(win->menu.insert_link);
+		gtk_widget_show(win->menu.insert_image);
 	}
 
 	/*
@@ -5973,6 +6028,8 @@
 		gtk_widget_set_sensitive(win->menu.add_pounce, TRUE);
 		gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
 		gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
+		gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
+		gtk_widget_set_sensitive(win->menu.insert_image, (prpl_info->options & OPT_PROTO_IM_IMAGE) && !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
 
 		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 		{
@@ -6007,6 +6064,8 @@
 		gtk_widget_set_sensitive(win->menu.alias, FALSE);
 		gtk_widget_set_sensitive(win->menu.add, FALSE);
 		gtk_widget_set_sensitive(win->menu.remove, FALSE);
+		gtk_widget_set_sensitive(win->menu.insert_link, TRUE);
+		gtk_widget_set_sensitive(win->menu.insert_image, FALSE);
 	}
 
 	/*
--- a/pidgin/gtkdialogs.h	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/gtkdialogs.h	Thu Jun 07 14:20:56 2007 +0000
@@ -36,10 +36,15 @@
 void pidgin_dialogs_im_with_user(PurpleAccount *, const char *);
 void pidgin_dialogs_info(void);
 void pidgin_dialogs_log(void);
+
+/**
+ * @deprecated This function is no longer used and will be removed in
+ *             Pidgin 3.0.0 unless there is sufficient demand to keep it.
+ */
 void pidgin_dialogs_alias_contact(PurpleContact *);
+
 void pidgin_dialogs_alias_buddy(PurpleBuddy *);
 void pidgin_dialogs_alias_chat(PurpleChat *);
-
 void pidgin_dialogs_remove_buddy(PurpleBuddy *);
 void pidgin_dialogs_remove_group(PurpleGroup *);
 void pidgin_dialogs_remove_chat(PurpleChat *);
--- a/pidgin/gtkdocklet-x11.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/gtkdocklet-x11.c	Thu Jun 07 14:20:56 2007 +0000
@@ -281,7 +281,7 @@
 	 * The x11 docklet tracks whether it successfully embedded in a pref and
 	 * allows for a longer timeout period if it successfully embedded the last
 	 * time it was run. This should hopefully solve problems with the buddy
-	 * list not properly starting hidden when gaim is started on login.
+	 * list not properly starting hidden when Pidgin is started on login.
 	 */
 	if(!recreate) {
 		pidgin_docklet_embedded();
--- a/pidgin/gtkrequest.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/gtkrequest.c	Thu Jun 07 14:20:56 2007 +0000
@@ -323,7 +323,8 @@
 	/* Setup the dialog */
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BORDER/2);
 	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER/2);
-	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
+	if (!multiline)
+		gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
 	gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
 	gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0);
 	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER);
@@ -341,7 +342,7 @@
 	/* Vertical box */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
 
-	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
 
 	/* Descriptive label */
 	primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
@@ -359,7 +360,7 @@
 	gtk_label_set_markup(GTK_LABEL(label), label_text);
 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-	gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
 	g_free(label_text);
 
--- a/pidgin/gtksavedstatuses.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/gtksavedstatuses.c	Thu Jun 07 14:20:56 2007 +0000
@@ -1088,7 +1088,6 @@
 	dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 	gtk_window_set_role(GTK_WINDOW(win), "status");
 	gtk_window_set_title(GTK_WINDOW(win), _("Status"));
-	gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
 	gtk_container_set_border_width(GTK_CONTAINER(win), PIDGIN_HIG_BORDER);
 
 	g_signal_connect(G_OBJECT(win), "delete_event",
@@ -1137,7 +1136,7 @@
 
 	/* Status message */
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
 
 	label = gtk_label_new_with_mnemonic(_("_Message:"));
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
--- a/pidgin/plugins/gevolution/gevolution.c	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/plugins/gevolution/gevolution.c	Thu Jun 07 14:20:56 2007 +0000
@@ -38,7 +38,6 @@
 
 #include <libedata-book/Evolution-DataServer-Addressbook.h>
 
-#include <libebook/e-book-listener.h>
 #include <libedata-book/e-data-book-factory.h>
 #include <bonobo/bonobo-main.h>
 
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Wed Jun 06 04:22:15 2007 +0000
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Thu Jun 07 14:20:56 2007 +0000
@@ -1068,6 +1068,7 @@
 
   have_gtk:
     ; GTK+ is already installed; check version.
+	; Change this to not even run the GTK installer if this version is already installed.
     ${VersionCompare} ${GTK_INSTALL_VERSION} $0 $3
     IntCmp $3 1 +1 good_version good_version
     ${VersionCompare} ${GTK_MIN_VERSION} $0 $3
--- a/valgrind-suppressions	Wed Jun 06 04:22:15 2007 +0000
+++ b/valgrind-suppressions	Thu Jun 07 14:20:56 2007 +0000
@@ -147,8 +147,8 @@
    fun:PR_Init
    fun:rsa_nss_init
    fun:GE_plugin_load
-   fun:gaim_plugin_load
-   fun:gaim_plugins_load_saved
+   fun:purple_plugin_load
+   fun:purple_plugins_load_saved
    fun:main
 }