From 3084439a659fa9aec750337f94cad4bca0c92898 Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Thu, 7 Dec 2006 08:03:25 +0000 Subject: [PATCH] * Added ModestMailOperationQueue * Added ModestFormmatter * Reformatted the modest-text-utils * Added some HTML formatter methods to the text utils * Added support to reply/forward HTML messages * Modified the tests in order to fit well with the new queue API * Removed a redundant method in the msg actions stuff * Refactored the reply/forward methods pmo-trunk-r522 --- src/Makefile.am | 6 +- src/gtk/modest-edit-msg-window.c | 2 +- src/modest-formatter.c | 298 +++++++++++++++++++++ src/modest-formatter.h | 71 +++++ src/modest-mail-operation-queue.c | 260 +++++++++++++++++++ src/modest-mail-operation-queue.h | 77 ++++++ src/modest-mail-operation.c | 340 ++++++++++++------------ src/modest-mail-operation.h | 19 +- src/modest-text-utils.c | 518 +++++++++++++++++++++---------------- src/modest-text-utils.h | 50 ++-- src/modest-tny-msg-actions.c | 25 -- src/modest-tny-msg-actions.h | 18 -- tests/Makefile.am | 6 +- tests/update-account.c | 34 ++- 14 files changed, 1229 insertions(+), 495 deletions(-) create mode 100644 src/modest-formatter.c create mode 100644 src/modest-formatter.h create mode 100644 src/modest-mail-operation-queue.c create mode 100644 src/modest-mail-operation-queue.h diff --git a/src/Makefile.am b/src/Makefile.am index 181ef2c..b5c99c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,8 +59,12 @@ modest_SOURCES=\ modest-marshal.h \ modest-mail-operation.c \ modest-mail-operation.h \ + modest-mail-operation-queue.c \ + modest-mail-operation-queue.h \ modest-tny-platform-factory.c \ - modest-tny-platform-factory.h + modest-tny-platform-factory.h \ + modest-formatter.c \ + modest-formatter.h modest_LDADD = \ $(MODEST_GSTUFF_LIBS) \ diff --git a/src/gtk/modest-edit-msg-window.c b/src/gtk/modest-edit-msg-window.c index 3c287f9..d7ff941 100644 --- a/src/gtk/modest-edit-msg-window.c +++ b/src/gtk/modest-edit-msg-window.c @@ -485,7 +485,7 @@ modest_edit_msg_window_new (ModestWidgetFactory *factory, buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body)); gtk_text_buffer_set_text (buf, - (const gchar *) modest_tny_msg_actions_find_body (msg, FALSE), + (const gchar *) modest_tny_msg_actions_find_body (msg, TRUE), -1); /* TODO: lower priority, select in the From: combo to diff --git a/src/modest-formatter.c b/src/modest-formatter.c new file mode 100644 index 0000000..2e175a6 --- /dev/null +++ b/src/modest-formatter.c @@ -0,0 +1,298 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "modest-formatter.h" +#include "modest-text-utils.h" + +typedef struct _ModestFormatterPrivate ModestFormatterPrivate; +struct _ModestFormatterPrivate { + gchar *content_type; +}; +#define MODEST_FORMATTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_FORMATTER, \ + ModestFormatterPrivate)) + +static GObjectClass *parent_class = NULL; + +typedef gchar* FormatterFunc (ModestFormatter *self, const gchar *text, TnyHeader *header); + +static TnyMsg *modest_formatter_do (ModestFormatter *self, + TnyMimePart *body, + TnyHeader *header, + FormatterFunc func); + +static gchar* modest_formatter_wrapper_cite (ModestFormatter *self, const gchar *text, TnyHeader *header); +static gchar* modest_formatter_wrapper_quote (ModestFormatter *self, const gchar *text, TnyHeader *header); +static gchar* modest_formatter_wrapper_inline (ModestFormatter *self, const gchar *text, TnyHeader *header); + +static gchar * +extract_text (ModestFormatter *self, TnyMimePart *body) +{ + TnyStream *stream; + GtkTextBuffer *buf; + GtkTextIter start, end; + gchar *text, *converted_text; + ModestFormatterPrivate *priv; + + buf = gtk_text_buffer_new (NULL); + stream = TNY_STREAM (tny_gtk_text_buffer_stream_new (buf)); + tny_stream_reset (stream); + tny_mime_part_decode_to_stream (body, stream); + tny_stream_reset (stream); + + g_object_unref (G_OBJECT(stream)); + g_object_unref (G_OBJECT(body)); + + gtk_text_buffer_get_bounds (buf, &start, &end); + text = gtk_text_buffer_get_text (buf, &start, &end, FALSE); + g_object_unref (buf); + + /* Convert to desired content type if needed */ + priv = MODEST_FORMATTER_GET_PRIVATE (self); + + if (strcmp (tny_mime_part_get_content_type (body), priv->content_type)) { + if (!strcmp (priv->content_type, "text/html")) + converted_text = modest_text_utils_convert_to_html (text); +/* else */ +/* converted_text = modest_text_utils_convert_to_plain (text); */ + + g_free (text); + text = converted_text; + } + + return text; +} + +static void +construct_from_text (TnyMimePart *part, + const gchar *text, + const gchar *content_type) +{ + TnyStream *text_body_stream; + + /* Create the stream */ + text_body_stream = TNY_STREAM (tny_camel_stream_new + (camel_stream_mem_new_with_buffer + (text, strlen(text)))); + + /* Construct MIME part */ + tny_stream_reset (text_body_stream); + tny_mime_part_construct_from_stream (part, text_body_stream, content_type); + tny_stream_reset (text_body_stream); + + /* Clean */ + g_object_unref (G_OBJECT (text_body_stream)); +} + +static TnyMsg * +modest_formatter_do (ModestFormatter *self, + TnyMimePart *body, + TnyHeader *header, + FormatterFunc func) +{ + TnyMsg *new_msg; + gchar *body_text = NULL, *txt = NULL; + ModestFormatterPrivate *priv; + + /* Build new part */ + new_msg = TNY_MSG (tny_camel_msg_new ()); + body_text = extract_text (self, body); + txt = (gchar *) func (self, (const gchar*) body_text, header); + priv = MODEST_FORMATTER_GET_PRIVATE (self); + construct_from_text (TNY_MIME_PART (new_msg), (const gchar*) txt, priv->content_type); + + /* Clean */ + g_free (body_text); + g_free (txt); + + return new_msg; +} + +TnyMsg * +modest_formatter_cite (ModestFormatter *self, TnyMimePart *body, TnyHeader *header) +{ + modest_formatter_do (self, body, header, modest_formatter_wrapper_cite); +} + +TnyMsg * +modest_formatter_quote (ModestFormatter *self, TnyMimePart *body, TnyHeader *header) +{ + modest_formatter_do (self, body, header, modest_formatter_wrapper_quote); +} + +TnyMsg * +modest_formatter_inline (ModestFormatter *self, TnyMimePart *body, TnyHeader *header) +{ + modest_formatter_do (self, body, header, modest_formatter_wrapper_inline); +} + +TnyMsg * +modest_formatter_attach (ModestFormatter *self, TnyMimePart *body, TnyHeader *header) +{ + TnyMsg *new_msg = NULL; + gchar *attach_text = NULL; + TnyMimePart *body_part = NULL, *attach_part = NULL; + ModestFormatterPrivate *priv; + + /* Build new part */ + new_msg = TNY_MSG (tny_camel_msg_new ()); + body_part = TNY_MIME_PART (tny_camel_mime_part_new (camel_mime_part_new())); + attach_part = TNY_MIME_PART (tny_camel_mime_part_new (camel_mime_part_new())); + + /* Create the two parts */ + priv = MODEST_FORMATTER_GET_PRIVATE (self); + attach_text = extract_text (self, body); + construct_from_text (body_part, "", priv->content_type); + construct_from_text (attach_part, (const gchar*) attach_text, priv->content_type); + tny_mime_part_set_filename (attach_part, tny_header_get_subject (header)); + + /* Add parts */ + tny_mime_part_add_part (TNY_MIME_PART (new_msg), body_part); + tny_mime_part_add_part (TNY_MIME_PART (new_msg), attach_part); + + /* Clean */ + g_free (attach_text); + + return new_msg; +} + +ModestFormatter* +modest_formatter_new (const gchar *content_type) +{ + ModestFormatter *formatter; + ModestFormatterPrivate *priv; + + formatter = g_object_new (MODEST_TYPE_FORMATTER, NULL); + priv = MODEST_FORMATTER_GET_PRIVATE (formatter); + priv->content_type = g_strdup (content_type); + + return formatter; +} + +static void +modest_formatter_instance_init (GTypeInstance *instance, gpointer g_class) +{ + ModestFormatter *self = (ModestFormatter *)instance; + ModestFormatterPrivate *priv = MODEST_FORMATTER_GET_PRIVATE (self); + + priv->content_type = NULL; +} + +static void +modest_formatter_finalize (GObject *object) +{ + ModestFormatter *self = (ModestFormatter *)object; + ModestFormatterPrivate *priv = MODEST_FORMATTER_GET_PRIVATE (self); + + if (priv->content_type) + g_free (priv->content_type); + + (*parent_class->finalize) (object); +} + +static void +modest_formatter_class_init (ModestFormatterClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + object_class = (GObjectClass*) class; + + g_type_class_add_private (object_class, sizeof (ModestFormatterPrivate)); +} + +GType +modest_formatter_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY(type == 0)) + { + static const GTypeInfo info = + { + sizeof (ModestFormatterClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) modest_formatter_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ModestFormatter), + 0, /* n_preallocs */ + modest_formatter_instance_init /* instance_init */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "ModestFormatter", + &info, 0); + } + + return type; +} + +/****************/ +static gchar * +modest_formatter_wrapper_cite (ModestFormatter *self, const gchar *text, TnyHeader *header) +{ + ModestFormatterPrivate *priv = MODEST_FORMATTER_GET_PRIVATE (self); + + return modest_text_utils_cite (text, + priv->content_type, + tny_header_get_from (header), + tny_header_get_date_sent (header)); +} + +static gchar * +modest_formatter_wrapper_inline (ModestFormatter *self, const gchar *text, TnyHeader *header) +{ + ModestFormatterPrivate *priv = MODEST_FORMATTER_GET_PRIVATE (self); + + return modest_text_utils_inline (text, + priv->content_type, + tny_header_get_from (header), + tny_header_get_date_sent (header), + tny_header_get_to (header), + tny_header_get_subject (header)); +} + +static gchar * +modest_formatter_wrapper_quote (ModestFormatter *self, const gchar *text, TnyHeader *header) +{ + ModestFormatterPrivate *priv = MODEST_FORMATTER_GET_PRIVATE (self); + + /* TODO: get 80 from the configuration */ + return modest_text_utils_quote (text, + priv->content_type, + tny_header_get_from (header), + tny_header_get_date_sent (header), + 80); +} diff --git a/src/modest-formatter.h b/src/modest-formatter.h new file mode 100644 index 0000000..92bb925 --- /dev/null +++ b/src/modest-formatter.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MODEST_FORMATTER_H__ +#define __MODEST_FORMATTER_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define MODEST_TYPE_FORMATTER (modest_formatter_get_type ()) +#define MODEST_FORMATTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MODEST_TYPE_FORMATTER, ModestFormatter)) +#define MODEST_FORMATTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MODEST_TYPE_FORMATTER, ModestFormatterClass)) +#define MODEST_IS_FORMATTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MODEST_TYPE_FORMATTER)) +#define MODEST_IS_FORMATTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MODEST_TYPE_FORMATTER)) +#define MODEST_FORMATTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MODEST_TYPE_FORMATTER, ModestFormatterClass)) + +typedef struct _ModestFormatter ModestFormatter; +typedef struct _ModestFormatterClass ModestFormatterClass; + +struct _ModestFormatter +{ + GObject parent; +}; + +struct _ModestFormatterClass +{ + GObjectClass parent; +}; + +GType modest_formatter_get_type (void); + +ModestFormatter* modest_formatter_new (const gchar *content_type); + +TnyMsg * modest_formatter_cite (ModestFormatter *self, TnyMimePart *part, TnyHeader *header); +TnyMsg * modest_formatter_quote (ModestFormatter *self, TnyMimePart *part, TnyHeader *header); +TnyMsg * modest_formatter_inline (ModestFormatter *self, TnyMimePart *part, TnyHeader *header); +TnyMsg * modest_formatter_attach (ModestFormatter *self, TnyMimePart *part, TnyHeader *header); + + +G_END_DECLS + +#endif diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c new file mode 100644 index 0000000..d4e0c01 --- /dev/null +++ b/src/modest-mail-operation-queue.c @@ -0,0 +1,260 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "modest-mail-operation-queue.h" + +/* 'private'/'protected' functions */ +static void modest_mail_operation_queue_class_init (ModestMailOperationQueueClass *klass); +static void modest_mail_operation_queue_init (ModestMailOperationQueue *obj); +static void modest_mail_operation_queue_finalize (GObject *obj); + +static GObject *modest_mail_operation_queue_constructor (GType type, guint n_construct_params, + GObjectConstructParam *construct_params); + +static void modest_mail_operation_queue_cancel_no_block_wrapper (ModestMailOperation *mail_op, + ModestMailOperationQueue *op_queue); + +static void modest_mail_operation_queue_cancel_no_block (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op); + +/* list my signals */ +enum { + /* MY_SIGNAL_1, */ + /* MY_SIGNAL_2, */ + LAST_SIGNAL +}; + +typedef struct _ModestMailOperationQueuePrivate ModestMailOperationQueuePrivate; +struct _ModestMailOperationQueuePrivate { + GQueue *op_queue; + GMutex *queue_lock; +}; +#define MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_MAIL_OPERATION_QUEUE, \ + ModestMailOperationQueuePrivate)) +/* globals */ +static GObjectClass *parent_class = NULL; +static ModestMailOperationQueue *singleton = NULL; + +/* uncomment the following if you have defined any signals */ +/* static guint signals[LAST_SIGNAL] = {0}; */ + +GType +modest_mail_operation_queue_get_type (void) +{ + static GType my_type = 0; + if (!my_type) { + static const GTypeInfo my_info = { + sizeof(ModestMailOperationQueueClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc) modest_mail_operation_queue_class_init, + NULL, /* class finalize */ + NULL, /* class data */ + sizeof(ModestMailOperationQueue), + 1, /* n_preallocs */ + (GInstanceInitFunc) modest_mail_operation_queue_init, + NULL + }; + + my_type = g_type_register_static (G_TYPE_OBJECT, + "ModestMailOperationQueue", + &my_info, 0); + } + return my_type; +} + +static void +modest_mail_operation_queue_class_init (ModestMailOperationQueueClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass*) klass; + parent_class = g_type_class_peek_parent (klass); + + gobject_class->finalize = modest_mail_operation_queue_finalize; + gobject_class->constructor = modest_mail_operation_queue_constructor; + + g_type_class_add_private (gobject_class, sizeof(ModestMailOperationQueuePrivate)); +} + +static void +modest_mail_operation_queue_init (ModestMailOperationQueue *obj) +{ + ModestMailOperationQueuePrivate *priv; + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(obj); + + priv->op_queue = g_queue_new (); + priv->queue_lock = g_mutex_new (); +} + +static GObject* +modest_mail_operation_queue_constructor (GType type, guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + + if (!singleton) { + object = G_OBJECT_CLASS (parent_class)->constructor (type, + n_construct_params, construct_params); + + singleton = MODEST_MAIL_OPERATION_QUEUE (object); + } else { + object = G_OBJECT (singleton); + g_object_freeze_notify (G_OBJECT (singleton)); + } + + return object; +} + +static void +modest_mail_operation_queue_finalize (GObject *obj) +{ + ModestMailOperationQueuePrivate *priv; + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(obj); + + g_mutex_lock (priv->queue_lock); + + if (priv->op_queue) { + if (!g_queue_is_empty (priv->op_queue)) + g_queue_foreach (priv->op_queue, (GFunc) g_object_unref, NULL); + g_queue_free (priv->op_queue); + } + + g_mutex_unlock (priv->queue_lock); + g_mutex_free (priv->queue_lock); + + G_OBJECT_CLASS(parent_class)->finalize (obj); +} + +ModestMailOperationQueue * +modest_mail_operation_queue_get_instance (void) +{ + ModestMailOperationQueue *self = g_object_new (MODEST_TYPE_MAIL_OPERATION_QUEUE, NULL); + + return MODEST_MAIL_OPERATION_QUEUE (self); +} + +void +modest_mail_operation_queue_add (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op) +{ + ModestMailOperationQueuePrivate *priv; + + if (!MODEST_IS_MAIL_OPERATION (mail_op) || + !MODEST_IS_MAIL_OPERATION_QUEUE (op_queue)) { + g_warning ("%s: bad parametters", G_GNUC_FUNCTION); + return; + } + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(op_queue); + + g_mutex_lock (priv->queue_lock); + g_queue_push_tail (priv->op_queue, g_object_ref (mail_op)); + g_mutex_unlock (priv->queue_lock); +} + +void +modest_mail_operation_queue_remove (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op) +{ + ModestMailOperationQueuePrivate *priv; + + if (!MODEST_IS_MAIL_OPERATION (mail_op) || + !MODEST_IS_MAIL_OPERATION_QUEUE (op_queue)) { + g_warning ("%s: invalid paramette", G_GNUC_FUNCTION); + return; + } + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(op_queue); + + g_mutex_lock (priv->queue_lock); + g_queue_remove (priv->op_queue, mail_op); + g_mutex_unlock (priv->queue_lock); + + g_object_unref (G_OBJECT (mail_op)); +} + + +/* Utility function intended to be used with g_queue_foreach */ +static void +modest_mail_operation_queue_cancel_no_block_wrapper (ModestMailOperation *mail_op, + ModestMailOperationQueue *op_queue) +{ + modest_mail_operation_queue_cancel_no_block (op_queue, mail_op); +} + +static void +modest_mail_operation_queue_cancel_no_block (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op) +{ + /* TODO: place here the cancel code */ +} + +void +modest_mail_operation_queue_cancel (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op) +{ + ModestMailOperationQueuePrivate *priv; + GList *iter; + + if (!MODEST_IS_MAIL_OPERATION (mail_op) || + !MODEST_IS_MAIL_OPERATION_QUEUE (op_queue)) { + g_warning ("%s: invalid paramette", G_GNUC_FUNCTION); + return; + } + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(op_queue); + + g_mutex_lock (priv->queue_lock); + modest_mail_operation_queue_cancel_no_block (op_queue, mail_op); + g_mutex_unlock (priv->queue_lock); +} + +void +modest_mail_operation_queue_cancel_all (ModestMailOperationQueue *op_queue) +{ + ModestMailOperationQueuePrivate *priv; + + if (!MODEST_IS_MAIL_OPERATION_QUEUE (op_queue)) { + g_warning ("%s: invalid paramette", G_GNUC_FUNCTION); + return; + } + + priv = MODEST_MAIL_OPERATION_QUEUE_GET_PRIVATE(op_queue); + + g_mutex_lock (priv->queue_lock); + g_queue_foreach (priv->op_queue, + (GFunc) modest_mail_operation_queue_cancel_no_block_wrapper, + op_queue); + g_mutex_unlock (priv->queue_lock); +} diff --git a/src/modest-mail-operation-queue.h b/src/modest-mail-operation-queue.h new file mode 100644 index 0000000..54972df --- /dev/null +++ b/src/modest-mail-operation-queue.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* modest-tny-platform-factory.h */ + +#ifndef __MODEST_MAIL_OPERATION_QUEUE_H__ +#define __MODEST_MAIL_OPERATION_QUEUE_H__ + +#include +#include "modest-mail-operation.h" + +G_BEGIN_DECLS + +/* convenience macros */ +#define MODEST_TYPE_MAIL_OPERATION_QUEUE (modest_mail_operation_queue_get_type()) +#define MODEST_MAIL_OPERATION_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_MAIL_OPERATION_QUEUE,ModestMailOperationQueue)) +#define MODEST_MAIL_OPERATION_QUEUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_MAIL_OPERATION_QUEUE,GObject)) +#define MODEST_IS_MAIL_OPERATION_QUEUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_MAIL_OPERATION_QUEUE)) +#define MODEST_IS_MAIL_OPERATION_QUEUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_MAIL_OPERATION_QUEUE)) +#define MODEST_MAIL_OPERATION_QUEUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_MAIL_OPERATION_QUEUE,ModestMailOperationQueueClass)) + +typedef struct _ModestMailOperationQueue ModestMailOperationQueue; +typedef struct _ModestMailOperationQueueClass ModestMailOperationQueueClass; + +struct _ModestMailOperationQueue { + GObject parent; +}; + +struct _ModestMailOperationQueueClass { + GObjectClass parent_class; +}; + +/* member functions */ +GType modest_mail_operation_queue_get_type (void) G_GNUC_CONST; + +ModestMailOperationQueue * modest_mail_operation_queue_get_instance (void); + +void modest_mail_operation_queue_add (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op); + +void modest_mail_operation_queue_remove (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op); + +void modest_mail_operation_queue_cancel (ModestMailOperationQueue *op_queue, + ModestMailOperation *mail_op); + +void modest_mail_operation_queue_cancel_all (ModestMailOperationQueue *op_queue); + +G_END_DECLS + +#endif /* __MODEST_MAIL_OPERATION_QUEUE_H__ */ diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index b656804..66611f9 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -47,6 +47,7 @@ #include "modest-tny-msg-actions.h" #include "modest-tny-platform-factory.h" #include "modest-marshal.h" +#include "modest-formatter.h" /* 'private'/'protected' functions */ static void modest_mail_operation_class_init (ModestMailOperationClass *klass); @@ -59,17 +60,11 @@ typedef enum _ModestMailOperationErrorCode ModestMailOperationErrorCode; enum _ModestMailOperationErrorCode { MODEST_MAIL_OPERATION_ERROR_BAD_ACCOUNT, MODEST_MAIL_OPERATION_ERROR_MISSING_PARAMETER, + MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED, MODEST_MAIL_OPERATION_NUM_ERROR_CODES }; -typedef struct -{ - ModestMailOperation *mail_op; - GCallback cb; - gpointer user_data; -} AsyncHelper; - static void set_error (ModestMailOperation *mail_operation, ModestMailOperationErrorCode error_code, const gchar *fmt, ...); @@ -78,11 +73,11 @@ static void status_update_cb (TnyFolder *folder, gint status, gpointer user_data); static void folder_refresh_cb (TnyFolder *folder, - gboolean cancelled, + gboolean canceled, GError **err, gpointer user_data); static void add_attachments (TnyMsg *msg, - const GList *attachments_list); + GList *attachments_list); static TnyMimePart * add_body_part (TnyMsg *msg, @@ -114,6 +109,8 @@ enum _ModestMailOperationSignals typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate; struct _ModestMailOperationPrivate { + guint failed; + guint canceled; guint done; guint total; GMutex *cb_lock; @@ -186,11 +183,13 @@ modest_mail_operation_init (ModestMailOperation *obj) priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj); - priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID; - priv->error = NULL; - priv->done = 0; - priv->total = 0; - priv->cb_lock = g_mutex_new (); + priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID; + priv->error = NULL; + priv->done = 0; + priv->failed = 0; + priv->canceled = 0; + priv->total = 0; + priv->cb_lock = g_mutex_new (); } static void @@ -273,9 +272,9 @@ modest_mail_operation_send_new_mail (ModestMailOperation *mail_op, (attachments_list == NULL) ? FALSE : TRUE); /* Add attachments */ - add_attachments (new_msg, attachments_list); + add_attachments (new_msg, (GList*) attachments_list); - /* Send mail */ + /* Send mail */ tny_transport_account_send (transport_account, new_msg, NULL); /* FIXME */ /* Clean */ @@ -284,115 +283,107 @@ modest_mail_operation_send_new_mail (ModestMailOperation *mail_op, g_free(content_type); } -/** - * modest_mail_operation_create_forward_mail: - * @msg: a valid #TnyMsg instance - * @forward_type: the type of forwarded message - * - * creates a forwarded message from an existing one - * - * Returns: a new #TnyMsg, or NULL in case of error - **/ -TnyMsg* -modest_mail_operation_create_forward_mail (TnyMsg *msg, - const gchar *from, - ModestMailOperationForwardType forward_type) +static void +add_if_attachment (gpointer data, gpointer user_data) { - TnyMsg *new_msg; - TnyHeader *new_header, *header; - gchar *new_subject, *new_body, *content_type; - TnyMimePart *text_body_part = NULL; + TnyMimePart *part; GList *attachments_list; - TnyList *parts; - TnyIterator *iter; - g_return_val_if_fail (TNY_IS_MSG (msg), NULL); - g_return_val_if_fail (from != NULL , NULL); - g_return_val_if_fail (forward_type > 0, NULL); + part = TNY_MIME_PART (data); + attachments_list = (GList *) user_data; - /* Create new objects */ - new_msg = TNY_MSG (tny_camel_msg_new ()); - new_header = TNY_HEADER (tny_camel_header_new ()); + if (tny_mime_part_is_attachment (part)) + attachments_list = g_list_prepend (attachments_list, part); +} + + +static TnyMsg * +create_reply_forward_mail (TnyMsg *msg, const gchar *from, gboolean is_reply, guint type) +{ + TnyMsg *new_msg; + TnyHeader *new_header, *header; + gchar *new_subject; + TnyMimePart *body; + ModestFormatter *formatter; + /* Get body from original msg */ header = tny_msg_get_header (msg); + body = modest_tny_msg_actions_find_body_part (msg, TRUE); + + /* TODO: select the formatter from account prefs */ + formatter = modest_formatter_new ("text/plain"); + + /* Format message body */ + if (is_reply) { + switch (type) { + case MODEST_MAIL_OPERATION_REPLY_TYPE_CITE: + default: + new_msg = modest_formatter_cite (formatter, body, header); + break; + case MODEST_MAIL_OPERATION_REPLY_TYPE_QUOTE: + new_msg = modest_formatter_quote (formatter, body, header); + break; + } + } else { + switch (type) { + case MODEST_MAIL_OPERATION_FORWARD_TYPE_INLINE: + default: + new_msg = modest_formatter_inline (formatter, body, header); + break; + case MODEST_MAIL_OPERATION_FORWARD_TYPE_ATTACHMENT: + new_msg = modest_formatter_attach (formatter, body, header); + break; + } + } + g_object_unref (G_OBJECT (formatter)); /* Fill the header */ - tny_msg_set_header (new_msg, new_header); + new_header = TNY_HEADER (tny_camel_header_new ()); + tny_msg_set_header (new_msg, new_header); tny_header_set_from (new_header, from); /* Change the subject */ - new_subject = (gchar *) modest_text_utils_derived_subject (tny_header_get_subject(header), - _("Fwd:")); + new_subject = (gchar *) modest_text_utils_derived_subject (tny_header_get_subject(header), + (is_reply) ? _("Re:") : _("Fwd:")); tny_header_set_subject (new_header, (const gchar *) new_subject); g_free (new_subject); - /* Get body from original msg */ - new_body = (gchar *) modest_tny_msg_actions_find_body (msg, TRUE); - if (!new_body) { - g_object_unref (new_msg); - return NULL; - } - content_type = get_content_type(new_body); - - /* Create the list of attachments */ - parts = TNY_LIST (tny_simple_list_new()); - tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); - iter = tny_list_create_iterator (parts); - attachments_list = NULL; + /* Clean */ + g_object_unref (G_OBJECT (new_header)); + g_object_unref (G_OBJECT (header)); - while (!tny_iterator_is_done(iter)) { - TnyMimePart *part; + return new_msg; +} - part = TNY_MIME_PART (tny_iterator_get_current (iter)); - if (tny_mime_part_is_attachment (part)) - attachments_list = g_list_prepend (attachments_list, part); +/** + * modest_mail_operation_create_forward_mail: + * @msg: a valid #TnyMsg instance + * @forward_type: the type of forwarded message + * + * creates a forwarded message from an existing one + * + * Returns: a new #TnyMsg, or NULL in case of error + **/ +TnyMsg* +modest_mail_operation_create_forward_mail (TnyMsg *msg, + const gchar *from, + ModestMailOperationForwardType forward_type) +{ + TnyMsg *new_msg; + TnyList *parts = NULL; + GList *attachments_list = NULL; - tny_iterator_next (iter); - } + new_msg = create_reply_forward_mail (msg, from, FALSE, forward_type); /* Add attachments */ + parts = TNY_LIST (tny_simple_list_new()); + tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); + tny_list_foreach (parts, add_if_attachment, attachments_list); add_attachments (new_msg, attachments_list); - switch (forward_type) { - TnyMimePart *attachment_part; - gchar *inlined_text; - - case MODEST_MAIL_OPERATION_FORWARD_TYPE_INLINE: - /* Prepend "Original message" text */ - inlined_text = (gchar *) - modest_text_utils_inlined_text (tny_header_get_from (header), - tny_header_get_date_sent (header), - tny_header_get_to (header), - tny_header_get_subject (header), - (const gchar*) new_body); - g_free (new_body); - new_body = inlined_text; - - /* Add body part */ - add_body_part (new_msg, new_body, - (const gchar *) content_type, - (tny_list_get_length (parts) > 0) ? TRUE : FALSE); - - break; - case MODEST_MAIL_OPERATION_FORWARD_TYPE_ATTACHMENT: - attachment_part = add_body_part (new_msg, new_body, - (const gchar *) content_type, TRUE); - - /* Set the subject as the name of the attachment */ - tny_mime_part_set_filename (attachment_part, tny_header_get_subject (header)); - - break; - default: - g_warning (_("Invalid forward type")); - g_free (new_msg); - } - /* Clean */ if (attachments_list) g_list_free (attachments_list); - g_object_unref (parts); - if (text_body_part) g_free (text_body_part); - g_free (content_type); - g_free (new_body); + g_object_unref (G_OBJECT (parts)); return new_msg; } @@ -415,18 +406,13 @@ modest_mail_operation_create_reply_mail (TnyMsg *msg, { TnyMsg *new_msg; TnyHeader *new_header, *header; - gchar *new_subject, *new_body, *content_type, *quoted; - TnyMimePart *text_body_part; - /* Create new objects */ - new_msg = TNY_MSG (tny_camel_msg_new ()); - new_header = TNY_HEADER (tny_camel_header_new ()); - header = tny_msg_get_header (msg); + new_msg = create_reply_forward_mail (msg, from, TRUE, reply_type); /* Fill the header */ - tny_msg_set_header (new_msg, new_header); - tny_header_set_to (new_header, tny_header_get_from (header)); - tny_header_set_from (new_header, from); + header = tny_msg_get_header (msg); + new_header = tny_msg_get_header (new_msg); + tny_header_set_to (new_header, tny_header_get_from (header)); switch (reply_mode) { gchar *new_cc = NULL; @@ -461,49 +447,9 @@ modest_mail_operation_create_reply_mail (TnyMsg *msg, break; } - /* Change the subject */ - new_subject = (gchar*) modest_text_utils_derived_subject (tny_header_get_subject(header), - _("Re:")); - tny_header_set_subject (new_header, (const gchar *) new_subject); - g_free (new_subject); - - /* Get body from original msg */ - new_body = (gchar*) modest_tny_msg_actions_find_body (msg, TRUE); - if (!new_body) { - g_object_unref (new_msg); - return NULL; - } - content_type = get_content_type(new_body); - - switch (reply_type) { - gchar *cited_text; - - case MODEST_MAIL_OPERATION_REPLY_TYPE_CITE: - /* Prepend "Original message" text */ - cited_text = (gchar *) modest_text_utils_cited_text (tny_header_get_from (header), - tny_header_get_date_sent (header), - (const gchar*) new_body); - g_free (new_body); - new_body = cited_text; - break; - case MODEST_MAIL_OPERATION_REPLY_TYPE_QUOTE: - /* FIXME: replace 80 with a value from ModestConf */ - quoted = (gchar*) modest_text_utils_quote (new_body, - tny_header_get_from (header), - tny_header_get_date_sent (header), - 80); - g_free (new_body); - new_body = quoted; - break; - } - /* Add body part */ - text_body_part = add_body_part (new_msg, new_body, - (const gchar *) content_type, TRUE); - /* Clean */ -/* g_free (text_body_part); */ - g_free (content_type); - g_free (new_body); + g_object_unref (G_OBJECT (new_header)); + g_object_unref (G_OBJECT (header)); return new_msg; } @@ -515,45 +461,53 @@ status_update_cb (TnyFolder *folder, const gchar *what, gint status, gpointer us } static void -folder_refresh_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data) +folder_refresh_cb (TnyFolder *folder, gboolean canceled, GError **err, gpointer user_data) { - AsyncHelper *helper = NULL; ModestMailOperation *mail_op = NULL; ModestMailOperationPrivate *priv = NULL; - helper = (AsyncHelper *) user_data; - mail_op = MODEST_MAIL_OPERATION (helper->mail_op); + mail_op = MODEST_MAIL_OPERATION (user_data); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(mail_op); g_mutex_lock (priv->cb_lock); - priv->done++; + if ((canceled && *err) || *err) { + priv->error = g_error_copy (*err); + priv->failed++; + } else if (canceled) { + priv->canceled++; + set_error (mail_op, + MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED, + _("Error trying to refresh folder %s. Operation canceled"), + tny_folder_get_name (folder)); + } else { + priv->done++; + } - if (cancelled) - priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELLED; - else - g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); + if (priv->done == priv->total) + priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + else if ((priv->done + priv->canceled + priv->failed) == priv->total) + if (priv->failed == priv->total) + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + else if (priv->failed == priv->total) + priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED; + else + priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS; g_mutex_unlock (priv->cb_lock); - if (priv->done == priv->total) { - ((ModestUpdateAccountCallback) (helper->cb)) (mail_op, helper->user_data); - g_slice_free (AsyncHelper, helper); - } + g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); } -void +gboolean modest_mail_operation_update_account (ModestMailOperation *mail_op, - TnyStoreAccount *store_account, - ModestUpdateAccountCallback callback, - gpointer user_data) + TnyStoreAccount *store_account) { ModestMailOperationPrivate *priv; TnyList *folders; TnyIterator *ifolders; TnyFolder *cur_folder; TnyFolderStoreQuery *query; - AsyncHelper *helper; g_return_if_fail (MODEST_IS_MAIL_OPERATION (mail_op)); g_return_if_fail (TNY_IS_STORE_ACCOUNT(store_account)); @@ -571,24 +525,23 @@ modest_mail_operation_update_account (ModestMailOperation *mail_op, ifolders = tny_list_create_iterator (folders); priv->total = tny_list_get_length (folders); priv->done = 0; + priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; gint i =0; - /* Async refresh folders */ + /* Async refresh folders. Reference the mail_op because + tinymail destroys the user_data */ for (tny_iterator_first (ifolders); !tny_iterator_is_done (ifolders); tny_iterator_next (ifolders)) { cur_folder = TNY_FOLDER (tny_iterator_get_current (ifolders)); - helper = g_slice_new0 (AsyncHelper); - helper->mail_op = mail_op; - helper->user_data = user_data; - helper->cb = G_CALLBACK (callback); - tny_folder_refresh_async (cur_folder, folder_refresh_cb, - status_update_cb, helper); + status_update_cb, g_object_ref (mail_op)); } g_object_unref (ifolders); + + return TRUE; } ModestMailOperationStatus @@ -644,6 +597,34 @@ modest_mail_operation_get_task_total (ModestMailOperation *mail_op) return priv->total; } +gboolean +modest_mail_operation_is_finished (ModestMailOperation *mail_op) +{ + ModestMailOperationPrivate *priv; + gboolean retval = FALSE; + + if (!MODEST_IS_MAIL_OPERATION (mail_op)) { + g_warning ("%s: invalid parametter", G_GNUC_FUNCTION); + return retval; + } + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op); + + g_mutex_lock (priv->cb_lock); + + if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS || + priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED || + priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED || + priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) { + retval = TRUE; + } else { + retval = FALSE; + } + g_mutex_unlock (priv->cb_lock); + + return retval; +} + /* ******************************************************************* */ /* ************************** STORE ACTIONS ************************* */ /* ******************************************************************* */ @@ -979,11 +960,10 @@ set_error (ModestMailOperation *mail_op, g_object_unref (priv->error); priv->error = error; - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; } static void -add_attachments (TnyMsg *msg, const GList *attachments_list) +add_attachments (TnyMsg *msg, GList *attachments_list) { GList *pos; TnyMimePart *attachment_part, *old_attachment; diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index b479571..57ddd58 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -71,13 +71,12 @@ typedef enum _ModestMailOperationReplyMode { typedef enum _ModestMailOperationStatus { MODEST_MAIL_OPERATION_STATUS_INVALID, MODEST_MAIL_OPERATION_STATUS_SUCCESS, + MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS, MODEST_MAIL_OPERATION_STATUS_FAILED, MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS, - MODEST_MAIL_OPERATION_STATUS_CANCELLED + MODEST_MAIL_OPERATION_STATUS_CANCELED } ModestMailOperationStatus; -typedef void (*ModestUpdateAccountCallback) (ModestMailOperation *mail_op, gpointer user_data); - struct _ModestMailOperation { GObject parent; /* insert public members, if any */ @@ -120,10 +119,8 @@ TnyMsg* modest_mail_operation_create_reply_mail (TnyMsg *msg, ModestMailOperationReplyType reply_type, ModestMailOperationReplyMode reply_mode); -void modest_mail_operation_update_account (ModestMailOperation *mail_op, - TnyStoreAccount *store_account, - ModestUpdateAccountCallback callback, - gpointer user_data); +gboolean modest_mail_operation_update_account (ModestMailOperation *mail_op, + TnyStoreAccount *store_account); /* Functions that perform store operations */ TnyFolder* modest_mail_operation_create_folder (ModestMailOperation *mail_op, @@ -166,11 +163,13 @@ guint modest_mail_operation_get_task_done (ModestMailOperation *mail_op guint modest_mail_operation_get_task_total (ModestMailOperation *mail_op); -ModestMailOperationStatus modest_mail_operation_get_status (ModestMailOperation *mail_op); +gboolean modest_mail_operation_is_finished (ModestMailOperation *mail_op); + +ModestMailOperationStatus modest_mail_operation_get_status (ModestMailOperation *mail_op); -const GError* modest_mail_operation_get_error (ModestMailOperation *mail_op); +const GError* modest_mail_operation_get_error (ModestMailOperation *mail_op); -void modest_mail_operation_cancel (ModestMailOperation *mail_op); +void modest_mail_operation_cancel (ModestMailOperation *mail_op); G_END_DECLS diff --git a/src/modest-text-utils.c b/src/modest-text-utils.c index fafb338..65b2e9a 100644 --- a/src/modest-text-utils.c +++ b/src/modest-text-utils.c @@ -40,18 +40,278 @@ #include #endif /*HAVE_CONFIG_H */ +/* defines */ +#define FORWARD_STRING _("-----Forwarded Message-----") +#define FROM_STRING _("From:") +#define SENT_STRING _("Sent:") +#define TO_STRING _("To:") +#define SUBJECT_STRING _("Subject:") + +/* + * we need these regexps to find URLs in plain text e-mails + */ +typedef struct _url_match_pattern_t url_match_pattern_t; +struct _url_match_pattern_t { + gchar *regex; + regex_t *preg; + gchar *prefix; +}; + +typedef struct _url_match_t url_match_t; +struct _url_match_t { + guint offset; + guint len; + const gchar* prefix; +}; + +#define MAIL_VIEWER_URL_MATCH_PATTERNS { \ + { "(file|rtsp|http|ftp|https)://[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]+[-A-Za-z0-9_$%&=?/~#]",\ + NULL, NULL },\ + { "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\ + NULL, "http://" },\ + { "ftp\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\ + NULL, "ftp://" },\ + { "(voipto|callto|chatto|jabberto|xmpp):[-_a-z@0-9.\\+]+", \ + NULL, NULL}, \ + { "mailto:[-_a-z0-9.\\+]+@[-_a-z0-9.]+", \ + NULL, NULL},\ + { "[-_a-z0-9.\\+]+@[-_a-z0-9.]+",\ + NULL, "mailto:"}\ + } + /* private */ -static GString *get_next_line (const char *b, const gsize blen, const gchar * iter); -static int get_indent_level (const char *l); -static void unquote_line (GString * l); -static void append_quoted (GString * buf, const int indent, - const GString * str, const int cutpoint); -static int get_breakpoint_utf8 (const gchar * s, const gint indent, - const gint limit); -static int get_breakpoint_ascii (const gchar * s, const gint indent, - const gint limit); -static int get_breakpoint (const gchar * s, const gint indent, - const gint limit); +static gchar* cite (const time_t sent_date, const gchar *from); +static void hyperlinkify_plain_text (GString *txt); +static gint cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2); +static void chk_partial_match (const url_match_t *match, guint* offset); +static GSList* get_url_matches (GString *txt); + +static GString* get_next_line (const char *b, const gsize blen, const gchar * iter); +static int get_indent_level (const char *l); +static void unquote_line (GString * l); +static void append_quoted (GString * buf, const int indent, const GString * str, + const int cutpoint); +static int get_breakpoint_utf8 (const gchar * s, const gint indent, const gint limit); +static int get_breakpoint_ascii (const gchar * s, const gint indent, const gint limit); +static int get_breakpoint (const gchar * s, const gint indent, const gint limit); + +static gchar* modest_text_utils_quote_plain_text (const gchar *text, + const gchar *cite, + int limit); + +static gchar* modest_text_utils_quote_html (const gchar *text, + const gchar *cite, + int limit); + + +/* ******************************************************************* */ +/* ************************* PUBLIC FUNCTIONS ************************ */ +/* ******************************************************************* */ + +gchar * +modest_text_utils_quote (const gchar *text, + const gchar *content_type, + const gchar *from, + const time_t sent_date, + int limit) +{ + gchar *retval, *cited; + + cited = cite (sent_date, from); + + if (!strcmp (content_type, "text/html")) + /* TODO: extract the of the HTML and pass it to + the function */ + retval = modest_text_utils_quote_html (text, cited, limit); + else + retval = modest_text_utils_quote_plain_text (text, cited, limit); + + g_free (cited); + + return retval; +} + + +gchar * +modest_text_utils_cite (const gchar *text, + const gchar *content_type, + const gchar *from, + time_t sent_date) +{ + gchar *tmp, *retval; + + tmp = cite (sent_date, from); + retval = g_strdup_printf ("%s%s\n", tmp, text); + g_free (tmp); + + return retval; +} + +gchar * +modest_text_utils_inline (const gchar *text, + const gchar *content_type, + const gchar *from, + time_t sent_date, + const gchar *to, + const gchar *subject) +{ + gchar sent_str[101]; + const gchar *plain_format = "%s\n%s %s\n%s %s\n%s %s\n%s %s\n\n%s"; + const gchar *html_format = \ + "%s
\n\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "

%s"; + const gchar *format; + + modest_text_utils_strftime (sent_str, 100, "%c", localtime (&sent_date)); + + if (!strcmp (content_type, "text/html")) + /* TODO: extract the of the HTML and pass it to + the function */ + format = html_format; + else + format = plain_format; + + return g_strdup_printf (format, + FORWARD_STRING, + FROM_STRING, from, + SENT_STRING, sent_str, + TO_STRING, to, + SUBJECT_STRING, subject, + text); +} + +/* just to prevent warnings: + * warning: `%x' yields only last 2 digits of year in some locales + */ +size_t +modest_text_utils_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) +{ + return strftime(s, max, fmt, tm); +} + +gchar * +modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix) +{ + gchar *tmp; + + if (!subject) + return g_strdup_printf ("%s ", prefix); + + tmp = g_strchug (g_strdup (subject)); + + if (!strncmp (tmp, prefix, strlen (prefix))) { + return tmp; + } else { + g_free (tmp); + return g_strdup_printf ("%s %s", prefix, subject); + } +} + +gchar * +modest_text_utils_remove_address (const gchar *address, const gchar *address_list) +{ + char *dup, *token, *ptr, *result; + GString *filtered_emails; + + if (!address_list) + return NULL; + + /* Search for substring */ + if (!strstr ((const char *) address_list, (const char *) address)) + return g_strdup (address_list); + + dup = g_strdup (address_list); + filtered_emails = g_string_new (NULL); + + token = strtok_r (dup, ",", &ptr); + + while (token != NULL) { + /* Add to list if not found */ + if (!strstr ((const char *) token, (const char *) address)) { + if (filtered_emails->len == 0) + g_string_append_printf (filtered_emails, "%s", token); + else + g_string_append_printf (filtered_emails, ",%s", token); + } + token = strtok_r (NULL, ",", &ptr); + } + result = filtered_emails->str; + + /* Clean */ + g_free (dup); + g_string_free (filtered_emails, FALSE); + + return result; +} + +gchar* +modest_text_utils_convert_to_html (const gchar *data) +{ + guint i; + gboolean first_space = TRUE; + GString *html; + gsize len; + + if (!data) + return NULL; + + len = strlen (data); + html = g_string_sized_new (len + 100); /* just a guess... */ + + g_string_append_printf (html, + "" + "" + "" + "" + ""); + + /* replace with special html chars where needed*/ + for (i = 0; i != len; ++i) { + char kar = data[i]; + switch (kar) { + + case 0: break; /* ignore embedded \0s */ + case '<' : g_string_append (html, "<"); break; + case '>' : g_string_append (html, ">"); break; + case '&' : g_string_append (html, """); break; + case '\n': g_string_append (html, "
\n"); break; + default: + if (kar == ' ') { + g_string_append (html, first_space ? " " : " "); + first_space = FALSE; + } else if (kar == '\t') + g_string_append (html, "    "); + else { + int charnum = 0; + first_space = TRUE; + /* optimization trick: accumulate 'normal' chars, then copy */ + do { + kar = data [++charnum + i]; + + } while ((i + charnum < len) && + (kar > '>' || (kar != '<' && kar != '>' + && kar != '&' && kar != ' ' + && kar != '\n' && kar != '\t'))); + g_string_append_len (html, &data[i], charnum); + i += (charnum - 1); + } + } + } + + g_string_append (html, "
"); + hyperlinkify_plain_text (html); + + return g_string_free (html, FALSE); +} + +/* ******************************************************************* */ +/* ************************* UTILIY FUNCTIONS ************************ */ +/* ******************************************************************* */ static GString * get_next_line (const gchar * b, const gsize blen, const gchar * iter) @@ -196,17 +456,6 @@ get_breakpoint (const gchar * s, const gint indent, const gint limit) } } - - -/* just to prevent warnings: - * warning: `%x' yields only last 2 digits of year in some locales - */ -size_t -modest_text_utils_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) -{ - return strftime(s, max, fmt, tm); -} - static gchar * cite (const time_t sent_date, const gchar *from) { @@ -218,9 +467,10 @@ cite (const time_t sent_date, const gchar *from) } -gchar * -modest_text_utils_quote (const gchar * to_quote, const gchar * from, - const time_t sent_date, const int limit) +static gchar * +modest_text_utils_quote_plain_text (const gchar *text, + const gchar *cite, + int limit) { const gchar *iter; gint indent, breakpoint, rem_indent = 0; @@ -228,18 +478,14 @@ modest_text_utils_quote (const gchar * to_quote, const gchar * from, gsize len; gchar *tmp; - /* format sent_date */ - tmp = cite (sent_date, from); - q = g_string_new (tmp); - g_free (tmp); - /* remaining will store the rest of the line if we have to break it */ + q = g_string_new (cite); remaining = g_string_new (""); - iter = to_quote; - len = strlen(to_quote); + iter = text; + len = strlen(text); do { - l = get_next_line (to_quote, len, iter); + l = get_next_line (text, len, iter); iter = iter + l->len + 1; indent = get_indent_level (l->str); unquote_line (l); @@ -274,138 +520,28 @@ modest_text_utils_quote (const gchar * to_quote, const gchar * from, rem_indent = indent; append_quoted (q, indent, l, breakpoint); g_string_free (l, TRUE); - } while ((iter < to_quote + len) || (remaining->str[0])); + } while ((iter < text + len) || (remaining->str[0])); return g_string_free (q, FALSE); } - -gchar * -modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix) -{ - gchar *tmp; - - if (!subject) - return g_strdup_printf ("%s ", prefix); - - tmp = g_strchug (g_strdup (subject)); - - if (!strncmp (tmp, prefix, strlen (prefix))) { - return tmp; - } else { - g_free (tmp); - return g_strdup_printf ("%s %s", prefix, subject); - } -} - - -gchar * -modest_text_utils_cited_text (const gchar *from, - time_t sent_date, - const gchar *text) -{ - gchar *tmp, *retval; - - tmp = cite (sent_date, from); - retval = g_strdup_printf ("%s%s\n", tmp, text); - g_free (tmp); - - return retval; -} - - -gchar * -modest_text_utils_inlined_text (const gchar *from, time_t sent_date, - const gchar *to, const gchar *subject, - const gchar *text) -{ - gchar sent_str[101]; - - modest_text_utils_strftime (sent_str, 100, "%c", localtime (&sent_date)); - - return g_strdup_printf ("%s\n%s %s\n%s %s\n%s %s\n%s %s\n\n%s", - _("-----Forwarded Message-----"), - _("From:"), from, - _("Sent:"), sent_str, - _("To:"), to, - _("Subject:"), subject, - text); -} - -gchar * -modest_text_utils_remove_address (const gchar *address, const gchar *address_list) +static gchar* +modest_text_utils_quote_html (const gchar *text, + const gchar *cite, + int limit) { - char *dup, *token, *ptr, *result; - GString *filtered_emails; - - if (!address_list) - return NULL; - - /* Search for substring */ - if (!strstr ((const char *) address_list, (const char *) address)) - return g_strdup (address_list); - - dup = g_strdup (address_list); - filtered_emails = g_string_new (NULL); - - token = strtok_r (dup, ",", &ptr); - - while (token != NULL) { - /* Add to list if not found */ - if (!strstr ((const char *) token, (const char *) address)) { - if (filtered_emails->len == 0) - g_string_append_printf (filtered_emails, "%s", token); - else - g_string_append_printf (filtered_emails, ",%s", token); - } - token = strtok_r (NULL, ",", &ptr); - } - result = filtered_emails->str; - - /* Clean */ - g_free (dup); - g_string_free (filtered_emails, FALSE); - - return result; + const gchar *format = \ + "\n" \ + "\n" \ + "\n" \ + "%s" \ + "
\n%s\n
\n" \ + "\n" \ + "\n"; + + return g_strdup_printf (format, cite, text); } - - - -/* - * we need these regexps to find URLs in plain text e-mails - */ -typedef struct _url_match_pattern_t url_match_pattern_t; -struct _url_match_pattern_t { - gchar *regex; - regex_t *preg; - gchar *prefix; -}; - -typedef struct _url_match_t url_match_t; -struct _url_match_t { - guint offset; - guint len; - const gchar* prefix; -}; - - -#define MAIL_VIEWER_URL_MATCH_PATTERNS { \ - { "(file|rtsp|http|ftp|https)://[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]+[-A-Za-z0-9_$%&=?/~#]",\ - NULL, NULL },\ - { "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\ - NULL, "http://" },\ - { "ftp\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\ - NULL, "ftp://" },\ - { "(voipto|callto|chatto|jabberto|xmpp):[-_a-z@0-9.\\+]+", \ - NULL, NULL}, \ - { "mailto:[-_a-z0-9.\\+]+@[-_a-z0-9.]+", \ - NULL, NULL},\ - { "[-_a-z0-9.\\+]+@[-_a-z0-9.]+",\ - NULL, "mailto:"}\ - } - - static gint cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2) { @@ -515,69 +651,3 @@ hyperlinkify_plain_text (GString *txt) g_slist_free (match_list); } - - - -gchar* -modest_text_utils_convert_to_html (const gchar *data) -{ - guint i; - gboolean first_space = TRUE; - GString *html; - gsize len; - - if (!data) - return NULL; - - len = strlen (data); - html = g_string_sized_new (len + 100); /* just a guess... */ - - g_string_append_printf (html, - "" - "" - "" - "" - ""); - - /* replace with special html chars where needed*/ - for (i = 0; i != len; ++i) { - char kar = data[i]; - switch (kar) { - - case 0: break; /* ignore embedded \0s */ - case '<' : g_string_append (html, "<"); break; - case '>' : g_string_append (html, ">"); break; - case '&' : g_string_append (html, """); break; - case '\n': g_string_append (html, "
\n"); break; - default: - if (kar == ' ') { - g_string_append (html, first_space ? " " : " "); - first_space = FALSE; - } else if (kar == '\t') - g_string_append (html, "    "); - else { - int charnum = 0; - first_space = TRUE; - /* optimization trick: accumulate 'normal' chars, then copy */ - do { - kar = data [++charnum + i]; - - } while ((i + charnum < len) && - (kar > '>' || (kar != '<' && kar != '>' - && kar != '&' && kar != ' ' - && kar != '\n' && kar != '\t'))); - g_string_append_len (html, &data[i], charnum); - i += (charnum - 1); - } - } - } - - g_string_append (html, "
"); - hyperlinkify_plain_text (html); - - return g_string_free (html, FALSE); -} - - - diff --git a/src/modest-text-utils.h b/src/modest-text-utils.h index f7da471..c3199f9 100644 --- a/src/modest-text-utils.h +++ b/src/modest-text-utils.h @@ -36,6 +36,19 @@ #include /** + * modest_text_utils_derived_subject: + * @subject: a string which contains the original subject + * @prefix: the prefix for the new subject (such as 'Re:' or 'Fwd:') + * + * create a 'derived' subject line for eg. replies and forwards + * + * Returns: a newly allocated string containing the resulting subject + */ +gchar* modest_text_utils_derived_subject (const gchar *subject, + const gchar* prefix); + + +/** * modest_text_utils_quote: * @buf: a string which contains the message to quote * @from: the sender of the original message @@ -46,20 +59,11 @@ * * Returns: a newly allocated string containing the quoted message */ -gchar* modest_text_utils_quote(const gchar *buf, const gchar *from, - const time_t sent_date, const int limit); - - -/** - * modest_text_utils_derived_subject: - * @subject: a string which contains the original subject - * @prefix: the prefix for the new subject (such as 'Re:' or 'Fwd:') - * - * create a 'derived' subject line for eg. replies and forwards - * - * Returns: a newly allocated string containing the resulting subject - */ -gchar* modest_text_utils_derived_subject (const gchar *subject, const gchar* prefix); +gchar* modest_text_utils_quote (const gchar *text, + const gchar *content_type, + const gchar *from, + const time_t sent_date, + int limit); /** @@ -72,9 +76,10 @@ gchar* modest_text_utils_derived_subject (const gchar *subject, const gchar* pre * * Returns: a newly allocated string containing the cited text */ -gchar* modest_text_utils_cited_text (const gchar *from, - time_t sent_date, - const gchar *text); +gchar* modest_text_utils_cite (const gchar *text, + const gchar *content_type, + const gchar *from, + time_t sent_date); /** * modest_text_utils_inlined_text @@ -89,11 +94,12 @@ gchar* modest_text_utils_cited_text (const gchar *from, * * Returns: a newly allocated string containing the quoted message */ -gchar* modest_text_utils_inlined_text (const gchar *from, - time_t sent_date, - const gchar *to, - const gchar *subject, - const gchar *text); +gchar* modest_text_utils_inline (const gchar *text, + const gchar *content_type, + const gchar *from, + time_t sent_date, + const gchar *to, + const gchar *subject); /** * modest_text_utils_remove_address diff --git a/src/modest-tny-msg-actions.c b/src/modest-tny-msg-actions.c index 442d69d..5baac6d 100644 --- a/src/modest-tny-msg-actions.c +++ b/src/modest-tny-msg-actions.c @@ -70,31 +70,6 @@ get_body_text (TnyMsg *msg, gboolean want_html) return to_quote; } -gchar* -modest_tny_msg_actions_quote (TnyMsg * self, const gchar * from, - time_t sent_date, gint limit, - const gchar * to_quote) -{ - gchar *quoted_msg = NULL; - const gchar *body; - - /* 2 cases: */ - - /* a) quote text from selection */ - if (to_quote != NULL) - return modest_text_utils_quote (to_quote, from, sent_date, - limit); - - /* b) try to find a text/plain part in the msg and quote it */ - body = get_body_text (self, FALSE); - if (body) - quoted_msg = modest_text_utils_quote (body, from, sent_date, limit); - - return quoted_msg; -} - - - static TnyMimePart* modest_tny_msg_actions_find_body_part_from_mime_part (TnyMimePart *msg, gboolean want_html) { diff --git a/src/modest-tny-msg-actions.h b/src/modest-tny-msg-actions.h index bed606a..ce0c62c 100644 --- a/src/modest-tny-msg-actions.h +++ b/src/modest-tny-msg-actions.h @@ -31,24 +31,6 @@ #define __MODEST_TNY_MSG_ACTIONS_H__ /** - * modest_tny_msg_actions_quote: - * @self: the message to quote - * @from: the original sender of the message - * @sent_date: the date the original message was sent - * @limit: characters per line limit for the quoted message - * @to_quote: a string to quote instead of the message body - * - * reply-quotes a message or @to_quote if it's not NULL. - - * Note: @from and @sent_date may be eliminated from the API in future versions - * - * Returns: a newly allocated string containing the quoted message - */ -gchar *modest_tny_msg_actions_quote (TnyMsg * self, const gchar * from, - time_t sent_date, gint limit, - const gchar *to_quote); - -/** * modest_tny_msg_actions_find_body_part: * @self: a message * @want_html: prefer HTML-part when there are multiple body parts? diff --git a/tests/Makefile.am b/tests/Makefile.am index d3be016..ffb3f42 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,9 +24,11 @@ folder_xfer_LDADD = \ ${top_srcdir}/src/modest-tny-platform-factory.o \ ${top_srcdir}/src/modest-conf.o \ ${top_srcdir}/src/modest-protocol-mgr.o \ + ${top_srcdir}/src/modest-formatter.o \ ${top_srcdir}/src/modest-pair.o \ ${top_srcdir}/src/modest-marshal.o \ ${top_srcdir}/src/modest-tny-account-store.o \ + ${top_srcdir}/src/modest-mail-operation-queue.o \ ${top_srcdir}/src/modest-mail-operation.o \ ${top_srcdir}/src/modest-tny-msg-actions.o \ ${top_srcdir}/src/modest-text-utils.o @@ -44,9 +46,11 @@ update_account_LDADD = \ ${top_srcdir}/src/modest-tny-platform-factory.o \ ${top_srcdir}/src/modest-conf.o \ ${top_srcdir}/src/modest-protocol-mgr.o \ + ${top_srcdir}/src/modest-formatter.o \ ${top_srcdir}/src/modest-pair.o \ ${top_srcdir}/src/modest-marshal.o \ ${top_srcdir}/src/modest-tny-account-store.o \ + ${top_srcdir}/src/modest-mail-operation-queue.o \ ${top_srcdir}/src/modest-mail-operation.o \ ${top_srcdir}/src/modest-tny-msg-actions.o \ - ${top_srcdir}/src/modest-text-utils.o \ No newline at end of file + ${top_srcdir}/src/modest-text-utils.o diff --git a/tests/update-account.c b/tests/update-account.c index 35f657c..d868806 100644 --- a/tests/update-account.c +++ b/tests/update-account.c @@ -37,27 +37,29 @@ #include #include #include -#include - -#include -#include +#include "modest-tny-platform-factory.h" +#include "modest-account-mgr.h" +#include "modest-mail-operation.h" +#include "modest-mail-operation-queue.h" GMainLoop *main_loop; static void -update_cb (ModestMailOperation *mail_op, gpointer user_data) +on_progress_changed (ModestMailOperation *mail_op, gpointer user_data) { - g_object_unref (G_OBJECT (mail_op)); - g_main_loop_quit (main_loop); -} + ModestMailOperationStatus status; + ModestMailOperationQueue *queue = NULL; -static void -progress_cb (ModestMailOperation *mail_op, gpointer user_data) -{ g_print ("Refreshed %d of %d\n", modest_mail_operation_get_task_done (mail_op), modest_mail_operation_get_task_total (mail_op)); + + if (modest_mail_operation_is_finished (mail_op)) { + queue = MODEST_MAIL_OPERATION_QUEUE (user_data); + modest_mail_operation_queue_remove (queue, mail_op); + g_main_loop_quit (main_loop); + } } static gboolean @@ -68,6 +70,7 @@ func (gpointer_data) TnyPlatformFactory *fact = NULL; ModestAccountMgr *acc_mgr = NULL; ModestMailOperation *mail_op = NULL; + ModestMailOperationQueue *queue = NULL; TnyAccountStore *account_store = NULL; TnyList *accounts; @@ -87,11 +90,16 @@ func (gpointer_data) g_object_unref (G_OBJECT (iter)); g_object_unref (G_OBJECT (accounts)); + queue = modest_mail_operation_queue_get_instance (); mail_op = modest_mail_operation_new (); g_signal_connect (G_OBJECT (mail_op), "progress_changed", - G_CALLBACK (progress_cb), NULL); - modest_mail_operation_update_account (mail_op, account, update_cb, NULL); + G_CALLBACK (on_progress_changed), queue); + + if (modest_mail_operation_update_account (mail_op, account)) + modest_mail_operation_queue_add (queue, mail_op); + + g_object_unref (G_OBJECT (mail_op)); return FALSE; } -- 1.7.9.5
%s%s
%s%s
%s%s
%s%s