X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-mail-operation.c;h=f88ff79352cefac47f6c369a207ab49bf1fa114f;hp=6676eecffe8c52854c0308582b4c8c7b059d8766;hb=c04e24ad16b9a570a1152ec2c05c953fe39a3c3c;hpb=eacecca70dc8d077b9ceb9c49c916883cf9aa08f diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 6676eec..f88ff79 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -70,7 +70,8 @@ static void get_msg_status_cb (GObject *obj, TnyStatus *status, gpointer user_data); -static void modest_mail_operation_notify_end (ModestMailOperation *self); +static void modest_mail_operation_notify_end (ModestMailOperation *self, + gboolean need_lock); static gboolean did_a_cancel = FALSE; @@ -84,6 +85,7 @@ enum _ModestMailOperationSignals typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate; struct _ModestMailOperationPrivate { TnyAccount *account; + gchar *account_name; guint done; guint total; GObject *source; @@ -104,6 +106,7 @@ struct _ModestMailOperationPrivate { typedef struct _GetMsgAsyncHelper { ModestMailOperation *mail_op; + TnyHeader *header; GetMsgAsyncUserCallback user_callback; gpointer user_data; } GetMsgAsyncHelper; @@ -206,6 +209,8 @@ modest_mail_operation_finalize (GObject *obj) priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj); + + if (priv->error) { g_error_free (priv->error); priv->error = NULL; @@ -298,8 +303,14 @@ modest_mail_operation_get_source (ModestMailOperation *self) { ModestMailOperationPrivate *priv; + g_return_val_if_fail (self, NULL); + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - + if (!priv) { + g_warning ("BUG: %s: priv == NULL", __FUNCTION__); + return NULL; + } + return g_object_ref (priv->source); } @@ -313,6 +324,11 @@ modest_mail_operation_get_status (ModestMailOperation *self) MODEST_MAIL_OPERATION_STATUS_INVALID); priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); + if (!priv) { + g_warning ("BUG: %s: priv == NULL", __FUNCTION__); + return MODEST_MAIL_OPERATION_STATUS_INVALID; + } + return priv->status; } @@ -325,6 +341,12 @@ modest_mail_operation_get_error (ModestMailOperation *self) g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL); priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); + + if (!priv) { + g_warning ("BUG: %s: priv == NULL", __FUNCTION__); + return NULL; + } + return priv->error; } @@ -339,18 +361,21 @@ modest_mail_operation_cancel (ModestMailOperation *self) } priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); - - /* cancel current operation in account */ - //tny_account_cancel (priv->account); + if (!priv) { + g_warning ("BUG: %s: priv == NULL", __FUNCTION__); + return FALSE; + } did_a_cancel = TRUE; /* Set new status */ priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED; - /* Notify about operation end */ - modest_mail_operation_notify_end (self); - + /* This emits progress-changed on which the mail operation queue is + * listening, so the mail operation is correctly removed from the + * queue without further explicit calls. */ + modest_mail_operation_notify_end (self, FALSE); + return TRUE; } @@ -453,6 +478,8 @@ modest_mail_operation_clone_state (ModestMailOperation *self) state->done = priv->done; state->total = priv->total; state->finished = modest_mail_operation_is_finished (self); + state->bytes_done = 0; + state->bytes_total = 0; return state; } @@ -477,6 +504,8 @@ modest_mail_operation_send_mail (ModestMailOperation *self, /* Get account and set it into mail_operation */ priv->account = g_object_ref (transport_account); + priv->done = 1; + priv->total = 1; send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account)); if (!TNY_IS_SEND_QUEUE(send_queue)) { @@ -484,11 +513,17 @@ modest_mail_operation_send_mail (ModestMailOperation *self, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, "modest: could not find send queue for account\n"); } else { + /* TODO: connect to the msg-sent in order to know when + the mail operation is finished */ tny_send_queue_add (send_queue, msg, &(priv->error)); + /* TODO: we're setting always success, do the check in + the handler */ + priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; } - /* Notify about operation end */ - modest_mail_operation_notify_end (self); + /* TODO: do this in the handler of the "msg-sent" + signal.Notify about operation end */ + modest_mail_operation_notify_end (self, FALSE); } void @@ -512,9 +547,6 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self, priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - /* Get account and set it into mail_operation */ - priv->account = g_object_ref (transport_account); - /* Check parametters */ if (to == NULL) { /* Set status failed and set an error */ @@ -588,6 +620,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list); } if (!msg) { + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, "modest: failed to create a new msg\n"); @@ -600,6 +633,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS); if (!folder) { + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, "modest: failed to create a new msg\n"); @@ -615,8 +649,8 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, } tny_folder_add_msg (folder, msg, &(priv->error)); - if (priv->error) - goto end; + if (!priv->error) + priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; end: if (msg) @@ -624,7 +658,7 @@ end: if (folder) g_object_unref (G_OBJECT(folder)); - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } typedef struct @@ -635,6 +669,9 @@ typedef struct gint max_size; gint retrieve_limit; gchar *retrieve_type; + gchar *account_name; + UpdateAccountCallback callback; + gpointer user_data; } UpdateAccountInfo; /***** I N T E R N A L F O L D E R O B S E R V E R *****/ @@ -758,12 +795,16 @@ recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all static gboolean idle_notify_progress (gpointer data) { + gdk_threads_enter (); + ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data); ModestMailOperationState *state; state = modest_mail_operation_clone_state (mail_op); g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL); g_slice_free (ModestMailOperationState, state); + + gdk_threads_leave (); return TRUE; } @@ -776,6 +817,8 @@ idle_notify_progress (gpointer data) static gboolean idle_notify_progress_once (gpointer data) { + gdk_threads_enter (); + ModestPair *pair; pair = (ModestPair *) data; @@ -786,6 +829,8 @@ idle_notify_progress_once (gpointer data) g_slice_free (ModestMailOperationState, (ModestMailOperationState*)pair->second); g_object_unref (pair->first); + gdk_threads_leave (); + return FALSE; } @@ -794,14 +839,15 @@ idle_notify_progress_once (gpointer data) * loop. We call it inside an idle call to achieve that */ static gboolean -notify_update_account_queue (gpointer data) +idle_notify_update_account_queue (gpointer data) { ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data); ModestMailOperationPrivate *priv = NULL; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(mail_op); - modest_mail_operation_notify_end (mail_op); + /* Do not need to block, the notify end will do it for us */ + modest_mail_operation_notify_end (mail_op, TRUE); g_object_unref (mail_op); return FALSE; @@ -831,6 +877,8 @@ compare_headers_by_date (gconstpointer a, static gboolean set_last_updated_idle (gpointer data) { + gdk_threads_enter (); + /* It does not matter if the time is not exactly the same than the time when this idle was called, it's just an approximation and it won't be very different */ @@ -840,19 +888,22 @@ set_last_updated_idle (gpointer data) time(NULL), TRUE); + gdk_threads_leave (); + return FALSE; } static gpointer update_account_thread (gpointer thr_user_data) { + static gboolean first_time = TRUE; UpdateAccountInfo *info; TnyList *all_folders = NULL; - GPtrArray *new_headers; + GPtrArray *new_headers = NULL; TnyIterator *iter = NULL; TnyFolderStoreQuery *query = NULL; - ModestMailOperationPrivate *priv; - ModestTnySendQueue *send_queue; + ModestMailOperationPrivate *priv = NULL; + ModestTnySendQueue *send_queue = NULL; info = (UpdateAccountInfo *) thr_user_data; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op); @@ -864,7 +915,7 @@ update_account_thread (gpointer thr_user_data) * for POP3, we do a logout-login upon send/receive -- many POP-servers (like Gmail) do not * show any updates unless we do that */ - if (TNY_IS_CAMEL_POP_STORE_ACCOUNT(priv->account)) + if (!first_time && TNY_IS_CAMEL_POP_STORE_ACCOUNT(priv->account)) tny_camel_pop_store_account_reconnect (TNY_CAMEL_POP_STORE_ACCOUNT(priv->account)); /* Get all the folders. We can do it synchronously because @@ -910,8 +961,6 @@ update_account_thread (gpointer thr_user_data) /* Refresh the folder */ /* Our observer receives notification of new emails during folder refreshes, * so we can use observer->new_headers. - * TODO: This does not seem to be providing accurate numbers. - * Possibly the observer is notified asynchronously. */ observer = g_object_new (internal_folder_observer_get_type (), NULL); tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer)); @@ -931,10 +980,6 @@ update_account_thread (gpointer thr_user_data) iter = tny_list_create_iterator (observer->new_headers); while (!tny_iterator_is_done (iter)) { TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); - /* printf (" DEBUG1.2 %s: checking size: account=%s, subject=%s\n", - * __FUNCTION__, tny_account_get_id (priv->account), - * tny_header_get_subject (header)); - */ /* Apply per-message size limits */ if (tny_header_get_message_size (header) < info->max_size) @@ -944,16 +989,24 @@ update_account_thread (gpointer thr_user_data) tny_iterator_next (iter); } g_object_unref (iter); + } else { + /* We do not need to do it the first time + because it's automatically done by the tree + model */ + if (G_UNLIKELY (!first_time)) + tny_folder_poke_status (TNY_FOLDER (folder)); } - tny_folder_remove_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer)); g_object_unref (observer); - observer = NULL; + observer = NULL; + g_object_unref (G_OBJECT (folder)); if (priv->error) + { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - - g_object_unref (G_OBJECT (folder)); + goto out; + } + tny_iterator_next (iter); } @@ -973,11 +1026,11 @@ update_account_thread (gpointer thr_user_data) * user to download them all, * as per the UI spec "Retrieval Limits" section in 4.4: */ - printf ("DEBUG: %s: account=%s, len=%d, retrieve_limit = %d\n", __FUNCTION__, - tny_account_get_id (priv->account), new_headers->len, info->retrieve_limit); if (new_headers->len > info->retrieve_limit) { - /* TODO: Ask the user, instead of just failing, showing mail_nc_msg_count_limit_exceeded, - * with 'Get all' and 'Newest only' buttons. */ + /* TODO: Ask the user, instead of just + * failing, showing + * mail_nc_msg_count_limit_exceeded, with 'Get + * all' and 'Newest only' buttons. */ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_RETRIEVAL_NUMBER_LIMIT, "The number of messages to retrieve exceeds the chosen limit for account %s\n", @@ -1013,7 +1066,7 @@ update_account_thread (gpointer thr_user_data) g_ptr_array_foreach (new_headers, (GFunc) g_object_unref, NULL); g_ptr_array_free (new_headers, FALSE); } - + /* Perform send */ priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND; priv->done = 0; @@ -1050,8 +1103,17 @@ update_account_thread (gpointer thr_user_data) /* Notify about operation end. Note that the info could be freed before this idle happens, but the mail operation will be still alive */ - g_idle_add (notify_update_account_queue, g_object_ref (info->mail_op)); - + g_idle_add (idle_notify_update_account_queue, g_object_ref (info->mail_op)); + + if (info->callback) { + /* This thread is not in the main lock */ + gdk_threads_enter (); + info->callback (info->mail_op, + (new_headers) ? new_headers->len : 0, + info->user_data); + gdk_threads_leave (); + } + /* Frees */ g_object_unref (query); g_object_unref (all_folders); @@ -1060,12 +1122,16 @@ update_account_thread (gpointer thr_user_data) g_free (info->retrieve_type); g_slice_free (UpdateAccountInfo, info); + first_time = FALSE; + return NULL; } gboolean modest_mail_operation_update_account (ModestMailOperation *self, - const gchar *account_name) + const gchar *account_name, + UpdateAccountCallback callback, + gpointer user_data) { GThread *thread; UpdateAccountInfo *info; @@ -1077,13 +1143,6 @@ modest_mail_operation_update_account (ModestMailOperation *self, g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE); g_return_val_if_fail (account_name, FALSE); - /* Make sure that we have a connection, and request one - * if necessary: - * TODO: Is there some way to trigger this for every attempt to - * use the network? */ - if (!modest_platform_connect_and_wait(NULL)) - return 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 */ @@ -1091,7 +1150,14 @@ modest_mail_operation_update_account (ModestMailOperation *self, priv->total = 0; priv->done = 0; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; - + + /* Make sure that we have a connection, and request one + * if necessary: + * TODO: Is there some way to trigger this for every attempt to + * use the network? */ + if (!modest_platform_connect_and_wait(NULL)) + goto error; + /* Get the Modest account */ modest_account = (TnyStoreAccount *) modest_tny_account_store_get_server_account (modest_runtime_get_account_store (), @@ -1099,13 +1165,10 @@ modest_mail_operation_update_account (ModestMailOperation *self, 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_notify_end (self); - - return FALSE; + goto error; } @@ -1115,13 +1178,10 @@ modest_mail_operation_update_account (ModestMailOperation *self, modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(), account_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", account_name); - modest_mail_operation_notify_end (self); - - return FALSE; + goto error; } /* Create the helper object */ @@ -1129,6 +1189,8 @@ modest_mail_operation_update_account (ModestMailOperation *self, info->mail_op = self; info->account = modest_account; info->transport_account = transport_account; + info->callback = callback; + info->user_data = user_data; /* Get the message size limit */ info->max_size = modest_conf_get_int (modest_runtime_get_conf (), @@ -1151,9 +1213,20 @@ modest_mail_operation_update_account (ModestMailOperation *self, /* printf ("DEBUG: %s: info->retrieve_limit = %d\n", __FUNCTION__, info->retrieve_limit); */ + /* Set account busy */ + modest_account_mgr_set_account_busy(mgr, account_name, TRUE); + priv->account_name = g_strdup(account_name); + thread = g_thread_create (update_account_thread, info, FALSE, NULL); return TRUE; + + error: + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + if (callback) + callback (self, 0, user_data); + modest_mail_operation_notify_end (self, FALSE); + return FALSE; } /* ******************************************************************* */ @@ -1196,7 +1269,7 @@ modest_mail_operation_create_folder (ModestMailOperation *self, } /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); return new_folder; } @@ -1251,7 +1324,7 @@ modest_mail_operation_remove_folder (ModestMailOperation *self, end: /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } static void @@ -1285,7 +1358,8 @@ static void transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, - TnyFolder *new_folder, GError **err, + TnyFolder *new_folder, + GError **err, gpointer user_data) { ModestMailOperation *self = NULL; @@ -1313,11 +1387,9 @@ transfer_folder_cb (TnyFolder *folder, /* Free */ g_object_unref (folder); g_object_unref (into); - if (new_folder != NULL) - g_object_unref (new_folder); /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, TRUE); } void @@ -1356,7 +1428,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, _("mail_in_ui_folder_move_target_error")); /* Notify the queue */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } else if (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) { /* Set status failed and set an error */ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; @@ -1365,7 +1437,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, _("FIXME: parent folder does not accept new folders")); /* Notify the queue */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } else { /* Pick references for async calls */ g_object_ref (folder); @@ -1409,7 +1481,7 @@ modest_mail_operation_rename_folder (ModestMailOperation *self, _("FIXME: unable to rename")); /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } else { /* Rename. Camel handles folder subscription/unsubscription */ TnyFolderStore *into; @@ -1455,6 +1527,7 @@ void modest_mail_operation_get_msg (ModestMailOperation *self, helper->mail_op = self; helper->user_callback = user_callback; helper->user_data = user_data; + helper->header = g_object_ref (header); tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper); @@ -1467,7 +1540,7 @@ void modest_mail_operation_get_msg (ModestMailOperation *self, _("Error trying to get a message. No folder found for header")); /* Notify the queue */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } } @@ -1507,15 +1580,20 @@ get_msg_cb (TnyFolder *folder, /* If user defined callback function was defined, call it */ if (helper->user_callback) { - helper->user_callback (self, NULL, msg, helper->user_data); + /* This callback is called into an iddle by tinymail, + and idles are not in the main lock */ + gdk_threads_enter (); + helper->user_callback (self, helper->header, msg, helper->user_data); + gdk_threads_leave (); } out: /* Free */ + g_object_unref (helper->header); g_slice_free (GetMsgAsyncHelper, helper); /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, TRUE); } static void @@ -1544,6 +1622,8 @@ get_msg_status_cb (GObject *obj, priv->total = 1; state = modest_mail_operation_clone_state (self); + state->bytes_done = status->position; + state->bytes_total = status->of_total; g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL); g_slice_free (ModestMailOperationState, state); } @@ -1577,8 +1657,11 @@ notify_get_msgs_full (gpointer data) info = (NotifyGetMsgsInfo *) data; - /* Call the user callback */ + /* Call the user callback. Idles are not in the main lock, so + lock it */ + gdk_threads_enter (); info->user_callback (info->mail_op, info->header, info->msg, info->user_data); + gdk_threads_leave (); g_slice_free (NotifyGetMsgsInfo, info); @@ -1596,8 +1679,11 @@ get_msgs_full_destroyer (gpointer data) info = (GetFullMsgsInfo *) data; - if (info->notify) + if (info->notify) { + gdk_threads_enter (); info->notify (info->user_data); + gdk_threads_leave (); + } /* free */ g_object_unref (info->headers); @@ -1674,7 +1760,7 @@ get_msgs_full_thread (gpointer thr_user_data) priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; /* Notify about operation end */ - g_idle_add (notify_update_account_queue, g_object_ref (info->mail_op)); + g_idle_add (idle_notify_update_account_queue, g_object_ref (info->mail_op)); /* Free thread resources. Will be called after all previous idles */ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL); @@ -1763,7 +1849,7 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self, MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT, _("emev_ni_ui_imap_msg_size_exceed_error")); /* Remove from queue and free resources */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); if (notify) notify (user_data); } @@ -1837,7 +1923,7 @@ modest_mail_operation_remove_msg (ModestMailOperation *self, g_object_unref (G_OBJECT (folder)); /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); } static void @@ -1901,7 +1987,9 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer /* If user defined callback function was defined, call it */ if (helper->user_callback) { + gdk_threads_enter (); helper->user_callback (priv->source, helper->user_data); + gdk_threads_leave (); } /* Free */ @@ -1912,7 +2000,7 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer g_object_unref (folder); /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, TRUE); } void @@ -1941,7 +2029,6 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, /* Apply folder rules */ rules = modest_tny_folder_get_rules (TNY_FOLDER (folder)); - if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) { /* Set status failed and set an error */ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; @@ -1949,7 +2036,7 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, _("FIXME: folder does not accept msgs")); /* Notify the queue */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, FALSE); return; } @@ -2015,8 +2102,11 @@ on_refresh_folder (TnyFolder *folder, out: /* Call user defined callback, if it exists */ - if (helper->user_callback) + if (helper->user_callback) { + gdk_threads_enter (); helper->user_callback (priv->source, folder, helper->user_data); + gdk_threads_leave (); + } /* Free */ g_object_unref (helper->mail_op); @@ -2024,7 +2114,7 @@ on_refresh_folder (TnyFolder *folder, g_object_unref (folder); /* Notify about operation end */ - modest_mail_operation_notify_end (self); + modest_mail_operation_notify_end (self, TRUE); } static void @@ -2098,12 +2188,35 @@ modest_mail_operation_refresh_folder (ModestMailOperation *self, * callback). */ static void -modest_mail_operation_notify_end (ModestMailOperation *self) +modest_mail_operation_notify_end (ModestMailOperation *self, + gboolean need_lock) { ModestMailOperationState *state; + ModestMailOperationPrivate *priv = NULL; + + g_return_if_fail (self); + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + if (!priv) { + g_warning ("BUG: %s: priv == NULL", __FUNCTION__); + return; + } + + /* Set the account back to not busy */ + if (priv->account_name) { + modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr(), + priv->account_name, FALSE); + g_free(priv->account_name); + priv->account_name = NULL; + } + /* Notify the observers about the mail opertation end */ state = modest_mail_operation_clone_state (self); + if (need_lock) + gdk_threads_enter (); g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL); + if (need_lock) + gdk_threads_leave (); g_slice_free (ModestMailOperationState, state); }