GError *err,
gpointer user_data);
+static gboolean _check_memory_low (ModestMailOperation *mail_op);
+
enum _ModestMailOperationSignals
{
PROGRESS_CHANGED_SIGNAL,
TRUE);
/* Cancel the sending of the following next messages */
- tny_send_queue_cancel (TNY_SEND_QUEUE (queue), TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, NULL);
+ if (TNY_IS_SEND_QUEUE (queue))
+ tny_send_queue_cancel (TNY_SEND_QUEUE (queue), TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, NULL);
}
return canceled;
CreateMsgInfo *info = (CreateMsgInfo *) thread_data;
TnyMsg *new_msg = NULL;
ModestMailOperationPrivate *priv;
+ gint attached = 0;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
if (info->html_body == NULL) {
new_msg = modest_tny_msg_new (info->to, info->from, info->cc,
info->bcc, info->subject, info->plain_body,
- info->attachments_list,
+ info->attachments_list, &attached,
&(priv->error));
} else {
new_msg = modest_tny_msg_new_html_plain (info->to, info->from, info->cc,
info->bcc, info->subject, info->html_body,
info->plain_body, info->attachments_list,
- info->images_list,
+ info->images_list, &attached,
&(priv->error));
}
tny_header_set_flag (header, info->priority_flags);
/* Set attachment flags in message */
- if (info->attachments_list != NULL)
+ if (info->attachments_list != NULL && attached > 0)
tny_header_set_flag (header, TNY_HEADER_FLAG_ATTACHMENTS);
g_object_unref (G_OBJECT(header));
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
mgr = modest_runtime_get_account_mgr ();
+ /* Set the last updated as the current time, do it even if the inbox refresh failed */
+ modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
+
if (canceled || err) {
priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
if (err)
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
"canceled");
+
/* Notify the user about the error and then exit */
update_account_notify_user_and_free (info, NULL);
return;
g_object_unref (info->inbox_observer);
info->inbox_observer = NULL;
- /* Update the last updated key, even if we don't have to get new headers */
- modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
-
if (new_headers_array->len == 0)
goto send_mail;
send_queue = modest_runtime_get_send_queue (transport_account, TRUE);
g_object_unref (transport_account);
- /* Get outbox folder */
- outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (send_queue));
- if (outbox) { /* this could fail in some cases */
- num_messages = tny_folder_get_all_count (outbox);
- g_object_unref (outbox);
- } else {
- g_warning ("%s: could not get outbox", __FUNCTION__);
- num_messages = 0;
- }
+ if (TNY_IS_SEND_QUEUE (send_queue)) {
+ /* Get outbox folder */
+ outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (send_queue));
+ if (outbox) { /* this could fail in some cases */
+ num_messages = tny_folder_get_all_count (outbox);
+ g_object_unref (outbox);
+ } else {
+ g_warning ("%s: could not get outbox", __FUNCTION__);
+ num_messages = 0;
+ }
- if (num_messages != 0) {
- /* Reenable suspended items */
- modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
-
- /* Try to send */
- tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
- modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue),
- info->interactive);
+ if (num_messages != 0) {
+ /* Reenable suspended items */
+ modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
+
+ /* Try to send */
+ tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
+ modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue),
+ info->interactive);
+ }
}
}
g_return_if_fail (TNY_IS_HEADER (header));
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
- folder = tny_header_get_folder (header);
-
priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
priv->total = 1;
priv->done = 0;
+ /* Check memory low */
+ if (_check_memory_low (self)) {
+ if (user_callback)
+ user_callback (self, header, FALSE, NULL, priv->error, user_data);
+ modest_mail_operation_notify_end (self);
+ return;
+ }
+
/* Get account and set it into mail_operation */
+ folder = tny_header_get_folder (header);
priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
/* Check for cached messages */
state->total = 0;
g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL],
0, state, NULL);
+ g_slice_free (ModestMailOperationState, state);
tny_folder_get_msg_async (folder, header, get_msg_async_cb, get_msg_status_cb, helper);
priv->done = 0;
priv->total = tny_list_get_length(header_list);
+ /* Check memory low */
+ if (_check_memory_low (self)) {
+ if (user_callback) {
+ TnyHeader *header = NULL;
+ TnyIterator *iter;
+
+ if (tny_list_get_length (header_list) > 0) {
+ iter = tny_list_create_iterator (header_list);
+ header = (TnyHeader *) tny_iterator_get_current (iter);
+ g_object_unref (iter);
+ }
+ user_callback (self, header, FALSE, NULL, priv->error, user_data);
+ if (header)
+ g_object_unref (header);
+ }
+ if (notify)
+ notify (user_data);
+ /* Notify about operation end */
+ modest_mail_operation_notify_end (self);
+ return;
+ }
+
/* Check uncached messages */
for (iter = tny_list_create_iterator (header_list), has_uncached_messages = FALSE;
!has_uncached_messages && !tny_iterator_is_done (iter);
if (traccount) {
ModestTnySendQueueStatus status;
ModestTnySendQueue *send_queue = modest_runtime_get_send_queue(traccount, TRUE);
- TnyIterator *iter = tny_list_create_iterator(headers);
- g_object_unref(remove_headers);
- remove_headers = TNY_LIST(tny_simple_list_new());
- while (!tny_iterator_is_done(iter)) {
- char *msg_id;
- TnyHeader *hdr = TNY_HEADER(tny_iterator_get_current(iter));
- msg_id = modest_tny_send_queue_get_msg_id (hdr);
- status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
- if (status != MODEST_TNY_SEND_QUEUE_SENDING) {
- tny_list_append(remove_headers, G_OBJECT(hdr));
+
+ if (TNY_IS_SEND_QUEUE (send_queue)) {
+ TnyIterator *iter = tny_list_create_iterator(headers);
+ g_object_unref(remove_headers);
+ remove_headers = TNY_LIST(tny_simple_list_new());
+ while (!tny_iterator_is_done(iter)) {
+ char *msg_id;
+ TnyHeader *hdr = TNY_HEADER(tny_iterator_get_current(iter));
+ msg_id = modest_tny_send_queue_get_msg_id (hdr);
+ status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
+ if (status != MODEST_TNY_SEND_QUEUE_SENDING) {
+ tny_list_append(remove_headers, G_OBJECT(hdr));
+ }
+ g_object_unref(hdr);
+ g_free(msg_id);
+ tny_iterator_next(iter);
}
- g_object_unref(hdr);
- g_free(msg_id);
- tny_iterator_next(iter);
+ g_object_unref(iter);
}
- g_object_unref(iter);
g_object_unref(traccount);
}
}
&(helper->sum_total_bytes), helper->total_bytes, TRUE);
}
+static void
+transfer_msgs_sync_folder_cb (TnyFolder *self,
+ gboolean cancelled,
+ GError *err,
+ gpointer user_data)
+{
+ XFerMsgsAsyncHelper *helper;
+ /* We don't care here about the results of the
+ synchronization */
+ helper = (XFerMsgsAsyncHelper *) user_data;
+
+ /* Notify about operation end */
+ modest_mail_operation_notify_end (helper->mail_op);
+
+ /* If user defined callback function was defined, call it */
+ if (helper->user_callback)
+ helper->user_callback (helper->mail_op, helper->user_data);
+
+ /* Free */
+ if (helper->more_msgs)
+ g_object_unref (helper->more_msgs);
+ if (helper->headers)
+ g_object_unref (helper->headers);
+ if (helper->dest_folder)
+ g_object_unref (helper->dest_folder);
+ if (helper->mail_op)
+ g_object_unref (helper->mail_op);
+ g_slice_free (XFerMsgsAsyncHelper, helper);
+}
static void
transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer user_data)
}
if (finished) {
-
- /* Update folder counts */
- tny_folder_poke_status (folder);
- tny_folder_poke_status (helper->dest_folder);
-
- /* Notify about operation end */
- modest_mail_operation_notify_end (self);
-
- /* If user defined callback function was defined, call it */
- if (helper->user_callback) {
- /* This is not a GDK lock because we are a Tinymail callback and
- * Tinymail already acquires the Gdk lock */
-
- /* no gdk_threads_enter (), CHECKED */
- helper->user_callback (self, helper->user_data);
- /* no gdk_threads_leave (), CHECKED */
- }
-
- /* Free */
- if (helper->more_msgs)
- g_object_unref (helper->more_msgs);
- if (helper->headers)
- g_object_unref (helper->headers);
- if (helper->dest_folder)
- g_object_unref (helper->dest_folder);
- if (helper->mail_op)
- g_object_unref (helper->mail_op);
- g_slice_free (XFerMsgsAsyncHelper, helper);
+ /* Synchronize the source folder contents. This should
+ be done by tinymail but the camel_folder_sync it's
+ actually disabled in transfer_msgs_thread_clean
+ because it's supposed to cause hangs */
+ tny_folder_sync_async (folder, helper->delete,
+ transfer_msgs_sync_folder_cb,
+ NULL, helper);
} else {
/* Transfer more messages */
tny_folder_transfer_msgs_async (folder,
ModestTnyFolderRules rules = 0;
TnyAccount *dst_account = NULL;
gboolean leave_on_server;
+ ModestMailOperationState *state;
g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self));
g_return_if_fail (headers && TNY_IS_LIST (headers));
helper->delete = (leave_on_server) ? FALSE : delete_original;
modest_mail_operation_notify_start (self);
+
+ /* Start notifying progress */
+ state = modest_mail_operation_clone_state (self);
+ state->done = 0;
+ state->total = 0;
+ g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL);
+ g_slice_free (ModestMailOperationState, state);
+
tny_folder_transfer_msgs_async (src_folder,
helper->headers,
folder,
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
- priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+ /* Check memory low */
+ if (_check_memory_low (self)) {
+ if (user_callback)
+ user_callback (self, folder, user_data);
+ /* Notify about operation end */
+ modest_mail_operation_notify_end (self);
+ return;
+ }
/* Get account and set it into mail_operation */
+ priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
priv->account = modest_tny_folder_get_account (folder);
priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE;
g_signal_handlers_disconnect_by_func (queue, run_queue_stop, self);
g_object_unref (self);
}
+
void
modest_mail_operation_run_queue (ModestMailOperation *self,
ModestTnySendQueue *queue)
}
static void
+shutdown_callback (ModestTnyAccountStore *account_store, gpointer userdata)
+{
+ ModestMailOperation *self = (ModestMailOperation *) userdata;
+ ModestMailOperationPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (account_store));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+
+ modest_mail_operation_notify_end (self);
+ g_object_unref (self);
+}
+
+void
+modest_mail_operation_shutdown (ModestMailOperation *self, ModestTnyAccountStore *account_store)
+{
+ ModestMailOperationPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (MODEST_IS_TNY_ACCOUNT_STORE (account_store));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ modest_mail_operation_queue_set_running_shutdown (modest_runtime_get_mail_operation_queue ());
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+ priv->account = NULL;
+ priv->op_type = MODEST_MAIL_OPERATION_TYPE_SHUTDOWN;
+
+ modest_mail_operation_notify_start (self);
+ g_object_ref (self);
+ modest_tny_account_store_shutdown (account_store, shutdown_callback, self);
+}
+
+static void
sync_folder_finish_callback (TnyFolder *self,
gboolean cancelled,
GError *err,
priv->done, priv->total,
priv->error && priv->error->message ? priv->error->message : "");
}
+
+/*
+ * Once the mail operations were objects this will be no longer
+ * needed. I don't like it, but we need it for the moment
+ */
+static gboolean
+_check_memory_low (ModestMailOperation *mail_op)
+{
+ if (modest_platform_check_memory_low (NULL, FALSE)) {
+ ModestMailOperationPrivate *priv;
+
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op);
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+ g_set_error (&(priv->error),
+ MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY,
+ "Not enough memory to complete the operation");
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}