im.pidgin.pidgin: bebf7d7e6a79c7790d2a56820eecfce4e8f2cd9e

nosnilmot at pidgin.im nosnilmot at pidgin.im
Sun Nov 18 16:06:02 EST 2007


-----------------------------------------------------------------
Revision: bebf7d7e6a79c7790d2a56820eecfce4e8f2cd9e
Ancestor: 0650760cfada782b67cad4bdb61334dccc84701b
Author: nosnilmot at pidgin.im
Date: 2007-11-18T21:03:29
Branch: im.pidgin.pidgin

Modified files:
        pidgin/gtkblist.c pidgin/gtkscrollbook.c
        pidgin/gtkscrollbook.h

ChangeLog: 

This fixes the problem where all accounts are disabled due to connection
errors, which leaves you with no enabled accounts, and therefore the
buddy list flips into "Welcome to Pidgin!" mode, thereby hiding all the
connection error mini dialogs. I'm amazed I haven't heard any noise about
this problem.

I attempted to fix up PidginScrollBook, and got part way there, but
gtk_container_get_children now doesn't return any kids. I suspect this is
due to the child widgets we care about already being children of the
notebook. I don't know nearly enough gtk to be sure if this is good or not.

There are still some buglets in how/when the buddy list notebook page is
selected, and I have a feeling some of the gtkblist.c changes could be
improved, but I believe this is more usable than before.

This took far too much time.

References #3989


-------------- next part --------------
============================================================
--- pidgin/gtkblist.c	b52220ccb089bc988a4f6d3b7bd1922e812d5b8f
+++ pidgin/gtkblist.c	192d7c9afaf702fa57c19d5bcf5d1bc9271c00a0
@@ -4226,18 +4226,44 @@ static void _prefs_change_sort_method(co
 		pidgin_blist_sort_method_set(val);
 }
 
-static void account_modified(PurpleAccount *account, PidginBuddyList *gtkblist)
+static gboolean pidgin_blist_select_notebook_page_cb(gpointer user_data)
 {
+	PidginBuddyList *gtkblist = (PidginBuddyList *)user_data;
+	int errors = 0;
 	GList *list;
-	if (!gtkblist)
-		return;
+	PidginBuddyListPrivate *priv;
 
-	if ((list = purple_accounts_get_all_active()) != NULL) {
+	priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist);
+
+	/* this is far too ugly thanks to me not wanting to fix #3989 properly right now */
+	if (priv->error_scrollbook != NULL) {
+#if GTK_CHECK_VERSION(2,2,0)
+		errors = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->error_scrollbook->notebook));
+#else
+		errors = g_list_length(GTK_NOTEBOOK(priv->error_scrollbook->notebook)->children);
+#endif
+	}
+	if ((list = purple_accounts_get_all_active()) != NULL || errors ||
+	    (list = gtk_container_get_children(GTK_CONTAINER(priv->error_scrollbook)))) {
 		gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1);
 		g_list_free(list);
 	} else
 		gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 0);
 
+	return FALSE;
+}
+
+static void pidgin_blist_select_notebook_page(PidginBuddyList *gtkblist)
+{
+	purple_timeout_add(0, pidgin_blist_select_notebook_page_cb, gtkblist);
+}
+
+static void account_modified(PurpleAccount *account, PidginBuddyList *gtkblist)
+{
+	if (!gtkblist)
+		return;
+
+	pidgin_blist_select_notebook_page(gtkblist);
 	update_menu_bar(gtkblist);
 }
 
@@ -4248,7 +4274,7 @@ account_status_changed(PurpleAccount *ac
 	if (!gtkblist)
 		return;
 
-	update_menu_bar(gtkblist);
+	account_modified(account, gtkblist);
 }
 
 static gboolean
@@ -4429,8 +4455,10 @@ remove_child_widget_by_account(GtkContai
                                PurpleAccount *account)
 {
 	GtkWidget *widget = find_child_widget_by_account(container, account);
-	if(widget)
+	if(widget) {
+		gtk_container_remove(container, widget);
 		gtk_widget_destroy(widget);
+	}
 }
 
 /* Generic error buttons */
@@ -4438,12 +4466,14 @@ generic_error_modify_cb(PurpleAccount *a
 static void
 generic_error_modify_cb(PurpleAccount *account)
 {
+	purple_account_clear_current_error(account);
 	pidgin_account_dialog_show(PIDGIN_MODIFY_ACCOUNT_DIALOG, account);
 }
 
 static void
 generic_error_enable_cb(PurpleAccount *account)
 {
+	purple_account_clear_current_error(account);
 	purple_account_set_enabled(account, purple_core_get_ui(), TRUE);
 }
 
@@ -4530,7 +4560,7 @@ remove_generic_error_dialog(PurpleAccoun
 {
 	PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist);
 	remove_child_widget_by_account(
-		GTK_CONTAINER(priv->error_scrollbook->notebook), account);
+		GTK_CONTAINER(priv->error_scrollbook), account);
 }
 
 
@@ -4712,6 +4742,7 @@ update_account_error_state(PurpleAccount
 	else
 		pidgin_blist_update_account_error_state(account, NULL);
 
+	pidgin_blist_select_notebook_page(gtkblist);
 	/* Don't bother updating the error if it hasn't changed.  This stops
 	 * URGENT being repeatedly set for network errors whenever they try to
 	 * reconnect.
@@ -4902,7 +4933,6 @@ static void pidgin_blist_show(PurpleBudd
 	GtkWidget *sw;
 	GtkWidget *sep;
 	GtkWidget *label;
-	GList *accounts;
 	char *pretty, *tmp;
 	GtkAccelGroup *accel_group;
 	GtkTreeSelection *selection;
@@ -4993,10 +5023,7 @@ static void pidgin_blist_show(PurpleBudd
 	gtkblist->vbox = gtk_vbox_new(FALSE, 0);
 	gtk_notebook_append_page(GTK_NOTEBOOK(gtkblist->notebook), gtkblist->vbox, NULL);
 	gtk_widget_show_all(gtkblist->notebook);
-	if ((accounts = purple_accounts_get_all_active())) {
-		g_list_free(accounts);
-		gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1);
-	}
+	pidgin_blist_select_notebook_page(gtkblist);
 
 	ebox = gtk_event_box_new();
 	gtk_box_pack_start(GTK_BOX(gtkblist->vbox), ebox, FALSE, FALSE, 0);
============================================================
--- pidgin/gtkscrollbook.c	f9c19ef06b850114fca3c67db3a2b089503239a0
+++ pidgin/gtkscrollbook.c	5a53af6d62a64b4ca8b24af84decf0161fb1dbcc
@@ -146,21 +146,74 @@ pidgin_scroll_book_add(GtkContainer *con
 static void
 pidgin_scroll_book_add(GtkContainer *container, GtkWidget *widget)
 {
+	GList *children;
+	PidginScrollBook *scroll_book;
+
+	g_return_if_fail(GTK_IS_WIDGET (widget));
+	g_return_if_fail (widget->parent == NULL);
+
+	scroll_book = PIDGIN_SCROLL_BOOK(container);
+	children = scroll_book->children;
+	children = g_list_append(children, widget);
 	gtk_widget_show(widget);
 	gtk_notebook_append_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), widget, NULL);
 	page_count_change_cb(PIDGIN_SCROLL_BOOK(container));
 }
 
 static void
+pidgin_scroll_book_remove(GtkContainer *container, GtkWidget *widget)
+{
+	int page;
+	GList *children;
+	GtkWidget *child;
+	PidginScrollBook *scroll_book;
+	g_return_if_fail(GTK_IS_WIDGET(widget));
+
+	scroll_book = PIDGIN_SCROLL_BOOK(container);
+	children = scroll_book->children;
+
+	while (children) {
+		child = children->data;
+		if (child == widget) {
+			gtk_widget_unparent (widget);
+			children = g_list_remove_link (scroll_book->children, children);
+			g_list_free(children);
+			break;
+		}
+	}
+
+	page = gtk_notebook_page_num(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), widget);
+	if (page >= 0) {
+		gtk_notebook_remove_page(GTK_NOTEBOOK(PIDGIN_SCROLL_BOOK(container)->notebook), page);
+	}
+}
+
+static void
 pidgin_scroll_book_forall(GtkContainer *container,
 			   gboolean include_internals,
 			   GtkCallback callback,
 			   gpointer callback_data)
 {
-	PidginScrollBook *scroll_book = PIDGIN_SCROLL_BOOK(container);
-	if (include_internals)
+	GList *children;
+	PidginScrollBook *scroll_book;
+
+	g_return_if_fail(GTK_IS_CONTAINER(container));
+
+	scroll_book = PIDGIN_SCROLL_BOOK(container);
+
+	if (include_internals) {
 		(*callback)(scroll_book->hbox, callback_data);
-	(*callback)(scroll_book->notebook, callback_data);
+		(*callback)(scroll_book->notebook, callback_data);
+	}
+
+	children = scroll_book->children;
+
+	while (children) {
+		GtkWidget *child;
+		child = children->data;
+		children = children->next;
+		(*callback)(child, callback_data);
+	}
 }
 
 static void
@@ -169,6 +222,7 @@ pidgin_scroll_book_class_init (PidginScr
 	GtkContainerClass *container_class = (GtkContainerClass*)klass;
 
 	container_class->add = pidgin_scroll_book_add;
+	container_class->remove = pidgin_scroll_book_remove;
 	container_class->forall = pidgin_scroll_book_forall;	
 	
 }
============================================================
--- pidgin/gtkscrollbook.h	20613d163ce0b07eb6cf55d1f8eb27889d694c75
+++ pidgin/gtkscrollbook.h	dc05d1813ddc65ea353fdf7c209aea7102a3cb2b
@@ -29,10 +29,6 @@
 
 #include <gtk/gtk.h>
 
-#if !GTK_CHECK_VERSION(2,4,0)
-#include "pidgincombobox.h"
-#endif
-
 G_BEGIN_DECLS
 
 #define PIDGIN_TYPE_SCROLL_BOOK             (pidgin_scroll_book_get_type ())
@@ -54,9 +50,9 @@ struct _PidginScrollBook
 	GtkWidget *label;
 	GtkWidget *left_arrow;
 	GtkWidget *right_arrow;
+	GList *children;
 	
 	/* Padding for future expansion */
-	void (*_gtk_reserved0) (void);
 	void (*_gtk_reserved1) (void);
 	void (*_gtk_reserved2) (void);
 	void (*_gtk_reserved3) (void);
@@ -66,7 +62,7 @@ struct _PidginScrollBookClass
 
 struct _PidginScrollBookClass
 {
-	GtkComboBoxClass parent_class;
+	GtkContainerClass parent_class;
 
 	/* Padding for future expansion */
 	void (*_gtk_reserved0) (void);


More information about the Commits mailing list