changeset 7912:4d4438f6ddce

[gaim-migrate @ 8573] I changed the disconnected dialog code a lot. I started off just trying to make the reconnect all button show and hide itself correctly, I think. Then I, uh "refactored" stuff a lot. It seems a lot more straight forward now. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 22 Dec 2003 01:22:25 +0000
parents 169e85869dcc
children e51fddcfc136
files src/gtkconn.c
diffstat 1 files changed, 186 insertions(+), 130 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkconn.c	Sun Dec 21 21:43:23 2003 +0000
+++ b/src/gtkconn.c	Mon Dec 22 01:22:25 2003 +0000
@@ -31,6 +31,9 @@
 
 #include "ui.h"
 
+/*
+ * The next couple of functions deal with the connection dialog
+ */
 struct signon_meter {
 	GaimAccount *account;
 	GtkWidget *button;
@@ -44,17 +47,29 @@
 		gint rows;
 		gint active_count;
 		GSList *meters;
-} *meter_win = NULL;
+};
+struct meter_window *meter_win = NULL;
 
-static void kill_meter(struct signon_meter *meter, const char *text);
+static void kill_meter(struct signon_meter *meter, const char *text)
+{
+	gtk_widget_set_sensitive(meter->button, FALSE);
+	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(meter->progress), 1);
+	gtk_label_set_text(GTK_LABEL(meter->status), text);
+	meter_win->active_count--;
+
+	if (meter_win->active_count == 0) {
+		gtk_widget_destroy(meter_win->window);
+		g_free(meter_win);
+		meter_win = NULL;
+	}
+}
 
 static void cancel_signon(GtkWidget *button, struct signon_meter *meter)
 {
 	if (meter->account->gc != NULL) {
 		meter->account->gc->wants_to_die = TRUE;
 		gaim_connection_destroy(meter->account->gc);
-	}
-	else {
+	} else {
 		kill_meter(meter, _("Done."));
 
 		if (gaim_connections_get_all() == NULL) {
@@ -67,7 +82,8 @@
 	}
 }
 
-static void cancel_all () {
+static void cancel_all ()
+{
 	GSList *m = meter_win ? meter_win->meters : NULL;
 	struct signon_meter *meter;
 
@@ -110,8 +126,6 @@
 	return image;
 }
 
-
-
 static struct signon_meter *
 new_meter(GaimConnection *gc, GtkWidget *widget,
 			   GtkWidget *table, gint *rows)
@@ -164,18 +178,6 @@
 	return meter;
 }
 
-static void kill_meter(struct signon_meter *meter, const char *text) {
-	gtk_widget_set_sensitive (meter->button, FALSE);
-	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(meter->progress), 1);
-	gtk_label_set_text(GTK_LABEL(meter->status), text);
-	meter_win->active_count--;
-	if (meter_win->active_count == 0) {
-		gtk_widget_destroy(meter_win->window);
-		g_free (meter_win);
-		meter_win = NULL;
-	}
-}
-
 static void gaim_gtk_connection_connect_progress(GaimConnection *gc,
 		const char *text, size_t step, size_t step_count)
 {
@@ -239,7 +241,7 @@
 	do_away_menu();
 	gaim_gtk_blist_update_protocol_actions();
 
-	if(meter)
+	if (meter)
 		kill_meter(meter, _("Done."));
 }
 
@@ -250,7 +252,7 @@
 	do_away_menu();
 	gaim_gtk_blist_update_protocol_actions();
 
-	if(meter)
+	if (meter)
 		kill_meter(meter, _("Done."));
 
 	if (gaim_connections_get_all() != NULL)
@@ -268,22 +270,92 @@
 {
 }
 
+/*
+ * The next couple of functions deal with the disconnected dialog
+ */
 struct disconnect_window {
 	GtkWidget *window;
 	GtkWidget *treeview;
 	GtkWidget *sw;
 	GtkWidget *label;
 	GtkWidget *reconnect_btn;
+	GtkWidget *reconnectall_btn;
 };
 struct disconnect_window *disconnect_window = NULL;
 
+static void disconnect_connection_change_cb(GaimConnection *gc, void *data);
+
+/*
+ * Destroy the dialog and remove the signals associated with it.
+ */
 static void disconnect_window_hide()
 {
+	gaim_signal_disconnect(gaim_connections_get_handle(), "signed-on",
+			disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb));
+
+	gaim_signal_disconnect(gaim_connections_get_handle(), "signed-off",
+			disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb));
+
 	gtk_widget_destroy(disconnect_window->window);
 	g_free(disconnect_window);
 	disconnect_window = NULL;
 }
 
+/*
+ * Make sure the Reconnect and Reconnect All buttons are correctly 
+ * shown or hidden.  Also make sure the label on the Reconnect 
+ * button is correctly set to either Reconnect or Remove.  If there 
+ * is more than one account then make sure the GtkTreeView is shown.  
+ * If there are no accounts disconnectd then hide the dialog.
+ */
+static void disconnect_window_update_buttons(GtkTreeModel *model)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection *sel;
+	const char *label_text;
+	GaimAccount *account = NULL;
+
+	if ((disconnect_window == NULL) || (model == NULL))
+		return;
+
+	if (!gtk_tree_model_get_iter_first(model, &iter)) {
+		/* No more accounts being shown.  Caloo calay! */
+		disconnect_window_hide();
+		return;
+	}
+
+	/*
+	 * If we have more than one disconnected account then show the 
+	 * GtkTreeView and the "Reconnect All" button
+	 */
+	if (gtk_tree_model_iter_next(model, &iter)) {
+		gtk_widget_show_all(disconnect_window->sw);
+		gtk_widget_show(disconnect_window->reconnectall_btn);
+	} else {
+		gtk_widget_hide_all(disconnect_window->sw);
+		gtk_widget_hide(disconnect_window->reconnectall_btn);
+	}
+
+	/*
+	 * Make sure one of the accounts is selected.
+	 */
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
+	if (!gtk_tree_selection_get_selected(sel, &model, &iter)) {
+		gtk_tree_model_get_iter_first(model, &iter);
+		gtk_tree_selection_select_iter(sel, &iter);
+	}
+
+	/*
+	 * Update the Reconnect/Remove button appropriately and set the 
+	 * label in the dialog to what it should be.
+	 */
+	gtk_tree_model_get(model, &iter, 3, &label_text, 4, &account, -1);
+	gtk_button_set_label(GTK_BUTTON(disconnect_window->reconnect_btn),
+		gaim_account_is_connected(account) ? _("_Remove") : _("_Reconnect"));
+	gtk_label_set_markup(GTK_LABEL(disconnect_window->label), label_text);
+	gtk_dialog_set_response_sensitive(GTK_DIALOG(disconnect_window->window), GTK_RESPONSE_ACCEPT, TRUE);
+}
+
 static void disconnect_response_cb(GtkDialog *dialog, gint id, GtkWidget *widget)
 {
 	GtkTreeIter iter;
@@ -291,18 +363,14 @@
 	GtkTreeModel *model = NULL;
 	GaimAccount *account = NULL;
 	
-	switch(id) {
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CLOSE:
-		disconnect_window_hide();
-		break;
-	case GTK_RESPONSE_APPLY: //Reconnect All
+	switch (id) {
+	case GTK_RESPONSE_APPLY: /* Reconnect All */
 		model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview));
 		if (gtk_tree_model_get_iter_first(model, &iter)) {
 			/* tree rows to be deleted */
 			GList *l_del = NULL, *l_del_iter = NULL;
 			/* accounts to be connected */
-			GList *l_accts = NULL, *l_accts_iter =NULL;
+			GList *l_accts = NULL, *l_accts_iter = NULL;
 			do {
 				GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
 				GtkTreeRowReference* del_row = gtk_tree_row_reference_new(model, path);
@@ -315,6 +383,11 @@
 			} while (gtk_tree_model_iter_next(model, &iter));
 
 			/* remove all rows */
+			/* We could just do the following, but we only want to remove accounts 
+			 * that are going to be reconnected, not accounts that have already 
+			 * been reconnected.
+			 */
+			/* gtk_list_store_clear(GTK_LIST_STORE(model)); */
 			l_del_iter = l_del;
 			while (l_del_iter != NULL) {
 				GtkTreeRowReference* del_row = l_del_iter->data;
@@ -336,24 +409,15 @@
 			}
 			g_list_free(l_accts);
 
-			/* 
-			 * if we don't have any rows left,
-			 * meaning that nothing was disconnected during our reconnections,
-			 * hide the dialog 
-			 */
-			if (!gtk_tree_model_get_iter_first(model, &iter))
-				disconnect_window_hide();
-			else {
-				gtk_tree_selection_select_iter(sel, &iter);
-				if (!gtk_tree_model_iter_next(model, &iter)) {
-					gtk_widget_hide_all(disconnect_window->sw);
-				}
-			}
 		}
 
+		disconnect_window_update_buttons(model);
+
 		break;
-	case GTK_RESPONSE_ACCEPT: //Reconnect Selected
+
+	case GTK_RESPONSE_ACCEPT: /* Reconnect Selected */
 		model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview));
+
 		/*
 		 * If we have more than one account disconnection displayed, then 
 		 * the scroll window is visible and we should use the selected 
@@ -368,8 +432,9 @@
 			if (!gtk_tree_model_get_iter_first(model, &iter))
 				return;
 		}
+
+		/* remove all disconnections of the account to be reconnected */
 		gtk_tree_model_get(model, &iter, 4, &account, -1);
-		/* remove all disconnections of the account to be reconnected */
 		if (gtk_tree_model_get_iter_first(model, &iter)) {
 			GList *l_del = NULL, *l_del_iter = NULL;
 			GaimAccount *account2 = NULL;
@@ -397,99 +462,88 @@
 		}
 
 		gaim_account_connect(account);
+		disconnect_window_update_buttons(model);
 
-		if (!gtk_tree_model_get_iter_first(model, &iter))
-			disconnect_window_hide();
-		else {
-			gtk_tree_selection_select_iter(sel, &iter);
-			if (!gtk_tree_model_iter_next(model, &iter))
-				gtk_widget_hide_all(disconnect_window->sw);
-		}
 		break;
+
+	case GTK_RESPONSE_DELETE_EVENT:
+	case GTK_RESPONSE_CLOSE:
+		disconnect_window_hide();
+		break;
+
 	}
 }
 
+/*
+ * Called whenever a different account is selected in the GtkListWhatever.
+ */
 static void disconnect_tree_cb(GtkTreeSelection *sel, GtkTreeModel *model) 
 {
-	GtkTreeIter  iter;
-
-	if (gtk_tree_selection_get_selected (sel, &model, &iter)) {
-		const char *label_text;
-		GaimAccount *account = NULL;
-		gtk_tree_model_get(model, &iter,
-			3, &label_text,	
-			4, &account, -1);
-		gtk_button_set_label(
-			GTK_BUTTON(disconnect_window->reconnect_btn),
-			gaim_account_is_connected(account)
-				? _("_Remove") 
-				: _("_Reconnect"));
-		gtk_label_set_markup(GTK_LABEL(disconnect_window->label), label_text);
-		gtk_dialog_set_response_sensitive(GTK_DIALOG(disconnect_window->window), GTK_RESPONSE_ACCEPT, TRUE);
-	} else
-		gtk_dialog_set_response_sensitive(GTK_DIALOG(disconnect_window->window), GTK_RESPONSE_ACCEPT, FALSE);
+	disconnect_window_update_buttons(model);
 }
 
+/*
+ * Update the icon next to the account in the disconnect dialog, and 
+ * gray the Reconnect All button if there is only 1 disconnected account.
+ */
 static void disconnect_connection_change_cb(GaimConnection *gc, void *data) {
-	if (disconnect_window) {
-		GaimAccount *account = gaim_connection_get_account(gc); 
-		gboolean signed_off = !gaim_account_is_connected(account); 
-		GtkTreeIter iter;
-		GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview));
-		GdkPixbuf *icon = create_prpl_icon(account);
-		GdkPixbuf *scale = gdk_pixbuf_scale_simple(icon, 16, 16, GDK_INTERP_BILINEAR);
-		/* mark all disconnections w/ the account type disconnected /w grey icon */
-		if (signed_off)
-			gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE);
-		if (gtk_tree_model_get_iter_first(model, &iter)) {
-			GList *l_disc_accts = NULL;
-			GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
-			GtkTreeIter iter_selected;
-			GtkTreePath *sel_path = NULL;
-			if (gtk_tree_selection_get_selected(sel, &model, &iter_selected))
-				sel_path = gtk_tree_model_get_path(model, &iter_selected);
-			do {
-				GaimAccount *account2 = NULL;
-				gtk_tree_model_get(model, &iter, 4, &account2, -1);
-				if (account2 == account) {
-					GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
-					gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, scale, -1);
-					/* update the reconnect button if appropriate */
-					if (sel_path != NULL && gtk_tree_path_compare(path, sel_path) == 0)
-						gtk_button_set_label(
-							GTK_BUTTON(disconnect_window->reconnect_btn),
-							signed_off ? _("_Reconnect") : _("_Remove"));	
-					gtk_tree_path_free(path);
-				}
-				if (!gaim_account_is_connected(account2)
+	GaimAccount *account = gaim_connection_get_account(gc); 
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	GdkPixbuf *icon;
+	GdkPixbuf *scale;
+	GList *l_disc_accts = NULL;
+
+	if (disconnect_window == NULL)
+		return;
+
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview));
+	icon = create_prpl_icon(account);
+	scale = gdk_pixbuf_scale_simple(icon, 16, 16, GDK_INTERP_BILINEAR);
+
+	/* Mark all disconnections w/ the account type disconnected /w grey icon */
+	if (!gaim_account_is_connected(account))
+		gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE);
+
+	gtk_tree_model_get_iter_first(model, &iter);
+	do {
+		GaimAccount *account2 = NULL;
+		/* Gray out the icon if this row is for this account */
+		gtk_tree_model_get(model, &iter, 4, &account2, -1);
+		if (account2 == account)
+			gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, scale, -1);
+
+		/* Add  */
+		if (!gaim_account_is_connected(account2)
 				&& g_list_find(l_disc_accts, account2) == NULL)
-					l_disc_accts = g_list_append(l_disc_accts, account2); 
-			} while (gtk_tree_model_iter_next(model, &iter));
-			
-			gtk_tree_path_free(sel_path);
+			l_disc_accts = g_list_append(l_disc_accts, account2); 
+	} while (gtk_tree_model_iter_next(model, &iter));
 
-			gtk_dialog_set_response_sensitive(
-				GTK_DIALOG(disconnect_window->window),
-				GTK_RESPONSE_APPLY,
-				g_list_length(l_disc_accts) > 1);
-			g_list_free(l_disc_accts);
-		}
-		if (icon != NULL) g_object_unref(G_OBJECT(icon));
-		if (scale  != NULL) g_object_unref(G_OBJECT(scale));
-	}
+	gtk_dialog_set_response_sensitive(
+		GTK_DIALOG(disconnect_window->window),
+		GTK_RESPONSE_APPLY,
+		g_list_length(l_disc_accts) > 1);
+	g_list_free(l_disc_accts);
+
+	if (icon != NULL)
+		g_object_unref(G_OBJECT(icon));
+	if (scale  != NULL)
+		g_object_unref(G_OBJECT(scale));
+
+	disconnect_window_update_buttons(model);
 }
 
 static void
 gaim_gtk_connection_report_disconnect(GaimConnection *gc, const char *text)
 {
 	char *label_text = NULL;
-	GtkTreeIter new_row_iter, iter;
+	GtkTreeIter new_iter;
 	GtkListStore *list_store;
 	GtkTreeViewColumn *col;
 	GtkTreeSelection *sel = NULL;
 
 	label_text = g_strdup_printf(_("<span weight=\"bold\" size=\"larger\">%s has been disconnected.</span>\n\n%s\n%s"),
-				     gaim_account_get_username(gaim_connection_get_account(gc)), gaim_date_full(), 
+				     gaim_account_get_username(gaim_connection_get_account(gc)), gaim_date_full(),
 				     text ? text : _("Reason Unknown."));
 
 	/* Build the window if it isn't there yet */
@@ -527,7 +581,7 @@
 			_("_Reconnect"),
 			GTK_RESPONSE_ACCEPT);
 
-		gtk_dialog_add_button(
+		disconnect_window->reconnectall_btn = gtk_dialog_add_button(
 			GTK_DIALOG(disconnect_window->window),
 			_("Reconnect _All"),
 			GTK_RESPONSE_APPLY);
@@ -539,15 +593,14 @@
 
 		gtk_widget_show_all(disconnect_window->window);
 
-
 		/* Tree View */
 		disconnect_window->sw = gtk_scrolled_window_new(NULL,NULL);
-		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(disconnect_window->sw), GTK_SHADOW_IN);
-		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(disconnect_window->sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+		gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(disconnect_window->sw), GTK_SHADOW_IN);
+		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(disconnect_window->sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 		gtk_box_pack_start(GTK_BOX(vbox), disconnect_window->sw, TRUE, TRUE, 0);
 
-		list_store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
-		disconnect_window->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL(list_store));
+		list_store = gtk_list_store_new(5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+		disconnect_window->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
 
 		rend = gtk_cell_renderer_pixbuf_new();
 		rend2 = gtk_cell_renderer_text_new();
@@ -577,31 +630,30 @@
 
 		gaim_signal_connect(gaim_connections_get_handle(), "signed-off",
 				disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb), NULL);
-
 	} else
 		list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview)));
 
 	/* Add this account to our list of disconnected accounts */
-	gtk_list_store_append(list_store, &new_row_iter);
-	gtk_list_store_set(list_store, &new_row_iter,
+	gtk_list_store_append(list_store, &new_iter);
+	gtk_list_store_set(list_store, &new_iter,
 			   0, NULL,
 			   1, gaim_account_get_username(gaim_connection_get_account(gc)),
 			   2, gaim_date_full(),
 			   3, label_text,
 			   4, gaim_connection_get_account(gc), -1);
 
-	if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &iter))
-	{
-		sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
-		gtk_tree_selection_select_iter(sel, &new_row_iter);
-		/* if we have more than one disconnected acct, display the treeview */
-		if (gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter))
-			gtk_widget_show_all(disconnect_window->sw);
-	}
+	/* Make sure the newly disconnected account is selected */
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
+	gtk_tree_selection_select_iter(sel, &new_iter);
+
+	disconnect_window_update_buttons(GTK_TREE_MODEL(list_store));
 
 	g_free(label_text);
 	gtk_window_present(GTK_WINDOW(disconnect_window->window));
 }
+/*
+ * End of disconnected dialog
+ */
 
 static GaimConnectionUiOps conn_ui_ops =
 {
@@ -618,6 +670,10 @@
 	return &conn_ui_ops;
 }
 
+/*
+ * This function needs to be moved out of here once away messages are 
+ * core/UI split.
+ */
 void away_on_login(const char *mesg)
 {
 	GSList *awy = away_messages;