diff pidgin/gtkblist.c @ 23395:7076f4e965c5

merge of '34ebad1a339cefdab142795e0b3a045ad7016658' and '868098fbe53290a8abcc3307c6fec2c6054a5e00'
author Casey Harkins <charkins@pidgin.im>
date Fri, 27 Jun 2008 00:01:59 +0000
parents 5d833ca5a265 dd146aa7d74d
children 1242a922a4bc fd0e8c6ffa4b 28a7992d37b2
line wrap: on
line diff
--- a/pidgin/gtkblist.c	Fri Jun 27 00:01:41 2008 +0000
+++ b/pidgin/gtkblist.c	Fri Jun 27 00:01:59 2008 +0000
@@ -57,6 +57,7 @@
 #include "gtkroomlist.h"
 #include "gtkstatusbox.h"
 #include "gtkscrollbook.h"
+#include "gtksmiley.h"
 #include "gtkutils.h"
 #include "pidgin/minidialog.h"
 #include "pidgin/pidgintooltip.h"
@@ -1529,6 +1530,48 @@
 	return FALSE;
 }
 
+static void
+set_node_custom_icon_cb(const gchar *filename, gpointer data)
+{
+	if (filename) {
+		PurpleBlistNode *node = (PurpleBlistNode*)data;
+
+		purple_buddy_icons_node_set_custom_icon_from_file(node,
+		                                                  filename);
+	}
+}
+
+static void
+set_node_custom_icon(GtkWidget *w, PurpleBlistNode *node)
+{
+	/* This doesn't keep track of the returned dialog (so that successive
+	 * calls could be made to re-display that dialog). Do we want that? */
+	GtkWidget *win = pidgin_buddy_icon_chooser_new(NULL, set_node_custom_icon_cb, node);
+	gtk_widget_show_all(win);
+}
+
+static void
+remove_node_custom_icon(GtkWidget *w, PurpleBlistNode *node)
+{
+	purple_buddy_icons_node_set_custom_icon(node, NULL, 0);
+}
+
+static void
+add_buddy_icon_menu_items(GtkWidget *menu, PurpleBlistNode *node)
+{
+	GtkWidget *item;
+
+	pidgin_new_item_from_stock(menu, _("Set Custom Icon"), NULL,
+	                           G_CALLBACK(set_node_custom_icon), node, 0,
+	                           0, NULL);
+
+	item = pidgin_new_item_from_stock(menu, _("Remove Custom Icon"), NULL,
+	                           G_CALLBACK(remove_node_custom_icon), node,
+	                           0, 0, NULL);
+	if (!purple_buddy_icons_node_has_custom_icon(node))
+		gtk_widget_set_sensitive(item, FALSE);
+}
+
 static GtkWidget *
 create_group_menu (PurpleBlistNode *node, PurpleGroup *g)
 {
@@ -1552,12 +1595,13 @@
 				NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
 	}
 
+	add_buddy_icon_menu_items(menu, node);
+
 	pidgin_append_blist_node_extended_menu(menu, node);
 
 	return menu;
 }
 
-
 static GtkWidget *
 create_chat_menu(PurpleBlistNode *node, PurpleChat *c)
 {
@@ -1590,6 +1634,8 @@
 	pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE,
 				 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL);
 
+	add_buddy_icon_menu_items(menu, node);
+
 	return menu;
 }
 
@@ -1611,6 +1657,8 @@
 	pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE,
 				 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL);
 
+	add_buddy_icon_menu_items(menu, node);
+
 	pidgin_separator(menu);
 
 	pidgin_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT,
@@ -1635,6 +1683,8 @@
 	if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
 		pidgin_separator(menu);
 
+		add_buddy_icon_menu_items(menu, node);
+
 		if(gtknode->contact_expanded) {
 			pidgin_new_item_from_stock(menu, _("_Collapse"),
 						 GTK_STOCK_ZOOM_OUT,
@@ -1719,6 +1769,8 @@
 	}
 
 #ifdef _WIN32
+	pidgin_blist_tooltip_destroy();
+
 	/* Unhook the tooltip-timeout since we don't want a tooltip
 	 * to appear and obscure the context menu we are about to show
 	   This is a workaround for GTK+ bug 107320. */
@@ -2492,51 +2544,71 @@
 
 
 static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
-		gboolean scaled, gboolean greyed)
-{
-	GdkPixbuf *buf, *ret = NULL;
+                                              gboolean scaled, gboolean greyed)
+{
+	gsize len;
 	GdkPixbufLoader *loader;
-	PurpleBuddyIcon *icon = NULL;
-	const guchar *data = NULL;
-	gsize len;
 	PurpleBuddy *buddy = NULL;
+	PurpleGroup *group = NULL;
+	const guchar *data = NULL;
+	GdkPixbuf *buf, *ret = NULL;
+	PurpleBuddyIcon *icon = NULL;
 	PurpleAccount *account = NULL;
-	PurplePluginProtocolInfo *prpl_info = NULL;
+	PurpleContact *contact = NULL;
 	PurpleStoredImage *custom_img;
-
-	if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+	PurplePluginProtocolInfo *prpl_info = NULL;
+	gint orig_width, orig_height, scale_width, scale_height;
+
+	if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
 		buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
-	} else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
+		contact = (PurpleContact*)node;
+	} else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
 		buddy = (PurpleBuddy*)node;
+		contact = purple_buddy_get_contact(buddy);
+	} else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
+		group = (PurpleGroup*)node;
+	} else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+		/* We don't need to do anything here. We just need to not fall
+		 * into the else block and return. */
 	} else {
 		return NULL;
 	}
 
-	if(buddy == NULL)
-		return NULL;
-
-	account = purple_buddy_get_account(buddy);
-
-	if(account && account->gc)
+	if (buddy) {
+		account = purple_buddy_get_account(buddy);
+	}
+
+	if(account && account->gc) {
 		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
+	}
 
 #if 0
 	if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"))
 		return NULL;
 #endif
 
-	custom_img = purple_buddy_icons_find_custom_icon(purple_buddy_get_contact(buddy));
-	if (custom_img)
-	{
+	/* If we have a contact then this is either a contact or a buddy and
+	 * we want to fetch the custom icon for the contact. If we don't have
+	 * a contact then this is a group or some other type of node and we
+	 * want to use that directly. */
+	if (contact) {
+		custom_img = purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
+	} else {
+		custom_img = purple_buddy_icons_node_find_custom_icon(node);
+	}
+
+	if (custom_img) {
 		data = purple_imgstore_get_data(custom_img);
 		len = purple_imgstore_get_size(custom_img);
 	}
 
 	if (data == NULL) {
-		/* Not sure I like this...*/
-		if (!(icon = purple_buddy_icons_find(buddy->account, buddy->name)))
-			return NULL;
-		data = purple_buddy_icon_get_data(icon, &len);
+		if (buddy) {
+			/* Not sure I like this...*/
+			if (!(icon = purple_buddy_icons_find(buddy->account, buddy->name)))
+				return NULL;
+			data = purple_buddy_icon_get_data(icon, &len);
+		}
 
 		if(data == NULL)
 			return NULL;
@@ -2554,56 +2626,68 @@
 		g_object_ref(G_OBJECT(buf));
 	g_object_unref(G_OBJECT(loader));
 
-	if (buf) {
-		int orig_width, orig_height;
-		int scale_width, scale_height;
-
-		if (greyed) {
+	if (!buf) {
+		return NULL;
+	}
+
+	if (greyed) {
+		gboolean offline = FALSE, idle = FALSE;
+
+		if (buddy) {
 			PurplePresence *presence = purple_buddy_get_presence(buddy);
 			if (!PURPLE_BUDDY_IS_ONLINE(buddy))
-				gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE);
+				offline = TRUE;
 			if (purple_presence_is_idle(presence))
-				gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE);
+				idle = TRUE;
+		} else if (group) {
+			if (purple_blist_get_group_online_count(group) == 0)
+				offline = TRUE;
 		}
 
-		/* i'd use the pidgin_buddy_icon_get_scale_size() thing,
-		 * but it won't tell me the original size, which I need for scaling
-		 * purposes */
-		scale_width = orig_width = gdk_pixbuf_get_width(buf);
-		scale_height = orig_height = gdk_pixbuf_get_height(buf);
-
-		if (prpl_info && prpl_info->icon_spec.scale_rules & PURPLE_ICON_SCALE_DISPLAY)
-			purple_buddy_icon_get_scale_size(&prpl_info->icon_spec, &scale_width, &scale_height);
-
-		if (scaled || scale_height > 200 || scale_width > 200) {
-			GdkPixbuf *tmpbuf;
-			float scale_size = scaled ? 32.0 : 200.0;
-			if(scale_height > scale_width) {
-				scale_width = scale_size * (double)scale_width / (double)scale_height;
-				scale_height = scale_size;
-			} else {
-				scale_height = scale_size * (double)scale_height / (double)scale_width;
-				scale_width = scale_size;
-			}
-			/* scale & round before making square, so rectangular (but non-square)
-			 * images get rounded corners too */
-			tmpbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height);
-			gdk_pixbuf_fill(tmpbuf, 0x00000000);
-			gdk_pixbuf_scale(buf, tmpbuf, 0, 0, scale_width, scale_height, 0, 0, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR);
-			if (pidgin_gdk_pixbuf_is_opaque(tmpbuf))
-				pidgin_gdk_pixbuf_make_round(tmpbuf);
-			ret = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_size, scale_size);
-			gdk_pixbuf_fill(ret, 0x00000000);
-			gdk_pixbuf_copy_area(tmpbuf, 0, 0, scale_width, scale_height, ret, (scale_size-scale_width)/2, (scale_size-scale_height)/2);
-			g_object_unref(G_OBJECT(tmpbuf));
+		if (offline)
+			gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE);
+
+		if (idle)
+			gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE);
+	}
+
+	/* I'd use the pidgin_buddy_icon_get_scale_size() thing, but it won't
+	 * tell me the original size, which I need for scaling purposes. */
+	scale_width = orig_width = gdk_pixbuf_get_width(buf);
+	scale_height = orig_height = gdk_pixbuf_get_height(buf);
+
+	if (prpl_info && prpl_info->icon_spec.scale_rules & PURPLE_ICON_SCALE_DISPLAY)
+		purple_buddy_icon_get_scale_size(&prpl_info->icon_spec, &scale_width, &scale_height);
+
+	if (scaled || scale_height > 200 || scale_width > 200) {
+		GdkPixbuf *tmpbuf;
+		float scale_size = scaled ? 32.0 : 200.0;
+		if(scale_height > scale_width) {
+			scale_width = scale_size * (double)scale_width / (double)scale_height;
+			scale_height = scale_size;
 		} else {
-			ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR);
+			scale_height = scale_size * (double)scale_height / (double)scale_width;
+			scale_width = scale_size;
 		}
-		g_object_unref(G_OBJECT(buf));
-	}
+		/* Scale & round before making square, so rectangular (but
+		 * non-square) images get rounded corners too. */
+		tmpbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height);
+		gdk_pixbuf_fill(tmpbuf, 0x00000000);
+		gdk_pixbuf_scale(buf, tmpbuf, 0, 0, scale_width, scale_height, 0, 0, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR);
+		if (pidgin_gdk_pixbuf_is_opaque(tmpbuf))
+			pidgin_gdk_pixbuf_make_round(tmpbuf);
+		ret = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_size, scale_size);
+		gdk_pixbuf_fill(ret, 0x00000000);
+		gdk_pixbuf_copy_area(tmpbuf, 0, 0, scale_width, scale_height, ret, (scale_size-scale_width)/2, (scale_size-scale_height)/2);
+		g_object_unref(G_OBJECT(tmpbuf));
+	} else {
+		ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR);
+	}
+	g_object_unref(G_OBJECT(buf));
 
 	return ret;
 }
+
 /* # - Status Icon
  * P - Protocol Icon
  * A - Buddy Icon
@@ -2652,6 +2736,7 @@
 	int name_width;
 	int width;
 	int height;
+	int padding;
 };
 
 static PangoLayout * create_pango_layout(const char *markup, int *width, int *height)
@@ -2680,6 +2765,7 @@
 	if (purple_account_is_disconnected(account))
 		gdk_pixbuf_saturate_and_pixelate(td->status_icon, td->status_icon, 0.0, FALSE);
 	td->layout = create_pango_layout(purple_account_get_username(account), &td->width, &td->height);
+	td->padding = SMALL_SPACE;
 	return td;
 }
 
@@ -2695,6 +2781,7 @@
 		account = ((PurpleChat*)(node))->account;
 	}
 
+	td->padding = TOOLTIP_BORDER;
 	td->status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE);
 	td->avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE);
 	if (account != NULL) {
@@ -2717,7 +2804,8 @@
 		 * above node types first. */
 		tmp = g_strdup(_("Unknown node type"));
 	}
-	node_name = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>", tmp);
+	node_name = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>",
+								tmp ? tmp : "");
 	g_free(tmp);
 
 	td->name_layout = create_pango_layout(node_name, &td->name_width, &td->name_height);
@@ -2859,7 +2947,7 @@
 			}
 		}
 
-		current_height += MAX(td->name_height + td->height, td->avatar_height) + TOOLTIP_BORDER;
+		current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
 	}
 	return FALSE;
 }
@@ -2950,8 +3038,7 @@
 		struct tooltip_data *td = list->data;
 		max_text_width = MAX(max_text_width, MAX(td->width, td->name_width));
 		max_avatar_width = MAX(max_avatar_width, td->avatar_width);
-		height += MAX(TOOLTIP_BORDER + MAX(STATUS_SIZE, td->avatar_height),
-				TOOLTIP_BORDER + td->height + td->name_height);
+		height += MAX(MAX(STATUS_SIZE, td->avatar_height), td->height + td->name_height) + td->padding;
 		if (td->status_icon)
 			status_size = MAX(status_size, STATUS_SIZE);
 	}
@@ -3153,7 +3240,7 @@
 	/* Buddies menu */
 	{ N_("/_Buddies"), NULL, NULL, 0, "<Branch>", NULL },
 	{ N_("/Buddies/New Instant _Message..."), "<CTL>M", pidgin_dialogs_im, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
-	{ N_("/Buddies/Join a _Chat..."), "<CTL>C", pidgin_blist_joinchat_show, 0, "<Item>", NULL },
+	{ N_("/Buddies/Join a _Chat..."), "<CTL>C", pidgin_blist_joinchat_show, 0, "<StockItem>", PIDGIN_STOCK_CHAT },
 	{ N_("/Buddies/Get User _Info..."), "<CTL>I", pidgin_dialogs_info, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
 	{ N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL },
 	{ "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL },
@@ -3173,7 +3260,7 @@
 
 	/* Accounts menu */
 	{ N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL },
-	{ N_("/Accounts/Manage"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL },
+	{ N_("/Accounts/Manage Accounts"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL },
 
 	/* Tools */
 	{ N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
@@ -3182,8 +3269,9 @@
 	{ N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
 	{ N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
 	{ N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
+	{ N_("/Tools/Smile_y"), "<CTL>Y", pidgin_smiley_manager_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SMILEY },
 	{ "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
-	{ N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<Item>", NULL },
+	{ N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_TRANSFER },
 	{ N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
 	{ N_("/Tools/System _Log"), NULL, gtk_blist_show_systemlog_cb, 3, "<Item>", NULL },
 	{ "/Tools/sep3", NULL, NULL, 0, "<Separator>", NULL },
@@ -3249,7 +3337,8 @@
 					g_list_length(purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv))));
 
 			if (prpl_info && (prpl_info->options & OPT_PROTO_CHAT_TOPIC)) {
-				char *topic = g_markup_escape_text(purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)), -1);
+				const char *chattopic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
+				char *topic = chattopic ? g_markup_escape_text(chattopic, -1) : NULL;
 				g_string_append_printf(str, _("\n<b>Topic:</b> %s"), topic ? topic : _("(no topic set)"));
 				g_free(topic);
 			}
@@ -5224,7 +5313,7 @@
 	tmp = g_strdup_printf(_("<span weight='bold' size='larger'>Welcome to %s!</span>\n\n"
 
 					       "You have no accounts enabled. Enable your IM accounts from the "
-					       "<b>Accounts</b> window at <b>Accounts->Manage</b>. Once you "
+					       "<b>Accounts</b> window at <b>Accounts->Manage Accounts</b>. Once you "
 					       "enable accounts, you'll be able to sign on, set your status, "
 					       "and talk to your friends."), PIDGIN_NAME);
 	pretty = pidgin_make_pretty_arrows(tmp);
@@ -5825,14 +5914,16 @@
 	return FALSE;
 }
 
-/*This version of pidgin_blist_update_group can take the original buddy
-or a group, but has much better algorithmic performance with a pre-known buddy*/
-static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node)
-{
+/* This version of pidgin_blist_update_group can take the original buddy or a
+ * group, but has much better algorithmic performance with a pre-known buddy.
+ */
+static void pidgin_blist_update_group(PurpleBuddyList *list,
+                                      PurpleBlistNode *node)
+{
+	gint count;
 	PurpleGroup *group;
-	int count;
+	PurpleBlistNode* gnode;
 	gboolean show = FALSE, show_offline = FALSE;
-	PurpleBlistNode* gnode;
 
 	g_return_if_fail(node != NULL);
 
@@ -5867,12 +5958,13 @@
 	}
 
 	if (show) {
+		gchar *title;
+		gboolean biglist;
 		GtkTreeIter iter;
 		GtkTreePath *path;
 		gboolean expanded;
 		GdkColor bgcolor;
-		char *title;
-
+		GdkPixbuf *avatar = NULL;
 
 		if(!insert_node(list, gnode, &iter))
 			return;
@@ -5884,17 +5976,23 @@
 		gtk_tree_path_free(path);
 
 		title = pidgin_get_group_title(gnode, expanded);
+		biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
+
+		if (biglist) {
+			avatar = pidgin_blist_get_buddy_icon(gnode, TRUE, TRUE);
+		}
 
 		gtk_tree_store_set(gtkblist->treemodel, &iter,
 				   STATUS_ICON_VISIBLE_COLUMN, FALSE,
 				   STATUS_ICON_COLUMN, NULL,
 				   NAME_COLUMN, title,
 				   NODE_COLUMN, gnode,
-	/* 			   BGCOLOR_COLUMN, &bgcolor,     */
+	/*			   BGCOLOR_COLUMN, &bgcolor,     */
 				   GROUP_EXPANDER_COLUMN, TRUE,
 				   GROUP_EXPANDER_VISIBLE_COLUMN, TRUE,
 				   CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE,
-				   BUDDY_ICON_VISIBLE_COLUMN, FALSE,
+				   BUDDY_ICON_COLUMN, avatar,
+				   BUDDY_ICON_VISIBLE_COLUMN, biglist,
 				   IDLE_VISIBLE_COLUMN, FALSE,
 				   EMBLEM_VISIBLE_COLUMN, FALSE,
 				   -1);
@@ -6184,7 +6282,7 @@
 				STATUS_ICON_COLUMN, status,
 				STATUS_ICON_VISIBLE_COLUMN, TRUE,
 				BUDDY_ICON_COLUMN, avatar ? avatar : gtkblist->empty_avatar,
-				BUDDY_ICON_VISIBLE_COLUMN,  purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"),
+				BUDDY_ICON_VISIBLE_COLUMN, showicons,
 				EMBLEM_COLUMN, emblem,
 				EMBLEM_VISIBLE_COLUMN, emblem != NULL,
 				PROTOCOL_ICON_COLUMN, prpl_icon,
@@ -6384,6 +6482,10 @@
 		purple_blist_add_buddy(b, NULL, g, NULL);
 		purple_account_add_buddy(data->account, b);
 
+		/* Offer to merge people with the same alias. */
+		if (whoalias != NULL)
+			gtk_blist_auto_personize((PurpleBlistNode *)g, whoalias);
+
 		/*
 		 * XXX
 		 * It really seems like it would be better if the call to
@@ -7526,12 +7628,58 @@
 	for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
 		menuitem = l->data;
 
-		if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage")))
+		if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage Accounts")))
 			gtk_widget_destroy(menuitem);
 	}
 
 	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
 		char *buf = NULL;
+		GtkWidget *image = NULL;
+		PurpleAccount *account = NULL;
+		GdkPixbuf *pixbuf = NULL;
+
+		account = accounts->data;
+
+		if(!purple_account_get_enabled(account, PIDGIN_UI)) {
+			if (!disabled_accounts) {
+				menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
+				gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
+				gtk_widget_show(menuitem);
+
+				submenu = gtk_menu_new();
+				gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
+				gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
+				gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
+				gtk_widget_show(submenu);
+
+				disabled_accounts = TRUE;
+			}
+
+			buf = g_strconcat(purple_account_get_username(account), " (",
+				purple_account_get_protocol_name(account), ")", NULL);
+			menuitem = gtk_image_menu_item_new_with_label(buf);
+			g_free(buf);
+			pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
+			if (pixbuf != NULL)
+			{
+				if (!purple_account_is_connected(account))
+					gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
+				image = gtk_image_new_from_pixbuf(pixbuf);
+				g_object_unref(G_OBJECT(pixbuf));
+				gtk_widget_show(image);
+				gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
+			}
+			g_signal_connect(G_OBJECT(menuitem), "activate",
+				G_CALLBACK(enable_account_cb), account);
+			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
+			gtk_widget_show(menuitem);
+		}
+	}
+
+	pidgin_separator(accountmenu);
+
+	for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
+		char *buf = NULL;
 		char *accel_path_buf = NULL;
 		GtkWidget *image = NULL;
 		PurpleConnection *gc = NULL;
@@ -7601,51 +7749,6 @@
 		}
 	}
 
-	if(disabled_accounts) {
-		pidgin_separator(accountmenu);
-		menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
-		gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
-		gtk_widget_show(menuitem);
-
-		submenu = gtk_menu_new();
-		gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
-		gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
-		gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
-		gtk_widget_show(submenu);
-
-		for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
-			char *buf = NULL;
-			GtkWidget *image = NULL;
-			PurpleAccount *account = NULL;
-			GdkPixbuf *pixbuf = NULL;
-
-			account = accounts->data;
-
-			if(!purple_account_get_enabled(account, PIDGIN_UI)) {
-
-				disabled_accounts = TRUE;
-
-				buf = g_strconcat(purple_account_get_username(account), " (",
-						purple_account_get_protocol_name(account), ")", NULL);
-				menuitem = gtk_image_menu_item_new_with_label(buf);
-				g_free(buf);
-				pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
-				if (pixbuf != NULL)
-				{
-					if (!purple_account_is_connected(account))
-						gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
-					image = gtk_image_new_from_pixbuf(pixbuf);
-					g_object_unref(G_OBJECT(pixbuf));
-					gtk_widget_show(image);
-					gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
-				}
-				g_signal_connect(G_OBJECT(menuitem), "activate",
-						G_CALLBACK(enable_account_cb), account);
-				gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
-				gtk_widget_show(menuitem);
-			}
-		}
-	}
 }
 
 static GList *plugin_submenus = NULL;