X-Git-Url: https://git.0d.be/?p=empathy.git;a=blobdiff_plain;f=src%2Fempathy-accounts-dialog.c;h=a00c1b5ebe8e82365f18e9f39523216a49bcf966;hp=9132395898beb92e66717e9024ec7b1be729da26;hb=647858dc34ec9786c88b22fea74fc45ff3bb14f6;hpb=84e30dab1428affe335ef904377d07f8b5fdeb66 diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c index 91323958..a00c1b5e 100644 --- a/src/empathy-accounts-dialog.c +++ b/src/empathy-accounts-dialog.c @@ -20,6 +20,7 @@ * Authors: Martyn Russell * Xavier Claessens * Cosimo Cecchi + * Jonathan Tellier */ #include @@ -42,13 +43,13 @@ #include #include #include +#include #include +#include #include "empathy-accounts-dialog.h" -#if 0 -/* FIXME MC-5 */ #include "empathy-import-dialog.h" -#endif +#include "empathy-import-utils.h" #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT #include @@ -56,6 +57,11 @@ /* Flashing delay for icons (milliseconds). */ #define FLASH_TIMEOUT 500 +/* The primary text of the dialog shown to the user when he is about to lose + * unsaved changes */ +#define PENDING_CHANGES_QUESTION_PRIMARY_TEXT \ + _("There are unsaved modification regarding your %s account.") + #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog) G_DEFINE_TYPE (EmpathyAccountsDialog, empathy_accounts_dialog, G_TYPE_OBJECT); @@ -72,8 +78,6 @@ typedef struct { GtkWidget *treeview; GtkWidget *button_add; - GtkWidget *button_remove; - GtkWidget *button_import; GtkWidget *frame_new_account; GtkWidget *combobox_protocol; @@ -88,6 +92,14 @@ typedef struct { GtkWidget *label_type; GtkWidget *settings_widget; + /* We have to keep a reference on the actual EmpathyAccountWidget, not just + * his GtkWidget. It is the only reliable source we can query to know if + * there are any unsaved changes to the currently selected account. We can't + * look at the account settings because it does not contain everything that + * can be changed using the EmpathyAccountWidget. For instance, it does not + * contain the state of the "Enabled" checkbox. */ + EmpathyAccountWidget *setting_widget_object; + gboolean connecting_show; guint connecting_id; @@ -99,10 +111,19 @@ typedef struct { GtkWindow *parent_window; EmpathyAccount *initial_selection; + + /* Those are needed when changing the selected row. When a user selects + * another account and there are unsaved changes on the currently selected + * one, a confirmation message box is presented to him. Since his answer + * is retrieved asynchronously, we keep some information as member of the + * EmpathyAccountsDialog object. */ + gboolean force_change_row; + GtkTreeRowReference *destination_row; + + } EmpathyAccountsDialogPriv; enum { - COL_ENABLED, COL_NAME, COL_STATUS, COL_ACCOUNT_POINTER, @@ -114,61 +135,144 @@ enum { PROP_PARENT = 1 }; -static void accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings); +static void accounts_dialog_account_display_name_changed_cb ( + EmpathyAccount *account, + GParamSpec *pspec, + gpointer user_data); -#if 0 -/* FIXME MC-5 */ -static void accounts_dialog_button_import_clicked_cb (GtkWidget *button, +static EmpathyAccountSettings * accounts_dialog_model_get_selected_settings ( EmpathyAccountsDialog *dialog); -#endif + +static gboolean accounts_dialog_get_settings_iter ( + EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings, + GtkTreeIter *iter); + +static void accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog); + +static void accounts_dialog_update (EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings); + +static void accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings); static void accounts_dialog_update_name_label (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) + const gchar *display_name) { gchar *text; EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - text = g_markup_printf_escaped ("%s", - empathy_account_settings_get_display_name (settings)); + text = g_markup_printf_escaped ("%s", display_name); gtk_label_set_markup (GTK_LABEL (priv->label_name), text); g_free (text); } -static GtkWidget * -get_account_setup_widget (EmpathyAccountSettings *settings) +static void +empathy_account_dialog_widget_cancelled_cb (EmpathyAccountWidget *widget_object, + EmpathyAccountsDialog *dialog) { - const gchar *cm = empathy_account_settings_get_cm (settings); - const gchar *proto = empathy_account_settings_get_protocol (settings); - - struct { - const gchar *cm; - const gchar *proto; - } dialogs[] = { - { "gabble", "jabber" }, - { "butterfly", "msn" }, - { "salut", "local-xmpp" }, - { "idle", "irc" }, - { "haze", "icq" }, - { "haze", "aim" }, - { "haze", "yahoo" }, - { "haze", "groupwise" }, - { "sofiasip", "sip" }, - { NULL, NULL } - }; - int i; - - for (i = 0; dialogs[i].cm != NULL; i++) + GtkTreeView *view; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccountSettings *settings; + EmpathyAccount *account; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + view = GTK_TREE_VIEW (priv->treeview); + selection = gtk_tree_view_get_selection (view); + + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + + gtk_tree_model_get (model, &iter, + COL_ACCOUNT_SETTINGS_POINTER, &settings, + COL_ACCOUNT_POINTER, &account, -1); + + empathy_account_widget_discard_pending_changes (priv->setting_widget_object); + + if (account == NULL) { - if (!tp_strdiff (cm, dialogs[i].cm) - && !tp_strdiff (proto, dialogs[i].proto)) - return empathy_account_widget_new_for_protocol (dialogs[i].proto, - settings); + /* We were creating an account. We remove the selected row */ + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + } + else + { + /* We were modifying an account. We discard the changes by reloading the + * settings and the UI. */ + accounts_dialog_update_settings (dialog, settings); + g_object_unref (account); } - return empathy_account_widget_new_for_protocol ("generic", settings); + if (settings != NULL) + g_object_unref (settings); +} + +static gchar * +get_default_display_name (EmpathyAccountSettings *settings) +{ + const gchar *login_id; + const gchar *protocol; + gchar *default_display_name; + + login_id = empathy_account_settings_get_string (settings, "account"); + protocol = empathy_account_settings_get_protocol (settings); + + if (login_id != NULL) + { + if (!tp_strdiff (protocol, "irc")) + { + const gchar* server; + server = empathy_account_settings_get_string (settings, "server"); + + /* To translators: The first parameter is the login id and the + * second one is the server. The resulting string will be something + * like: "MyUserName on chat.freenode.net". + * You should reverse the order of these arguments if the + * server should come before the login id in your locale.*/ + default_display_name = g_strdup_printf (_("%1$s on %2$s"), + login_id, server); + } + else + { + default_display_name = g_strdup (login_id); + } + } + else if (protocol != NULL) + { + /* To translators: The parameter is the protocol name. The resulting + * string will be something like: "Jabber Account" */ + default_display_name = g_strdup_printf (_("%s Account"), protocol); + } + else + { + default_display_name = g_strdup (_("New account")); + } + + return default_display_name; +} + +static void +empathy_account_dialog_account_created_cb (EmpathyAccountWidget *widget_object, + EmpathyAccountsDialog *dialog) +{ + gchar *display_name; + EmpathyAccountSettings *settings = + accounts_dialog_model_get_selected_settings (dialog); + + display_name = get_default_display_name (settings); + + empathy_account_settings_set_display_name_async (settings, + display_name, NULL, NULL); + + g_free (display_name); + + accounts_dialog_update_settings (dialog, settings); + + if (settings) + g_object_unref (settings); } static void @@ -178,7 +282,18 @@ account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog, EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); gchar *icon_name; - priv->settings_widget = get_account_setup_widget (settings); + priv->setting_widget_object = + empathy_account_widget_new_for_protocol (settings, FALSE); + + priv->settings_widget = + empathy_account_widget_get_widget (priv->setting_widget_object); + + priv->settings_widget = + empathy_account_widget_get_widget (priv->setting_widget_object); + g_signal_connect (priv->setting_widget_object, "account-created", + G_CALLBACK (empathy_account_dialog_account_created_cb), dialog); + g_signal_connect (priv->setting_widget_object, "cancelled", + G_CALLBACK (empathy_account_dialog_widget_cancelled_cb), dialog); gtk_container_add (GTK_CONTAINER (priv->alignment_settings), priv->settings_widget); @@ -189,9 +304,11 @@ account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog, gtk_image_set_from_icon_name (GTK_IMAGE (priv->image_type), icon_name, GTK_ICON_SIZE_DIALOG); gtk_widget_set_tooltip_text (priv->image_type, - empathy_account_settings_get_protocol (settings)); + empathy_protocol_name_to_display_name + (empathy_account_settings_get_protocol (settings))); - accounts_dialog_update_name_label (dialog, settings); + accounts_dialog_update_name_label (dialog, + empathy_account_settings_get_display_name (settings)); } static void @@ -227,6 +344,25 @@ accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog) } } +static gboolean +accounts_dialog_has_pending_change (EmpathyAccountsDialog *dialog, + EmpathyAccount **account) +{ + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeSelection *selection; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, account, -1); + + return *account != NULL && priv->setting_widget_object != NULL + && empathy_account_widget_contains_pending_changes ( + priv->setting_widget_object); +} + static void accounts_dialog_protocol_changed_cb (GtkWidget *widget, EmpathyAccountsDialog *dialog) @@ -238,6 +374,15 @@ accounts_dialog_protocol_changed_cb (GtkWidget *widget, cm = empathy_protocol_chooser_dup_selected ( EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto); + if (cm == NULL) + return; + + if (proto == NULL) + { + g_object_unref (cm); + return; + } + if (tp_connection_manager_protocol_can_register (proto)) { gtk_widget_show (priv->radiobutton_register); @@ -252,21 +397,16 @@ accounts_dialog_protocol_changed_cb (GtkWidget *widget, } static void -accounts_dialog_button_add_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +accounts_dialog_setup_ui_to_add_account (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; + GtkTreeView *view; + GtkTreeModel *model; EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); view = GTK_TREE_VIEW (priv->treeview); model = gtk_tree_view_get_model (view); - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_unselect_all (selection); gtk_widget_set_sensitive (priv->button_add, FALSE); - gtk_widget_set_sensitive (priv->button_remove, FALSE); gtk_widget_hide (priv->vbox_details); gtk_widget_hide (priv->frame_no_protocol); gtk_widget_show (priv->frame_new_account); @@ -284,6 +424,93 @@ accounts_dialog_button_add_clicked_cb (GtkWidget *button, gtk_widget_grab_focus (priv->combobox_protocol); } +static void +accounts_dialog_show_question_dialog (EmpathyAccountsDialog *dialog, + gchar *primary_text, + gchar *secondary_text, + GCallback response_callback, + gpointer user_data, + const gchar *first_button_text, + ...) +{ + va_list button_args; + GtkWidget *message_dialog; + const gchar *button_text; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + message_dialog = gtk_message_dialog_new (GTK_WINDOW (priv->window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + primary_text); + + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (message_dialog), secondary_text); + + va_start (button_args, first_button_text); + for (button_text = first_button_text; + button_text; + button_text = va_arg (button_args, const gchar *)) + { + gint response_id; + response_id = va_arg (button_args, gint); + + gtk_dialog_add_button (GTK_DIALOG (message_dialog), button_text, response_id); + } + va_end (button_args); + + g_signal_connect (message_dialog, "response", response_callback, user_data); + + gtk_widget_show (message_dialog); +} + +static void +accounts_dialog_add_pending_changes_response_cb (GtkDialog *message_dialog, + gint response_id, + gpointer *user_data) +{ + EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (user_data); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + gtk_widget_destroy (GTK_WIDGET (message_dialog)); + + if (response_id == GTK_RESPONSE_YES) + { + empathy_account_widget_discard_pending_changes ( + priv->setting_widget_object); + accounts_dialog_setup_ui_to_add_account (dialog); + } +} + +static void +accounts_dialog_button_add_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) +{ + EmpathyAccount *account = NULL; + + if (accounts_dialog_has_pending_change (dialog, &account)) + { + gchar *question_dialog_primary_text = g_strdup_printf ( + PENDING_CHANGES_QUESTION_PRIMARY_TEXT, + empathy_account_get_display_name (account)); + + accounts_dialog_show_question_dialog (dialog, + question_dialog_primary_text, + _("You are about to create a new account, which will discard\n" + "your changes. Are you sure you want to proceed?"), + G_CALLBACK (accounts_dialog_add_pending_changes_response_cb), + dialog, + GTK_STOCK_CANCEL, GTK_RESPONSE_NO, + GTK_STOCK_DISCARD, GTK_RESPONSE_YES, NULL); + + g_free (question_dialog_primary_text); + } + else + { + accounts_dialog_setup_ui_to_add_account (dialog); + } +} + static void accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, EmpathyAccountSettings *settings) @@ -315,7 +542,7 @@ accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, if (empathy_connection_managers_get_cms_num (priv->cms) > 0) { /* We have no account configured but we have some - * profiles instsalled. The user obviously wants to add + * profiles installed. The user obviously wants to add * an account. Click on the Add button for him. */ accounts_dialog_button_add_clicked_cb (priv->button_add, dialog); @@ -327,7 +554,6 @@ accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, gtk_widget_hide (priv->frame_new_account); gtk_widget_show (priv->frame_no_protocol); gtk_widget_set_sensitive (priv->button_add, FALSE); - gtk_widget_set_sensitive (priv->button_remove, FALSE); return; } @@ -337,7 +563,6 @@ accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, gtk_widget_hide (priv->frame_no_protocol); gtk_widget_show (priv->vbox_details); gtk_widget_set_sensitive (priv->button_add, TRUE); - gtk_widget_set_sensitive (priv->button_remove, TRUE); if (priv->settings_widget) { @@ -428,38 +653,6 @@ accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column, g_object_unref (pixbuf); } -static void -accounts_dialog_enable_toggled_cb (GtkCellRendererToggle *cell_renderer, - gchar *path, - EmpathyAccountsDialog *dialog) -{ - EmpathyAccount *account; - GtkTreeModel *model; - GtkTreePath *treepath; - GtkTreeIter iter; - gboolean enabled; - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); - treepath = gtk_tree_path_new_from_string (path); - gtk_tree_model_get_iter (model, &iter, treepath); - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_POINTER, &account, - -1); - gtk_tree_path_free (treepath); - - if (account == NULL) - return; - - enabled = empathy_account_is_enabled (account); - empathy_account_set_enabled (account, !enabled); - - DEBUG ("%s account %s", enabled ? "Disabled" : "Enable", - empathy_account_get_display_name (account)); - - g_object_unref (account); -} - static gboolean accounts_dialog_row_changed_foreach (GtkTreeModel *model, GtkTreePath *path, @@ -521,9 +714,97 @@ accounts_dialog_name_edited_cb (GtkCellRendererText *renderer, empathy_account_settings_set_display_name_async (settings, new_text, NULL, NULL); + g_object_set (settings, "display-name-overridden", TRUE, NULL); g_object_unref (settings); } +static void +accounts_dialog_delete_account_response_cb (GtkDialog *message_dialog, + gint response_id, + gpointer user_data) +{ + EmpathyAccount *account; + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreeSelection *selection; + EmpathyAccountsDialog *account_dialog = EMPATHY_ACCOUNTS_DIALOG (user_data); + EmpathyAccountsDialogPriv *priv = GET_PRIV (account_dialog); + + if (response_id == GTK_RESPONSE_YES) + { + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + + gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1); + + if (account != NULL) + { + g_signal_handlers_disconnect_by_func (account, + accounts_dialog_account_display_name_changed_cb, account_dialog); + empathy_account_remove_async (account, NULL, NULL); + g_object_unref (account); + account = NULL; + } + + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + accounts_dialog_model_select_first (account_dialog); + } + + gtk_widget_destroy (GTK_WIDGET (message_dialog)); +} + +static void +accounts_dialog_view_delete_activated_cb (EmpathyCellRendererActivatable *cell, + const gchar *path_string, + EmpathyAccountsDialog *dialog) +{ + EmpathyAccount *account; + GtkTreeModel *model; + GtkTreeIter iter; + gchar *question_dialog_primary_text; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + if (!gtk_tree_model_get_iter_from_string (model, &iter, path_string)) + return; + + gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1); + + if (account == NULL || !empathy_account_is_valid (account)) + { + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + accounts_dialog_model_select_first (dialog); + return; + } + + question_dialog_primary_text = g_strdup_printf ( + _("You are about to remove your %s account!\n" + "Are you sure you want to proceed?"), + empathy_account_get_display_name (account)); + + accounts_dialog_show_question_dialog (dialog, question_dialog_primary_text, + _("Any associated conversations and chat rooms will NOT be " + "removed if you decide to proceed.\n" + "\n" + "Should you decide to add the account back at a later time, " + "they will still be available."), + G_CALLBACK (accounts_dialog_delete_account_response_cb), + dialog, + GTK_STOCK_CANCEL, GTK_RESPONSE_NO, + GTK_STOCK_REMOVE, GTK_RESPONSE_YES, NULL); + + g_free (question_dialog_primary_text); + + if (account != NULL) + { + g_object_unref (account); + account = NULL; + } +} + static void accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) { @@ -533,22 +814,10 @@ accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); view = GTK_TREE_VIEW (priv->treeview); - gtk_tree_view_set_headers_visible (view, TRUE); - - /* Enabled column */ - cell = gtk_cell_renderer_toggle_new (); - gtk_tree_view_insert_column_with_attributes (view, -1, - _("Enabled"), - cell, - "active", COL_ENABLED, - NULL); - g_signal_connect (cell, "toggled", - G_CALLBACK (accounts_dialog_enable_toggled_cb), - dialog); + gtk_tree_view_set_headers_visible (view, FALSE); /* Account column */ column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Accounts")); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_append_column (view, column); @@ -576,6 +845,17 @@ accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) g_signal_connect (cell, "editing-started", G_CALLBACK (accounts_dialog_name_editing_started_cb), dialog); + + /* Delete column */ + cell = empathy_cell_renderer_activatable_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + g_object_set (cell, + "icon-name", GTK_STOCK_DELETE, + NULL); + + g_signal_connect (cell, "path-activated", + G_CALLBACK (accounts_dialog_view_delete_activated_cb), + dialog); } static EmpathyAccountSettings * @@ -614,10 +894,103 @@ accounts_dialog_model_selection_changed (GtkTreeSelection *selection, settings = accounts_dialog_model_get_selected_settings (dialog); accounts_dialog_update_settings (dialog, settings); - if (settings) + if (settings != NULL) g_object_unref (settings); } +static void +accounts_dialog_selection_change_response_cb (GtkDialog *message_dialog, + gint response_id, + gpointer *user_data) +{ + EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (user_data); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + gtk_widget_destroy (GTK_WIDGET (message_dialog)); + + if (response_id == GTK_RESPONSE_YES && priv->destination_row != NULL) + { + /* The user wants to lose unsaved changes to the currently selected + * account and select another account. We discard the changes and + * select the other account. */ + GtkTreePath *path; + GtkTreeSelection *selection; + + priv->force_change_row = TRUE; + empathy_account_widget_discard_pending_changes ( + priv->setting_widget_object); + + path = gtk_tree_row_reference_get_path (priv->destination_row); + selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (priv->treeview)); + + if (path != NULL) + { + /* This will trigger a call to + * accounts_dialog_account_selection_change() */ + gtk_tree_selection_select_path (selection, path); + gtk_tree_path_free (path); + } + + gtk_tree_row_reference_free (priv->destination_row); + } + else + { + priv->force_change_row = FALSE; + } +} + +static gboolean +accounts_dialog_account_selection_change (GtkTreeSelection *selection, + GtkTreeModel *model, + GtkTreePath *path, + gboolean path_currently_selected, + gpointer data) +{ + EmpathyAccount *account = NULL; + EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (data); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (priv->force_change_row) + { + /* We came back here because the user wants to discard changes to his + * modified account. The changes have already been discarded so we + * just change the selected row. */ + priv->force_change_row = FALSE; + return TRUE; + } + + if (accounts_dialog_has_pending_change (dialog, &account)) + { + /* The currently selected account has some unsaved changes. We ask + * the user if he really wants to lose his changes and select another + * account */ + gchar *question_dialog_primary_text; + priv->destination_row = gtk_tree_row_reference_new (model, path); + + question_dialog_primary_text = g_strdup_printf ( + PENDING_CHANGES_QUESTION_PRIMARY_TEXT, + empathy_account_get_display_name (account)); + + accounts_dialog_show_question_dialog (dialog, + question_dialog_primary_text, + _("You are about to select another account, which will discard\n" + "your changes. Are you sure you want to proceed?"), + G_CALLBACK (accounts_dialog_selection_change_response_cb), + dialog, + GTK_STOCK_CANCEL, GTK_RESPONSE_NO, + GTK_STOCK_DISCARD, GTK_RESPONSE_YES, NULL); + + g_free (question_dialog_primary_text); + } + else + { + return TRUE; + } + + return FALSE; +} + static void accounts_dialog_model_setup (EmpathyAccountsDialog *dialog) { @@ -626,7 +999,6 @@ accounts_dialog_model_setup (EmpathyAccountsDialog *dialog) EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); store = gtk_list_store_new (COL_COUNT, - G_TYPE_BOOLEAN, /* enabled */ G_TYPE_STRING, /* name */ G_TYPE_UINT, /* status */ EMPATHY_TYPE_ACCOUNT, /* account */ @@ -637,6 +1009,8 @@ accounts_dialog_model_setup (EmpathyAccountsDialog *dialog) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + gtk_tree_selection_set_select_function (selection, + accounts_dialog_account_selection_change, dialog, NULL); g_signal_connect (selection, "changed", G_CALLBACK (accounts_dialog_model_selection_changed), @@ -724,27 +1098,6 @@ accounts_dialog_get_account_iter (EmpathyAccountsDialog *dialog, return FALSE; } -static EmpathyAccount * -accounts_dialog_model_get_selected_account (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - EmpathyAccount *account; - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - - view = GTK_TREE_VIEW (priv->treeview); - selection = gtk_tree_view_get_selection (view); - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return NULL; - - gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1); - - return account; -} - static void accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog, EmpathyAccountSettings *settings) @@ -757,33 +1110,6 @@ accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog, if (accounts_dialog_get_settings_iter (dialog, settings, &iter)) gtk_tree_selection_select_iter (selection, &iter); } - -static gboolean -accounts_dialog_model_remove_selected (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - EmpathyAccount *account; - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - - view = GTK_TREE_VIEW (priv->treeview); - selection = gtk_tree_view_get_selection (view); - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return FALSE; - - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_POINTER, &account, - -1); - - if (account != NULL) - empathy_account_remove_async (account, NULL, NULL); - - return gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -} - static void accounts_dialog_add (EmpathyAccountsDialog *dialog, EmpathyAccountSettings *settings) @@ -799,7 +1125,6 @@ accounts_dialog_add (EmpathyAccountsDialog *dialog, gtk_list_store_append (GTK_LIST_STORE (model), &iter); gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, FALSE, COL_NAME, name, COL_STATUS, TP_CONNECTION_STATUS_DISCONNECTED, COL_ACCOUNT_SETTINGS_POINTER, settings, @@ -849,6 +1174,37 @@ accounts_dialog_connection_changed_cb (EmpathyAccountManager *manager, dialog); } +static void +accounts_dialog_account_display_name_changed_cb (EmpathyAccount *account, + GParamSpec *pspec, + gpointer user_data) +{ + const gchar *display_name; + GtkTreeIter iter; + GtkTreeModel *model; + EmpathyAccountSettings *settings; + EmpathyAccount *selected_account; + EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (user_data); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + display_name = empathy_account_get_display_name (account); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + settings = accounts_dialog_model_get_selected_settings (dialog); + selected_account = empathy_account_settings_get_account (settings); + + if (accounts_dialog_get_account_iter (dialog, account, &iter)) + { + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_NAME, display_name, + -1); + } + + if (selected_account == account) + accounts_dialog_update_name_label (dialog, display_name); + + g_object_unref (settings); +} + static void accounts_dialog_add_account (EmpathyAccountsDialog *dialog, EmpathyAccount *account) @@ -872,7 +1228,6 @@ accounts_dialog_add_account (EmpathyAccountsDialog *dialog, settings = empathy_account_settings_new_for_account (account); gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, COL_NAME, name, COL_STATUS, status, COL_ACCOUNT_POINTER, account, @@ -886,6 +1241,9 @@ accounts_dialog_add_account (EmpathyAccountsDialog *dialog, TP_CONNECTION_STATUS_DISCONNECTED, dialog); + g_signal_connect (account, "notify::display-name", + G_CALLBACK (accounts_dialog_account_display_name_changed_cb), dialog); + g_object_unref (settings); } @@ -913,7 +1271,6 @@ accounts_dialog_update (EmpathyAccountsDialog *dialog, accounts_dialog_get_settings_iter (dialog, settings, &iter); gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, COL_NAME, name, COL_STATUS, status, COL_ACCOUNT_POINTER, account, @@ -939,8 +1296,12 @@ accounts_dialog_account_removed_cb (EmpathyAccountManager *manager, EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); if (accounts_dialog_get_account_iter (dialog, account, &iter)) - gtk_list_store_remove (GTK_LIST_STORE ( + { + g_signal_handlers_disconnect_by_func (account, + accounts_dialog_account_display_name_changed_cb, dialog); + gtk_list_store_remove (GTK_LIST_STORE ( gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))), &iter); + } } static void @@ -949,7 +1310,6 @@ enable_or_disable_account (EmpathyAccountsDialog *dialog, gboolean enabled) { GtkTreeModel *model; - GtkTreeIter iter; EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); /* Update the status in the model */ @@ -958,11 +1318,6 @@ enable_or_disable_account (EmpathyAccountsDialog *dialog, DEBUG ("Account %s is now %s", empathy_account_get_display_name (account), enabled ? "enabled" : "disabled"); - - if (accounts_dialog_get_account_iter (dialog, account, &iter)) - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, - -1); } static void @@ -1004,7 +1359,14 @@ accounts_dialog_account_changed_cb (EmpathyAccountManager *manager, selected_settings = accounts_dialog_model_get_selected_settings (dialog); if (settings == selected_settings) - accounts_dialog_update_name_label (dialog, settings); + accounts_dialog_update_name_label (dialog, + empathy_account_settings_get_display_name (settings)); + + if (settings) + g_object_unref (settings); + + if (selected_settings) + g_object_unref (selected_settings); } static void @@ -1012,18 +1374,24 @@ accounts_dialog_button_create_clicked_cb (GtkWidget *button, EmpathyAccountsDialog *dialog) { EmpathyAccountSettings *settings; - gchar *str; + gchar *str; + const gchar *display_name; TpConnectionManager *cm; TpConnectionManagerProtocol *proto; EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); cm = empathy_protocol_chooser_dup_selected ( EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto); + display_name = empathy_protocol_name_to_display_name (proto->name); - /* Create account */ - /* To translator: %s is the protocol name */ - str = g_strdup_printf (_("New %s account"), proto->name); + if (display_name == NULL) + display_name = proto->name; + /* Create account */ + /* To translator: %s is the name of the protocol, such as "Google Talk" or + * "Yahoo!" + */ + str = g_strdup_printf (_("New %s account"), display_name); settings = empathy_account_settings_new (cm->name, proto->name, str); g_free (str); @@ -1052,86 +1420,58 @@ accounts_dialog_button_back_clicked_cb (GtkWidget *button, EmpathyAccountSettings *settings; settings = accounts_dialog_model_get_selected_settings (dialog); - accounts_dialog_update (dialog, settings); + accounts_dialog_update_settings (dialog, settings); + + if (settings) + g_object_unref (settings); } static void accounts_dialog_button_help_clicked_cb (GtkWidget *button, EmpathyAccountsDialog *dialog) { - empathy_url_show (button, "ghelp:empathy?empathy-create-account"); + empathy_url_show (button, "ghelp:empathy?accounts-window"); } static void -accounts_dialog_button_remove_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +accounts_dialog_close_response_cb (GtkDialog *message_dialog, + gint response_id, + gpointer user_data) { - EmpathyAccount *account; - GtkWidget *message_dialog; - gint res; - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + GtkWidget *account_dialog = GTK_WIDGET (user_data); - account = accounts_dialog_model_get_selected_account (dialog); + gtk_widget_destroy (GTK_WIDGET (message_dialog)); - if (account == NULL || !empathy_account_is_valid (account)) - { - accounts_dialog_model_remove_selected (dialog); - accounts_dialog_model_select_first (dialog); - return; - } - message_dialog = gtk_message_dialog_new - (GTK_WINDOW (priv->window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("You are about to remove your %s account!\n" - "Are you sure you want to proceed?"), - empathy_account_get_display_name (account)); - - gtk_message_dialog_format_secondary_text - (GTK_MESSAGE_DIALOG (message_dialog), - _("Any associated conversations and chat rooms will NOT be " - "removed if you decide to proceed.\n" - "\n" - "Should you decide to add the account back at a later time, " - "they will still be available.")); - - gtk_dialog_add_button (GTK_DIALOG (message_dialog), - GTK_STOCK_CANCEL, - GTK_RESPONSE_NO); - gtk_dialog_add_button (GTK_DIALOG (message_dialog), - GTK_STOCK_REMOVE, - GTK_RESPONSE_YES); - - gtk_widget_show (message_dialog); - res = gtk_dialog_run (GTK_DIALOG (message_dialog)); - - if (res == GTK_RESPONSE_YES) - { - accounts_dialog_model_remove_selected (dialog); - accounts_dialog_model_select_first (dialog); - } - gtk_widget_destroy (message_dialog); + if (response_id == GTK_RESPONSE_YES) + gtk_widget_destroy (account_dialog); } -#if 0 -/* FIXME MC-5 */ -static void -accounts_dialog_button_import_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - - empathy_import_dialog_show (GTK_WINDOW (priv->window), TRUE); -} -#endif - static void accounts_dialog_response_cb (GtkWidget *widget, gint response, EmpathyAccountsDialog *dialog) { - if (response == GTK_RESPONSE_CLOSE) + EmpathyAccount *account = NULL; + + if (accounts_dialog_has_pending_change (dialog, &account)) + { + gchar *question_dialog_primary_text; + question_dialog_primary_text = g_strdup_printf ( + PENDING_CHANGES_QUESTION_PRIMARY_TEXT, + empathy_account_get_display_name (account)); + + accounts_dialog_show_question_dialog (dialog, + question_dialog_primary_text, + _("You are about to close the window, which will discard\n" + "your changes. Are you sure you want to proceed?"), + G_CALLBACK (accounts_dialog_close_response_cb), + widget, + GTK_STOCK_CANCEL, GTK_RESPONSE_NO, + GTK_STOCK_DISCARD, GTK_RESPONSE_YES, NULL); + + g_free (question_dialog_primary_text); + } + else if (response == GTK_RESPONSE_CLOSE) gtk_widget_destroy (widget); } @@ -1202,8 +1542,6 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog) "image_type", &priv->image_type, "label_name", &priv->label_name, "button_add", &priv->button_add, - "button_remove", &priv->button_remove, - "button_import", &priv->button_import, NULL); g_free (filename); @@ -1213,18 +1551,13 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog) "button_create", "clicked", accounts_dialog_button_create_clicked_cb, "button_back", "clicked", accounts_dialog_button_back_clicked_cb, "button_add", "clicked", accounts_dialog_button_add_clicked_cb, - "button_remove", "clicked", accounts_dialog_button_remove_clicked_cb, -#if 0 - /* FIXME MC-5 */ - "button_import", "clicked", accounts_dialog_button_import_clicked_cb, -#endif "button_help", "clicked", accounts_dialog_button_help_clicked_cb, NULL); g_object_unref (gui); priv->combobox_protocol = empathy_protocol_chooser_new (); - gtk_box_pack_end (GTK_BOX (priv->hbox_type), + gtk_box_pack_start (GTK_BOX (priv->hbox_type), priv->combobox_protocol, TRUE, TRUE, 0); gtk_widget_show (priv->combobox_protocol); @@ -1400,24 +1733,20 @@ do_constructed (GObject *object) EMPATHY_PREFS_IMPORT_ASKED, &import_asked); -#if 0 - /* FIXME MC-5 */ - if (empathy_import_dialog_accounts_to_import ()) + if (empathy_import_accounts_to_import ()) { if (!import_asked) { + GtkWidget *import_dialog; + empathy_conf_set_bool (empathy_conf_get (), EMPATHY_PREFS_IMPORT_ASKED, TRUE); - empathy_import_dialog_show (GTK_WINDOW (priv->window), + import_dialog = empathy_import_dialog_new (GTK_WINDOW (priv->window), FALSE); + gtk_widget_show (import_dialog); } } - else - { - gtk_widget_set_sensitive (priv->button_import, FALSE); - } -#endif } static void