* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "modest-mail-operation.h"
-/* include other impl specific header files */
#include <string.h>
#include <stdarg.h>
#include <tny-mime-part.h>
#include "modest-tny-platform-factory.h"
#include "modest-marshal.h"
#include "modest-error.h"
+#include "modest-mail-operation.h"
#define KB 1024
static void modest_mail_operation_notify_end (ModestMailOperation *self);
+static gboolean did_a_cancel = FALSE;
+
enum _ModestMailOperationSignals
{
PROGRESS_CHANGED_SIGNAL,
typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate;
struct _ModestMailOperationPrivate {
- guint id;
+ TnyAccount *account;
guint done;
guint total;
GObject *source;
GError *error;
ErrorCheckingUserCallback error_checking;
+ gpointer error_checking_user_data;
ModestMailOperationStatus status;
ModestMailOperationTypeOperation op_type;
};
gpointer user_data;
} XFerMsgAsyncHelper;
-typedef struct _XFerFolderAsyncHelper
-{
- ModestMailOperation *mail_op;
-
-} XFerFolderAsyncHelper;
-
/* globals */
static GObjectClass *parent_class = NULL;
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
+
}
static void
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
+ priv->account = NULL;
priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID;
priv->op_type = MODEST_MAIL_OPERATION_TYPE_UNKNOWN;
priv->error = NULL;
- priv->error_checking = NULL;
- priv->id = 0;
priv->done = 0;
priv->total = 0;
priv->source = NULL;
+ priv->error_checking = NULL;
+ priv->error_checking_user_data = NULL;
}
static void
g_object_unref (priv->source);
priv->source = NULL;
}
+ if (priv->account) {
+ g_object_unref (priv->account);
+ priv->account = NULL;
+ }
+
G_OBJECT_CLASS(parent_class)->finalize (obj);
}
ModestMailOperation*
modest_mail_operation_new_with_error_handling (ModestMailOperationTypeOperation op_type,
GObject *source,
- ErrorCheckingUserCallback error_handler)
+ ErrorCheckingUserCallback error_handler,
+ gpointer user_data)
{
ModestMailOperation *obj;
ModestMailOperationPrivate *priv;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS);
- if (priv->error_checking == NULL)
- return;
- priv->error_checking (priv->source, self);
+ if (priv->error_checking != NULL)
+ priv->error_checking (self, priv->error_checking_user_data);
}
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
- /* TODO: Tinymail does not support cancel operation */
-/* tny_account_cancel (); */
+ /* cancel current operation in account */
+ tny_account_cancel (priv->account);
+
+ did_a_cancel = TRUE;
/* Set new status */
priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
TnyTransportAccount *transport_account,
TnyMsg* msg)
{
- TnySendQueue *send_queue;
+ TnySendQueue *send_queue = NULL;
+ ModestMailOperationPrivate *priv;
g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
g_return_if_fail (TNY_IS_MSG (msg));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+ /* Get account and set it into mail_operation */
+ priv->account = g_object_ref (transport_account);
+
send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
- if (!TNY_IS_SEND_QUEUE(send_queue))
- g_printerr ("modest: could not find send queue for account\n");
- else {
- GError *err = NULL;
- tny_send_queue_add (send_queue, msg, &err);
- if (err) {
- g_printerr ("modest: error adding msg to send queue: %s\n",
- err->message);
- g_error_free (err);
- } else {
- /* g_message ("modest: message added to send queue"); */
- }
+ if (!TNY_IS_SEND_QUEUE(send_queue)) {
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
+ "modest: could not find send queue for account\n");
+ } else {
+ tny_send_queue_add (send_queue, msg, &(priv->error));
}
/* Notify about operation end */
void
modest_mail_operation_send_new_mail (ModestMailOperation *self,
TnyTransportAccount *transport_account,
+ TnyMsg *draft_msg,
const gchar *from, const gchar *to,
const gchar *cc, const gchar *bcc,
const gchar *subject, const gchar *plain_body,
const GList *attachments_list,
TnyHeaderFlags priority_flags)
{
- TnyMsg *new_msg;
+ TnyMsg *new_msg = NULL;
+ TnyFolder *folder = NULL;
+ TnyHeader *header = NULL;
ModestMailOperationPrivate *priv = NULL;
- /* GList *node = NULL; */
g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
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 */
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
_("Error trying to send a mail. You need to set at least one recipient"));
return;
}
- /* TODO: add priority handling. It's received in the priority_flags operator, and
- it should have effect in the sending operation */
+ /* Set priority flags in message */
+ header = tny_msg_get_header (new_msg);
+ tny_header_set_flags (header, priority_flags);
/* Call mail operation */
modest_mail_operation_send_mail (self, transport_account, new_msg);
+ folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
+ if (folder) {
+ if (draft_msg != NULL) {
+ header = tny_msg_get_header (draft_msg);
+ /* Note: This can fail (with a warning) if the message is not really already in a folder,
+ * because this function requires it to have a UID. */
+ tny_folder_remove_msg (folder, header, NULL);
+ g_object_unref (header);
+ }
+ }
+
/* Free */
g_object_unref (G_OBJECT (new_msg));
}
void
modest_mail_operation_save_to_drafts (ModestMailOperation *self,
TnyTransportAccount *transport_account,
+ TnyMsg *draft_msg,
const gchar *from, const gchar *to,
const gchar *cc, const gchar *bcc,
const gchar *subject, const gchar *plain_body,
{
TnyMsg *msg = NULL;
TnyFolder *folder = NULL;
+ TnyHeader *header = NULL;
ModestMailOperationPrivate *priv = NULL;
- GError *err = NULL;
-
- /* GList *node = NULL; */
g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+ /* Get account and set it into mail_operation */
+ priv->account = g_object_ref (transport_account);
+
if (html_body == NULL) {
msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
} else {
msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
}
if (!msg) {
- g_printerr ("modest: failed to create a new msg\n");
- goto cleanup;
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
+ "modest: failed to create a new msg\n");
+ goto end;
}
+ /* add priority flags */
+ header = tny_msg_get_header (msg);
+ tny_header_set_flags (header, priority_flags);
+
folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
if (!folder) {
- g_printerr ("modest: failed to find Drafts folder\n");
- goto cleanup;
- }
-
- tny_folder_add_msg (folder, msg, &err);
- if (err) {
- g_printerr ("modest: error adding msg to Drafts folder: %s",
- err->message);
- g_error_free (err);
- goto cleanup;
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
+ "modest: failed to create a new msg\n");
+ goto end;
}
- modest_mail_operation_notify_end (self);
+ if (draft_msg != NULL) {
+ header = tny_msg_get_header (draft_msg);
+ tny_folder_remove_msg (folder, header, NULL);
+ g_object_unref (header);
+ }
+
+ tny_folder_add_msg (folder, msg, &(priv->error));
+ if (priv->error)
+ goto end;
- /* Free */
-cleanup:
+end:
if (msg)
g_object_unref (G_OBJECT(msg));
if (folder)
g_object_unref (G_OBJECT(folder));
+
+ modest_mail_operation_notify_end (self);
}
typedef struct
static void
foreach_add_item (gpointer header, gpointer user_data)
{
+ /* printf("DEBUG: %s: header subject=%s\n",
+ * __FUNCTION__, tny_header_get_subject(TNY_HEADER(header)));
+ */
tny_list_prepend (TNY_LIST (user_data),
g_object_ref (G_OBJECT (header)));
}
static void
internal_folder_observer_update (TnyFolderObserver *self, TnyFolderChange *change)
{
+ InternalFolderObserver *derived = (InternalFolderObserver *)self;
+
TnyFolderChangeChanged changed;
changed = tny_folder_change_get_changed (change);
list = tny_simple_list_new ();
tny_folder_change_get_added_headers (change, list);
+ /* printf ("DEBUG: %s: Calling foreach with a list of size=%d\n",
+ * __FUNCTION__, tny_list_get_length(list));
+ */
+
/* Add them to the folder observer */
tny_list_foreach (list, foreach_add_item,
- ((InternalFolderObserver *)self)->new_headers);
+ derived->new_headers);
g_object_unref (G_OBJECT (list));
}
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);
g_object_unref (mail_op);
return FALSE;
}
+static int
+compare_headers_by_date (gconstpointer a,
+ gconstpointer b)
+{
+ TnyHeader **header1, **header2;
+ time_t sent1, sent2;
+
+ header1 = (TnyHeader **) a;
+ header2 = (TnyHeader **) b;
+
+ sent1 = tny_header_get_date_sent (*header1);
+ sent2 = tny_header_get_date_sent (*header2);
+
+ /* We want the most recent ones (greater time_t) at the
+ beginning */
+ if (sent1 < sent2)
+ return 1;
+ else
+ return -1;
+}
+
+static gboolean
+set_last_updated_idle (gpointer data)
+{
+ /* 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 */
+ modest_account_mgr_set_int (modest_runtime_get_account_mgr (),
+ (gchar *) data,
+ MODEST_ACCOUNT_LAST_UPDATED,
+ time(NULL),
+ TRUE);
+
+ return FALSE;
+}
+
static gpointer
update_account_thread (gpointer thr_user_data)
{
UpdateAccountInfo *info;
- TnyList *all_folders = NULL, *new_headers;
+ TnyList *all_folders = NULL;
+ GPtrArray *new_headers;
TnyIterator *iter = NULL;
TnyFolderStoreQuery *query = NULL;
ModestMailOperationPrivate *priv;
ModestTnySendQueue *send_queue;
- gint timeout, msg_num;
+
info = (UpdateAccountInfo *) thr_user_data;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
- /* Get all the folders We can do it synchronously because
+ /* Get account and set it into mail_operation */
+ priv->account = g_object_ref (info->account);
+
+ /* 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 ();
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
+ with a source function 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, idle_notify_progress, info->mail_op);
+ gint timeout = g_timeout_add (250, idle_notify_progress, info->mail_op);
/* Refresh folders */
- new_headers = tny_simple_list_new ();
+ new_headers = g_ptr_array_new ();
iter = tny_list_create_iterator (all_folders);
- while (!tny_iterator_is_done (iter) && !priv->error) {
+
+ while (!tny_iterator_is_done (iter) && !priv->error && !did_a_cancel) {
InternalFolderObserver *observer;
TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
/* 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));
- tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
+
+ /* This gets the status information (headers) from the server.
+ * We use the blocking version, because we are already in a separate
+ * thread.
+ */
- /* If the retrieve type is headers only do nothing more */
- if (!strcmp (info->retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) ||
- !strcmp (info->retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS)) {
+ if (!g_ascii_strcasecmp (info->retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) ||
+ !g_ascii_strcasecmp (info->retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS)) {
TnyIterator *iter;
+ /* If the retrieve type is full messages, refresh and get the messages */
+ tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
+
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)
- tny_list_prepend (new_headers, G_OBJECT (header));
+ g_ptr_array_add (new_headers, g_object_ref (header));
g_object_unref (header);
tny_iterator_next (iter);
}
g_object_unref (iter);
- }
+ } else /* If it's headers only, then just poke the folder status (this will update the unread and total count of folder observers, like the folder list model*/
+ tny_folder_poke_status (TNY_FOLDER (folder));
+
tny_folder_remove_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer));
g_object_unref (observer);
+ observer = NULL;
if (priv->error)
priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
g_object_unref (G_OBJECT (folder));
tny_iterator_next (iter);
}
- g_object_unref (G_OBJECT (iter));
- g_source_remove (timeout);
+ did_a_cancel = FALSE;
- /* Apply message count limit */
- /* TODO if the number of messages exceeds the maximum, ask the
- user to download them all */
- msg_num = 0;
- priv->total = MIN (tny_list_get_length (new_headers), info->retrieve_limit);
- iter = tny_list_create_iterator (new_headers);
- while ((msg_num < info->retrieve_limit) && !tny_iterator_is_done (iter)) {
-
- TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
- TnyFolder *folder = tny_header_get_folder (header);
- TnyMsg *msg = tny_folder_get_msg (folder, header, NULL);
- ModestMailOperationState *state;
- ModestPair* pair;
-
- priv->done++;
- /* We can not just use the mail operation because the
- values of done and total could change before the
- idle is called */
- state = modest_mail_operation_clone_state (info->mail_op);
- pair = modest_pair_new (g_object_ref (info->mail_op), state, FALSE);
- g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_notify_progress_once,
- pair, (GDestroyNotify) modest_pair_free);
-
- g_object_unref (msg);
- g_object_unref (folder);
- g_object_unref (header);
+ g_object_unref (G_OBJECT (iter));
+ g_source_remove (timeout);
- msg_num++;
- tny_iterator_next (iter);
+ if (new_headers->len > 0) {
+ gint msg_num = 0;
+
+ /* Order by date */
+ g_ptr_array_sort (new_headers, (GCompareFunc) compare_headers_by_date);
+
+ /* Apply message count limit */
+ /* If the number of messages exceeds the maximum, ask the
+ * 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. */
+ 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",
+ tny_account_get_name (TNY_ACCOUNT (info->transport_account)));
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+ goto out;
+ }
+
+ priv->done = 0;
+ priv->total = MIN (new_headers->len, info->retrieve_limit);
+ while (msg_num < priv->total) {
+
+ TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers, msg_num));
+ TnyFolder *folder = tny_header_get_folder (header);
+ TnyMsg *msg = tny_folder_get_msg (folder, header, NULL);
+ ModestMailOperationState *state;
+ ModestPair* pair;
+
+ priv->done++;
+ /* We can not just use the mail operation because the
+ values of done and total could change before the
+ idle is called */
+ state = modest_mail_operation_clone_state (info->mail_op);
+ pair = modest_pair_new (g_object_ref (info->mail_op), state, FALSE);
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_notify_progress_once,
+ pair, (GDestroyNotify) modest_pair_free);
+
+ g_object_unref (msg);
+ g_object_unref (folder);
+
+ msg_num++;
+ }
+ g_ptr_array_foreach (new_headers, (GFunc) g_object_unref, NULL);
+ g_ptr_array_free (new_headers, FALSE);
}
- g_object_unref (iter);
- g_object_unref (new_headers);
/* Perform send */
priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND;
priv->done = 0;
priv->total = 0;
-
- send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(info->transport_account));
-
- timeout = g_timeout_add (250, idle_notify_progress, info->mail_op);
- modest_tny_send_queue_flush (send_queue);
- g_source_remove (timeout);
-
- g_object_unref (G_OBJECT(send_queue));
+ if (priv->account != NULL)
+ g_object_unref (priv->account);
+ priv->account = g_object_ref (info->transport_account);
+
+ send_queue = modest_runtime_get_send_queue (info->transport_account);
+ if (send_queue) {
+ timeout = g_timeout_add (250, idle_notify_progress, info->mail_op);
+ modest_tny_send_queue_try_to_send (send_queue);
+ g_source_remove (timeout);
+ } else {
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
+ "cannot create a send queue for %s\n",
+ tny_account_get_name (TNY_ACCOUNT (info->transport_account)));
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+ }
/* Check if the operation was a success */
if (!priv->error) {
priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
/* 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);
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+ set_last_updated_idle,
+ g_strdup (tny_account_get_id (TNY_ACCOUNT (info->account))),
+ (GDestroyNotify) g_free);
}
out:
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 */
/* Get the Modest account */
modest_account = (TnyStoreAccount *)
- modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
+ modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
account_name,
TNY_ACCOUNT_TYPE_STORE);
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;
}
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;
}
MODEST_ACCOUNT_LIMIT_RETRIEVE, FALSE);
if (info->retrieve_limit == 0)
info->retrieve_limit = G_MAXINT;
+
+ /* printf ("DEBUG: %s: info->retrieve_limit = %d\n", __FUNCTION__, info->retrieve_limit); */
thread = g_thread_create (update_account_thread, info, FALSE, NULL);
TnyFolderStore *parent,
const gchar *name)
{
- ModestTnyFolderRules rules;
ModestMailOperationPrivate *priv;
TnyFolder *new_folder = NULL;
- gboolean can_create = FALSE;
g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
g_return_val_if_fail (name, NULL);
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
/* Check parent */
- if (!TNY_IS_FOLDER (parent)) {
- g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
- MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
- _("mail_in_ui_folder_create_error"));
- } else {
+ if (TNY_IS_FOLDER (parent)) {
/* Check folder rules */
- rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
- if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
+ ModestTnyFolderRules rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
+ if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
+ /* 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_FOLDER_RULES,
_("mail_in_ui_folder_create_error"));
- else
- can_create = TRUE;
+ }
}
- if (can_create) {
+ if (!priv->error) {
/* Create the folder */
new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
+ if (!priv->error)
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
}
/* Notify about operation end */
/* Check folder rules */
rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
if (rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE) {
+ /* 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_FOLDER_RULES,
_("mail_in_ui_folder_delete_error"));
}
/* Get the account */
- account = tny_folder_get_account (folder);
+ account = modest_tny_folder_get_account (folder);
+ priv->account = g_object_ref(account);
/* Delete folder or move to trash */
if (remove_to_trash) {
modest_mail_operation_notify_end (self);
}
-void
-modest_mail_operation_rename_folder (ModestMailOperation *self,
- TnyFolder *folder,
- const gchar *name)
-{
- ModestMailOperationPrivate *priv;
- ModestTnyFolderRules rules;
-
- g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
- g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
- g_return_if_fail (name);
-
- priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
-
- /* Check folder rules */
- rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
- if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
- g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
- MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
- _("FIXME: unable to rename"));
- } else {
- /* Rename. Camel handles folder subscription/unsubscription */
- TnyFolderStore *into;
- TnyFolder *nfol;
-
- into = tny_folder_get_folder_store (folder);
- nfol = tny_folder_copy (folder, into, name, TRUE, &(priv->error));
- if (into)
- g_object_unref (into);
- if (nfol)
- g_object_unref (nfol);
-
- CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
-
- }
-
- /* Notify about operation end */
- modest_mail_operation_notify_end (self);
- }
-
static void
transfer_folder_status_cb (GObject *obj,
TnyStatus *status,
gpointer user_data)
{
- XFerMsgAsyncHelper *helper = NULL;
ModestMailOperation *self;
ModestMailOperationPrivate *priv;
ModestMailOperationState *state;
g_return_if_fail (status != NULL);
g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
- helper = (XFerMsgAsyncHelper *) user_data;
- g_return_if_fail (helper != NULL);
-
- self = helper->mail_op;
+ self = MODEST_MAIL_OPERATION (user_data);
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
if ((status->position == 1) && (status->of_total == 100))
static void
-transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, 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;
ModestMailOperationPrivate *priv = NULL;
- helper = (XFerFolderAsyncHelper *) user_data;
- self = helper->mail_op;
+ self = MODEST_MAIL_OPERATION (user_data);
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
}
/* Free */
- g_slice_free (XFerFolderAsyncHelper, helper);
g_object_unref (folder);
g_object_unref (into);
if (new_folder != NULL)
TnyFolderStore *parent,
gboolean delete_original)
{
- XFerFolderAsyncHelper *helper = NULL;
ModestMailOperationPrivate *priv = NULL;
ModestTnyFolderRules parent_rules, rules;
g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
- g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
g_return_if_fail (TNY_IS_FOLDER (folder));
+ g_return_if_fail (TNY_IS_FOLDER (parent));
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
- /* Pick references for async calls */
- g_object_ref (folder);
- g_object_ref (parent);
+ /* Get account and set it into mail_operation */
+ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
+ priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
/* Get folder rules */
rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
parent_rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
+ if (!TNY_IS_FOLDER_STORE (parent)) {
+
+ }
+
/* The moveable restriction is applied also to copy operation */
- if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
+ if ((!TNY_IS_FOLDER_STORE (parent)) || (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE)) {
+ /* 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_FOLDER_RULES,
_("mail_in_ui_folder_move_target_error"));
/* Notify the queue */
modest_mail_operation_notify_end (self);
} else if (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
+ /* 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_FOLDER_RULES,
_("FIXME: parent folder does not accept new folders"));
/* Notify the queue */
modest_mail_operation_notify_end (self);
} else {
- helper = g_slice_new0 (XFerFolderAsyncHelper);
- helper->mail_op = self;
+ /* Pick references for async calls */
+ g_object_ref (folder);
+ g_object_ref (parent);
/* Move/Copy folder */
tny_folder_copy_async (folder,
delete_original,
transfer_folder_cb,
transfer_folder_status_cb,
- helper);
+ self);
}
}
+void
+modest_mail_operation_rename_folder (ModestMailOperation *self,
+ TnyFolder *folder,
+ const gchar *name)
+{
+ ModestMailOperationPrivate *priv;
+ ModestTnyFolderRules rules;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
+ g_return_if_fail (name);
+
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ /* Get account and set it into mail_operation */
+ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
+
+ /* Check folder rules */
+ rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
+ if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
+ /* 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_FOLDER_RULES,
+ _("FIXME: unable to rename"));
+
+ /* Notify about operation end */
+ modest_mail_operation_notify_end (self);
+ } else {
+ /* Rename. Camel handles folder subscription/unsubscription */
+ TnyFolderStore *into;
+
+ into = tny_folder_get_folder_store (folder);
+ tny_folder_copy_async (folder, into, name, TRUE,
+ transfer_folder_cb,
+ transfer_folder_status_cb,
+ self);
+ if (into)
+ g_object_unref (into);
+
+ }
+ }
/* ******************************************************************* */
/* ************************** MSG ACTIONS ************************* */
/* Get message from folder */
if (folder) {
+ /* Get account and set it into mail_operation */
+ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
+
helper = g_slice_new0 (GetMsgAsyncHelper);
helper->mail_op = self;
helper->user_callback = user_callback;
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"));
+
+ /* Notify the queue */
+ modest_mail_operation_notify_end (self);
}
}
tny_iterator_next (iter);
}
+ /* Set operation status */
+ if (priv->status == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+
/* Notify about operation end */
g_idle_add (notify_update_account_queue, info->mail_op);
gpointer user_data,
GDestroyNotify notify)
{
+ TnyHeader *header = NULL;
+ TnyFolder *folder = NULL;
GThread *thread;
ModestMailOperationPrivate *priv = NULL;
GetFullMsgsInfo *info = NULL;
gboolean size_ok = TRUE;
gint max_size;
- GError *error = NULL;
+ TnyIterator *iter = NULL;
g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
priv->done = 0;
priv->total = tny_list_get_length(header_list);
+ /* Get account and set it into mail_operation */
+ if (tny_list_get_length (header_list) >= 1) {
+ iter = tny_list_create_iterator (header_list);
+ header = TNY_HEADER (tny_iterator_get_current (iter));
+ folder = tny_header_get_folder (header);
+ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
+ g_object_unref (header);
+ g_object_unref (folder);
+
+ if (tny_list_get_length (header_list) == 1) {
+ g_object_unref (iter);
+ iter = NULL;
+ }
+ }
+
/* Get msg size limit */
max_size = modest_conf_get_int (modest_runtime_get_conf (),
MODEST_CONF_MSG_SIZE_LIMIT,
- &error);
- if (error) {
- g_clear_error (&error);
+ &(priv->error));
+ if (priv->error) {
+ g_clear_error (&(priv->error));
max_size = G_MAXINT;
} else {
max_size = max_size * KB;
/* Check message size limits. If there is only one message
always retrieve it */
- if (tny_list_get_length (header_list) > 1) {
- TnyIterator *iter;
-
- iter = tny_list_create_iterator (header_list);
+ if (iter != NULL) {
while (!tny_iterator_is_done (iter) && size_ok) {
- TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+ header = TNY_HEADER (tny_iterator_get_current (iter));
if (tny_header_get_message_size (header) >= max_size)
size_ok = FALSE;
g_object_unref (header);
thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
} else {
+ /* Set status failed and set an error */
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
/* FIXME: the error msg is different for pop */
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
- MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
- _("emev_ni_ui_imap_msg_sizelimit_error"));
+ 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);
if (notify)
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
folder = tny_header_get_folder (header);
+ /* Get account and set it into mail_operation */
+ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
+
priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
/* Delete or move to trash */
TnyFolder *trash_folder;
TnyStoreAccount *store_account;
- store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
+ store_account = TNY_STORE_ACCOUNT (modest_tny_folder_get_account (folder));
trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
TNY_FOLDER_TYPE_TRASH);
if (trash_folder) {
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;
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
_("FIXME: folder does not accept msgs"));
g_object_unref (header);
g_object_unref (iter);
+ /* Get account and set it into mail_operation */
+ priv->account = modest_tny_folder_get_account (src_folder);
+
/* Transfer messages */
tny_folder_transfer_msgs_async (src_folder,
headers,
priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+ /* Get account and set it into mail_operation */
+ priv->account = modest_tny_folder_get_account (folder);
+
/* Refresh the folder. TODO: tinymail could issue a status
updates before the callback call then this could happen. We
must review the design */
state = modest_mail_operation_clone_state (self);
g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL);
g_slice_free (ModestMailOperationState, state);
-
- /* Notify the queue */
- modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
}