# HG changeset patch # User Mark Doliner # Date 1072056145 0 # Node ID 4d4438f6ddce730006dc2b0f53e3057a9e23e311 # Parent 169e85869dcc6dd378acbb9f4c506314a1c40b2e [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 diff -r 169e85869dcc -r 4d4438f6ddce src/gtkconn.c --- 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(_("%s has been disconnected.\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;