2007-07-03 Murray Cumming <murrayc@murrayc.com>
[modest] / src / modest-tny-account.c
index 61e61c5..8b750e3 100644 (file)
@@ -32,6 +32,7 @@
 #include <modest-tny-account-store.h>
 #include <modest-tny-local-folders-account.h>
 #include <modest-runtime.h>
+#include <modest-platform.h>
 #include <tny-simple-list.h>
 #include <modest-tny-folder.h>
 #include <modest-tny-outbox-account.h>
@@ -82,6 +83,11 @@ modest_tny_account_get_special_folder (TnyAccount *account,
                local_account = modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store(),
                                                                             MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
                                                                             account_id);
+               if (!local_account) {
+                       g_printerr ("modest: %s: modest_tny_account_store_get_tny_account_by(ID) returned NULL for %s\n", __FUNCTION__, account_id);
+               return NULL;
+               }
+       
                g_free (account_id);
        } else {
                /* Other local folders are all in one on-disk directory: */
@@ -99,9 +105,17 @@ modest_tny_account_get_special_folder (TnyAccount *account,
 
        /* There is no need to do this _async, as these are local folders. */
        /* TODO: However, this seems to fail sometimes when the network is busy, 
-        * returning an empty list. murrayc. */
+        * returning an empty list. murrayc. */ 
        tny_folder_store_get_folders (TNY_FOLDER_STORE (local_account),
                                      folders, NULL, NULL);
+                                     
+       if (tny_list_get_length (folders) == 0) {
+               gchar* url_string = tny_account_get_url_string (local_account);
+               g_printerr ("modest: %s: tny_folder_store_get_folders() returned an empty list for account with URL '%s'\n", 
+                       __FUNCTION__, url_string);
+               g_free (url_string);
+       }
+       
        iter = tny_list_create_iterator (folders);
 
        while (!tny_iterator_is_done (iter)) {
@@ -120,9 +134,43 @@ modest_tny_account_get_special_folder (TnyAccount *account,
        g_object_unref (G_OBJECT (iter));
        g_object_unref (G_OBJECT (local_account));
 
+       /*
+       if (!special_folder) {
+               g_warning ("%s: Returning NULL.", __FUNCTION__);        
+       }
+       */
+       
        return special_folder;
 }
 
+static void
+on_connection_status_changed (TnyAccount *account, TnyConnectionStatus status, gpointer user_data)
+{
+       printf ("DEBUG: %s: status=%d\n", __FUNCTION__, status);
+       
+       if (status == TNY_CONNECTION_STATUS_DISCONNECTED) {
+               /* We are trying to use the network with an account, 
+                * but the accounts are set as offline, because our TnyDevice is offline,
+                * because libconic says we are offline.
+                * So ask the user to go online:
+                */
+               modest_platform_connect_and_wait(NULL); 
+       } else if (status == TNY_CONNECTION_STATUS_CONNECTED_BROKEN) {
+               printf ("DEBUG: %s: Connection broken. Forcing TnyDevice offline.\n", 
+                       __FUNCTION__);
+                       
+               /* Something went wrong during some network operation.
+                * Stop trying to use the network now,
+                * by forcing accounts into offline mode:
+                * 
+                * When libconic reconnects, it will set the device back online again,
+                * regardless of it being forced offline before.
+                */
+               TnyDevice *device = modest_runtime_get_device ();
+               tny_device_force_offline (device);
+       }
+}
+
 /* Camel options: */
 
 /* These seem to be listed in 
@@ -166,7 +214,8 @@ modest_tny_account_get_special_folder (TnyAccount *account,
 /**
  * modest_tny_account_new_from_server_account:
  * @account_mgr: a valid account mgr instance
- * @account_name: the server account name for which to create a corresponding tny account
+ * @session: A valid TnySessionCamel instance.
+ * @account_data: the server account for which to create a corresponding tny account
  * @type: the type of account to create (TNY_ACCOUNT_TYPE_STORE or TNY_ACCOUNT_TYPE_TRANSPORT)
  * 
  * get a tnyaccount corresponding to the server_accounts (store or transport) for this account.
@@ -176,11 +225,13 @@ modest_tny_account_get_special_folder (TnyAccount *account,
  */
 static TnyAccount*
 modest_tny_account_new_from_server_account (ModestAccountMgr *account_mgr,
+                                           TnySessionCamel *session,
                                            ModestServerAccountData *account_data)
 {
        gchar *url = NULL;
 
        g_return_val_if_fail (account_mgr, NULL);
+       g_return_val_if_fail (session, NULL);
        g_return_val_if_fail (account_data, NULL);
 
        /* sanity checks */
@@ -216,6 +267,14 @@ modest_tny_account_new_from_server_account (ModestAccountMgr *account_mgr,
        }
        tny_account_set_id (tny_account, account_data->account_name);
 
+       /* This must be set quite early, or other set() functions will fail. */
+    tny_camel_account_set_session (TNY_CAMEL_ACCOUNT (tny_account), session);
+    
+       /* Handle connection requests:
+        * This (badly-named) signal will be called when we try to use an offline account. */
+       g_signal_connect (G_OBJECT (tny_account), "connection-status-changed",
+                       G_CALLBACK (on_connection_status_changed), NULL);
+
        /* Proto */
        const gchar* proto_name =
                modest_protocol_info_get_transport_store_protocol_name(account_data->proto);
@@ -335,7 +394,8 @@ modest_tny_account_new_from_server_account (ModestAccountMgr *account_mgr,
 
 TnyAccount*
 modest_tny_account_new_from_server_account_name (ModestAccountMgr *account_mgr,
-                                           const gchar *server_account_name)
+                                               TnySessionCamel *session,
+                                               const gchar *server_account_name)
 {
        ModestServerAccountData *account_data = 
                modest_account_mgr_get_server_account_data (account_mgr, 
@@ -344,7 +404,7 @@ modest_tny_account_new_from_server_account_name (ModestAccountMgr *account_mgr,
                return NULL;
 
        TnyAccount *result = modest_tny_account_new_from_server_account (
-               account_mgr, account_data);
+               account_mgr, session, account_data);
 
        modest_account_mgr_free_server_account_data (account_mgr, account_data);
        
@@ -377,6 +437,7 @@ modest_tny_account_new_from_account (ModestAccountMgr *account_mgr, const gchar
 
        g_return_val_if_fail (account_mgr, NULL);
        g_return_val_if_fail (account_name, NULL);
+       g_return_val_if_fail (session, NULL);
 
        account_data = modest_account_mgr_get_account_data (account_mgr, account_name);
        if (!account_data) {
@@ -396,7 +457,7 @@ modest_tny_account_new_from_account (ModestAccountMgr *account_mgr, const gchar
                return NULL;
        }
        
-       tny_account = modest_tny_account_new_from_server_account (account_mgr, server_data);
+       tny_account = modest_tny_account_new_from_server_account (account_mgr, session, server_data);
        if (!tny_account) { 
                g_printerr ("modest: failed to create tny account for %s (%s)\n",
                            account_data->account_name, server_data->account_name);
@@ -404,7 +465,6 @@ modest_tny_account_new_from_account (ModestAccountMgr *account_mgr, const gchar
                return NULL;
        }
        
-       tny_camel_account_set_session (TNY_CAMEL_ACCOUNT(tny_account), session);
        tny_account_set_forget_pass_func (tny_account,
                                          forget_pass_func ? forget_pass_func : forget_pass_dummy);
        tny_account_set_pass_func (tny_account,
@@ -448,6 +508,9 @@ typedef struct
        gpointer user_data;
 } GetMmcAccountNameData;
 
+
+
+
 /* Gets the memory card name: */
 static void 
 on_modest_file_system_info(HildonFileSystemInfoHandle *handle,
@@ -460,30 +523,23 @@ on_modest_file_system_info(HildonFileSystemInfoHandle *handle,
                g_warning ("%s: error=%s", __FUNCTION__, error->message);
        }
        
-       if (error) {
-/*             printf ("  DEBUG: %s: error=%s\n", __FUNCTION__, error->message); */
-       }
+       TnyAccount *account = TNY_ACCOUNT (callback_data->account);
+       
+       const gchar *previous_display_name = NULL;
        
        const gchar *display_name = NULL;
        if (!error && info) {
                display_name = hildon_file_system_info_get_display_name(info);
+               previous_display_name = tny_account_get_name (account);
        }
-       
-       TnyAccount *account = TNY_ACCOUNT (callback_data->account);
-       
-       const gchar * previous_display_name = tny_account_get_name (account);
-       
-       /* Use the new name if it is different: */
-       if (display_name && 
-               (previous_display_name && (strcmp (display_name, previous_display_name) != 0))) {
-               /* printf ("DEBUG: %s: display name=%s\n", __FUNCTION__,  display_name); */
-               tny_account_set_name (account, display_name);
+                
+       /* printf ("DEBUG: %s: display name=%s\n", __FUNCTION__,  display_name); */
+       tny_account_set_name (account, display_name);
                
-               /* Inform the application that the name is now ready: */
-               if (callback_data->callback)
-                       (*(callback_data->callback)) (callback_data->account, 
-                               callback_data->user_data);
-       }
+       /* Inform the application that the name is now ready: */
+       if (callback_data->callback)
+               (*(callback_data->callback)) (callback_data->account, 
+                       callback_data->user_data);
        
        g_object_unref (callback_data->account);
        g_slice_free (GetMmcAccountNameData, callback_data);
@@ -491,31 +547,54 @@ on_modest_file_system_info(HildonFileSystemInfoHandle *handle,
 
 void modest_tny_account_get_mmc_account_name (TnyStoreAccount* self, ModestTnyAccountGetMmcAccountNameCallback callback, gpointer user_data)
 {
+       /* Just use the hard-coded path for the single memory card,
+        * rather than try to figure out the path to the specific card by 
+        * looking at the maildir URI:
+        */
+       const gchar *uri_real = MODEST_MCC1_VOLUMEPATH_URI;
+
+       /*
        gchar* uri = tny_account_get_url_string (TNY_ACCOUNT (self));
        if (!uri)
                return;
+
+       TODO: This gets the name of the folder, but we want the name of the volume.
+       gchar *uri_real = NULL;
+       const gchar* prefix = "maildir://localhost/";
+       if ((strstr (uri, prefix) == uri) && (strlen(uri) > strlen(prefix)) )
+               uri_real = g_strconcat ("file:///", uri + strlen (prefix), NULL);
+       */
+
+       if (uri_real) {
+               //This is freed in the callback:
+               GetMmcAccountNameData * callback_data = g_slice_new0(GetMmcAccountNameData);
+               callback_data->account = self;
+               g_object_ref (callback_data->account); /* Unrefed when we destroy the struct. */
+               callback_data->callback = callback;
+               callback_data->user_data = user_data;
                
-       //This is freed in the callback:
-       GetMmcAccountNameData * callback_data = g_slice_new0(GetMmcAccountNameData);
-       callback_data->account = self;
-       g_object_ref (callback_data->account); /* Unrefed when we destroy the struct. */
-       callback_data->user_data = user_data;
-               
-       /* TODO: gnome_vfs_volume_get_display_name() does not return 
-        * the same string. But why not? Why does hildon needs its own 
-        * function for this?
-        */
-       hildon_file_system_info_async_new(uri, 
-               on_modest_file_system_info, callback_data /* user_data */);
+               /* TODO: gnome_vfs_volume_get_display_name() does not return 
+                * the same string. But why not? Why does hildon needs its own 
+                * function for this?
+                */
+               /* printf ("DEBUG: %s Calling hildon_file_system_info_async_new() with URI=%s\n", __FUNCTION__, uri_real); */
+               hildon_file_system_info_async_new(uri_real, 
+                       on_modest_file_system_info, callback_data /* user_data */);
 
-       g_free (uri);
+               /* g_free (uri_real); */
+       }
+
+       /* g_free (uri); */
 }
 
                                
 
 TnyAccount*
-modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySessionCamel *session, const gchar* location_filepath)
+modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySessionCamel *session,
+                                         const gchar* location_filepath)
 {
+
+       
        /* Make sure that the directories exist: */
        modest_init_local_folders (location_filepath);
 
@@ -524,6 +603,8 @@ modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySess
        gchar *maildir, *url_string;
 
        g_return_val_if_fail (account_mgr, NULL);
+       g_return_val_if_fail (session, NULL);
+
        
        if (!location_filepath) {
                /* A NULL filepath means that this is the special local-folders maildir 
@@ -609,10 +690,13 @@ modest_tny_account_new_for_local_folders (ModestAccountMgr *account_mgr, TnySess
 
 
 TnyAccount*
-modest_tny_account_new_for_per_account_local_outbox_folder (ModestAccountMgr *account_mgr, const gchar* account_name, TnySessionCamel *session)
+modest_tny_account_new_for_per_account_local_outbox_folder (ModestAccountMgr *account_mgr,
+                                                           const gchar* account_name,
+                                                           TnySessionCamel *session)
 {
        g_return_val_if_fail (account_mgr, NULL);
        g_return_val_if_fail (account_name, NULL);
+       g_return_val_if_fail (session, NULL);
        
        /* Notice that we create a ModestTnyOutboxAccount here, 
         * instead of just a TnyCamelStoreAccount,