Work to fix bug NB#81989:
[modest] / src / modest-tny-account-store.c
index 5d8307e..05f8fc2 100644 (file)
 #include <tny-gtk-lockable.h>
 #include <camel/camel.h>
 #include <modest-platform.h>
+#include "modest-ui-actions.h"
+#include <widgets/modest-account-settings-dialog.h>
 
 #ifdef MODEST_PLATFORM_MAEMO
 #include <tny-maemo-conic-device.h>
 #include <maemo/modest-maemo-utils.h>
-#include <maemo/modest-account-settings-dialog.h>
 #endif
 
 #include <libgnomevfs/gnome-vfs-volume-monitor.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,
@@ -121,9 +126,7 @@ typedef struct _ModestTnyAccountStorePrivate ModestTnyAccountStorePrivate;
 struct _ModestTnyAccountStorePrivate {
        gchar              *cache_dir;  
        GHashTable         *password_hash;
-#ifdef MODEST_PLATFORM_MAEMO
        GHashTable         *account_settings_dialog_hash;
-#endif
        ModestAccountMgr   *account_mgr;
        TnySessionCamel    *session;
        TnyDevice          *device;
@@ -271,12 +274,10 @@ modest_tny_account_store_instance_init (ModestTnyAccountStore *obj)
        priv->password_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                     g_free, g_free);
 
-#ifdef MODEST_PLATFORM_MAEMO                                                        
        /* A hash-map of modest account names to dialog pointers,
         * so we can avoid showing the account settings twice for the same modest account: */                                 
        priv->account_settings_dialog_hash = g_hash_table_new_full (g_str_hash, g_str_equal, 
                                                                    g_free, NULL);
-#endif
        
        /* Respond to volume mounts and unmounts, such 
         * as the insertion/removal of the memory card: */
@@ -475,7 +476,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);
@@ -487,7 +488,6 @@ on_account_changed (ModestAccountMgr *acc_mgr,
                g_object_unref (iter);
 }
 
-#ifdef MODEST_PLATFORM_MAEMO
 static void 
 on_account_settings_hide (GtkWidget *widget, gpointer user_data)
 {
@@ -499,7 +499,6 @@ on_account_settings_hide (GtkWidget *widget, gpointer user_data)
        if (account_name)
                g_hash_table_remove (priv->account_settings_dialog_hash, account_name);
 }
-#endif
 
 static void 
 show_password_warning_only ()
@@ -509,13 +508,12 @@ 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"));
 }
 
-#ifdef MODEST_PLATFORM_MAEMO
 static void 
 show_wrong_password_dialog (TnyAccount *account)
 { 
@@ -542,7 +540,6 @@ show_wrong_password_dialog (TnyAccount *account)
        /* Show an explanatory temporary banner: */
        modest_platform_information_banner (GTK_WIDGET(dialog), NULL, _("mcen_ib_username_pw_incorrect"));
 }
-#endif
 
 /* This callback will be called by Tinymail when it needs the password
  * from the user or the account settings.
@@ -624,9 +621,7 @@ get_password (TnyAccount *account, const gchar * prompt_not_used, gboolean *canc
                );
                if (settings_have_password) {
                        /* The password must be wrong, so show the account settings dialog so it can be corrected: */
-#ifdef MODEST_PLATFORM_MAEMO
                        show_wrong_password_dialog (account);
-#endif
                        
                        if (cancel)
                                *cancel = TRUE;
@@ -757,12 +752,10 @@ modest_tny_account_store_finalize (GObject *obj)
                priv->password_hash = NULL;
        }
 
-#ifdef MODEST_PLATFORM_MAEMO
        if (priv->account_settings_dialog_hash) {
                g_hash_table_destroy (priv->account_settings_dialog_hash);
                priv->account_settings_dialog_hash = NULL;
        }
-#endif
 
        if (priv->outbox_of_transport) {
                g_hash_table_destroy (priv->outbox_of_transport);
@@ -1057,7 +1050,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"),
@@ -1077,9 +1069,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:
@@ -1467,6 +1475,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, FALSE, main_window);
+       }
+}
+
 static TnyAccount*
 create_tny_account (ModestTnyAccountStore *self,
                    const gchar *name,
@@ -1488,6 +1525,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 {
@@ -1629,6 +1675,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);
@@ -1642,6 +1697,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));