* fix for compile breakage
[modest] / src / modest-mail-operation.c
index 6eff5c8..0237ad9 100644 (file)
@@ -56,14 +56,6 @@ static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
 static void modest_mail_operation_init       (ModestMailOperation *obj);
 static void modest_mail_operation_finalize   (GObject *obj);
 
-static void     update_folders_cb    (TnyFolderStore *self, 
-                                     TnyList *list, 
-                                     GError **err, 
-                                     gpointer user_data);
-static void     update_folders_status_cb (GObject *obj,
-                                         TnyStatus *status,  
-                                         gpointer user_data);
-
 static void     update_process_msg_status_cb (GObject *obj,
                                              TnyStatus *status,  
                                              gpointer user_data);
@@ -399,6 +391,13 @@ cleanup:
                g_object_unref (G_OBJECT(folder));
 }
 
+typedef struct 
+{
+       ModestMailOperation *mail_op;
+       TnyStoreAccount *account;
+       TnyTransportAccount *transport_account;
+} UpdateAccountInfo;
+
 static void
 recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
 {
@@ -413,9 +412,7 @@ recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all
                TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
 
                tny_list_prepend (all_folders, G_OBJECT (folder));
-
-               recurse_folders (folder, query, all_folders);
-           
+               recurse_folders (folder, query, all_folders);    
                g_object_unref (G_OBJECT (folder));
 
                tny_iterator_next (iter);
@@ -424,69 +421,83 @@ recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all
         g_object_unref (G_OBJECT (folders));
 }
 
-static void
-update_folders_status_cb (GObject *obj,
-                         TnyStatus *status,  
-                         gpointer user_data)
+/* 
+ * Used by update_account_thread to emit the signal from the main
+ * loop. We call it inside an idle call to achieve that 
+ */
+static gboolean
+notify_update_account_observers (gpointer data)
 {
-       ModestMailOperation *self;
-       ModestMailOperationPrivate *priv;
+       ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
 
-       g_return_if_fail (status != NULL);
-       g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
+       g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
 
-       /* Temporary FIX: useful when tinymail send us status
-          information *after* calling the function callback */
-       if (!MODEST_IS_MAIL_OPERATION (user_data))
-               return;
-
-       self = MODEST_MAIL_OPERATION (user_data);
-       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+       return TRUE;
+}
 
-       if ((status->position == 1) && (status->of_total == 100))
-               return;
+/* 
+ * Used by update_account_thread to notify the queue from the main
+ * loop. We call it inside an idle call to achieve that
+ */
+static gboolean
+notify_update_account_queue (gpointer data)
+{
+       ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
 
-       priv->done = status->position;
-       priv->total = status->of_total;
+       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), 
+                                           mail_op);
+       g_object_unref (mail_op);
 
-       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
+       return FALSE;
 }
 
-static void
-update_folders_cb (TnyFolderStore *folder_store, TnyList *list, GError **err, gpointer user_data)
+static gpointer
+update_account_thread (gpointer thr_user_data)
 {
-       ModestMailOperation *self;
+       UpdateAccountInfo *info;
+       TnyList *all_folders = NULL;
+       TnyIterator *iter = NULL;
+       TnyFolderStoreQuery *query = NULL;
        ModestMailOperationPrivate *priv;
-       TnyIterator *iter;
-       TnyList *all_folders;
-       
-       self  = MODEST_MAIL_OPERATION (user_data);
-       priv  = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+       ModestTnySendQueue *send_queue;
+       gint timeout;
 
-       /* g_message (__FUNCTION__); */
-       
-       if (*err) {
-               priv->error = g_error_copy (*err);
+       info = (UpdateAccountInfo *) thr_user_data;
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
+
+       /* Get all the folders We can do it synchronously because
+          we're already running in a different thread than the UI */
+       all_folders = tny_simple_list_new ();
+       query = tny_folder_store_query_new ();
+       tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
+       tny_folder_store_get_folders (TNY_FOLDER_STORE (info->account),
+                                     all_folders,
+                                     query,
+                                     &(priv->error));
+       if (priv->error) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                goto out;
        }
 
-       /* Get all the folders We can do it synchronously because
-          we're already running in a different thread than the UI */
-       all_folders = tny_list_copy (list);
        iter = tny_list_create_iterator (all_folders);
        while (!tny_iterator_is_done (iter)) {
                TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
 
-               recurse_folders (folder, NULL, all_folders);
+               recurse_folders (folder, query, all_folders);
                tny_iterator_next (iter);
        }
        g_object_unref (G_OBJECT (iter));
 
+       /* Update status and notify. We need to call the notification
+          with a source functopm in order to call it from the main
+          loop. We need that in order not to get into trouble with
+          Gtk+. We use a timeout in order to provide more status
+          information, because the sync tinymail call does not
+          provide it for the moment */
+       timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
+
        /* Refresh folders */
        iter = tny_list_create_iterator (all_folders);
-       priv->total = tny_list_get_length (all_folders);
-
        while (!tny_iterator_is_done (iter) && !priv->error) {
 
                TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
@@ -496,59 +507,114 @@ update_folders_cb (TnyFolderStore *folder_store, TnyList *list, GError **err, gp
 
                if (priv->error) {
                        priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               } else {        
-                       /* Update status and notify */
-                       priv->done++;
-                       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
                }
-    
+
                g_object_unref (G_OBJECT (folder));
-           
                tny_iterator_next (iter);
        }
-
        g_object_unref (G_OBJECT (iter));
- out:
-       g_object_unref (G_OBJECT (list));
+       g_source_remove (timeout);
 
+       /* Perform send */
+       priv->id = MODEST_MAIL_OPERATION_ID_SEND;
+
+       send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(info->transport_account));
+
+       timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
+       modest_tny_send_queue_flush (send_queue);
+       g_source_remove (timeout);
+
+       g_object_unref (G_OBJECT(send_queue));
+       
        /* Check if the operation was a success */
-       if (priv->done == priv->total && !priv->error)
+       if (!priv->error) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
 
-       /* Free */
-       g_object_unref (G_OBJECT (folder_store));
+               /* Update the last updated key */
+               modest_account_mgr_set_int (modest_runtime_get_account_mgr (), 
+                                           tny_account_get_id (TNY_ACCOUNT (info->account)), 
+                                           MODEST_ACCOUNT_LAST_UPDATED, 
+                                           time(NULL), 
+                                           TRUE);
+       }
 
+ out:
        /* Notify the queue */
-       modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
+       g_idle_add (notify_update_account_queue, g_object_ref (info->mail_op));
+
+       /* Frees */
+       g_object_unref (query);
+       g_object_unref (all_folders);
+       g_object_unref (info->mail_op);
+       g_object_unref (info->account);
+       g_object_unref (info->transport_account);
+       g_slice_free (UpdateAccountInfo, info);
+
+       return NULL;
 }
 
 gboolean
 modest_mail_operation_update_account (ModestMailOperation *self,
-                                     TnyStoreAccount *store_account)
+                                     const gchar *account_name)
 {
+       GThread *thread;
+       UpdateAccountInfo *info;
        ModestMailOperationPrivate *priv;
-       TnyList *folders;
+       TnyStoreAccount *modest_account;
+       TnyTransportAccount *transport_account;
+       gchar *modest_acc_name;
 
        g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
-       g_return_val_if_fail (TNY_IS_STORE_ACCOUNT(store_account), FALSE);
-
-       /* Pick async call reference */
-       g_object_ref (store_account);
+       g_return_val_if_fail (account_name, FALSE);
 
+       /* Init mail operation. Set total and done to 0, and do not
+          update them, this way the progress objects will know that
+          we have no clue about the number of the objects */
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
-
        priv->total = 0;
        priv->done  = 0;
        priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
        
-       /* Get subscribed folders & refresh them */
-       folders = TNY_LIST (tny_simple_list_new ());
+       /* Get the Modest account */
+       modest_account = (TnyStoreAccount *)
+               modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
+                                                                    account_name,
+                                                                    TNY_ACCOUNT_TYPE_STORE);
+
+       if (!modest_account) {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                            MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
+                            "cannot get tny store account for %s\n", account_name);
+               modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), 
+                                                   self);
+               return FALSE;
+       }
+
+       /* Get the transport account, we can not do it in the thread
+          due to some problems with dbus */
+       modest_acc_name = (gchar *) g_object_get_data (G_OBJECT (modest_account), "modest_account");
+       transport_account = (TnyTransportAccount *)
+               modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
+                                                                                   modest_acc_name);
+       if (!transport_account) {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                            MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
+                            "cannot get tny transport account for %s\n", modest_acc_name);
+               modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), 
+                                                   self);
+               return FALSE;
+       }
+
+       /* Create the helper object */
+       info = g_slice_new (UpdateAccountInfo);
+       info->mail_op = g_object_ref (self);
+       info->account = modest_account;
+       info->transport_account = transport_account;
+
+       thread = g_thread_create (update_account_thread, info, FALSE, NULL);
 
-       /* g_message ("tny_folder_store_get_folders_async"); */
-       tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
-                                           folders, update_folders_cb, NULL, 
-                                           update_folders_status_cb, self);
-       
        return TRUE;
 }
 
@@ -814,7 +880,7 @@ transfer_folder_status_cb (GObject *obj,
 
 
 static void
-transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, const gchar *new_name, gboolean cancelled, GError **err, gpointer user_data)
+transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
 {
        XFerFolderAsyncHelper *helper = NULL;
        ModestMailOperation *self = NULL;
@@ -844,6 +910,7 @@ transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, const gchar *new_na
        g_slice_free   (XFerFolderAsyncHelper, helper);
        g_object_unref (folder);
        g_object_unref (into);
+       g_object_unref (new_folder);
 
        /* Notify the queue */
        modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
@@ -1267,9 +1334,9 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer
        }
 
        /* Free */
-       g_object_unref (helper->headers);
-       g_object_unref (helper->dest_folder);
-       g_object_unref (helper->mail_op);
+/*     g_object_unref (helper->headers); */
+/*     g_object_unref (helper->dest_folder); */
+/*     g_object_unref (helper->mail_op); */
        g_slice_free   (XFerMsgAsyncHelper, helper);
        g_object_unref (folder);
 
@@ -1303,15 +1370,15 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
 
        /* Create the helper */
        helper = g_slice_new0 (XFerMsgAsyncHelper);
-       helper->mail_op = g_object_ref(self);
-       helper->dest_folder = folder;
-       helper->headers = headers;
+       helper->mail_op = self;
+       helper->dest_folder = g_object_ref(folder);
+       helper->headers = g_object_ref(headers);
 
        /* Get source folder */
        iter = tny_list_create_iterator (headers);
        header = TNY_HEADER (tny_iterator_get_current (iter));
        src_folder = tny_header_get_folder (header);
-/*     g_object_unref (header); */
+       g_object_unref (header);
        g_object_unref (iter);
 
        /* Transfer messages */
@@ -1320,7 +1387,7 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
                                        folder, 
                                        delete_original, 
                                        transfer_msgs_cb, 
-                                       transfer_msgs_status_cb, 
+                                       transfer_msgs_status_cb,
                                        helper);
 }