X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fmodest-mail-operation.c;h=56e7c3b261f4248b53f9cf2d836f6901640ef7f7;hb=84a21a79f776304e1fbc6ee28be69bbf27231608;hp=357843f5c3682e2f6f38bcebb7694ad30885a280;hpb=560ace2e328a05c336b746733799bdecb37c3b42;p=modest diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 357843f..56e7c3b 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -101,6 +101,7 @@ struct _ModestMailOperationPrivate { GError *error; ErrorCheckingUserCallback error_checking; gpointer error_checking_user_data; + ErrorCheckingUserDataDestroyer error_checking_user_data_destroyer; ModestMailOperationStatus status; ModestMailOperationTypeOperation op_type; }; @@ -134,6 +135,9 @@ typedef struct _XFerMsgAsyncHelper XferAsyncUserCallback user_callback; gboolean delete; gpointer user_data; + gint last_total_bytes; + gint sum_total_bytes; + gint total_bytes; } XFerMsgAsyncHelper; typedef void (*ModestMailOperationCreateMsgCallback) (ModestMailOperation *mail_op, @@ -330,7 +334,8 @@ modest_mail_operation_new (GObject *source) ModestMailOperation* modest_mail_operation_new_with_error_handling (GObject *source, ErrorCheckingUserCallback error_handler, - gpointer user_data) + gpointer user_data, + ErrorCheckingUserDataDestroyer error_handler_destroyer) { ModestMailOperation *obj; ModestMailOperationPrivate *priv; @@ -341,6 +346,7 @@ modest_mail_operation_new_with_error_handling (GObject *source, g_return_val_if_fail (error_handler != NULL, obj); priv->error_checking = error_handler; priv->error_checking_user_data = user_data; + priv->error_checking_user_data_destroyer = error_handler_destroyer; return obj; } @@ -353,6 +359,7 @@ modest_mail_operation_execute_error_handler (ModestMailOperation *self) priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS); + /* Call the user callback */ if (priv->error_checking != NULL) priv->error_checking (self, priv->error_checking_user_data); } @@ -643,7 +650,7 @@ create_msg_thread (gpointer thread_data) if (info->attachments_list != NULL) flags |= TNY_HEADER_FLAG_ATTACHMENTS; - tny_header_set_flags (header, flags); + tny_header_set_flag (header, flags); g_object_unref (G_OBJECT(header)); } else { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; @@ -743,8 +750,10 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self, modest_mail_operation_send_mail (self, info->transport_account, msg); /* Remove old mail from its source folder */ - draft_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_DRAFTS); - outbox_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_OUTBOX); + draft_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), + TNY_FOLDER_TYPE_DRAFTS); + outbox_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), + TNY_FOLDER_TYPE_OUTBOX); if (info->draft_msg != NULL) { TnyFolder *folder = NULL; TnyFolder *src_folder = NULL; @@ -752,6 +761,10 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self, folder = tny_msg_get_folder (info->draft_msg); if (folder == NULL) goto end; folder_type = modest_tny_folder_guess_folder_type (folder); + + if (folder_type == TNY_FOLDER_TYPE_INVALID) + g_warning ("%s: BUG: folder of type TNY_FOLDER_TYPE_INVALID", __FUNCTION__); + if (folder_type == TNY_FOLDER_TYPE_OUTBOX) src_folder = outbox_folder; else @@ -1593,7 +1606,7 @@ modest_mail_operation_create_folder (ModestMailOperation *self, modest_tny_folder_get_account (TNY_FOLDER (parent)); /* Check for already existing folder */ - if (modest_tny_folder_has_subfolder_with_name (parent, name)) { + if (modest_tny_folder_has_subfolder_with_name (parent, name, TRUE)) { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS, @@ -1822,7 +1835,7 @@ new_name_valid_if_local_account (ModestMailOperationPrivate *priv, priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS, - _("ckdg_ib_folder_already_exists")); + _CS("ckdg_ib_folder_already_exists")); return FALSE; } else return TRUE; @@ -1880,7 +1893,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, /* Do not move a parent into a child */ goto error; } else if (TNY_IS_FOLDER_STORE (parent) && - modest_tny_folder_has_subfolder_with_name (parent, folder_name)) { + modest_tny_folder_has_subfolder_with_name (parent, folder_name, TRUE)) { /* Check that the new folder name is not used by any parent subfolder */ goto error; @@ -2013,42 +2026,31 @@ modest_mail_operation_get_msg (ModestMailOperation *self, priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; - /* Get message from folder */ - if (folder) { - /* Get account and set it into mail_operation */ - priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); + /* Get account and set it into mail_operation */ + priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); + + /* Check for cached messages */ + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) + priv->op_type = MODEST_MAIL_OPERATION_TYPE_OPEN; + else + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; + + helper = g_slice_new0 (GetMsgAsyncHelper); + helper->mail_op = self; + helper->user_callback = user_callback; + helper->user_data = user_data; + helper->header = g_object_ref (header); - /* Check for cached messages */ - if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) - priv->op_type = MODEST_MAIL_OPERATION_TYPE_OPEN; - else - priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; - - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->mail_op = self; - helper->user_callback = user_callback; - helper->user_data = user_data; - helper->header = g_object_ref (header); - - // The callback's reference so that the mail op is not - // finalized until the async operation is completed even if - // the user canceled the request meanwhile. - g_object_ref (G_OBJECT (helper->mail_op)); - - modest_mail_operation_notify_start (self); - tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper); + /* The callback's reference so that the mail op is not + * finalized until the async operation is completed even if + * the user canceled the request meanwhile. + */ + g_object_ref (G_OBJECT (helper->mail_op)); - g_object_unref (G_OBJECT (folder)); - } else { - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, - _("Error trying to get a message. No folder found for header")); + modest_mail_operation_notify_start (self); + tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper); - /* Notify the queue */ - modest_mail_operation_notify_end (self); - } + g_object_unref (G_OBJECT (folder)); } static void @@ -2414,8 +2416,8 @@ modest_mail_operation_remove_msg (ModestMailOperation *self, /* remove message from folder */ tny_folder_remove_msg (folder, header, &(priv->error)); if (!priv->error) { - tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED); - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); + tny_header_set_flag (header, TNY_HEADER_FLAG_DELETED); + tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN); modest_mail_operation_notify_start (self); @@ -2512,7 +2514,7 @@ transfer_msgs_status_cb (GObject *obj, ModestMailOperation *self; ModestMailOperationPrivate *priv; ModestMailOperationState *state; - + gboolean is_num_bytes; g_return_if_fail (status != NULL); g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS); @@ -2523,19 +2525,30 @@ transfer_msgs_status_cb (GObject *obj, self = helper->mail_op; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - priv->done = status->position; - priv->total = status->of_total; + /* We know that tinymail sends us information about + transferred bytes with this particular message */ + is_num_bytes = (g_ascii_strcasecmp (status->message, "Retrieving message") == 0); state = modest_mail_operation_clone_state (self); + if (is_num_bytes && !((status->position == 1) && (status->of_total == 100))) { + /* We know that we're in a different message when the + total number of bytes to transfer is different. Of + course it could fail if we're transferring messages + of the same size, but this is a workarround */ + if (status->of_total != helper->last_total_bytes) { + priv->done++; + helper->sum_total_bytes += helper->last_total_bytes; + helper->last_total_bytes = status->of_total; + } + state->bytes_done += status->position + helper->sum_total_bytes; + state->bytes_total = helper->total_bytes; - /* This is not a GDK lock because we are a Tinymail callback and - * Tinymail already acquires the Gdk lock */ - - /* no gdk_threads_enter (), CHECKED */ - - g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL); - /* no gdk_threads_leave (), CHECKED */ + /* Notify the status change. Only notify about changes + referred to bytes */ + g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], + 0, state, NULL); + } g_slice_free (ModestMailOperationState, state); } @@ -2581,8 +2594,8 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u iter = tny_list_create_iterator (helper->headers); while (!tny_iterator_is_done (iter)) { header = TNY_HEADER (tny_iterator_get_current (iter)); - tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED); - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); + tny_header_set_flag (header, TNY_HEADER_FLAG_DELETED); + tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN); g_object_unref (header); tny_iterator_next (iter); @@ -2618,6 +2631,24 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u g_slice_free (XFerMsgAsyncHelper, helper); } +static guint +compute_message_list_size (TnyList *headers) +{ + TnyIterator *iter; + guint size = 0; + + iter = tny_list_create_iterator (headers); + while (!tny_iterator_is_done (iter)) { + TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); + size += tny_header_get_message_size (header); + g_object_unref (header); + tny_iterator_next (iter); + } + g_object_unref (iter); + + return size; +} + void modest_mail_operation_xfer_msgs (ModestMailOperation *self, TnyList *headers, @@ -2633,12 +2664,12 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, TnyHeader *header = NULL; ModestTnyFolderRules rules = 0; - g_return_if_fail (MODEST_IS_MAIL_OPERATION (self)); - g_return_if_fail (TNY_IS_LIST (headers)); - g_return_if_fail (TNY_IS_FOLDER (folder)); + g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self)); + g_return_if_fail (headers && TNY_IS_LIST (headers)); + g_return_if_fail (folder && TNY_IS_FOLDER (folder)); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - priv->total = 1; + priv->total = tny_list_get_length (headers); priv->done = 0; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; @@ -2663,9 +2694,17 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, src_folder = tny_header_get_folder (header); g_object_unref (header); } - g_object_unref (iter); + if (src_folder == NULL) { + /* Notify the queue */ + modest_mail_operation_notify_end (self); + + g_warning ("%s: cannot find folder from header", __FUNCTION__); + return; + } + + /* Check folder source and destination */ if (src_folder == folder) { /* Set status failed and set an error */ @@ -2690,6 +2729,9 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, helper->user_callback = user_callback; helper->user_data = user_data; helper->delete = delete_original; + helper->last_total_bytes = 0; + helper->sum_total_bytes = 0; + helper->total_bytes = compute_message_list_size (headers); /* Get account and set it into mail_operation */ priv->account = modest_tny_folder_get_account (src_folder); @@ -2749,7 +2791,7 @@ on_refresh_folder (TnyFolder *folder, } /* Free */ - g_slice_free (RefreshAsyncHelper, helper); + g_slice_free (RefreshAsyncHelper, helper); /* Notify about operation end */ modest_mail_operation_notify_end (self); @@ -2862,6 +2904,10 @@ modest_mail_operation_notify_end (ModestMailOperation *self) not wrapp this emission because we assume that this function is always called from within the main lock */ g_signal_emit (G_OBJECT (self), signals[OPERATION_FINISHED_SIGNAL], 0, NULL); + + /* Remove the error user data */ + if (priv->error_checking_user_data && priv->error_checking_user_data_destroyer) + priv->error_checking_user_data_destroyer (priv->error_checking_user_data); } TnyAccount *