# HG changeset patch
# Node ID c2460462d196
# Parent  dd8052e0a74f
diff --git a/libpurple/account.c b/libpurple/account.c
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -1112,6 +1112,8 @@
 
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
 
+	purple_account_clear_current_error(account);
+
 	username = purple_account_get_username(account);
 
 	if (!purple_account_get_enabled(account)) {
diff --git a/libpurple/accounts.c b/libpurple/accounts.c
--- a/libpurple/accounts.c
+++ b/libpurple/accounts.c
@@ -637,7 +637,6 @@
              gpointer unused)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
-	purple_account_clear_current_error(account);
 
 	purple_signal_emit(purple_accounts_get_handle(), "account-signed-on",
 	                   account);
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -97,16 +97,6 @@
 	/* GBoxed reference count */
 	int box_count;
 
-	/* Used to hold error minidialogs.  Gets packed
-	 * inside PidginBuddyList.error_buttons
-	 */
-	PidginScrollBook *error_scrollbook;
-
-	/* Pointer to the mini-dialog about having signed on elsewhere, if one
-	 * is showing; %NULL otherwise.
-	 */
-	PidginMiniDialog *signed_on_elsewhere;
-
 	guint select_notebook_page_timeout;
 
 
@@ -3097,453 +3087,6 @@
 		pidgin_blist_sort_method_set(val);
 }
 
-/***********************************/
-/* Connection error handling stuff */
-/***********************************/
-
-#define OBJECT_DATA_KEY_ACCOUNT "account"
-#define DO_NOT_CLEAR_ERROR "do-not-clear-error"
-
-static gboolean
-find_account_widget(GObject *widget,
-                    PurpleAccount *account)
-{
-	if (g_object_get_data(widget, OBJECT_DATA_KEY_ACCOUNT) == account)
-		return 0; /* found */
-	else
-		return 1;
-}
-
-static void
-pack_protocol_icon_start(GtkWidget *box,
-                     PurpleAccount *account)
-{
-	GdkPixbuf *pixbuf;
-	GtkWidget *image;
-
-	pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
-	if (pixbuf != NULL) {
-		image = gtk_image_new_from_pixbuf(pixbuf);
-		g_object_unref(pixbuf);
-
-		gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
-	}
-}
-
-static void
-add_error_dialog(PidginBuddyList *gtkblist,
-                 GtkWidget *dialog)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	gtk_container_add(GTK_CONTAINER(priv->error_scrollbook), dialog);
-}
-
-static GtkWidget *
-find_child_widget_by_account(GtkContainer *container,
-                             PurpleAccount *account)
-{
-	GList *l = NULL;
-	GList *children = NULL;
-	GtkWidget *ret = NULL;
-	/* XXX: Workaround for the currently incomplete implementation of PidginScrollBook */
-	if(PIDGIN_IS_SCROLL_BOOK(container)) {
-		PidginScrollBook *scroll_book = PIDGIN_SCROLL_BOOK(container);
-		GtkWidget *notebook = pidgin_scroll_book_get_notebook(scroll_book);
-		container = GTK_CONTAINER(notebook);
-	}
-	children = gtk_container_get_children(container);
-	l = g_list_find_custom(children, account, (GCompareFunc) find_account_widget);
-	if (l)
-		ret = GTK_WIDGET(l->data);
-	g_list_free(children);
-	return ret;
-}
-
-static void
-remove_child_widget_by_account(GtkContainer *container,
-                               PurpleAccount *account)
-{
-	GtkWidget *widget = find_child_widget_by_account(container, account);
-	if(widget) {
-		/* Since we are destroying the widget in response to a change in
-		 * error, we should not clear the error.
-		 */
-		g_object_set_data(G_OBJECT(widget), DO_NOT_CLEAR_ERROR,
-			GINT_TO_POINTER(TRUE));
-		gtk_widget_destroy(widget);
-	}
-}
-
-/* Generic error buttons */
-
-static void
-generic_account_connect_cb(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
-                           G_GNUC_UNUSED GtkButton *button,
-                           gpointer user_data)
-{
-	PurpleAccount *account = user_data;
-	purple_account_connect(account);
-}
-
-static void
-generic_error_modify_cb(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
-                        G_GNUC_UNUSED GtkButton *button,
-                        gpointer user_data)
-{
-	PurpleAccount *account = user_data;
-	purple_account_clear_current_error(account);
-	pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, account);
-}
-
-static void
-generic_error_enable_cb(G_GNUC_UNUSED PidginMiniDialog *mini_dialog,
-                        G_GNUC_UNUSED GtkButton *button,
-                        gpointer user_data)
-{
-	PurpleAccount *account = user_data;
-	purple_account_clear_current_error(account);
-	purple_account_set_enabled(account, TRUE);
-}
-
-static void
-generic_error_destroy_cb(GtkWidget *dialog,
-                         PurpleAccount *account)
-{
-	/* If the error dialog is being destroyed in response to the
-	 * account-error-changed signal, we don't want to clear the current
-	 * error.
-	 */
-	if (g_object_get_data(G_OBJECT(dialog), DO_NOT_CLEAR_ERROR) == NULL)
-		purple_account_clear_current_error(account);
-}
-
-#define SSL_FAQ_URI "https://developer.pidgin.im/wiki/FAQssl"
-
-static void
-ssl_faq_clicked_cb(PidginMiniDialog *mini_dialog,
-                   GtkButton *button,
-                   gpointer ignored)
-{
-	purple_notify_uri(NULL, SSL_FAQ_URI);
-}
-
-static void
-add_generic_error_dialog(PurpleAccount *account,
-                         const PurpleConnectionErrorInfo *err)
-{
-	GtkWidget *mini_dialog;
-	const char *username = purple_account_get_username(account);
-	gboolean enabled = purple_account_get_enabled(account);
-	char *primary;
-
-	if (enabled)
-		primary = g_strdup_printf(_("%s disconnected"), username);
-	else
-		primary = g_strdup_printf(_("%s disabled"), username);
-
-	mini_dialog = pidgin_mini_dialog_new_with_buttons(
-		primary, err->description, "dialog-error", account,
-		enabled ? _("Reconnect") : _("Re-enable"),
-		enabled ? generic_account_connect_cb : generic_error_enable_cb,
-		_("Modify Account"), generic_error_modify_cb,
-		NULL);
-
-	g_free(primary);
-
-	g_object_set_data(G_OBJECT(mini_dialog), OBJECT_DATA_KEY_ACCOUNT,
-		account);
-
-	 if(err->type == PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT)
-		pidgin_mini_dialog_add_non_closing_button(PIDGIN_MINI_DIALOG(mini_dialog),
-				_("SSL FAQs"), ssl_faq_clicked_cb, NULL);
-
-	g_signal_connect_after(mini_dialog, "destroy",
-		(GCallback)generic_error_destroy_cb,
-		account);
-
-	add_error_dialog(gtkblist, mini_dialog);
-}
-
-static void
-remove_generic_error_dialog(PurpleAccount *account)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	remove_child_widget_by_account(
-		GTK_CONTAINER(priv->error_scrollbook), account);
-}
-
-
-static void
-update_generic_error_message(PurpleAccount *account,
-                             const char *description)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	GtkWidget *mini_dialog = find_child_widget_by_account(
-		GTK_CONTAINER(priv->error_scrollbook), account);
-	pidgin_mini_dialog_set_description(PIDGIN_MINI_DIALOG(mini_dialog),
-		description);
-}
-
-
-/* Notifications about accounts which were disconnected with
- * PURPLE_CONNECTION_ERROR_NAME_IN_USE
- */
-
-typedef void (*AccountFunction)(PurpleAccount *);
-
-static void
-elsewhere_foreach_account(PidginMiniDialog *mini_dialog,
-                          AccountFunction f)
-{
-	PurpleAccount *account;
-	GList *labels = gtk_container_get_children(
-		GTK_CONTAINER(mini_dialog->contents));
-	GList *l;
-
-	for (l = labels; l; l = l->next) {
-		account = g_object_get_data(G_OBJECT(l->data), OBJECT_DATA_KEY_ACCOUNT);
-		if (account)
-			f(account);
-		else
-			purple_debug_warning("gtkblist", "mini_dialog's child "
-				"didn't have an account stored in it!");
-	}
-	g_list_free(labels);
-}
-
-static void
-enable_account(PurpleAccount *account)
-{
-	purple_account_set_enabled(account, TRUE);
-}
-
-static void
-reconnect_elsewhere_accounts(PidginMiniDialog *mini_dialog,
-                             GtkButton *button,
-                             gpointer unused)
-{
-	elsewhere_foreach_account(mini_dialog, enable_account);
-}
-
-static void
-clear_elsewhere_errors(PidginMiniDialog *mini_dialog,
-                       gpointer unused)
-{
-	elsewhere_foreach_account(mini_dialog, purple_account_clear_current_error);
-}
-
-static void
-ensure_signed_on_elsewhere_minidialog(PidginBuddyList *gtkblist)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	PidginMiniDialog *mini_dialog;
-
-	if(priv->signed_on_elsewhere)
-		return;
-
-	mini_dialog = priv->signed_on_elsewhere =
-		pidgin_mini_dialog_new(_("Welcome back!"), NULL, "pidgin-disconnect");
-
-	pidgin_mini_dialog_add_button(mini_dialog, _("Re-enable"),
-		reconnect_elsewhere_accounts, NULL);
-
-	/* Make dismissing the dialog clear the errors.  The "destroy" signal
-	 * does not appear to fire at quit, which is fortunate!
-	 */
-	g_signal_connect(G_OBJECT(mini_dialog), "destroy",
-		(GCallback) clear_elsewhere_errors, NULL);
-
-	add_error_dialog(gtkblist, GTK_WIDGET(mini_dialog));
-
-	/* Set priv->signed_on_elsewhere to NULL when the dialog is destroyed */
-	g_signal_connect(G_OBJECT(mini_dialog), "destroy",
-		(GCallback) gtk_widget_destroyed, &(priv->signed_on_elsewhere));
-}
-
-static void
-update_signed_on_elsewhere_minidialog_title(void)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	PidginMiniDialog *mini_dialog = priv->signed_on_elsewhere;
-	guint accounts;
-	char *title;
-
-	if (mini_dialog == NULL)
-		return;
-
-	accounts = pidgin_mini_dialog_get_num_children(mini_dialog);
-	if (accounts == 0) {
-		gtk_widget_destroy(GTK_WIDGET(mini_dialog));
-		return;
-	}
-
-	title = g_strdup_printf(
-		ngettext("%d account was disabled because you signed on from another location:",
-			 "%d accounts were disabled because you signed on from another location:",
-			 accounts),
-		accounts);
-	pidgin_mini_dialog_set_description(mini_dialog, title);
-	g_free(title);
-}
-
-static GtkWidget *
-create_account_label(PurpleAccount *account)
-{
-	GtkWidget *hbox, *label;
-	const char *username = purple_account_get_username(account);
-	char *markup;
-	char *description;
-
-	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
-	g_object_set_data(G_OBJECT(hbox), OBJECT_DATA_KEY_ACCOUNT, account);
-
-	pack_protocol_icon_start(hbox, account);
-
-	label = gtk_label_new(NULL);
-	markup = g_strdup_printf("<span size=\"smaller\">%s</span>", username);
-	gtk_label_set_markup(GTK_LABEL(label), markup);
-	g_free(markup);
-	gtk_label_set_xalign(GTK_LABEL(label), 0);
-	gtk_label_set_yalign(GTK_LABEL(label), 0);
-	g_object_set(G_OBJECT(label), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-	description = purple_account_get_current_error(account)->description;
-	if (description != NULL && *description != '\0')
-		gtk_widget_set_tooltip_text(label, description);
-	gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
-
-	return hbox;
-}
-
-static void
-add_to_signed_on_elsewhere(PurpleAccount *account)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	PidginMiniDialog *mini_dialog;
-	GtkWidget *account_label;
-
-	ensure_signed_on_elsewhere_minidialog(gtkblist);
-	mini_dialog = priv->signed_on_elsewhere;
-
-	if(find_child_widget_by_account(GTK_CONTAINER(mini_dialog->contents), account))
-		return;
-
-	account_label = create_account_label(account);
-	gtk_box_pack_start(mini_dialog->contents, account_label, FALSE, FALSE, 0);
-	gtk_widget_show_all(account_label);
-
-	update_signed_on_elsewhere_minidialog_title();
-}
-
-static void
-remove_from_signed_on_elsewhere(PurpleAccount *account)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	PidginMiniDialog *mini_dialog = priv->signed_on_elsewhere;
-	if(mini_dialog == NULL)
-		return;
-
-	remove_child_widget_by_account(GTK_CONTAINER(mini_dialog->contents), account);
-
-	update_signed_on_elsewhere_minidialog_title();
-}
-
-
-static void
-update_signed_on_elsewhere_tooltip(PurpleAccount *account,
-                                   const char *description)
-{
-	PidginBuddyListPrivate *priv =
-	        pidgin_buddy_list_get_instance_private(gtkblist);
-	GtkContainer *c = GTK_CONTAINER(priv->signed_on_elsewhere->contents);
-	GtkWidget *label = find_child_widget_by_account(c, account);
-	gtk_widget_set_tooltip_text(label, description);
-}
-
-
-/* Call appropriate error notification code based on error types */
-static void
-update_account_error_state(PurpleAccount *account,
-                           const PurpleConnectionErrorInfo *old,
-                           const PurpleConnectionErrorInfo *new,
-                           PidginBuddyList *gtkblist)
-{
-	gboolean descriptions_differ;
-	const char *desc;
-
-	if (old == NULL && new == NULL)
-		return;
-
-	if (old != NULL && new == NULL) {
-		if(old->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE)
-			remove_from_signed_on_elsewhere(account);
-		else
-			remove_generic_error_dialog(account);
-		return;
-	}
-
-	if (old == NULL && new != NULL) {
-		if(new->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE)
-			add_to_signed_on_elsewhere(account);
-		else
-			add_generic_error_dialog(account, new);
-		return;
-	}
-
-	/* else, new and old are both non-NULL */
-
-	descriptions_differ = !purple_strequal(old->description, new->description);
-	desc = new->description;
-
-	switch (new->type) {
-	case PURPLE_CONNECTION_ERROR_NAME_IN_USE:
-		if (old->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE
-		    && descriptions_differ) {
-			update_signed_on_elsewhere_tooltip(account, desc);
-		} else {
-			remove_generic_error_dialog(account);
-			add_to_signed_on_elsewhere(account);
-		}
-		break;
-	default:
-		if (old->type == PURPLE_CONNECTION_ERROR_NAME_IN_USE) {
-			remove_from_signed_on_elsewhere(account);
-			add_generic_error_dialog(account, new);
-		} else if (descriptions_differ) {
-			update_generic_error_message(account, desc);
-		}
-		break;
-	}
-}
-
-/* In case accounts are loaded before the blist (which they currently are),
- * let's call update_account_error_state ourselves on every account's current
- * state when the blist starts.
- */
-static void
-show_initial_account_errors(PidginBuddyList *gtkblist)
-{
-	PurpleAccountManager *manager = NULL;
-	GList *l = NULL;
-	PurpleAccount *account;
-	const PurpleConnectionErrorInfo *err;
-
-	manager = purple_account_manager_get_default();
-	l = purple_account_manager_get_all(manager);
-	for(; l; l = l->next) {
-		account = l->data;
-		err = purple_account_get_current_error(account);
-
-		update_account_error_state(account, NULL, err, gtkblist);
-	}
-}
-
 /* This assumes there are not things like groupless buddies or multi-leveled groups.
  * I'm sure other things in this code assumes that also.
  */
@@ -3733,7 +3276,6 @@
 
 static void pidgin_blist_show(PurpleBuddyList *list)
 {
-	PidginBuddyListPrivate *priv;
 	GSimpleActionGroup *action_group = NULL;
 	void *handle;
 	GtkTreeViewColumn *column;
@@ -3747,7 +3289,6 @@
 	}
 
 	gtkblist = PIDGIN_BUDDY_LIST(list);
-	priv = pidgin_buddy_list_get_instance_private(gtkblist);
 
 	gtkblist->window = pidgin_contact_list_window_new();
 	g_signal_connect(G_OBJECT(gtkblist->window), "focus-in-event",
@@ -3840,10 +3381,6 @@
 	gtkblist->scrollbook = pidgin_scroll_book_new();
 	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->scrollbook, FALSE, FALSE, 0);
 
-	priv->error_scrollbook = PIDGIN_SCROLL_BOOK(pidgin_scroll_book_new());
-	gtk_box_pack_start(GTK_BOX(gtkblist->vbox),
-		GTK_WIDGET(priv->error_scrollbook), FALSE, FALSE, 0);
-
 	/* Update some dynamic things */
 	pidgin_blist_update_sort_methods();
 
@@ -3863,11 +3400,6 @@
 
 	/* Setup some purple signal handlers. */
 
-	handle = purple_accounts_get_handle();
-	purple_signal_connect(handle, "account-error-changed", gtkblist,
-	                      G_CALLBACK(update_account_error_state),
-	                      gtkblist);
-
 	handle = purple_conversations_get_handle();
 	purple_signal_connect(handle, "conversation-updated", gtkblist,
 	                      G_CALLBACK(conversation_updated_cb),
@@ -3882,8 +3414,6 @@
 	                      G_CALLBACK(conversation_created_cb),
 	                      gtkblist);
 
-	show_initial_account_errors(gtkblist);
-
 	/* emit our created signal */
 	handle = pidgin_blist_get_handle();
 	purple_signal_emit(handle, "gtkblist-created", list);
