2007-07-23 Murray Cumming <murrayc@murrayc.com>
[modest] / src / modest-tny-account.c
index ca2e6c8..c5fb06f 100644 (file)
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <modest-platform.h>
 #include <modest-tny-platform-factory.h>
 #include <modest-tny-account.h>
 #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>
@@ -74,16 +74,24 @@ modest_tny_account_get_special_folder (TnyAccount *account,
        if (special_type == TNY_FOLDER_TYPE_OUTBOX) {
                const gchar *modest_account_name = 
                        modest_tny_account_get_parent_modest_account_name_for_server_account (account);
-               g_assert (modest_account_name);
-
-               gchar *account_id = g_strdup_printf (
-                       MODEST_PER_ACCOUNT_LOCAL_OUTBOX_FOLDER_ACCOUNT_ID_PREFIX "%s", 
-                       modest_account_name);
                
-               local_account = modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store(),
-                                                                            MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
-                                                                            account_id);
-               g_free (account_id);
+               if (modest_account_name) {
+                       gchar *account_id = g_strdup_printf (
+                               MODEST_PER_ACCOUNT_LOCAL_OUTBOX_FOLDER_ACCOUNT_ID_PREFIX "%s", 
+                               modest_account_name);
+                       
+                       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 {
+                       g_warning ("%s: modest_account_name was NULL.", __FUNCTION);
+               }
        } else {
                /* Other local folders are all in one on-disk directory: */
                local_account = modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store(),
@@ -100,9 +108,22 @@ 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. */ 
+       GError *error = NULL;
        tny_folder_store_get_folders (TNY_FOLDER_STORE (local_account),
-                                     folders, NULL, NULL);
+                                     folders, NULL, &error);
+       if (error) {
+               g_warning ("%s: tny_folder_store_get_folders() failed:\n  error=%s\n", 
+                       __FUNCTION__, error->message);
+       }
+                                     
+       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)) {
@@ -110,7 +131,7 @@ modest_tny_account_get_special_folder (TnyAccount *account,
                        TNY_FOLDER (tny_iterator_get_current (iter));
                if (modest_tny_folder_get_local_folder_type (folder) == special_type) {
                        special_folder = folder;
-                       break;
+                       break; /* Leaving a ref for the special_folder return value. */
                }
                
                g_object_unref (G_OBJECT(folder));
@@ -121,55 +142,13 @@ modest_tny_account_get_special_folder (TnyAccount *account,
        g_object_unref (G_OBJECT (iter));
        g_object_unref (G_OBJECT (local_account));
 
-       return special_folder;
-}
-
-typedef struct
-{
-       GSourceFunc func;
-       GMainLoop* loop;
-} UtilIdleData;
-
-static gboolean util_on_idle(gpointer user_data)
-{
-       /* We are now in the main thread, 
-        * so we can call the function:
-        */
-       UtilIdleData *idle_data = (UtilIdleData*)user_data;
-       if (idle_data && idle_data->func)
-               (*(idle_data->func))(NULL);
-
-       /* Stop the main loop so that the caller can continue: */
-       if (idle_data->loop)
-               g_main_loop_quit (idle_data->loop);
-
-       return FALSE; /* Stop calling this callback. */
-}
-
-static void
-util_run_in_main_thread_and_wait(GSourceFunc function)
-{
-       UtilIdleData *data = g_slice_new0 (UtilIdleData);
-       data->func = function;
-       data->loop = g_main_loop_new (NULL, FALSE /* not running */);
+       /*
+       if (!special_folder) {
+               g_warning ("%s: Returning NULL.", __FUNCTION__);        
+       }
+       */
        
-       /* Cause the function to be run in an idle-handler, which is always 
-        * in the main thread:
-        */
-       g_idle_add (util_on_idle, &data);
-
-       /* This main loop will run until the idle handler has stopped it: */
-       g_main_loop_run (data->loop);
-       g_main_loop_unref (data->loop);
-
-       g_slice_free (UtilIdleData, data);
-}
-
-static gboolean 
-connect_and_wait(gpointer user_data)
-{
-       modest_platform_connect_and_wait(NULL);
-       return TRUE; /* Ignored */
+       return special_folder;
 }
 
 static void
@@ -178,16 +157,23 @@ on_connection_status_changed (TnyAccount *account, TnyConnectionStatus status, g
        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,
+               /* A tinymail network operation failed, and tinymail then noticed that 
+                * the account is offline, because our TnyDevice is offline,
                 * because libconic says we are offline.
-                * So ask the user to go online:
+                * So ask the user to go online again.
+                * 
+                * Note that this signal will not be emitted if the account was offline 
+                * when the network operation was first attempted. For those cases, 
+                * the application must do its own explicit checks.
                 *
                 * We make sure that this UI is shown in the main thread, to avoid races,
                 * because tinymail does not guarantee that this signal handler will be called 
                 * in the main thread.
                 */
-               util_run_in_main_thread_and_wait (&connect_and_wait);
+               /* TODO: Commented out, because this causes hangs, probably related to 
+                * our use of mainloops:
+                * modest_platform_connect_and_wait (NULL);
+                */
        } else if (status == TNY_CONNECTION_STATUS_CONNECTED_BROKEN) {
                printf ("DEBUG: %s: Connection broken. Forcing TnyDevice offline.\n", 
                        __FUNCTION__);
@@ -199,8 +185,13 @@ on_connection_status_changed (TnyAccount *account, TnyConnectionStatus status, g
                 * When libconic reconnects, it will set the device back online again,
                 * regardless of it being forced offline before.
                 */
+               /* TODO: Find out when this is falsely being emitted. */
+               printf ("  DEBUG: %s: Not forcing offline because tinymail is sometimes reporting false connection breaks.\n", 
+                       __FUNCTION__);
+               /*
                TnyDevice *device = modest_runtime_get_device ();
                tny_device_force_offline (device);
+               */
        }
 }
 
@@ -497,19 +488,20 @@ modest_tny_account_new_from_account (ModestAccountMgr *account_mgr, const gchar
                modest_account_mgr_free_account_data (account_mgr, account_data);
                return NULL;
        }
-       
+
+
+       /* This name is what shows up in the folder view -- so for some POP/IMAP/... server
+        * account, we set its name to the account of which it is part. */
+       if (account_data->display_name)
+               tny_account_set_name (tny_account, account_data->display_name);
+
        tny_account_set_forget_pass_func (tny_account,
                                          forget_pass_func ? forget_pass_func : forget_pass_dummy);
        tny_account_set_pass_func (tny_account,
                                   get_pass_func ? get_pass_func: get_pass_dummy);
        
 
-        /* This name is what shows up in the folder view -- so for some POP/IMAP/... server
-       *  account, we set its name to the account of which it is part. */
-
-        if (account_data->display_name)
-                tny_account_set_name (tny_account, account_data->display_name);
-
         modest_tny_account_set_parent_modest_account_name_for_server_account (tny_account, account_name);
 
         modest_account_mgr_free_account_data (account_mgr, account_data);
@@ -741,6 +733,8 @@ modest_tny_account_new_for_per_account_local_outbox_folder (ModestAccountMgr *ac
                return NULL;
        }
        
+       printf ("DEBUG: %s: Setting session for account: session=%p\n", 
+               __FUNCTION__, session);
        tny_camel_account_set_session (TNY_CAMEL_ACCOUNT(tny_account), session);
        
        /* Make sure that the paths exists on-disk so that TnyCamelStoreAccount can 
@@ -791,9 +785,12 @@ modest_tny_account_new_for_per_account_local_outbox_folder (ModestAccountMgr *ac
 
 
 typedef gint (*TnyStatsFunc) (TnyFolderStats *stats);
+#define TASK_GET_ALL_COUNT     0
+#define TASK_GET_LOCAL_SIZE    1
+#define TASK_GET_FOLDER_COUNT  2
 
 typedef struct _RecurseFoldersHelper {
-       TnyStatsFunc function;
+       gint task;
        guint sum;
        guint folders;
 } RecurseFoldersHelper;
@@ -812,22 +809,19 @@ recurse_folders (TnyFolderStore *store,
        helper->folders += tny_list_get_length (folders);
 
        while (!tny_iterator_is_done (iter)) {
-               TnyFolderStats *stats;
                TnyFolder *folder;
 
                folder = TNY_FOLDER (tny_iterator_get_current (iter));
-               stats = tny_folder_get_stats (folder);
 
-               if (stats) {
-                       /* initially, we sometimes get -1 from tinymail; ignore that */
-                       if (helper->function && helper->function (stats) > 0)
-                               helper->sum += helper->function (stats);
+               if (helper->task == TASK_GET_ALL_COUNT)
+                       helper->sum += tny_folder_get_all_count (folder);
+
+               if (helper->task == TASK_GET_LOCAL_SIZE)
+                       helper->sum += tny_folder_get_local_size (folder);
+
+               if (TNY_IS_FOLDER_STORE (folder))
+                       recurse_folders (TNY_FOLDER_STORE (folder), query, helper);
 
-                       if (TNY_IS_FOLDER_STORE (folder)) {
-                               recurse_folders (TNY_FOLDER_STORE (folder), query, helper);
-                       }
-                       g_object_unref (stats);
-               }    
                g_object_unref (folder);
                tny_iterator_next (iter);
        }
@@ -845,7 +839,7 @@ modest_tny_folder_store_get_folder_count (TnyFolderStore *self)
 
        /* Create helper */
        helper = g_malloc0 (sizeof (RecurseFoldersHelper));
-       helper->function = NULL;
+       helper->task = TASK_GET_FOLDER_COUNT;
        helper->sum = 0;
        helper->folders = 0;
 
@@ -868,7 +862,7 @@ modest_tny_folder_store_get_message_count (TnyFolderStore *self)
        
        /* Create helper */
        helper = g_malloc0 (sizeof (RecurseFoldersHelper));
-       helper->function = (TnyStatsFunc) tny_folder_stats_get_all_count;
+       helper->task = TASK_GET_ALL_COUNT;
        helper->sum = 0;
 
        recurse_folders (self, NULL, helper);
@@ -890,7 +884,7 @@ modest_tny_folder_store_get_local_size (TnyFolderStore *self)
 
        /* Create helper */
        helper = g_malloc0 (sizeof (RecurseFoldersHelper));
-       helper->function = (TnyStatsFunc) tny_folder_stats_get_local_size;
+       helper->task = TASK_GET_LOCAL_SIZE;
        helper->sum = 0;
 
        recurse_folders (self, NULL, helper);