* src/modest-tny-account-store.c:
[modest] / src / modest-tny-account-store.c
index 6fbc996..ac14b62 100644 (file)
@@ -58,6 +58,7 @@
 #include <tny-gtk-lockable.h>
 #include <camel/camel.h>
 #include <modest-platform.h>
+#include "modest-ui-actions.h"
 
 #ifdef MODEST_PLATFORM_MAEMO
 #include <tny-maemo-conic-device.h>
@@ -107,6 +108,10 @@ static void    modest_tny_account_store_forget_password_in_memory (ModestTnyAcco
 
 static void    add_connection_specific_transport_accounts         (ModestTnyAccountStore *self);
 
+static void    connection_status_changed   (TnyAccount *account, 
+                                           TnyConnectionStatus status, 
+                                           gpointer data);
+
 /* list my signals */
 enum {
        ACCOUNT_CHANGED_SIGNAL,
@@ -475,7 +480,7 @@ on_account_changed (ModestAccountMgr *acc_mgr,
                if (tny_account) {
                        if (!strcmp (tny_account_get_id (tny_account), account_name)) {
                                found = TRUE;
-                               modest_tny_account_update_from_account (tny_account);
+                               modest_tny_account_update_from_account (tny_account, get_password, forget_password);
                                g_signal_emit (G_OBJECT(self), signals[ACCOUNT_CHANGED_SIGNAL], 0, tny_account);
                        }
                        g_object_unref (tny_account);
@@ -491,16 +496,13 @@ on_account_changed (ModestAccountMgr *acc_mgr,
 static void 
 on_account_settings_hide (GtkWidget *widget, gpointer user_data)
 {
-       TnyAccount *account = (TnyAccount*)user_data;
-       
        /* This is easier than using a struct for the user_data: */
        ModestTnyAccountStore *self = modest_runtime_get_account_store();
        ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
        
-       const gchar *modest_account_name = 
-                       modest_tny_account_get_parent_modest_account_name_for_server_account (account);
-       if (modest_account_name)
-               g_hash_table_remove (priv->account_settings_dialog_hash, modest_account_name);
+       gchar *account_name = (gchar *) user_data;
+       if (account_name)
+               g_hash_table_remove (priv->account_settings_dialog_hash, account_name);
 }
 #endif
 
@@ -512,7 +514,7 @@ show_password_warning_only ()
        
        /* Show an explanatory temporary banner: */
        if (main_window) 
-               modest_platform_information_banner (GTK_WIDGET(main_window), NULL, 
+               modest_platform_information_banner (NULL, NULL, 
                                                    _("mcen_ib_username_pw_incorrect"));
        else
                g_warning ("%s: %s", __FUNCTION__, _("mcen_ib_username_pw_incorrect"));
@@ -524,12 +526,12 @@ show_wrong_password_dialog (TnyAccount *account)
 { 
        /* This is easier than using a struct for the user_data: */
        ModestTnyAccountStore *self = modest_runtime_get_account_store();
-       ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
-       ModestWindow *main_window;
        const gchar *modest_account_name;
+       GtkWidget *main_window;
+       GtkWidget *dialog;
 
-       main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
-                                                        FALSE); /* don't create */
+       main_window = (GtkWidget *) modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
+                                                                      FALSE); /* don't create */
        if (!main_window) {
                g_warning ("%s: password was wrong; ignoring because no main window", __FUNCTION__);
                return;
@@ -541,53 +543,10 @@ show_wrong_password_dialog (TnyAccount *account)
                        __FUNCTION__);
        }
        
-       /* Check whether this window is already open,
-        * for instance because of a previous get_password() call: 
-        */
-       gpointer dialog_as_gpointer = NULL;
-       gboolean found = FALSE;
-       if (priv->account_settings_dialog_hash) {
-               found = g_hash_table_lookup_extended (priv->account_settings_dialog_hash,
-                       modest_account_name, NULL, (gpointer*)&dialog_as_gpointer);
-       }
-       ModestAccountSettingsDialog *dialog = dialog_as_gpointer;
-                                       
-       gboolean created_dialog = FALSE;
-       if (!found || !dialog) {
-               ModestAccountSettings *settings;
-               dialog = modest_account_settings_dialog_new ();
-               settings = modest_account_mgr_load_account_settings (priv->account_mgr, modest_account_name);
-               modest_account_settings_dialog_set_account (dialog, settings);
-               g_object_unref (settings);
-               modest_account_settings_dialog_switch_to_user_info (dialog);
-               modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
-               
-               g_hash_table_insert (priv->account_settings_dialog_hash, g_strdup (modest_account_name), dialog);
-               
-               created_dialog = TRUE;
-       }
-       
+       dialog = modest_tny_account_store_show_account_settings_dialog (self, modest_account_name);
+       modest_account_settings_dialog_save_password (MODEST_ACCOUNT_SETTINGS_DIALOG (dialog));
        /* Show an explanatory temporary banner: */
        modest_platform_information_banner (GTK_WIDGET(dialog), NULL, _("mcen_ib_username_pw_incorrect"));
-               
-       if (created_dialog) {
-               /* Forget it when it closes: */
-               g_signal_connect_object (G_OBJECT (dialog), "hide", G_CALLBACK (on_account_settings_hide), 
-                       account, 0);
-                       
-               /* Show it and delete it when it closes: */
-               gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
-               g_signal_connect_swapped (dialog, 
-                                         "response", 
-                                         G_CALLBACK (gtk_widget_destroy), 
-                                         dialog);
-               gtk_widget_show (GTK_WIDGET (dialog));
-       }
-       else {
-               /* Just show it instead of showing it and deleting it when it closes,
-                * though it is probably open already: */
-               gtk_window_present (GTK_WINDOW (dialog));
-       }
 }
 #endif
 
@@ -1104,7 +1063,6 @@ modest_tny_account_store_alert (TnyAccountStore *self,
        case TNY_SERVICE_ERROR_UNAVAILABLE:
                /* You must be working online for this operation */
        case TNY_SERVICE_ERROR_CONNECT:
-               /* TODO: Show the appropriate message, depending on whether it's POP or IMAP: */                
                switch (proto) {
                case MODEST_PROTOCOL_STORE_POP:
                        prompt = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
@@ -1124,9 +1082,25 @@ modest_tny_account_store_alert (TnyAccountStore *self,
                break;
                
        case TNY_SERVICE_ERROR_AUTHENTICATE:
-               /* This is "Secure connection failed", even though the logical
-                * ID has _certificate_ in the name: */
-               prompt = g_strdup (_("mail_ni_ssl_certificate_error")); 
+               /* It seems that there's no better error to show with
+                * POP and IMAP because TNY_SERVICE_ERROR_AUTHENTICATE
+                * may appear if there's a timeout during auth */
+               switch (proto) {
+               case MODEST_PROTOCOL_STORE_POP:
+                       prompt = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
+                                                 server_name);
+                       break;
+               case MODEST_PROTOCOL_STORE_IMAP:
+                       prompt = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"),
+                                                 server_name);
+                       break;
+               case MODEST_PROTOCOL_TRANSPORT_SMTP:
+                       prompt = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"),
+                                                 server_name);
+                       break;
+               default:
+                       g_return_val_if_reached (FALSE);
+               }
                break;
                        
        case TNY_SERVICE_ERROR_CERTIFICATE:
@@ -1486,6 +1460,7 @@ modest_tny_account_store_get_mmc_folders_account (ModestTnyAccountStore *self)
 {
        g_return_val_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (self), NULL);
        
+       /* New reference */
        return modest_tny_account_store_get_tny_account_by (self, MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
                                                            MODEST_MMC_ACCOUNT_ID);
 
@@ -1513,6 +1488,35 @@ add_existing_accounts (ModestTnyAccountStore *self)
        modest_account_mgr_free_account_names (account_names);
 }
 
+static void 
+connection_status_changed (TnyAccount *account, 
+                          TnyConnectionStatus status, 
+                          gpointer data)
+{
+       if (status == TNY_CONNECTION_STATUS_CONNECTED) {
+               const gchar *account_name;
+               ModestWindow *main_window;
+               ModestTnyAccountStorePrivate *priv = NULL;
+               
+               priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (data);
+
+               /* Remove this handler */
+               priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers, 
+                                                                 G_OBJECT (account),
+                                                                 "connection_status_changed");
+
+               /* Set the username as succedded */
+               modest_account_mgr_set_server_account_username_has_succeeded (modest_runtime_get_account_mgr (), 
+                                                                             tny_account_get_id (account), 
+                                                                             TRUE);
+
+               /* Perform a send receive */
+               account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+               main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (), FALSE);
+               modest_ui_actions_do_send_receive (account_name, FALSE, FALSE, main_window);
+       }
+}
+
 static TnyAccount*
 create_tny_account (ModestTnyAccountStore *self,
                    const gchar *name,
@@ -1534,6 +1538,15 @@ create_tny_account (ModestTnyAccountStore *self,
                   we use a new account if any */
                modest_tny_account_store_forget_password_in_memory (self, 
                                                                    tny_account_get_id (account));
+
+               /* Install a signal handler that will refresh the
+                  account the first time it becomes online */
+               priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, 
+                                                              G_OBJECT (account), 
+                                                              "connection_status_changed",
+                                                              G_CALLBACK (connection_status_changed),
+                                                              self);
+
                /* Set the account store */                             
                g_object_set_data (G_OBJECT(account), "account_store", self);
        } else {
@@ -1675,6 +1688,15 @@ on_account_disconnect_when_removing (TnyCamelAccount *account,
        self = MODEST_TNY_ACCOUNT_STORE (user_data);
        priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self);
 
+       /* Remove the connection-status-changed handler if it's still there */
+       if (modest_signal_mgr_is_connected (priv->sighandlers, 
+                                           G_OBJECT (account),
+                                           "connection_status_changed")) {
+               priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers, 
+                                                                 G_OBJECT (account),
+                                                                 "connection_status_changed");
+       }
+
        /* Remove it from the list of accounts */
        if (TNY_IS_STORE_ACCOUNT (account))
                tny_list_remove (priv->store_accounts, (GObject *) account);
@@ -1688,6 +1710,9 @@ on_account_disconnect_when_removing (TnyCamelAccount *account,
        /* Unref the extra reference added by get_server_account */
        g_object_unref (account);
 
+       /* Cancel all pending operations */
+       tny_account_cancel (TNY_ACCOUNT (account));
+
        /* Clear the cache if it's an store account */
        if (TNY_IS_STORE_ACCOUNT (account))
                tny_store_account_delete_cache (TNY_STORE_ACCOUNT (account));
@@ -1900,7 +1925,49 @@ modest_tny_account_store_get_transport_account_from_outbox_header(ModestTnyAccou
                g_object_unref (account);
                tny_iterator_next (acc_iter);
        }
-
        g_object_unref(acc_iter);
+
+       /* New reference */
        return header_acc;
 }
+
+GtkWidget *
+modest_tny_account_store_show_account_settings_dialog (ModestTnyAccountStore *self,
+                                                     const gchar *account_name)
+{
+       ModestTnyAccountStorePrivate *priv;
+       gpointer dialog_as_gpointer = NULL;
+       gboolean found;
+
+       priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
+       found = g_hash_table_lookup_extended (priv->account_settings_dialog_hash,
+                                             account_name, NULL, (gpointer*)&dialog_as_gpointer);
+
+       if (found)
+               return (GtkWidget *) dialog_as_gpointer;
+       else {
+               ModestAccountSettings *settings;
+               GtkWidget *dialog;
+               dialog = (GtkWidget *) modest_account_settings_dialog_new ();
+               settings = modest_account_mgr_load_account_settings (priv->account_mgr, account_name);
+               modest_account_settings_dialog_set_account (MODEST_ACCOUNT_SETTINGS_DIALOG (dialog), settings);
+               g_object_unref (settings);
+               modest_account_settings_dialog_switch_to_user_info (MODEST_ACCOUNT_SETTINGS_DIALOG (dialog));
+               modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
+               
+               g_hash_table_insert (priv->account_settings_dialog_hash, g_strdup (account_name), dialog);
+               
+               g_signal_connect (G_OBJECT (dialog), "hide", G_CALLBACK (on_account_settings_hide), 
+                                 g_strdup (account_name));
+                       
+               /* Show it and delete it when it closes: */
+               g_signal_connect_swapped (dialog, 
+                                         "response", 
+                                         G_CALLBACK (gtk_widget_destroy), 
+                                         dialog);
+               gtk_widget_show (GTK_WIDGET (dialog));
+
+               return dialog;
+       }
+       
+}