changeset 18243:a8b19e002cb4

propagate from branch 'im.pidgin.pidgin' (head e9da27c3123d1223162bf9fb76f58822873e18f8) to branch 'im.pidgin.soc.2007.remotelogging' (head da5442aedd302aafb260948b66ce0549a3e0a0e4)
author Richard Laager <rlaager@wiktel.com>
date Sun, 24 Jun 2007 20:01:43 +0000
parents b14dfa2f49a1 (current diff) bc4518599c10 (diff)
children b7c30039b531
files COPYRIGHT libpurple/protocols/qq/group_misc.c libpurple/protocols/qq/group_misc.h
diffstat 88 files changed, 946 insertions(+), 520 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Fri Jun 22 17:36:48 2007 +0000
+++ b/COPYRIGHT	Sun Jun 24 20:01:43 2007 +0000
@@ -276,6 +276,7 @@
 Julien Pivotto
 Ari Pollak
 Robey Pointer
+Eric Polino
 Stephen Pope
 Nathan Poznick
 Jory A. Pratt
--- a/ChangeLog.API	Fri Jun 22 17:36:48 2007 +0000
+++ b/ChangeLog.API	Sun Jun 24 20:01:43 2007 +0000
@@ -66,15 +66,23 @@
 		Added:
 		* gtk_imhtml_setup_entry
 		* pidgin_create_window
-		* pidgin_retrieve_user_info, shows immediate feedback when getting
-		  information about a user.
+		* pidgin_retrieve_user_info and pidgin_retrieve_user_info_in_chat,
+		  shows immediate feedback when getting information about a user.
 		* gtk_imhtml_animation_new
 		    Can be used for inserting an animated image into an IMHTML.
 		* pidgin_menu_position_func_helper
+		* pidgin_blist_get_name_markup, returns the buddy list markup
+		  text for a given buddy.
 
 		Changed:
 		* pidgin_append_menu_action returns the menuitem added to the menu.
 		* pidgin_separator returns the separator added to the menu.
+		* PidginConversation has struct members to handle the new info
+		  pane:
+		  	* infopane
+			* infopane_hbox
+			* infopane_model
+			* infopane_iter
 
 	Finch:
 		Added:
--- a/doc/gtkrc-2.0	Fri Jun 22 17:36:48 2007 +0000
+++ b/doc/gtkrc-2.0	Sun Jun 24 20:01:43 2007 +0000
@@ -39,16 +39,17 @@
 }
 widget_class "*" style "my-style-name"
 
-# This style sets the expander size on a treeview to 0, which has the result
+# This sets the expander size on a treeview to 0, which has the result
 # of reducing the indent for items in the tree. This can be applied to the
-# Pidgin buddy list to reduce it's width.
-style "my-narrow-tree"
-{
-  GtkTreeView::expander_size = 0
-}
-
+# Pidgin buddy list to reduce the width of group and contact rows.
+# With the recent (~2.0.0) buddy list changes this isn't particularly
+# important anymore.
+#style "my-narrow-tree"
+#{
+#  GtkTreeView::expander_size = 0
+#}
 # And apply the style to the buddy list:
-widget "*pidgin_blist_treeview" style "my-narrow-tree"
+#widget "*pidgin_blist_treeview" style "my-narrow-tree"
 
 # In Pidgin, you can set custom keybindings in your theme.
 # Here is an example to follow:
--- a/finch/finch.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/finch.c	Sun Jun 24 20:01:43 2007 +0000
@@ -19,6 +19,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "finch.h"
+
 #include "account.h"
 #include "conversation.h"
 #include "core.h"
@@ -37,7 +39,6 @@
 #include "whiteboard.h"
 
 #include "gntdebug.h"
-#include "finch.h"
 #include "gntprefs.h"
 #include "gntui.h"
 #include "gntidle.h"
--- a/finch/gntaccount.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntaccount.c	Sun Jun 24 20:01:43 2007 +0000
@@ -33,6 +33,8 @@
 #include <gnttree.h>
 #include <gntwindow.h>
 
+#include "finch.h"
+
 #include <account.h>
 #include <accountopt.h>
 #include <connection.h>
@@ -42,7 +44,6 @@
 
 #include "gntaccount.h"
 #include "gntblist.h"
-#include "finch.h"
 
 #include <string.h>
 
--- a/finch/gntblist.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntblist.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "finch.h"
+
 #include <account.h>
 #include <blist.h>
 #include <notify.h>
@@ -33,7 +35,6 @@
 #include <util.h>
 #include "debug.h"
 
-#include "finch.h"
 #include "gntbox.h"
 #include "gntcombobox.h"
 #include "gntentry.h"
--- a/finch/gntconn.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntconn.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "finch.h"
+
 #include "account.h"
 #include "core.h"
 #include "connection.h"
@@ -29,7 +31,6 @@
 #include "request.h"
 
 #include "gntconn.h"
-#include "finch.h"
 
 #define INITIAL_RECON_DELAY_MIN  8000
 #define INITIAL_RECON_DELAY_MAX 60000
--- a/finch/gntconv.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntconv.c	Sun Jun 24 20:01:43 2007 +0000
@@ -24,12 +24,13 @@
  */
 #include <string.h>
 
+#include "finch.h"
+
 #include <cmds.h>
 #include <idle.h>
 #include <prefs.h>
 #include <util.h>
 
-#include "finch.h"
 #include "gntaccount.h"
 #include "gntblist.h"
 #include "gntconv.h"
@@ -484,7 +485,24 @@
 	gnt_box_set_title(GNT_BOX(ggc->window), title);
 	gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE);
 	gnt_box_set_pad(GNT_BOX(ggc->window), 0);
-	gnt_widget_set_name(ggc->window, "conversation-window");
+
+	switch(conv->type){
+		case PURPLE_CONV_TYPE_UNKNOWN:
+			gnt_widget_set_name(ggc->window, "conversation-window-unknown" );
+			break;
+		case PURPLE_CONV_TYPE_IM:
+			gnt_widget_set_name(ggc->window, "conversation-window-im" );
+			break;
+		case PURPLE_CONV_TYPE_CHAT:
+			gnt_widget_set_name(ggc->window, "conversation-window-chat" );
+			break;
+		case PURPLE_CONV_TYPE_MISC:
+			gnt_widget_set_name(ggc->window, "conversation-window-misc" );
+			break;
+		case PURPLE_CONV_TYPE_ANY:
+			gnt_widget_set_name(ggc->window, "conversation-window-any" );
+			break;
+	}
 
 	gg_create_menu(ggc);
 
@@ -553,7 +571,8 @@
 	
 	if (ggc->list == NULL) {
 		g_free(ggc->u.chat);
-		gnt_widget_destroy(ggc->window);
+		if (ggc->window)
+			gnt_widget_destroy(ggc->window);
 		g_free(ggc);
 	}
 }
--- a/finch/gntnotify.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntnotify.c	Sun Jun 24 20:01:43 2007 +0000
@@ -29,10 +29,11 @@
 #include <gnttree.h>
 #include <gntutils.h>
 
+#include "finch.h"
+
 #include <util.h>
 
 #include "gntnotify.h"
-#include "finch.h"
 
 static struct
 {
--- a/finch/gntplugin.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntplugin.c	Sun Jun 24 20:01:43 2007 +0000
@@ -29,10 +29,11 @@
 #include <gntline.h>
 #include <gnttree.h>
 
+#include "finch.h"
+
 #include "notify.h"
 #include "request.h"
 
-#include "finch.h"
 #include "gntplugin.h"
 #include "gntrequest.h"
 
@@ -46,7 +47,7 @@
 
 static GHashTable *confwins;
 
-static void process_pref_frame(PurplePluginPrefFrame *frame);
+static GntWidget *process_pref_frame(PurplePluginPrefFrame *frame);
 
 static void
 decide_conf_button(PurplePlugin *plugin)
@@ -83,7 +84,7 @@
 			gnt_tree_set_choice(GNT_TREE(tree), plugin, TRUE);
 		}
 
-		if ((win = g_hash_table_lookup(confwins, plugin)) != NULL)
+		if (confwins && (win = g_hash_table_lookup(confwins, plugin)) != NULL)
 		{
 			gnt_widget_destroy(win);
 		}
@@ -220,7 +221,11 @@
 	else if (plugin->info->prefs_info &&
 			plugin->info->prefs_info->get_plugin_pref_frame)
 	{
-		process_pref_frame(plugin->info->prefs_info->get_plugin_pref_frame(plugin));
+		GntWidget *win = process_pref_frame(plugin->info->prefs_info->get_plugin_pref_frame(plugin));
+		if (confwins == NULL)
+			confwin_init();
+		g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(remove_confwin), plugin);
+		g_hash_table_insert(confwins, plugin, win);
 		return;
 	}
 	else
@@ -307,7 +312,7 @@
 	decide_conf_button(gnt_tree_get_selection_data(GNT_TREE(tree)));
 }
 
-static void
+static GntWidget*
 process_pref_frame(PurplePluginPrefFrame *frame)
 {
 	PurpleRequestField *field;
@@ -359,7 +364,7 @@
 		}
 	}
 
-	purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
+	return purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
 			_("Save"), G_CALLBACK(finch_request_save_in_prefs), _("Cancel"), NULL,
 			NULL, NULL, NULL,
 			NULL);
--- a/finch/gntprefs.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntprefs.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,10 +22,11 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "finch.h"
+
 #include <prefs.h>
 #include <savedstatuses.h>
 
-#include "finch.h"
 #include "gntprefs.h"
 #include "gntrequest.h"
 
--- a/finch/gntrequest.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntrequest.c	Sun Jun 24 20:01:43 2007 +0000
@@ -399,7 +399,7 @@
 							purple_request_field_string_get_default_value(field));
 				gnt_entry_set_masked(GNT_ENTRY(entry),
 						purple_request_field_string_is_masked(field));
-				if (purple_str_has_prefix(hint, "screenname")) {
+				if (hint && purple_str_has_prefix(hint, "screenname")) {
 					PurpleBlistNode *node = purple_blist_get_root();
 					gboolean offline = purple_str_has_suffix(hint, "all");
 					for (; node; node = purple_blist_node_next(node, offline)) {
@@ -673,7 +673,7 @@
 			switch (pt) {
 				case PURPLE_PREF_INT:
 				{
-					long int tmp;
+					long int tmp = GPOINTER_TO_INT(val);
 					if (type == PURPLE_REQUEST_FIELD_LIST) /* Lists always return string */
 						sscanf(val, "%ld", &tmp);
 					purple_prefs_set_int(id, (gint)tmp);
--- a/finch/gntstatus.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntstatus.c	Sun Jun 24 20:01:43 2007 +0000
@@ -31,10 +31,11 @@
 #include <gntline.h>
 #include <gnttree.h>
 
+#include "finch.h"
+
 #include <notify.h>
 #include <request.h>
 
-#include "finch.h"
 #include "gntstatus.h"
 
 static struct
--- a/finch/gntui.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/gntui.c	Sun Jun 24 20:01:43 2007 +0000
@@ -19,6 +19,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "internal.h"
+
 #include "gntui.h"
 
 #include "gntaccount.h"
@@ -33,7 +35,6 @@
 #include "gntprefs.h"
 #include "gntrequest.h"
 #include "gntstatus.h"
-#include "internal.h"
 
 #include <prefs.h>
 
--- a/finch/libgnt/gntfilesel.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/gntfilesel.c	Sun Jun 24 20:01:43 2007 +0000
@@ -46,6 +46,7 @@
 static GntWindowClass *parent_class = NULL;
 static guint signals[SIGS] = { 0 };
 static void (*orig_map)(GntWidget *widget);
+static void (*orig_size_request)(GntWidget *widget);
 
 static void
 gnt_file_sel_destroy(GntWidget *widget)
@@ -552,6 +553,19 @@
 }
 
 static void
+gnt_file_sel_size_request(GntWidget *widget)
+{
+	GntFileSel *sel;
+	if (widget->priv.height > 0)
+		return;
+
+	sel = GNT_FILE_SEL(widget);
+	sel->dirs->priv.height = 16;
+	sel->files->priv.height = 16;
+	orig_size_request(widget);
+}
+
+static void
 gnt_file_sel_class_init(GntFileSelClass *klass)
 {
 	GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass);
@@ -560,6 +574,8 @@
 	kl->destroy = gnt_file_sel_destroy;
 	orig_map = kl->map;
 	kl->map = gnt_file_sel_map;
+	orig_size_request = kl->size_request;
+	kl->size_request = gnt_file_sel_size_request;
 
 	signals[SIG_FILE_SELECTED] = 
 		g_signal_new("file_selected",
--- a/finch/libgnt/gntmain.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/gntmain.c	Sun Jun 24 20:01:43 2007 +0000
@@ -429,10 +429,14 @@
 
 	setup_io();
 
+#ifdef NO_WIDECHAR
+	ascii_only = TRUE;
+#else
 	if (locale && (strstr(locale, "UTF") || strstr(locale, "utf")))
 		ascii_only = FALSE;
 	else
 		ascii_only = TRUE;
+#endif
 
 	initscr();
 	typeahead(-1);
--- a/finch/libgnt/gnttree.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/gnttree.c	Sun Jun 24 20:01:43 2007 +0000
@@ -303,7 +303,7 @@
 
 		notfirst = TRUE;
 
-		if (len > width - 2) {
+		if (len > width) {
 			len = width - 1;
 			cut = TRUE;
 		}
--- a/finch/libgnt/gntwidget.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/gntwidget.c	Sun Jun 24 20:01:43 2007 +0000
@@ -576,7 +576,7 @@
 		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS);
 		g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0);
 	}
-	else if (!set)
+	else if (!set && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS))
 	{
 		GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS);
 		g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0);
--- a/finch/libgnt/gntwm.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/gntwm.c	Sun Jun 24 20:01:43 2007 +0000
@@ -1458,23 +1458,50 @@
 static gboolean
 match_title(gpointer title, gpointer n, gpointer wid_title)
 {
-	/* maybe check for regex.h? */
+	/* XXX: do any regex magic here. */
 	if (g_strrstr((gchar *)wid_title, (gchar *)title))
 		return TRUE;
 	return FALSE;
 }
 
-static GntWS *
-new_widget_find_workspace(GntWM *wm, GntWidget *widget, gchar *wid_title)
+#if !GLIB_CHECK_VERSION(2,4,0)
+struct
+{
+	gpointer data;
+	gpointer value;
+} table_find_data;
+
+static void
+table_find_helper(gpointer key, gpointer value, gpointer data)
 {
-	GntWS *ret;
-	const gchar *name;
-	ret = g_hash_table_find(wm->title_places, match_title, wid_title);
+	GHRFunc func = data;
+	if (func(key, value, table_find_data.data))
+		table_find_data.value = value;
+}
+
+static gpointer
+g_hash_table_find(GHashTable * table, GHRFunc func, gpointer data)
+{
+	table_find_data.data = data;
+	table_find_data.value = NULL;
+	g_hash_table_foreach(table, table_find_helper, func);
+	return table_find_data.value;
+}
+#endif
+
+static GntWS *
+new_widget_find_workspace(GntWM *wm, GntWidget *widget)
+{
+	GntWS *ret = NULL;
+	const gchar *name, *title;
+	title = GNT_BOX(widget)->title;
+	if (title)
+		ret = g_hash_table_find(wm->title_places, match_title, (gpointer)title);
 	if (ret)
 		return ret;
 	name = gnt_widget_get_name(widget);
 	if (name)
-		ret = g_hash_table_lookup(wm->name_places, name);
+		ret = g_hash_table_find(wm->name_places, match_title, (gpointer)name);
 	return ret ? ret : wm->cws;
 }
 
@@ -1537,8 +1564,7 @@
 			GntWidget *w = NULL;
 
 			if (GNT_IS_BOX(widget)) {
-				char *title = GNT_BOX(widget)->title;
-				ws = new_widget_find_workspace(wm, widget, title);
+				ws = new_widget_find_workspace(wm, widget);
 			}
 
 			if (ws->ordered)
--- a/finch/libgnt/gntws.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/gntws.c	Sun Jun 24 20:01:43 2007 +0000
@@ -87,8 +87,12 @@
 
 void gnt_ws_add_widget(GntWS *ws, GntWidget* wid)
 {
+	GntWidget *oldfocus;
+	oldfocus = ws->ordered ? ws->ordered->data : NULL;
 	ws->list = g_list_append(ws->list, wid);
 	ws->ordered = g_list_prepend(ws->ordered, wid);
+	if (oldfocus)
+		gnt_widget_set_focus(oldfocus, FALSE);
 }
 
 void gnt_ws_remove_widget(GntWS *ws, GntWidget* wid)
--- a/finch/libgnt/wms/s.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/finch/libgnt/wms/s.c	Sun Jun 24 20:01:43 2007 +0000
@@ -1,6 +1,8 @@
 #include <string.h>
 #include <sys/types.h>
 
+#include "internal.h"
+
 #include "gnt.h"
 #include "gntbox.h"
 #include "gntmenu.h"
--- a/libpurple/account.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/account.h	Sun Jun 24 20:01:43 2007 +0000
@@ -369,7 +369,7 @@
  *                  as a NULL-terminated list of id/value pairs.
  */
 void purple_account_set_status(PurpleAccount *account, const char *status_id,
-							 gboolean active, ...);
+							 gboolean active, ...) G_GNUC_NULL_TERMINATED;
 
 
 /**
--- a/libpurple/accountopt.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/accountopt.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "internal.h"
+
 #include "accountopt.h"
 #include "util.h"
 
--- a/libpurple/cmds.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/cmds.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
 
 #include <string.h>
 
+#include "internal.h"
+
 #include "account.h"
 #include "util.h"
 #include "cmds.h"
--- a/libpurple/core.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/core.c	Sun Jun 24 20:01:43 2007 +0000
@@ -222,11 +222,10 @@
 	purple_sound_uninit();
 
 	purple_plugins_uninit();
-	purple_signals_uninit();
-
 #ifdef HAVE_DBUS
 	purple_dbus_uninit();
 #endif
+	purple_signals_uninit();
 
 	g_free(core->ui);
 	g_free(core);
@@ -512,7 +511,7 @@
 
 				if ((linklen = readlink(name, buf, sizeof(buf) - 1) == -1))
 				{
-					char *name_utf8 = g_filename_to_utf8(name);
+					char *name_utf8 = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
 					purple_debug_error("core", "Error reading symlink %s: %s. Please report this at http://developer.pidgin.im\n",
 					                   name_utf8, strerror(errno));
 					g_free(name_utf8);
--- a/libpurple/example/nullclient.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/example/nullclient.c	Sun Jun 24 20:01:43 2007 +0000
@@ -20,6 +20,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
+
+/* XXX: we probably shouldn't include internal.h in examples */
+#include "internal.h"
+
 #include "account.h"
 #include "conversation.h"
 #include "core.h"
--- a/libpurple/imgstore.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/imgstore.c	Sun Jun 24 20:01:43 2007 +0000
@@ -25,6 +25,8 @@
 */
 
 #include <glib.h>
+#include "internal.h"
+
 #include "dbus-maybe.h"
 #include "debug.h"
 #include "imgstore.h"
--- a/libpurple/imgstore.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/imgstore.h	Sun Jun 24 20:01:43 2007 +0000
@@ -28,7 +28,6 @@
 
 #include <glib.h>
 
-struct _PurpleStoredImage;
 typedef struct _PurpleStoredImage PurpleStoredImage;
 
 #ifdef __cplusplus
--- a/libpurple/internal.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/internal.h	Sun Jun 24 20:01:43 2007 +0000
@@ -111,6 +111,14 @@
 # include <unistd.h>
 #endif
 
+#ifndef MAXPATHLEN
+# ifdef PATH_MAX
+#  define MAXPATHLEN PATH_MAX
+# else
+#  define MAXPATHLEN 1024
+# endif
+#endif
+
 #ifndef HOST_NAME_MAX
 # define HOST_NAME_MAX 255
 #endif
@@ -170,6 +178,14 @@
 #	endif
 #endif
 
+#ifndef G_GNUC_NULL_TERMINATED
+#	if     __GNUC__ >= 4
+#		define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
+#	else
+#		define G_GNUC_NULL_TERMINATED
+#	endif
+#endif
+
 /* Safer ways to work with static buffers. When using non-static
  * buffers, either use g_strdup_* functions (preferred) or use
  * g_strlcpy/g_strlcpy directly. */
--- a/libpurple/mime.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/mime.c	Sun Jun 24 20:01:43 2007 +0000
@@ -29,6 +29,8 @@
 #include <glib/glist.h>
 #include <glib/gstring.h>
 
+#include "internal.h"
+
 /* this should become "util.h" if we ever get this into purple proper */
 #include "debug.h"
 #include "mime.h"
--- a/libpurple/ntlm.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/ntlm.c	Sun Jun 24 20:01:43 2007 +0000
@@ -25,6 +25,8 @@
 
 #include <glib.h>
 #include <stdlib.h>
+#include "internal.h"
+
 #include "util.h"
 #include "ntlm.h"
 #include "cipher.h"
--- a/libpurple/plugins/perl/common/Conversation.xs	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/plugins/perl/common/Conversation.xs	Sun Jun 24 20:01:43 2007 +0000
@@ -62,6 +62,7 @@
 		const_iv(RAW),
 		const_iv(IMAGES),
 		const_iv(NOTIFY),
+		const_iv(NO_LINKIFY),
 	};
 	static const constiv cbflags_const_iv[] = {
 #undef const_iv
--- a/libpurple/plugins/perl/perl-common.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/plugins/perl/perl-common.h	Sun Jun 24 20:01:43 2007 +0000
@@ -9,6 +9,9 @@
 #include <EXTERN.h>
 #include <perl.h>
 
+/* XXX: perl defines it's own _ but I think it's safe to undef it */
+#undef _
+#include "internal.h"
 #include "plugin.h"
 #include "value.h"
 
--- a/libpurple/protocols/gg/gg.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/gg/gg.h	Sun Jun 24 20:01:43 2007 +0000
@@ -25,6 +25,7 @@
 #define _PURPLE_GG_H
 
 #include <libgadu.h>
+#include "internal.h"
 #include "search.h"
 #include "connection.h"
 
--- a/libpurple/protocols/jabber/jabber.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sun Jun 24 20:01:43 2007 +0000
@@ -1116,9 +1116,11 @@
 
 char *jabber_status_text(PurpleBuddy *b)
 {
-	JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name,
-			FALSE);
 	char *ret = NULL;
+	JabberBuddy *jb = NULL;
+	
+	if (b->account->gc && b->account->gc->proto_data)
+		jb = jabber_buddy_find(b->account->gc->proto_data, b->name, FALSE);
 
 	if(jb && !PURPLE_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) {
 		ret = g_strdup(_("Not Authorized"));
--- a/libpurple/protocols/jabber/libxmpp.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Sun Jun 24 20:01:43 2007 +0000
@@ -25,8 +25,9 @@
  * share code.
  */
 
+#include "internal.h"
+
 #include "accountopt.h"
-#include "internal.h"
 #include "version.h"
 
 #include "iq.h"
--- a/libpurple/protocols/jabber/presence.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/jabber/presence.c	Sun Jun 24 20:01:43 2007 +0000
@@ -515,7 +515,7 @@
 		buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "",
 				jid->node ? "@" : "", jid->domain);
 		if((b = purple_find_buddy(js->gc->account, buddy_name)) == NULL) {
-			purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%x)",
+			purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%x)\n",
 				buddy_name, purple_account_get_username(js->gc->account), js->gc->account);
 			jabber_id_free(jid);
 			g_free(avatar_hash);
--- a/libpurple/protocols/jabber/si.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/jabber/si.c	Sun Jun 24 20:01:43 2007 +0000
@@ -20,9 +20,9 @@
  *
  */
 
-#include "blist.h"
+#include "internal.h"
 
-#include "internal.h"
+#include "blist.h"
 #include "cipher.h"
 #include "debug.h"
 #include "ft.h"
--- a/libpurple/protocols/oscar/oscar.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sun Jun 24 20:01:43 2007 +0000
@@ -5573,7 +5573,7 @@
 	status = purple_presence_get_active_status(presence);
 	id = purple_status_get_id(status);
 
-	if (!purple_presence_is_online(presence))
+	if ((od != NULL) && !purple_presence_is_online(presence))
 	{
 		char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, b->name);
 		if (aim_ssi_waitingforauth(od->ssi.local, gname, b->name))
--- a/libpurple/protocols/qq/Makefile.am	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/Makefile.am	Sun Jun 24 20:01:43 2007 +0000
@@ -34,8 +34,6 @@
 	group_info.h \
 	group_join.c \
 	group_join.h \
-	group_misc.c \
-	group_misc.h \
 	group_network.c \
 	group_network.h \
 	group_opt.c \
--- a/libpurple/protocols/qq/buddy_list.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/buddy_list.c	Sun Jun 24 20:01:43 2007 +0000
@@ -23,8 +23,10 @@
  */
 
 #include <string.h>
+
+#include "qq.h"
+
 #include "debug.h"
-
 #include "notify.h"
 #include "utils.h"
 #include "packet_parse.h"
@@ -35,9 +37,8 @@
 #include "char_conv.h"
 #include "crypt.h"
 #include "header_info.h"
-#include "keep_alive.h"	
+#include "keep_alive.h"
 #include "send_core.h"
-#include "qq.h"	
 #include "group.h"
 #include "group_find.h"
 #include "group_internal.h"
--- a/libpurple/protocols/qq/buddy_status.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/buddy_status.c	Sun Jun 24 20:01:43 2007 +0000
@@ -23,6 +23,7 @@
  */
 
 #include <string.h>
+#include "internal.h"
 #include "debug.h"
 #include "prefs.h"
 
--- a/libpurple/protocols/qq/file_trans.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/file_trans.c	Sun Jun 24 20:01:43 2007 +0000
@@ -26,6 +26,8 @@
 #define random rand
 #endif
 
+#include "internal.h"
+
 #include "debug.h"
 #include "ft.h"
 #include "cipher.h"
--- a/libpurple/protocols/qq/group_conv.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_conv.c	Sun Jun 24 20:01:43 2007 +0000
@@ -23,11 +23,12 @@
  */
 
 #include <glib.h>
+#include "qq.h"
+
 #include "conversation.h"
 
 #include "buddy_status.h"
 #include "group_conv.h"
-#include "qq.h"
 #include "utils.h"
 
 /* show group conversation window */
--- a/libpurple/protocols/qq/group_find.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_find.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,13 +22,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "qq.h"
+
 #include "conversation.h"
 #include "debug.h"
 #include "util.h"
 
 #include "group_find.h"
 #include "group_network.h"
-#include "qq.h"
 #include "utils.h"
 
 /* find the internal_group_id by the reply packet sequence
--- a/libpurple/protocols/qq/group_free.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_free.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "debug.h"
 
 #include "buddy_status.h"
--- a/libpurple/protocols/qq/group_im.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_im.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "conversation.h"
 #include "debug.h"
 #include "notify.h"
--- a/libpurple/protocols/qq/group_info.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_info.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "conversation.h"
 #include "debug.h"
 
--- a/libpurple/protocols/qq/group_internal.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_internal.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,13 +22,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
 #include "blist.h"
 #include "debug.h"
 
 #include "buddy_opt.h"
 #include "group_free.h"
 #include "group_internal.h"
-#include "group_misc.h"
 #include "utils.h"
 
 static gchar *_qq_group_set_my_status_desc(qq_group *group)
--- a/libpurple/protocols/qq/group_join.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_join.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "debug.h"
 #include "notify.h"
 #include "request.h"
--- a/libpurple/protocols/qq/group_misc.c	Fri Jun 22 17:36:48 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/**
- * @file group_misc.c
- *
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "debug.h"
-
-#include "buddy_status.h"
-#include "group_misc.h"
-#include "utils.h"
--- a/libpurple/protocols/qq/group_misc.h	Fri Jun 22 17:36:48 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/**
- * @file group_misc.h
- *
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _QQ_GROUP_MISC_H_
-#define _QQ_GROUP_MISC_H_
-
-#include <glib.h>
-#include "group.h"
-
-#endif
--- a/libpurple/protocols/qq/group_network.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_network.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "debug.h"
 #include "notify.h"
 
--- a/libpurple/protocols/qq/group_opt.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_opt.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "qq.h"
+
 #include "debug.h"
 #include "notify.h"
 #include "request.h"
@@ -35,7 +37,6 @@
 #include "group_network.h"
 #include "group_opt.h"
 #include "packet_parse.h"
-#include "qq.h"
 #include "utils.h"
 
 /* TODO: can't we use qsort here? */
--- a/libpurple/protocols/qq/group_search.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/group_search.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "debug.h"
 
 #include "char_conv.h"
--- a/libpurple/protocols/qq/header_info.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/header_info.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "header_info.h"
 
 #define QQ_CLIENT_062E 0x062e	/* GB QQ2000c build 0630 */
--- a/libpurple/protocols/qq/im.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/im.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "conversation.h"
 #include "debug.h"
 #include "internal.h"
--- a/libpurple/protocols/qq/keep_alive.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/keep_alive.c	Sun Jun 24 20:01:43 2007 +0000
@@ -28,6 +28,8 @@
  * Puzzlebird, Nov-Dec 2002
  */
 
+#include "internal.h"
+
 #include "debug.h"
 #include "server.h"
 
--- a/libpurple/protocols/qq/qq.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/qq.h	Sun Jun 24 20:01:43 2007 +0000
@@ -26,8 +26,8 @@
 #define _QQ_QQ_H_
 
 #include <glib.h>
+#include "internal.h"
 #include "ft.h"
-#include "internal.h"
 #include "proxy.h"
 #include "roomlist.h"
 
--- a/libpurple/protocols/qq/send_file.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/send_file.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "qq.h"
+
 #include "send_file.h"
 #include "debug.h"
 #include "network.h"
@@ -34,7 +36,6 @@
 #include "im.h"
 #include "keep_alive.h"
 #include "packet_parse.h"
-#include "qq.h"
 #include "send_core.h"
 #include "utils.h"
 
--- a/libpurple/protocols/qq/sendqueue.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/qq/sendqueue.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,9 +22,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "connection.h"
 #include "debug.h"
-#include "internal.h"
 #include "notify.h"
 #include "prefs.h"
 #include "request.h"
--- a/libpurple/protocols/yahoo/yahoo_auth.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_auth.c	Sun Jun 24 20:01:43 2007 +0000
@@ -7,6 +7,8 @@
  *
  */
 
+#include "internal.h"
+
 #include "yahoo.h"
 #include "yahoo_auth.h"
 
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Sun Jun 24 20:01:43 2007 +0000
@@ -20,8 +20,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "prpl.h"
-#include "internal.h"
 #include "util.h"
 #include "debug.h"
 #include "notify.h"
--- a/libpurple/protocols/yahoo/yahoochat.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Sun Jun 24 20:01:43 2007 +0000
@@ -26,6 +26,8 @@
  *
  */
 
+#include "internal.h"
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -37,7 +39,6 @@
 #include "conversation.h"
 #include "notify.h"
 #include "util.h"
-#include "internal.h"
 
 #include "yahoo.h"
 #include "yahoo_packet.h"
--- a/libpurple/protocols/zephyr/ZVariables.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/protocols/zephyr/ZVariables.c	Sun Jun 24 20:01:43 2007 +0000
@@ -9,6 +9,7 @@
  *	"mit-copyright.h". 
  */
 
+#include "libpurple/internal.h"
 #include "internal.h"
 #include "util.h"
 
--- a/libpurple/prpl.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/prpl.h	Sun Jun 24 20:01:43 2007 +0000
@@ -378,7 +378,7 @@
  *                  beginning with the value for @a attr_id.
  */
 void purple_prpl_got_account_status(PurpleAccount *account,
-								  const char *status_id, ...);
+								  const char *status_id, ...) G_GNUC_NULL_TERMINATED;
 /**
  * Notifies Purple that a user's idle state and time have changed.
  *
@@ -418,7 +418,7 @@
  *                  beginning with the value for @a attr_id.
  */
 void purple_prpl_got_user_status(PurpleAccount *account, const char *name,
-							   const char *status_id, ...);
+							   const char *status_id, ...) G_GNUC_NULL_TERMINATED;
 
 /**
  * Notifies libpurple that a user's status has been deactivated
--- a/libpurple/request.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/request.c	Sun Jun 24 20:01:43 2007 +0000
@@ -22,6 +22,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "internal.h"
+
 #include "notify.h"
 #include "request.h"
 #include "debug.h"
--- a/libpurple/request.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/request.h	Sun Jun 24 20:01:43 2007 +0000
@@ -1228,7 +1228,7 @@
 						  const char *ok_text, GCallback ok_cb,
 						  const char *cancel_text, GCallback cancel_cb,
 						  PurpleAccount *account, const char *who, PurpleConversation *conv,
-						  void *user_data, ...);
+						  void *user_data, ...) G_GNUC_NULL_TERMINATED;
 
 /**
  * Prompts the user for multiple-choice input.
--- a/libpurple/roomlist.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/roomlist.c	Sun Jun 24 20:01:43 2007 +0000
@@ -25,6 +25,8 @@
 
 #include <glib.h>
 
+#include "internal.h"
+
 #include "account.h"
 #include "connection.h"
 #include "debug.h"
--- a/libpurple/savedstatuses.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/savedstatuses.c	Sun Jun 24 20:01:43 2007 +0000
@@ -29,6 +29,7 @@
 #include "notify.h"
 #include "savedstatuses.h"
 #include "dbus-maybe.h"
+#include "request.h"
 #include "status.h"
 #include "util.h"
 #include "xmlnode.h"
@@ -110,6 +111,7 @@
 	g_return_if_fail(substatus != NULL);
 
 	g_free(substatus->message);
+	purple_request_close_with_handle(substatus);
 	PURPLE_DBUS_UNREGISTER_POINTER(substatus);
 	g_free(substatus);
 }
@@ -128,7 +130,7 @@
 		status->substatuses = g_list_remove(status->substatuses, substatus);
 		free_saved_status_sub(substatus);
 	}
-
+	purple_request_close_with_handle(status);
 	PURPLE_DBUS_UNREGISTER_POINTER(status);
 	g_free(status);
 }
@@ -569,6 +571,9 @@
 
 	schedule_save();
 
+	purple_signal_emit(purple_savedstatuses_get_handle(), "savedstatus-added",
+		status);
+
 	return status;
 }
 
@@ -584,6 +589,9 @@
 	status->title = g_strdup(title);
 
 	schedule_save();
+
+	purple_signal_emit(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", status);
 }
 
 void
@@ -594,6 +602,8 @@
 	status->type = type;
 
 	schedule_save();
+	purple_signal_emit(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", status);
 }
 
 void
@@ -608,6 +618,9 @@
 		status->message = g_strdup(message);
 
 	schedule_save();
+
+	purple_signal_emit(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", status);
 }
 
 void
@@ -637,6 +650,8 @@
 	substatus->message = g_strdup(message);
 
 	schedule_save();
+	purple_signal_emit(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", saved_status);
 }
 
 void
@@ -660,6 +675,9 @@
 			return;
 		}
 	}
+
+	purple_signal_emit(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", saved_status);
 }
 
 /*
@@ -683,16 +701,12 @@
 	}
 }
 
-gboolean
-purple_savedstatus_delete(const char *title)
+void
+purple_savedstatus_delete_by_status(PurpleSavedStatus *status)
 {
-	PurpleSavedStatus *status;
 	time_t creation_time, current, idleaway;
 
-	status = purple_savedstatus_find(title);
-
-	if (status == NULL)
-		return FALSE;
+	g_return_if_fail(status != NULL);
 
 	saved_statuses = g_list_remove(saved_statuses, status);
 	creation_time = purple_savedstatus_get_creation_time(status);
@@ -713,6 +727,25 @@
 	if (idleaway == creation_time)
 		purple_prefs_set_int("/purple/savedstatus/idleaway", 0);
 
+	purple_signal_emit(purple_savedstatuses_get_handle(),
+			"savedstatus-deleted", status);
+}
+
+gboolean
+purple_savedstatus_delete(const char *title)
+{
+	PurpleSavedStatus *status;
+
+	status = purple_savedstatus_find(title);
+
+	if (status == NULL)
+		return FALSE;
+
+	if (purple_savedstatus_get_current() == status)
+		return FALSE;
+
+	purple_savedstatus_delete_by_status(status);
+
 	return TRUE;
 }
 
@@ -1171,6 +1204,21 @@
 					 purple_value_new(PURPLE_TYPE_SUBTYPE,
 									PURPLE_SUBTYPE_SAVEDSTATUS));
 
+	purple_signal_register(handle, "savedstatus-added",
+		purple_marshal_VOID__POINTER, NULL, 1,
+		purple_value_new(PURPLE_TYPE_SUBTYPE,
+			PURPLE_SUBTYPE_SAVEDSTATUS));
+
+	purple_signal_register(handle, "savedstatus-deleted",
+		purple_marshal_VOID__POINTER, NULL, 1,
+		purple_value_new(PURPLE_TYPE_SUBTYPE,
+			PURPLE_SUBTYPE_SAVEDSTATUS));
+
+	purple_signal_register(handle, "savedstatus-modified",
+		purple_marshal_VOID__POINTER, NULL, 1,
+		purple_value_new(PURPLE_TYPE_SUBTYPE,
+			PURPLE_SUBTYPE_SAVEDSTATUS));
+
 	purple_signal_connect(purple_accounts_get_handle(), "account-removed",
 			handle,
 			PURPLE_CALLBACK(purple_savedstatus_unset_all_substatuses),
--- a/libpurple/savedstatuses.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/savedstatuses.h	Sun Jun 24 20:01:43 2007 +0000
@@ -149,6 +149,16 @@
 gboolean purple_savedstatus_delete(const char *title);
 
 /**
+ * Delete a saved status.  This removes the saved status from the list
+ * of saved statuses, and writes the revised list to status.xml.
+ *
+ * @param saved_status the status to delete, the pointer is invalid after
+ *        the call
+ *
+ */
+void purple_savedstatus_delete_by_status(PurpleSavedStatus *saved_status);
+
+/**
  * Returns all saved statuses.
  *
  * @constreturn A list of saved statuses.
--- a/libpurple/server.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/server.c	Sun Jun 24 20:01:43 2007 +0000
@@ -198,7 +198,7 @@
 {
 	PurplePluginProtocolInfo *prpl_info = NULL;
 
-	if (b != NULL && b->account->gc->prpl != NULL)
+	if (b != NULL && b->account->gc && b->account->gc->prpl != NULL)
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(b->account->gc->prpl);
 
 	if (b && prpl_info && prpl_info->alias_buddy) {
--- a/libpurple/status.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/status.c	Sun Jun 24 20:01:43 2007 +0000
@@ -152,10 +152,10 @@
 	{ PURPLE_STATUS_UNSET,           "unset",           N_("Unset")           },
 	{ PURPLE_STATUS_OFFLINE,         "offline",         N_("Offline")         },
 	{ PURPLE_STATUS_AVAILABLE,       "available",       N_("Available")       },
-	{ PURPLE_STATUS_UNAVAILABLE,     "unavailable",     N_("Unavailable")     },
+	{ PURPLE_STATUS_UNAVAILABLE,     "unavailable",     N_("Do not disturb")     },
 	{ PURPLE_STATUS_INVISIBLE,       "invisible",       N_("Invisible")       },
 	{ PURPLE_STATUS_AWAY,            "away",            N_("Away")            },
-	{ PURPLE_STATUS_EXTENDED_AWAY,   "extended_away",   N_("Extended Away")   },
+	{ PURPLE_STATUS_EXTENDED_AWAY,   "extended_away",   N_("Extended away")   },
 	{ PURPLE_STATUS_MOBILE,          "mobile",          N_("Mobile")          }
 };
 
--- a/libpurple/status.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/status.h	Sun Jun 24 20:01:43 2007 +0000
@@ -227,7 +227,7 @@
 												gboolean independent,
 												const char *attr_id,
 												const char *attr_name,
-												PurpleValue *attr_value, ...);
+												PurpleValue *attr_value, ...) G_GNUC_NULL_TERMINATED;
 
 /**
  * Destroys a status type.
@@ -270,7 +270,7 @@
  * @param ...         Additional attribute information.
  */
 void purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
-								const char *name, PurpleValue *value, ...);
+								const char *name, PurpleValue *value, ...) G_GNUC_NULL_TERMINATED;
 
 /**
  * Adds multiple attributes to a status type using a va_list.
--- a/libpurple/whiteboard.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/libpurple/whiteboard.c	Sun Jun 24 20:01:43 2007 +0000
@@ -23,6 +23,7 @@
 
 #include <string.h>
 
+#include "internal.h"
 #include "whiteboard.h"
 #include "prpl.h"
 
--- a/pidgin/gtkblist.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkblist.c	Sun Jun 24 20:01:43 2007 +0000
@@ -151,11 +151,7 @@
 	if (!gtkblist)
 		return "dim grey";
 	if (!dim_grey_string[0]) {
-		GtkStyle *style = gtk_widget_get_style(gtkblist->treeview);
-		snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x",
-			 style->text_aa[GTK_STATE_NORMAL].red >> 8,
-			 style->text_aa[GTK_STATE_NORMAL].green >> 8,
-			 style->text_aa[GTK_STATE_NORMAL].blue >> 8);
+		snprintf(dim_grey_string, sizeof(dim_grey_string), "%s", pidgin_get_dim_grey_string(gtkblist->treeview)); 
 	}
 	return dim_grey_string;
 }
@@ -295,15 +291,30 @@
 static void gtk_blist_join_chat(PurpleChat *chat)
 {
 	PurpleConversation *conv;
-
-	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
-											   purple_chat_get_name(chat),
+	PurplePluginProtocolInfo *prpl_info;
+	const char *name;
+	char *chat_name;
+
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(chat->account)));
+
+	if (prpl_info && prpl_info->get_chat_name)
+		chat_name = prpl_info->get_chat_name(chat->components);
+	else
+		chat_name = NULL;
+
+	if (chat_name)
+		name = chat_name;
+	else
+		name = purple_chat_get_name(chat);
+
+	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name,
 											   chat->account);
 
 	if (conv != NULL)
 		purple_conversation_present(conv);
 
 	serv_join_chat(chat->account->gc, chat->components);
+	g_free(chat_name);
 }
 
 static void gtk_blist_menu_join_cb(GtkWidget *w, PurpleChat *chat)
@@ -311,6 +322,7 @@
 	gtk_blist_join_chat(chat);
 }
 
+#if GTK_CHECK_VERSION(2,6,0)
 static void gtk_blist_renderer_editing_cancelled_cb(GtkCellRenderer *renderer, PurpleBuddyList *list)
 {
 	editing_blist = FALSE;
@@ -355,6 +367,7 @@
 	}
 	editing_blist = TRUE;
 }
+#endif
 
 static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *arg1,
 					 char *arg2, PurpleBuddyList *list)
@@ -2092,51 +2105,6 @@
 	}
 }
 
-static void
-roundify(GdkPixbuf *pixbuf) {
-	int width, height, rowstride;
-	guchar *pixels;
-
-	if (!gdk_pixbuf_get_has_alpha(pixbuf))
-		return;
-
-	width = gdk_pixbuf_get_width(pixbuf);
-	height = gdk_pixbuf_get_height(pixbuf);
-	rowstride = gdk_pixbuf_get_rowstride(pixbuf);
-	pixels = gdk_pixbuf_get_pixels(pixbuf);
-
-	if (width < 6 || height < 6)
-		return;
-
-	/* Top left */
-	pixels[3] = 0;
-	pixels[7] = 0x80;
-	pixels[11] = 0xC0;
-	pixels[rowstride + 3] = 0x80;
-	pixels[rowstride * 2 + 3] = 0xC0;
-
-	/* Top right */
-	pixels[width * 4 - 1] = 0;
-	pixels[width * 4 - 5] = 0x80;
-	pixels[width * 4 - 9] = 0xC0;
-	pixels[rowstride + (width * 4) - 1] = 0x80;
-	pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0;
-
-	/* Bottom left */
-	pixels[(height - 1) * rowstride + 3] = 0;
-	pixels[(height - 1) * rowstride + 7] = 0x80;
-	pixels[(height - 1) * rowstride + 11] = 0xC0;
-	pixels[(height - 2) * rowstride + 3] = 0x80;
-	pixels[(height - 3) * rowstride + 3] = 0xC0;
-
-	/* Bottom right */
-	pixels[height * rowstride - 1] = 0;
-	pixels[(height - 1) * rowstride - 1] = 0x80;
-	pixels[(height - 2) * rowstride - 1] = 0xC0;
-	pixels[height * rowstride - 5] = 0x80;
-	pixels[height * rowstride - 9] = 0xC0;
-}
-
 /* Altered from do_colorshift in gnome-panel */
 static void
 do_alphashift (GdkPixbuf *dest, GdkPixbuf *src, int shift)
@@ -2273,7 +2241,7 @@
 			gdk_pixbuf_fill(ret, 0x00000000);
 			gdk_pixbuf_scale(buf, ret, (32-scale_width)/2, (32-scale_height)/2, scale_width, scale_height, (32-scale_width)/2, (32-scale_height)/2, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR);
 			if (pidgin_gdk_pixbuf_is_opaque(ret))
-				roundify(ret);
+				pidgin_gdk_pixbuf_make_round(ret);
 		} else {
 			ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR);
 		}
@@ -3282,7 +3250,7 @@
 	return ret;
 }
 
-static gchar *pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected)
+gchar *pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased)
 {
 	const char *name;
 	char *esc, *text = NULL;
@@ -3307,15 +3275,19 @@
 	}
 
 	/* XXX Good luck cleaning up this crap */
-
-	contact = (PurpleContact*)((PurpleBlistNode*)b)->parent;
-	if(contact)
-		gtkcontactnode = ((PurpleBlistNode*)contact)->ui_data;
-
-	if(gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias)
-		name = contact->alias;
-	else
-		name = purple_buddy_get_alias(b);
+	if (aliased) {
+		contact = (PurpleContact*)((PurpleBlistNode*)b)->parent;
+		if(contact)
+			gtkcontactnode = ((PurpleBlistNode*)contact)->ui_data;
+
+		if(gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias)
+			name = contact->alias;
+		else
+			name = purple_buddy_get_alias(b);
+	} else {
+		name = b->name;
+	}
+	
 	esc = g_markup_escape_text(name, strlen(name));
 
 	presence = purple_buddy_get_presence(b);
@@ -4463,8 +4435,10 @@
 #endif
 										"markup", NAME_COLUMN,
 										NULL);
+#if GTK_CHECK_VERSION(2,6,0)
 	g_signal_connect(G_OBJECT(rend), "editing-started", G_CALLBACK(gtk_blist_renderer_editing_started_cb), NULL);
 	g_signal_connect(G_OBJECT(rend), "editing-canceled", G_CALLBACK(gtk_blist_renderer_editing_cancelled_cb), list);
+#endif
 	g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), list);
 	g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL);
 #if GTK_CHECK_VERSION(2,6,0)
@@ -4967,7 +4941,7 @@
 	}
 
 	emblem = pidgin_blist_get_emblem((PurpleBlistNode*) buddy);
-	mark = pidgin_blist_get_name_markup(buddy, selected);
+	mark = pidgin_blist_get_name_markup(buddy, selected, TRUE);
 
 	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time") &&
 		purple_presence_is_idle(presence) &&
--- a/pidgin/gtkblist.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkblist.h	Sun Jun 24 20:01:43 2007 +0000
@@ -360,4 +360,14 @@
 void pidgin_blist_set_headline(const char *text, GdkPixbuf *pixbuf, GCallback callback, gpointer user_data,
 		GDestroyNotify destroy);
 
+/**
+ * Returns a buddy's Pango markup appropriate for setting in a GtkCellRenderer.
+ *
+ * @param buddy The buddy to return markup from
+ * @param selected  Whether this buddy is selected. If TRUE, the markup will not change the color.
+ * @param aliased  TRUE to return the appropriate alias of this buddy, FALSE to return its screenname
+ * @return The markup for this buddy
+ */
+gchar *pidgin_blist_get_name_markup(PurpleBuddy *buddy, gboolean selected, gboolean aliased);
+
 #endif /* _PIDGINBLIST_H_ */
--- a/pidgin/gtkconv.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkconv.c	Sun Jun 24 20:01:43 2007 +0000
@@ -82,6 +82,12 @@
 	PIDGIN_CONV_COLORIZE_TITLE		= 1 << 6
 }PidginConvFields;
 
+enum {
+	ICON_COLUMN,
+	TEXT_COLUMN,
+	NUM_COLUMNS
+} PidginInfopaneColumns;
+
 #define	PIDGIN_CONV_ALL	((1 << 7) - 1)
 
 #define SEND_COLOR "#204a87"
@@ -178,6 +184,8 @@
 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
+static gboolean infopane_release_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv);
+static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv);
 
 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) {
 	static GdkColor col;
@@ -622,23 +630,10 @@
 static void chat_do_info(PidginConversation *gtkconv, const char *who)
 {
 	PurpleConversation *conv = gtkconv->active_conv;
-	PurplePluginProtocolInfo *prpl_info = NULL;
 	PurpleConnection *gc;
 
 	if ((gc = purple_conversation_get_gc(conv))) {
-		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
-
-		/*
-		 * If there are special needs for getting info on users in
-		 * buddy chat "rooms"...
-		 */
-		if (prpl_info->get_cb_info != NULL)
-		{
-			prpl_info->get_cb_info(gc,
-				purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who);
-		}
-		else
-			pidgin_retrieve_user_info(gc, who);
+		pidgin_retrieve_user_info_in_chat(gc, who, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)));
 	}
 }
 
@@ -2350,6 +2345,10 @@
 	gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status);
 	gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status);
 
+	gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), 
+			&(gtkconv->infopane_iter),
+			ICON_COLUMN, status, -1);
+
 	if (status != NULL)
 		g_object_unref(status);
 
@@ -2405,16 +2404,22 @@
 	gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL);
 	buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter);
 
-	pidgin_buddy_icon_get_scale_size(buf, &prpl_info->icon_spec,
-			PURPLE_ICON_SCALE_DISPLAY, &scale_width, &scale_height);
-
-	/* this code is ugly, and scares me */
-	scale = gdk_pixbuf_scale_simple(buf,
-		MAX(gdk_pixbuf_get_width(buf) * scale_width /
-		    gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1),
-		MAX(gdk_pixbuf_get_height(buf) * scale_height /
-		    gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1),
+ 	scale_width = gdk_pixbuf_get_width(buf);
+        scale_height = gdk_pixbuf_get_height(buf);
+        if (scale_width == scale_height) {
+		scale_width = scale_height = 32;
+	} else if (scale_height > scale_width) {
+                scale_width = 32 * scale_width / scale_height;
+                scale_height = 32;
+        } else {
+                scale_height = 32 * scale_height / scale_width;
+                scale_width = 32;
+        }
+
+	scale = gdk_pixbuf_scale_simple(buf, scale_width, scale_height,
 		GDK_INTERP_BILINEAR);
+	if (pidgin_gdk_pixbuf_is_opaque(scale))
+		pidgin_gdk_pixbuf_make_round(scale);
 
 	gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->u.im->icon), scale);
 	g_object_unref(G_OBJECT(scale));
@@ -4261,11 +4266,9 @@
 		
 		hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 		gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-		gtk_widget_show(hbox);
 
 		label = gtk_label_new(_("Topic:"));
 		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-		gtk_widget_show(label);
 
 		gtkchat->topic_text = gtk_entry_new();
 
@@ -4277,7 +4280,6 @@
 		}
 
 		gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0);
-		gtk_widget_show(gtkchat->topic_text);
 		g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event",
 			             G_CALLBACK(entry_key_press_cb), gtkconv);
 	}
@@ -4377,7 +4379,9 @@
 static GtkWidget *
 setup_common_pane(PidginConversation *gtkconv)
 {
-	GtkWidget *paned, *vbox, *frame, *imhtml_sw;
+	GtkWidget *paned, *vbox, *frame, *imhtml_sw, *event_box;
+	GtkCellRenderer *rend;
+	GtkTreePath *path;
 	PurpleConversation *conv = gtkconv->active_conv;
 	gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT);
 	GtkPolicyType imhtml_sw_hscroll;
@@ -4390,6 +4394,47 @@
 	gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE);
 	gtk_widget_show(vbox);
 
+	/* Setup the info pane */
+	event_box = gtk_event_box_new();
+	gtk_widget_show(event_box);
+	gtkconv->infopane_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), event_box, FALSE, FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(event_box), gtkconv->infopane_hbox);
+	gtk_widget_show(gtkconv->infopane_hbox);
+	gtk_widget_add_events(event_box,
+	                      GDK_BUTTON1_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
+	g_signal_connect(G_OBJECT(event_box), "button_press_event",
+	                 G_CALLBACK(infopane_press_cb), gtkconv);
+	g_signal_connect(G_OBJECT(event_box), "button_release_event",
+	                 G_CALLBACK(infopane_release_cb), gtkconv);
+
+
+	gtkconv->infopane = gtk_cell_view_new();
+	gtkconv->infopane_model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
+	gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), 
+				GTK_TREE_MODEL(gtkconv->infopane_model));
+	gtk_list_store_append(gtkconv->infopane_model, &(gtkconv->infopane_iter));
+	gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox), gtkconv->infopane, TRUE, TRUE, 0);
+	path = gtk_tree_path_new_from_string("0");
+	gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(gtkconv->infopane), path);
+	gtk_tree_path_free(path);
+	gtk_widget_set_size_request(gtkconv->infopane, -1, 32);
+	gtk_widget_show(gtkconv->infopane);
+
+	rend = gtk_cell_renderer_pixbuf_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", ICON_COLUMN, NULL);
+	g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
+
+	rend = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, TRUE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "markup", TEXT_COLUMN, NULL);
+	g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL);
+
+#if GTK_CHECK_VERSION(2, 6, 0)
+	g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+#endif
+
 	/* Setup the gtkimhtml widget */
 	frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw);
 	if (chat) {
@@ -6117,11 +6162,13 @@
 		pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->imhtml);
 
 	if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
-			(fields & PIDGIN_CONV_SET_TITLE))
+			(fields & PIDGIN_CONV_SET_TITLE) ||
+    			(fields & PIDGIN_CONV_TOPIC))
 	{
 		char *title;
 		PurpleConvIm *im = NULL;
 		PurpleAccount *account = purple_conversation_get_account(conv);
+		char *markup = NULL;
 		AtkObject *accessibility_obj;
 		/* I think this is a little longer than it needs to be but I'm lazy. */
 		char style[51];
@@ -6137,6 +6184,25 @@
 		else
 			title = g_strdup(purple_conversation_get_title(conv));
 
+		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+		 	PurpleBuddy *buddy = purple_find_buddy(account, conv->name);
+			if (buddy)
+				markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
+			else
+				markup = title;
+		} else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+			PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
+			markup = g_strdup_printf("%s\n<span color='%s' size='smaller'>%s</span>",
+						purple_conversation_get_title(conv),
+						pidgin_get_dim_grey_string(gtkconv->infopane),
+						purple_conv_chat_get_topic(chat));
+		}
+		gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter),
+				TEXT_COLUMN, markup, -1);
+	
+		if (title != markup)
+			g_free(markup);
+
 		*style = '\0';
 
 		if (!GTK_WIDGET_REALIZED(gtkconv->tab_label))
@@ -6296,7 +6362,6 @@
 	GdkPixbuf *buf;
 
 	GtkWidget *event;
-	GtkWidget *frame;
 	GdkPixbuf *scale;
 	int scale_width, scale_height;
 
@@ -6395,54 +6460,55 @@
 	}
 
 	if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) {
+		GdkPixbuf *stat;
 		gtkconv->u.im->iter = NULL;
-		buf = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim);
+		stat = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim);
+		buf = gdk_pixbuf_add_alpha(stat, FALSE, 0, 0, 0);
 	} else {
+		GdkPixbuf *stat;
 		gtkconv->u.im->iter =
 			gdk_pixbuf_animation_get_iter(gtkconv->u.im->anim, NULL); /* LEAK */
-		buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter);
+		stat = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter);
+		buf = gdk_pixbuf_add_alpha(stat, FALSE, 0, 0, 0);
 		if (gtkconv->u.im->animate)
 			start_anim(NULL, gtkconv);
 	}
 
-	pidgin_buddy_icon_get_scale_size(buf, &prpl_info->icon_spec,
-			PURPLE_ICON_SCALE_DISPLAY, &scale_width, &scale_height);
-	scale = gdk_pixbuf_scale_simple(buf,
-				MAX(gdk_pixbuf_get_width(buf) * scale_width /
-				    gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1),
-				MAX(gdk_pixbuf_get_height(buf) * scale_height /
-				    gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1),
+	scale_width = gdk_pixbuf_get_width(buf);
+	scale_height = gdk_pixbuf_get_height(buf);
+	if (scale_width == scale_height) {
+		scale_width = scale_height = 32;
+	} else if (scale_height > scale_width) {
+		scale_width = 32 * scale_width / scale_height;
+		scale_height = 32;
+	} else {
+		scale_height = 32 * scale_height / scale_width;
+		scale_width = 32;
+	}
+	scale = gdk_pixbuf_scale_simple(buf, scale_width, scale_height,
 				GDK_INTERP_BILINEAR);
-
+	g_object_unref(buf);
+	if (pidgin_gdk_pixbuf_is_opaque(scale))
+		pidgin_gdk_pixbuf_make_round(scale);
 	gtkconv->u.im->icon_container = gtk_vbox_new(FALSE, 0);
 
-	frame = gtk_frame_new(NULL);
-	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
-	gtk_box_pack_start(GTK_BOX(gtkconv->u.im->icon_container), frame,
-					   FALSE, FALSE, 0);
-
 	event = gtk_event_box_new();
-	gtk_container_add(GTK_CONTAINER(frame), event);
+	gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
 	g_signal_connect(G_OBJECT(event), "button-press-event",
 					 G_CALLBACK(icon_menu), gtkconv);
 	gtk_widget_show(event);
 
 	gtkconv->u.im->icon = gtk_image_new_from_pixbuf(scale);
 	gtkconv->auto_resize = TRUE;
-	/* Reset the size request to allow the buddy icon to resize */
-	gtk_widget_set_size_request(gtkconv->lower_hbox, -1, -1);
-	g_idle_add(reset_auto_resize_cb, gtkconv);
-	gtk_widget_set_size_request(gtkconv->u.im->icon, scale_width, scale_height);
 	gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon);
 	gtk_widget_show(gtkconv->u.im->icon);
 
 	g_object_unref(G_OBJECT(scale));
 
-	gtk_box_pack_start(GTK_BOX(gtkconv->lower_hbox),
+	gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox),
 			   gtkconv->u.im->icon_container, FALSE, FALSE, 0);
 
 	gtk_widget_show(gtkconv->u.im->icon_container);
-	gtk_widget_show(frame);
 
 	/* The buddy icon code needs badly to be fixed. */
 	if(pidgin_conv_window_is_active_conversation(conv))
@@ -7540,6 +7606,45 @@
 /*
  * THANK YOU GALEON!
  */
+
+static gboolean
+infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
+{
+	int nb_x, nb_y;
+
+	if (e->button != 1 || e->type != GDK_BUTTON_PRESS)
+		return FALSE;
+
+	if (gtkconv->win->in_drag) {
+		  purple_debug(PURPLE_DEBUG_WARNING, "gtkconv",
+                           "Already in the middle of a window drag at tab_press_cb\n");
+                return TRUE;
+        }
+	
+	gtkconv->win->in_predrag = TRUE;
+	gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
+
+        gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y);
+
+        gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x      + nb_x;
+        gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y      + nb_y;
+        gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width  + gtkconv->win->drag_min_x;
+        gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y;
+
+
+	/* Connect the new motion signals. */
+	gtkconv->win->drag_motion_signal =
+		g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
+		                 G_CALLBACK(notebook_motion_cb), gtkconv->win);
+
+	gtkconv->win->drag_leave_signal =
+		g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event",
+		                 G_CALLBACK(notebook_leave_cb), gtkconv->win);
+
+	return FALSE;
+
+}
+
 static gboolean
 notebook_press_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win)
 {
@@ -7629,6 +7734,12 @@
 }
 
 static gboolean
+infopane_release_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
+{
+	return FALSE;
+}
+
+static gboolean
 notebook_release_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win)
 {
 	PidginWindow *dest_win;
@@ -7959,6 +8070,11 @@
 		return FALSE;
 	}
 
+	if (!purple_account_is_connected(gtkconv->active_conv->account)) {
+		/* Do not allow aliasing someone on a disconnected account. */
+		return FALSE;
+	}
+
 	/* alias label */
 	entry = gtk_entry_new();
 	gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE);
@@ -8320,8 +8436,7 @@
 		/* Er, bug in notebooks? Switch to the page manually. */
 		gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
 
-		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
-		                           purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs"));
+		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
 	} else
 		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), TRUE);
 
@@ -8415,7 +8530,7 @@
 	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, !tabs_side && !angle, TRUE, GTK_PACK_START);
 
 	/* show the widgets */
-	gtk_widget_show(gtkconv->icon);
+/* XXX	gtk_widget_show(gtkconv->icon); */
 	gtk_widget_show(gtkconv->tab_label);
 	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs"))
 		gtk_widget_show(gtkconv->close);
@@ -8437,14 +8552,16 @@
 
 	gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
 
-	/* go back to tabless if need be */
+	/* go back to tabless */
 	if (pidgin_conv_window_get_gtkconv_count(win) <= 2) {
-		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
-		                           purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs"));
+		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
 	}
 
 	win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv);
 
+	if (!win->gtkconvs || !win->gtkconvs->next)
+		gtk_notebook_set_show_tabs(win->notebook, FALSE);
+
 	if (!win->gtkconvs && win != hidden_convwin)
 		pidgin_conv_window_destroy(win);
 }
--- a/pidgin/gtkconv.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkconv.h	Sun Jun 24 20:01:43 2007 +0000
@@ -158,6 +158,10 @@
 	} u;
 
 	time_t newday;
+	GtkWidget *infopane_hbox;
+	GtkWidget *infopane;
+	GtkListStore *infopane_model;
+	GtkTreeIter infopane_iter;
 };
 
 /*@}*/
--- a/pidgin/gtkimhtml.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkimhtml.c	Sun Jun 24 20:01:43 2007 +0000
@@ -29,6 +29,7 @@
 #endif
 
 #include "pidgin.h"
+#include "internal.h"
 
 #include "debug.h"
 #include "util.h"
@@ -53,19 +54,6 @@
 #include <windows.h>
 #endif
 
-#ifdef ENABLE_NLS
-#  include <libintl.h>
-#  define _(x) gettext(x)
-#  ifdef gettext_noop
-#    define N_(String) gettext_noop (String)
-#  else
-#    define N_(String) (String)
-#  endif
-#else
-#  define N_(String) (String)
-#  define _(x) (x)
-#endif
-
 #include <pango/pango-font.h>
 
 /* GTK+ < 2.4.x hack, see pidgin.h for details. */
--- a/pidgin/gtkmain.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkmain.c	Sun Jun 24 20:01:43 2007 +0000
@@ -496,7 +496,7 @@
 			"no fault of your own.\n\n"
 			"If you can reproduce the crash, please notify the developers\n"
 			"by reporting a bug at:\n"
-			"%snewticket/\n\n"
+			"%ssimpleticket/\n\n"
 			"Please make sure to specify what you were doing at the time\n"
 			"and post the backtrace from the core file.  If you do not know\n"
 			"how to get the backtrace, please read the instructions at\n"
--- a/pidgin/gtkprefs.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkprefs.c	Sun Jun 24 20:01:43 2007 +0000
@@ -1214,9 +1214,10 @@
 	}
 
 	gtk_widget_show_all(ret);
-	if (proxy_info == NULL ||
+	/* Only hide table if not running gnome otherwise we hide the IP address table! */
+	if (!purple_running_gnome() && (proxy_info == NULL ||
 	    purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_NONE ||
-	    purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_ENVVAR)
+	    purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_ENVVAR))
 		gtk_widget_hide(table);
 	return ret;
 }
--- a/pidgin/gtksavedstatuses.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtksavedstatuses.c	Sun Jun 24 20:01:43 2007 +0000
@@ -23,8 +23,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "internal.h"
+
 #include "account.h"
-#include "internal.h"
 #include "notify.h"
 #include "request.h"
 #include "savedstatuses.h"
@@ -285,9 +286,11 @@
 
 	for (l = sel_titles; l != NULL; l = l->next) {
 		title = l->data;
-		if (status_window_find_savedstatus(&iter, title))
-			gtk_list_store_remove(status_window->model, &iter);
-		purple_savedstatus_delete(title);
+		if (purple_savedstatus_find(title) != purple_savedstatus_get_current()) {
+			if (status_window_find_savedstatus(&iter, title))
+				gtk_list_store_remove(status_window->model, &iter);
+			purple_savedstatus_delete(title);
+		}
 		g_free(title);
 	}
 	g_list_free(sel_titles);
@@ -302,6 +305,7 @@
 	GList *sel_paths, *l, *sel_titles = NULL;
 	GtkTreeModel *model = GTK_TREE_MODEL(dialog->model);
 	char *title;
+	gpointer handle;
 
 	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
 #if GTK_CHECK_VERSION(2,2,0)
@@ -324,13 +328,16 @@
 	}
 	g_list_free(sel_paths);
 
-	if (g_list_length(sel_titles) == 1)
+	if (g_list_length(sel_titles) == 1) {
 		title = g_strdup_printf(_("Are you sure you want to delete %s?"),
 				(const gchar *)sel_titles->data);
-	else
+		handle = purple_savedstatus_find(sel_titles->data);
+	} else {
 		title = g_strdup(_("Are you sure you want to delete the selected saved statuses?"));
+		handle = dialog;
+	}
 
-	purple_request_action(dialog, NULL, title, NULL, 0,
+	purple_request_action(handle, NULL, title, NULL, 0,
 		 NULL, NULL, NULL,
 		 sel_titles, 2,
 		_("Delete"), status_window_delete_confirm_cb,
@@ -349,17 +356,39 @@
 status_selected_cb(GtkTreeSelection *sel, gpointer user_data)
 {
 	StatusWindow *dialog = user_data;
-	int num_selected = 0;
+	GList *sel_paths, *tmp;
+	gboolean can_use = TRUE, can_delete = TRUE;
+	int num_selected;
+	GtkTreeModel *model = GTK_TREE_MODEL(dialog->model);
 
 #if GTK_CHECK_VERSION(2,2,0)
-	num_selected = gtk_tree_selection_count_selected_rows(sel);
+	sel_paths = gtk_tree_selection_get_selected_rows(sel, NULL);
 #else
-	gtk_tree_selection_selected_foreach(sel, count_selected_helper, &num_selected);
+	gtk_tree_selection_selected_foreach(sel, list_selected_helper, &sel_paths);
 #endif
 
-	gtk_widget_set_sensitive(dialog->use_button, (num_selected == 1));
+	for (tmp = sel_paths, num_selected = 0; tmp; tmp = tmp->next, num_selected++) {
+		GtkTreeIter iter;
+		char *title;
+
+		if (gtk_tree_model_get_iter(model, &iter, tmp->data)) {
+			gtk_tree_model_get(model, &iter,
+					STATUS_WINDOW_COLUMN_TITLE, &title, -1);
+			if (purple_savedstatus_find(title) == purple_savedstatus_get_current()) {
+				can_use = can_delete = FALSE;
+			}
+
+			g_free(title);
+		}
+
+		gtk_tree_path_free(tmp->data);
+	}
+
+	gtk_widget_set_sensitive(dialog->use_button, (num_selected == 1) && can_use);
 	gtk_widget_set_sensitive(dialog->modify_button, (num_selected > 0));
-	gtk_widget_set_sensitive(dialog->delete_button, (num_selected > 0));
+	gtk_widget_set_sensitive(dialog->delete_button, can_delete);
+
+    g_list_free(sel_paths);
 }
 
 static void
@@ -421,6 +450,12 @@
 	status_window_modify_cb(NULL, dialog);
 }
 
+static void
+saved_status_updated_cb(PurpleSavedStatus *status, StatusWindow *sw)
+{
+	populate_saved_status_list(sw);
+}
+
 static GtkWidget *
 create_saved_status_list(StatusWindow *dialog)
 {
@@ -529,6 +564,13 @@
 	return FALSE;
 }
 
+static void
+current_status_changed(PurpleSavedStatus *old, PurpleSavedStatus *new_status,
+		StatusWindow *dialog)
+{
+	status_selected_cb(gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)), dialog);
+}
+
 void
 pidgin_status_window_show(void)
 {
@@ -615,6 +657,19 @@
 	g_signal_connect(G_OBJECT(button), "clicked",
 					 G_CALLBACK(status_window_close_cb), dialog);
 
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-changed", status_window,
+			PURPLE_CALLBACK(current_status_changed), dialog);
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-added", status_window,
+			PURPLE_CALLBACK(saved_status_updated_cb), dialog);
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-deleted", status_window,
+			PURPLE_CALLBACK(saved_status_updated_cb), dialog);
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", status_window,
+			PURPLE_CALLBACK(saved_status_updated_cb), dialog);
+
 	gtk_widget_show_all(win);
 }
 
@@ -629,6 +684,7 @@
 
 	purple_request_close_with_handle(status_window);
 	purple_notify_close_with_handle(status_window);
+	purple_signals_disconnect_by_handle(status_window);
 	g_free(status_window);
 	status_window = NULL;
 }
@@ -804,8 +860,10 @@
 	gtk_widget_destroy(dialog->window);
 	g_free(dialog->original_title);
 
+/*
 	if (status_window != NULL)
 	  add_status_to_saved_status_list(status_window->model, saved_status);
+*/
 
 	/* If they clicked on "Save & Use" or "Use," then activate the status */
 	if (button != dialog->save_button)
--- a/pidgin/gtkstatusbox.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkstatusbox.c	Sun Jun 24 20:01:43 2007 +0000
@@ -41,12 +41,14 @@
 
 #include <gdk/gdkkeysyms.h>
 
+#include "internal.h"
+
 #include "account.h"
 #include "buddyicon.h"
 #include "core.h"
-#include "internal.h"
 #include "imgstore.h"
 #include "network.h"
+#include "request.h"
 #include "savedstatuses.h"
 #include "status.h"
 #include "debug.h"
@@ -1017,7 +1019,7 @@
 static void
 pidgin_status_box_regenerate(PidginStatusBox *status_box)
 {
-	GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4;
+	GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4, *pixbuf5;
 	GtkIconSize icon_size;
 
 	icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL);
@@ -1047,15 +1049,19 @@
 			                                  icon_size, "PidginStatusBox");
 			pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), PIDGIN_STOCK_STATUS_INVISIBLE,
 			                                  icon_size, "PidginStatusBox");
+			pixbuf5 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), PIDGIN_STOCK_STATUS_BUSY,
+							  icon_size, "PidginStatusBox");
 
 			pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf, _("Available"), NULL, GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE));
 			pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf2, _("Away"), NULL, GINT_TO_POINTER(PURPLE_STATUS_AWAY));
+			pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf5, _("Do not disturb"), NULL, GINT_TO_POINTER(PURPLE_STATUS_UNAVAILABLE));
 			pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf4, _("Invisible"), NULL, GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE));
 			pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf3, _("Offline"), NULL, GINT_TO_POINTER(PURPLE_STATUS_OFFLINE));
 
 			if (pixbuf2)	g_object_unref(G_OBJECT(pixbuf2));
 			if (pixbuf3)	g_object_unref(G_OBJECT(pixbuf3));
 			if (pixbuf4)	g_object_unref(G_OBJECT(pixbuf4));
+			if (pixbuf5)	g_object_unref(G_OBJECT(pixbuf5));
 		}
 
 		add_popular_statuses(status_box);
@@ -1223,6 +1229,12 @@
 }
 
 static void
+saved_status_updated_cb(PurpleSavedStatus *status, PidginStatusBox *status_box)
+{
+	pidgin_status_box_regenerate(status_box);
+}
+
+static void
 spellcheck_prefs_cb(const char *name, PurplePrefType type,
 					gconstpointer value, gpointer data)
 {
@@ -1514,6 +1526,56 @@
 	pidgin_status_box_changed(status_box);
 }
 
+static void tree_view_delete_current_selection_cb(gpointer data)
+{
+	PurpleSavedStatus *saved;
+
+	saved = purple_savedstatus_find_by_creation_time(GPOINTER_TO_INT(data));
+	g_return_if_fail(saved != NULL);
+
+	if (purple_savedstatus_get_current() != saved)
+		purple_savedstatus_delete_by_status(saved);
+}
+
+static void
+tree_view_delete_current_selection(PidginStatusBox *status_box, GtkTreePath *path)
+{
+	GtkTreeIter iter;
+	gpointer data;
+	PurpleSavedStatus *saved;
+	gchar *msg;
+
+	if (status_box->active_row) {
+		/* don't delete active status */
+		if (gtk_tree_path_compare(path, gtk_tree_row_reference_get_path(status_box->active_row)) == 0)
+			return;
+	}
+
+	if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(status_box->dropdown_store), &iter, path))
+		return;
+
+	gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter,
+			   DATA_COLUMN, &data,
+			   -1);
+
+	saved = purple_savedstatus_find_by_creation_time(GPOINTER_TO_INT(data));
+	g_return_if_fail(saved != NULL);
+	if (saved == purple_savedstatus_get_current())
+		return;
+
+	msg = g_strdup_printf(_("Are you sure you want to delete %s?"), purple_savedstatus_get_title(saved));
+
+	purple_request_action(saved, NULL, msg, NULL, 0,
+		NULL, NULL, NULL,
+		data, 2,
+		_("Delete"), tree_view_delete_current_selection_cb,
+		_("Cancel"), NULL);
+
+	g_free(msg);
+
+	pidgin_status_box_popdown(status_box);
+}
+
 static gboolean
 treeview_button_release_cb(GtkWidget *widget, GdkEventButton *event, PidginStatusBox *status_box)
 {
@@ -1561,18 +1623,25 @@
 		if (event->keyval == GDK_Escape) {
 			pidgin_status_box_popdown(box);
 			return TRUE;
-		} else if (event->keyval == GDK_Return) {
+		} else {
 			GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(box->tree_view));
 			GtkTreeIter iter;
 			GtkTreePath *path;
 
 			if (gtk_tree_selection_get_selected(sel, NULL, &iter)) {
+				gboolean ret = TRUE;
 				path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter);
-				treeview_activate_current_selection(box, path);
+				if (event->keyval == GDK_Return) {
+					treeview_activate_current_selection(box, path);
+				} else if (event->keyval == GDK_Delete) {
+					tree_view_delete_current_selection(box, path);
+				} else
+					ret = FALSE;
+
 				gtk_tree_path_free (path);
-				return TRUE;
+				return ret;
 			}
-		}
+		} 
 	}
 	return FALSE;
 }
@@ -1742,6 +1811,15 @@
 						status_box,
 						PURPLE_CALLBACK(current_savedstatus_changed_cb),
 						status_box);
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-added", status_box,
+			PURPLE_CALLBACK(saved_status_updated_cb), status_box);
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-deleted", status_box,
+			PURPLE_CALLBACK(saved_status_updated_cb), status_box);
+	purple_signal_connect(purple_savedstatuses_get_handle(),
+			"savedstatus-modified", status_box,
+			PURPLE_CALLBACK(saved_status_updated_cb), status_box);
 	purple_signal_connect(purple_accounts_get_handle(), "account-enabled", status_box,
 						PURPLE_CALLBACK(account_enabled_cb),
 						status_box);
--- a/pidgin/gtkutils.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkutils.c	Sun Jun 24 20:01:43 2007 +0000
@@ -913,15 +913,44 @@
 	g_free(filename);
 }
 
-void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name)
+static void
+show_retrieveing_info(PurpleConnection *conn, const char *name)
 {
 	PurpleNotifyUserInfo *info = purple_notify_user_info_new();
 	purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
 	purple_notify_userinfo(conn, name, info, NULL, NULL);
 	purple_notify_user_info_destroy(info);
+}
+
+void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name)
+{
+	show_retrieveing_info(conn, name);
 	serv_get_info(conn, name);
 }
 
+void pidgin_retrieve_user_info_in_chat(PurpleConnection *conn, const char *name, int chat)
+{
+	char *who = NULL;
+	PurplePluginProtocolInfo *prpl_info = NULL;
+
+	if (chat < 0) {
+		pidgin_retrieve_user_info(conn, name);
+		return;
+	}
+
+	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(conn->prpl);
+	if (prpl_info == NULL || prpl_info->get_cb_info == NULL) {
+		pidgin_retrieve_user_info(conn, name);
+		return;
+	}
+
+	if (prpl_info->get_cb_real_name)
+		who = prpl_info->get_cb_real_name(conn, chat, name);
+	show_retrieveing_info(conn, who ? who : name);
+	prpl_info->get_cb_info(conn, chat, name);
+	g_free(who);
+}
+
 gboolean
 pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts,
 							PurpleAccount **ret_account, char **ret_protocol,
@@ -3066,6 +3095,65 @@
         return TRUE;
 }
 
+void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf) {
+	int width, height, rowstride;
+        guchar *pixels;
+        if (!gdk_pixbuf_get_has_alpha(pixbuf))
+                return;
+        width = gdk_pixbuf_get_width(pixbuf);
+        height = gdk_pixbuf_get_height(pixbuf);
+        rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+        pixels = gdk_pixbuf_get_pixels(pixbuf);
+
+        if (width < 6 || height < 6)
+                return;
+        /* Top left */
+        pixels[3] = 0;
+        pixels[7] = 0x80;
+        pixels[11] = 0xC0;
+        pixels[rowstride + 3] = 0x80;
+        pixels[rowstride * 2 + 3] = 0xC0;
+
+        /* Top right */
+        pixels[width * 4 - 1] = 0;
+        pixels[width * 4 - 5] = 0x80;
+        pixels[width * 4 - 9] = 0xC0;
+        pixels[rowstride + (width * 4) - 1] = 0x80;
+        pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0;
+
+        /* Bottom left */
+        pixels[(height - 1) * rowstride + 3] = 0;
+        pixels[(height - 1) * rowstride + 7] = 0x80;
+        pixels[(height - 1) * rowstride + 11] = 0xC0;
+        pixels[(height - 2) * rowstride + 3] = 0x80;
+        pixels[(height - 3) * rowstride + 3] = 0xC0;
+
+        /* Bottom right */
+        pixels[height * rowstride - 1] = 0;
+        pixels[(height - 1) * rowstride - 1] = 0x80;
+        pixels[(height - 2) * rowstride - 1] = 0xC0;
+        pixels[height * rowstride - 5] = 0x80;
+        pixels[height * rowstride - 9] = 0xC0;
+}
+
+const char *pidgin_get_dim_grey_string(GtkWidget *widget) {
+	static char dim_grey_string[8] = "";
+	GtkStyle *style;
+
+	if (!widget)
+		return "dim grey";
+
+ 	style = gtk_widget_get_style(widget);
+	if (!style)
+		return "dim grey";
+	
+	snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x",
+	style->text_aa[GTK_STATE_NORMAL].red >> 8,
+	style->text_aa[GTK_STATE_NORMAL].green >> 8,
+	style->text_aa[GTK_STATE_NORMAL].blue >> 8);
+	return dim_grey_string;
+}
+
 #if !GTK_CHECK_VERSION(2,2,0)
 GtkTreePath *
 gtk_tree_path_new_from_indices (gint first_index, ...)
--- a/pidgin/gtkutils.h	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/gtkutils.h	Sun Jun 24 20:01:43 2007 +0000
@@ -329,6 +329,15 @@
 void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name);
 
 /**
+ * Get information about a user in a chat. Show immediate feedback.
+ *
+ * @param conn   The connection to get information from.
+ * @param name   The user to get information about.
+ * @param chatid The chat id.
+ */
+void pidgin_retrieve_user_info_in_chat(PurpleConnection *conn, const char *name, int chatid);
+
+/**
  * Parses an application/x-im-contact MIME message and returns the
  * data inside.
  *
@@ -565,6 +574,22 @@
  */
 gboolean pidgin_gdk_pixbuf_is_opaque(GdkPixbuf *pixbuf);
 
+/**
+ * Rounds the corners of a 32x32 GdkPixbuf in place
+ *
+ * @param pixbuf  The buddy icon to transform
+ */
+void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf);
+
+/**
+ * Returns an HTML-style color string for use as a dim grey
+ * string
+ *
+ * @param widget  The widget to return dim grey for
+ * @return The dim grey string
+ */
+const char *pidgin_get_dim_grey_string(GtkWidget *widget);
+
 #if !GTK_CHECK_VERSION(2,2,0)
 /**
  * This is copied from Gtk to support Gtk 2.0
--- a/pidgin/pidginstock.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/pidginstock.c	Sun Jun 24 20:01:43 2007 +0000
@@ -105,7 +105,7 @@
 	{ PIDGIN_STOCK_STATUS_AWAY, 	   "status", "away.png",	TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AWAY_I },
 	{ PIDGIN_STOCK_STATUS_BUSY, 	"status", "busy.png", 		TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_BUSY_I },
 	{ PIDGIN_STOCK_STATUS_CHAT, 	"status", "chat.png",		TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL },
-	{ PIDGIN_STOCK_STATUS_INVISIBLE,"status", "invisible.png",	TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL },
+	{ PIDGIN_STOCK_STATUS_INVISIBLE,"status", "invisible.png",	TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL },
 	{ PIDGIN_STOCK_STATUS_XA, 	"status", "extended-away.png",	TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, PIDGIN_STOCK_STATUS_XA_I },
 	{ PIDGIN_STOCK_STATUS_LOGIN, 	"status", "log-in.png",		TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL },
 	{ PIDGIN_STOCK_STATUS_LOGOUT, 	"status", "log-out.png",	TRUE, TRUE, TRUE, TRUE, FALSE, FALSE , NULL },
--- a/pidgin/plugins/pidginrc.c	Fri Jun 22 17:36:48 2007 +0000
+++ b/pidgin/plugins/pidginrc.c	Sun Jun 24 20:01:43 2007 +0000
@@ -27,49 +27,49 @@
 
 static guint pref_callback;
 
-static const char *color_prefs[] = {
+static const gchar *color_prefs[] = {
 	"/plugins/gtk/purplerc/color/GtkWidget::cursor-color",
 	"/plugins/gtk/purplerc/color/GtkWidget::secondary-cursor-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-color"
 };
-static const char *color_prefs_set[] = {
+static const gchar *color_prefs_set[] = {
 	"/plugins/gtk/purplerc/set/color/GtkWidget::cursor-color",
 	"/plugins/gtk/purplerc/set/color/GtkWidget::secondary-cursor-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-color"
 };
-static const char *color_names[] = {
+static const gchar *color_names[] = {
 	N_("Cursor Color"),
 	N_("Secondary Cursor Color"),
 	N_("Hyperlink Color")
 };
 static GtkWidget *color_widgets[G_N_ELEMENTS(color_prefs)];
 
-static const char *widget_size_prefs[] = {
+static const gchar *widget_size_prefs[] = {
 	"/plugins/gtk/purplerc/size/GtkTreeView::horizontal_separator"
 };
-static const char *widget_size_prefs_set[] = {
+static const gchar *widget_size_prefs_set[] = {
 	"/plugins/gtk/purplerc/set/size/GtkTreeView::horizontal_separator"
 };
-static const char *widget_size_names[] = {
+static const gchar *widget_size_names[] = {
 	N_("GtkTreeView Horizontal Separation")
 };
 static GtkWidget *widget_size_widgets[G_N_ELEMENTS(widget_size_prefs)];
 
-static const char *font_prefs[] = {
+static const gchar *font_prefs[] = {
 	"/plugins/gtk/purplerc/font/*pidgin_conv_entry",
 	"/plugins/gtk/purplerc/font/*pidgin_conv_imhtml",
 	"/plugins/gtk/purplerc/font/*pidgin_log_imhtml",
 	"/plugins/gtk/purplerc/font/*pidgin_request_imhtml",
 	"/plugins/gtk/purplerc/font/*pidgin_notify_imhtml",
 };
-static const char *font_prefs_set[] = {
+static const gchar *font_prefs_set[] = {
 	"/plugins/gtk/purplerc/set/font/*pidgin_conv_entry",
 	"/plugins/gtk/purplerc/set/font/*pidgin_conv_imhtml",
 	"/plugins/gtk/purplerc/set/font/*pidgin_log_imhtml",
 	"/plugins/gtk/purplerc/set/font/*pidgin_request_imhtml",
 	"/plugins/gtk/purplerc/set/font/*pidgin_notify_imhtml",
 };
-static const char *font_names[] = {
+static const gchar *font_names[] = {
 	N_("Conversation Entry"),
 	N_("Conversation History"),
 	N_("Log Viewer"),
@@ -79,53 +79,56 @@
 static GtkWidget *font_widgets[G_N_ELEMENTS(font_prefs)];
 
 /*
-static const char *widget_bool_prefs[] = {
+static const gchar *widget_bool_prefs[] = {
 };
-static const char *widget_bool_prefs_set[] = {
+static const gchar *widget_bool_prefs_set[] = {
 };
-static const char *widget_bool_names[] = {
+static const gchar *widget_bool_names[] = {
 };
 static GtkWidget *widget_bool_widgets[G_N_ELEMENTS(widget_bool_prefs)];
 */
 
-static void
-purplerc_make_changes()
+static GString *
+make_gtkrc_string()
 {
-	int i;
-	char *prefbase = NULL;
-#if GTK_CHECK_VERSION(2,4,0)
-	GtkSettings *setting = NULL;
-#endif
+	gint i;
+	gchar *prefbase = NULL;
 	GString *style_string = g_string_new("");
 
 	if (purple_prefs_get_bool("/plugins/gtk/purplerc/set/gtk-font-name")) {
-		const char *pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-font-name");
+		const gchar *pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-font-name");
 
-		if (pref != NULL && strcmp(pref, ""))
-			g_string_append_printf(style_string, "gtk-font-name = \"%s\"\n", pref);
+		if (pref != NULL && strcmp(pref, "")) {
+			g_string_append_printf(style_string,
+			                       "gtk-font-name = \"%s\"\n",
+			                       pref);
+		}
 	}
 
 	if (purple_prefs_get_bool("/plugins/gtk/purplerc/set/gtk-key-theme-name")) {
-		const char *pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-key-theme-name");
+		const gchar *pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-key-theme-name");
 
-		if (pref != NULL && strcmp(pref, ""))
-			g_string_append_printf(style_string, "gtk-key-theme-name = \"%s\"\n", pref);
+		if (pref != NULL && strcmp(pref, "")) {
+			g_string_append_printf(style_string,
+			                       "gtk-key-theme-name = \"%s\"\n",
+			                       pref);
+		}
 	}
 
-	g_string_append(style_string, "style \"purplerc_style\" {\n");
+	g_string_append(style_string, "style \"purplerc_style\"\n{");
 
 	for (i = 0; i < G_N_ELEMENTS(color_prefs); i++) {
 		if (purple_prefs_get_bool(color_prefs_set[i])) {
-			const char *pref;
-
-			prefbase = g_path_get_basename(color_prefs[i]);
-			pref = purple_prefs_get_string(color_prefs[i]);
+			const gchar *pref;
 
-			if (pref != NULL && strcmp(pref, ""))
-			    g_string_append_printf(style_string,
-			                           "%s = \"%s\"\n",
-			                           prefbase, pref);
-			g_free(prefbase);
+			pref = purple_prefs_get_string(color_prefs[i]);
+			if (pref != NULL && strcmp(pref, "")) {
+				prefbase = g_path_get_basename(color_prefs[i]);
+				g_string_append_printf(style_string,
+				                       "\n\t%s = \"%s\"",
+				                       prefbase, pref);
+				g_free(prefbase);
+			}
 		}
 	}
 
@@ -133,7 +136,7 @@
 		if (purple_prefs_get_bool(widget_size_prefs_set[i])) {
 			prefbase = g_path_get_basename(widget_size_prefs[i]);
 			g_string_append_printf(style_string,
-			                       "%s = %d\n", prefbase,
+			                       "\n\t%s = %d", prefbase,
 			                       purple_prefs_get_int(widget_size_prefs[i]));
 			g_free(prefbase);
 		}
@@ -144,37 +147,47 @@
 		if (purple_prefs_get_bool(widget_bool_prefs_set[i])) {
 			prefbase = g_path_get_basename(widget_bool_prefs[i]);
 			g_string_append_printf(style_string,
-			                       "%s = %d\n", prefbase,
+			                       "\t%s = %d\n", prefbase,
 			                       purple_prefs_get_bool(widget_bool_prefs[i]));
 			g_free(prefbase);
 		}
 	}
 	*/
 
-	g_string_append(style_string, "}");
-	g_string_append(style_string, "widget_class \"*\" style \"purplerc_style\"\n");
+	g_string_append(style_string, "\n}\nwidget_class \"*\" style \"purplerc_style\"\n");
 
 	for (i = 0; i < G_N_ELEMENTS(font_prefs); i++) {
 		if (purple_prefs_get_bool(font_prefs_set[i])) {
-			const char *pref;
-
-			prefbase = g_path_get_basename(font_prefs[i]);
-			pref = purple_prefs_get_string(font_prefs[i]);
+			const gchar *pref;
 
-			if (pref != NULL && strcmp(pref, ""))
+			pref = purple_prefs_get_string(font_prefs[i]);
+			if (pref != NULL && strcmp(pref, "")) {
+				prefbase = g_path_get_basename(font_prefs[i]);
 				g_string_append_printf(style_string,
-				                       "style \"%s_style\"\n"
-				                       "{font_name = \"%s\"}\n"
-				                       "widget \"%s\" "
+				                       "style \"%s_style\"\n{\n"
+				                       "\tfont_name = \"%s\"\n}"
+				                       "\nwidget \"%s\" "
 				                       "style \"%s_style\"\n",
 				                       prefbase, pref,
 				                       prefbase, prefbase);
-			g_free(prefbase);
+				g_free(prefbase);
+			}
 		}
 	}
 
-	gtk_rc_parse_string(style_string->str);
-	g_string_free(style_string, TRUE);
+	return style_string;
+}
+
+static void
+purplerc_make_changes()
+{
+	GString *str = make_gtkrc_string();
+#if GTK_CHECK_VERSION(2,4,0)
+	GtkSettings *setting = NULL;
+#endif
+
+	gtk_rc_parse_string(str->str);
+	g_string_free(str, TRUE);
 
 #if GTK_CHECK_VERSION(2,4,0)
 	setting = gtk_settings_get_default();
@@ -185,92 +198,10 @@
 static void
 purplerc_write(GtkWidget *widget, gpointer data)
 {
-	int i;
-	GString *style_string = g_string_new("");
-	char *prefbase = NULL;
-
-	if (purple_prefs_get_bool("/plugins/gtk/purplerc/set/gtk-font-name")) {
-		const char *pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-font-name");
-
-		if (pref != NULL && strcmp(pref, ""))
-			g_string_append_printf(style_string,
-			                       "gtk-font-name = \"%s\"\n",
-			                       pref);
-	}
-
-	if (purple_prefs_get_bool("/plugins/gtk/purplerc/set/gtk-key-theme-name")) {
-		const char *pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-key-theme-name");
-
-		if (pref != NULL && strcmp(pref, ""))
-			g_string_append_printf(style_string,
-			                       "gtk-key-theme-name = \"%s\"\n",
-			                       pref);
-	}
-
-	g_string_append(style_string, "style \"purplerc_style\" {\n");
-
-	for (i = 0; i < G_N_ELEMENTS(color_prefs); i++) {
-		if (purple_prefs_get_bool(color_prefs_set[i])) {
-			const char *pref;
-
-			prefbase = g_path_get_basename(color_prefs[i]);
-			pref = purple_prefs_get_string(color_prefs[i]);
-
-			if (pref != NULL && strcmp(pref, ""))
-			    g_string_append_printf(style_string,
-			                           "%s = \"%s\"\n",
-			                           prefbase, pref);
-			g_free(prefbase);
-		}
-	}
-
-	for (i = 0; i < G_N_ELEMENTS(widget_size_prefs); i++) {
-		if (purple_prefs_get_bool(widget_size_prefs_set[i])) {
-			prefbase = g_path_get_basename(widget_size_prefs[i]);
-			g_string_append_printf(style_string,
-			                       "%s = %d\n", prefbase,
-			                       purple_prefs_get_int(widget_size_prefs[i]));
-			g_free(prefbase);
-		}
-	}
-
-	/*
-	for (i = 0; i < G_N_ELEMENTS(widget_bool_prefs); i++) {
-		if (purple_prefs_get_bool(widget_bool_prefs_set[i])) {
-			prefbase = g_path_get_basename(widget_bool_prefs[i]);
-			g_string_append_printf(style_string,
-			                       "%s = %d\n", prefbase,
-			                       purple_prefs_get_bool(widget_bool_prefs[i]));
-			g_free(prefbase);
-		}
-	}
-	*/
-
-	g_string_append(style_string, "}");
-	g_string_append(style_string, "widget_class \"*\" style \"purplerc_style\"\n");
-
-	for (i = 0; i < G_N_ELEMENTS(font_prefs); i++) {
-		if (purple_prefs_get_bool(font_prefs_set[i])) {
-			const char *pref;
-
-			prefbase = g_path_get_basename(font_prefs[i]);
-			pref = purple_prefs_get_string(font_prefs[i]);
-
-			if (pref != NULL && strcmp(pref, ""))
-				g_string_append_printf(style_string,
-				                       "style \"%s_style\"\n"
-				                       "{font_name = \"%s\"}\n"
-				                       "widget \"%s\" "
-				                       "style \"%s_style\"\n",
-				                       prefbase, pref,
-				                       prefbase, prefbase);
-			g_free(prefbase);
-		}
-	}
-
-	purple_util_write_data_to_file("gtkrc-2.0", style_string->str, -1);
-
-	g_string_free(style_string, TRUE);
+	GString *str = make_gtkrc_string();
+	str = g_string_prepend(str, "# This file automatically written by the Pidgin GTK+ Theme Control plugin.\n# Any changes to this file will be overwritten by the plugin when told to\n# write the settings again.\n# The FAQ (http://developer.pidgin.im/wiki/FAQ) contains some further examples\n# of possible pidgin gtkrc settings.\n");
+	purple_util_write_data_to_file("gtkrc-2.0", str->str, -1);
+	g_string_free(str, TRUE);
 }
 
 static void
@@ -283,7 +214,7 @@
 
 static void
 purplerc_pref_changed_cb(const char *name, PurplePrefType type,
-                       gconstpointer value, gpointer data)
+                         gconstpointer value, gpointer data)
 {
 	purplerc_make_changes();
 }
@@ -291,12 +222,12 @@
 static void
 purplerc_color_response(GtkDialog *color_dialog, gint response, gpointer data)
 {
-	int subscript = GPOINTER_TO_INT(data);
+	gint subscript = GPOINTER_TO_INT(data);
 
 	if (response == GTK_RESPONSE_OK) {
+		GdkColor color;
+		gchar colorstr[8];
 		GtkWidget *colorsel = GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel;
-		GdkColor color;
-		char colorstr[8];
 
 		gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(colorsel), &color);
 
@@ -311,11 +242,11 @@
 static void
 purplerc_set_color(GtkWidget *widget, gpointer data)
 {
+	GdkColor color;
+	gchar title[128];
+	const gchar *pref = NULL;
 	GtkWidget *color_dialog = NULL;
-	GdkColor color;
-	char title[128];
-	const char *pref = NULL;
-	int subscript = GPOINTER_TO_INT(data);
+	gint subscript = GPOINTER_TO_INT(data);
 
 	g_snprintf(title, sizeof(title), _("Select Color for %s"),
 	           _(color_names[GPOINTER_TO_INT(data)]));
@@ -337,14 +268,21 @@
 static void
 purplerc_font_response(GtkDialog *font_dialog, gint response, gpointer data)
 {
-	int subscript = GPOINTER_TO_INT(data);
+	const gchar *prefpath;
+	gint subscript = GPOINTER_TO_INT(data);
 
 	if (response == GTK_RESPONSE_OK) {
-		char *fontname = NULL;
+		gchar *fontname = NULL;
+
+		if (subscript == -1) {
+			prefpath = "/plugins/gtk/purplerc/gtk-font-name";
+		} else {
+			prefpath = font_prefs[subscript];
+		}
 
 		fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(font_dialog));
 
-		purple_prefs_set_string(font_prefs[subscript], fontname);
+		purple_prefs_set_string(prefpath, fontname);
 		g_free(fontname);
 	}
 	gtk_widget_destroy(GTK_WIDGET(font_dialog));
@@ -353,53 +291,25 @@
 static void
 purplerc_set_font(GtkWidget *widget, gpointer data)
 {
+	gchar title[128];
 	GtkWidget *font_dialog = NULL;
-	char title[128];
-	const char *pref = NULL;
-	int subscript = GPOINTER_TO_INT(data);
+	gint subscript = GPOINTER_TO_INT(data);
+	const gchar *pref = NULL, *prefpath = NULL;
 
-	g_snprintf(title, sizeof(title), _("Select Font for %s"),
-	           _(font_names[subscript]));
+	if (subscript == -1) {
+		g_snprintf(title, sizeof(title), _("Select Interface Font"));
+		prefpath = "/plugins/gtk/purplerc/gtk-font-name";
+	} else {
+		g_snprintf(title, sizeof(title), _("Select Font for %s"),
+		           _(font_names[subscript]));
+		prefpath = font_prefs[subscript];
+	}
+
 	font_dialog = gtk_font_selection_dialog_new(title);
 	g_signal_connect(G_OBJECT(font_dialog), "response",
 	                 G_CALLBACK(purplerc_font_response), data);
 
-	pref = purple_prefs_get_string(font_prefs[subscript]);
-
-	if (pref != NULL && strcmp(pref, "")) {
-		gtk_font_selection_set_font_name(GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font_dialog)->fontsel), pref);
-	}
-
-	gtk_window_present(GTK_WINDOW(font_dialog));
-}
-
-static void
-purplerc_font_response_special(GtkDialog *font_dialog, gint response,
-                             gpointer data)
-{
-	if (response == GTK_RESPONSE_OK) {
-		char *fontname = NULL;
-
-		fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(font_dialog));
-
-		purple_prefs_set_string("/plugins/gtk/purplerc/gtk-font-name",
-		                      fontname);
-		g_free(fontname);
-	}
-	gtk_widget_destroy(GTK_WIDGET(font_dialog));
-}
-
-static void
-purplerc_set_font_special(GtkWidget *widget, gpointer data)
-{
-	GtkWidget *font_dialog = NULL;
-	const char *pref = NULL;
-
-	font_dialog = gtk_font_selection_dialog_new(_("Select Interface Font"));
-	g_signal_connect(G_OBJECT(font_dialog), "response",
-	                 G_CALLBACK(purplerc_font_response_special), NULL);
-
-	pref = purple_prefs_get_string("/plugins/gtk/purplerc/gtk-font-name");
+	pref = purple_prefs_get_string(prefpath);
 
 	if (pref != NULL && strcmp(pref, "")) {
 		gtk_font_selection_set_font_name(GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font_dialog)->fontsel), pref);
@@ -413,8 +323,10 @@
 {
 	purplerc_make_changes();
 
-	pref_callback = purple_prefs_connect_callback(plugin, "/plugins/gtk/purplerc",
-	                                            purplerc_pref_changed_cb, NULL);
+	pref_callback = purple_prefs_connect_callback(plugin,
+	                                              "/plugins/gtk/purplerc",
+	                                              purplerc_pref_changed_cb,
+	                                              NULL);
 
 	return TRUE;
 }
@@ -433,17 +345,23 @@
 	/* Note: Intentionally not using the size group argument to the
 	 * pidgin_prefs_labeled_* functions they only add the text label to
 	 * the size group not the whole thing, which isn't what I want. */
-	int i;
-	char *tmp;
+	gint i;
+	gchar *tmp;
 	GtkWidget *check = NULL, *widget = NULL;
-	GtkSizeGroup *labelsg = NULL, *widgetsg = NULL;
-	GtkWidget *ret = NULL, *frame = NULL, *hbox = NULL, *vbox = NULL;
+	GtkWidget *ret = NULL, *hbox = NULL, *frame = NULL;
+	GtkSizeGroup *labelsg = NULL, *widgetsg = NULL, *buttonsg = NULL;
+#ifndef _WIN32
+	const gchar *homepath = "$HOME";
+#else
+	const gchar *homepath = "\%APPDATA\%";
+#endif
 
 	ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
 	gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
 
 	labelsg  = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 	widgetsg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+	buttonsg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	frame = pidgin_make_frame(ret, _("General"));
 	/* interface font */
@@ -451,12 +369,12 @@
 	gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
 	check = pidgin_prefs_checkbox(_("GTK+ Interface Font"),
-	                                "/plugins/gtk/purplerc/set/gtk-font-name",
-	                                hbox);
+	                              "/plugins/gtk/purplerc/set/gtk-font-name",
+	                              hbox);
 	gtk_size_group_add_widget(labelsg, check);
 
 	widget = pidgin_pixbuf_button_from_stock("", GTK_STOCK_SELECT_FONT,
-	                                       PIDGIN_BUTTON_HORIZONTAL);
+	                                         PIDGIN_BUTTON_HORIZONTAL);
 	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
 	gtk_size_group_add_widget(widgetsg, widget);
 	gtk_widget_set_sensitive(widget,
@@ -464,20 +382,20 @@
 	g_signal_connect(G_OBJECT(check), "toggled",
 	                 G_CALLBACK(pidgin_toggle_sensitive), widget);
 	g_signal_connect(G_OBJECT(widget), "clicked",
-	                 G_CALLBACK(purplerc_set_font_special), NULL);
+	                 G_CALLBACK(purplerc_set_font), GINT_TO_POINTER(-1));
 
 	/* key theme name */
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
 	gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
 	check = pidgin_prefs_checkbox(_("GTK+ Text Shortcut Theme"),
-	                                "/plugins/gtk/purplerc/set/gtk-key-theme-name",
-	                                hbox);
+	                              "/plugins/gtk/purplerc/set/gtk-key-theme-name",
+	                              hbox);
 	gtk_size_group_add_widget(labelsg, check);
 
 	widget = pidgin_prefs_labeled_entry(hbox, "",
-	                                      "/plugins/gtk/purplerc/gtk-key-theme-name",
-	                                      NULL);
+	                                    "/plugins/gtk/purplerc/gtk-key-theme-name",
+	                                    NULL);
 	/*
 	gtk_size_group_add_widget(widgetsg, widget);
 	*/
@@ -492,7 +410,7 @@
 		gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
 		check = pidgin_prefs_checkbox(_(widget_bool_names[i]),
-		                                widget_bool_prefs_set[i], hbox);
+		                              widget_bool_prefs_set[i], hbox);
 		gtk_size_group_add_widget(labelsg, check);
 
 		widget_bool_widgets[i] = pidgin_prefs_checkbox("", widget_bool_prefs[i], hbox);
@@ -514,7 +432,7 @@
 		gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
 		check = pidgin_prefs_checkbox(_(color_names[i]),
-		                                color_prefs_set[i], hbox);
+		                              color_prefs_set[i], hbox);
 		gtk_size_group_add_widget(labelsg, check);
 
 		color_widgets[i] = pidgin_pixbuf_button_from_stock("", GTK_STOCK_SELECT_COLOR, PIDGIN_BUTTON_HORIZONTAL);
@@ -538,7 +456,7 @@
 		gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
 		check = pidgin_prefs_checkbox(_(widget_size_names[i]),
-		                                widget_size_prefs_set[i], hbox);
+		                              widget_size_prefs_set[i], hbox);
 		gtk_size_group_add_widget(labelsg, check);
 
 		widget_size_widgets[i] = pidgin_prefs_labeled_spin_button(hbox, "", widget_size_prefs[i], 0, 50, NULL);
@@ -559,7 +477,7 @@
 		gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
 		check = pidgin_prefs_checkbox(_(font_names[i]),
-		                                font_prefs_set[i], hbox);
+		                              font_prefs_set[i], hbox);
 		gtk_size_group_add_widget(labelsg, check);
 
 		font_widgets[i] = pidgin_pixbuf_button_from_stock("", GTK_STOCK_SELECT_FONT, PIDGIN_BUTTON_HORIZONTAL);
@@ -572,27 +490,29 @@
 		                 G_CALLBACK(pidgin_toggle_sensitive),
 		                 font_widgets[i]);
 		g_signal_connect(G_OBJECT(font_widgets[i]), "clicked",
-		                 G_CALLBACK(purplerc_set_font), GINT_TO_POINTER(i));
+		                 G_CALLBACK(purplerc_set_font),
+		                 GINT_TO_POINTER(i));
 	}
 
-	frame = pidgin_make_frame(ret, _("Tools"));
+	frame = pidgin_make_frame(ret, _("Gtkrc File Tools"));
 
-	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
-	gtk_box_pack_start(GTK_BOX(frame), vbox, FALSE, FALSE, 0);
+	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
+	gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
 
-	tmp = g_strdup_printf(_("Write settings to %s%sgtkrc-2.0"), purple_user_dir(), G_DIR_SEPARATOR_S);
+	tmp = g_strdup_printf(_("Write settings to %s%sgtkrc-2.0"),
+	                      homepath, G_DIR_SEPARATOR_S);
 	check = gtk_button_new_with_label(tmp);
 	g_free(tmp);
-	gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(labelsg, check);
-	g_signal_connect(G_OBJECT(check), "clicked", G_CALLBACK(purplerc_write),
-	                 NULL);
+	gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, FALSE, 0);
+	gtk_size_group_add_widget(buttonsg, check);
+	g_signal_connect(G_OBJECT(check), "clicked",
+	                 G_CALLBACK(purplerc_write), NULL);
 
 	check = gtk_button_new_with_label(_("Re-read gtkrc files"));
-	gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
-	gtk_size_group_add_widget(labelsg, check);
-	g_signal_connect(G_OBJECT(check), "clicked", G_CALLBACK(purplerc_reread),
-	                 NULL);
+	gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, FALSE, 0);
+	gtk_size_group_add_widget(buttonsg, check);
+	g_signal_connect(G_OBJECT(check), "clicked",
+	                 G_CALLBACK(purplerc_reread), NULL);
 
 	gtk_widget_show_all(ret);
 	return ret;
@@ -645,7 +565,7 @@
 static void
 purplerc_init(PurplePlugin *plugin)
 {
-	int i;
+	gint i;
 
 	purple_prefs_add_none("/plugins");
 	purple_prefs_add_none("/plugins/gtk");