* Added ModestMailOperationQueue
authorSergio Villar Senin <svillar@igalia.com>
Thu, 7 Dec 2006 08:03:25 +0000 (08:03 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Thu, 7 Dec 2006 08:03:25 +0000 (08:03 +0000)
* 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

14 files changed:
src/Makefile.am
src/gtk/modest-edit-msg-window.c
src/modest-formatter.c [new file with mode: 0644]
src/modest-formatter.h [new file with mode: 0644]
src/modest-mail-operation-queue.c [new file with mode: 0644]
src/modest-mail-operation-queue.h [new file with mode: 0644]
src/modest-mail-operation.c
src/modest-mail-operation.h
src/modest-text-utils.c
src/modest-text-utils.h
src/modest-tny-msg-actions.c
src/modest-tny-msg-actions.h
tests/Makefile.am
tests/update-account.c

index 181ef2c..b5c99c4 100644 (file)
@@ -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)                           \
index 3c287f9..d7ff941 100644 (file)
@@ -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 (file)
index 0000000..2e175a6
--- /dev/null
@@ -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 <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+#include <tny-header.h>
+#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 (file)
index 0000000..92bb925
--- /dev/null
@@ -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 <tny-msg.h>
+#include <tny-header.h>
+#include <tny-mime-part.h>
+
+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 (file)
index 0000000..d4e0c01
--- /dev/null
@@ -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 (file)
index 0000000..54972df
--- /dev/null
@@ -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 <glib-object.h>
+#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__ */
index b656804..66611f9 100644 (file)
@@ -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;
index b479571..57ddd58 100644 (file)
@@ -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
 
index fafb338..65b2e9a 100644 (file)
 #include <config.h>
 #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 <body> 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<br>\n<table width=\"100%\" border=\"0\" cellspacing=\"2\" cellpadding=\"2\">\n" \
+               "<tr><td>%s</td><td>%s</td></tr>\n" \
+               "<tr><td>%s</td><td>%s</td></tr>\n" \
+               "<tr><td>%s</td><td>%s</td></tr>\n" \
+               "<tr><td>%s</td><td>%s</td></tr>\n" \
+               "<br><br>%s";
+       const gchar *format;
+
+       modest_text_utils_strftime (sent_str, 100, "%c", localtime (&sent_date));
+
+       if (!strcmp (content_type, "text/html"))
+               /* TODO: extract the <body> 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,
+                               "<html>"
+                               "<head>"
+                               "<meta http-equiv=\"content-type\""
+                               " content=\"text/html; charset=utf8\">"
+                               "</head>"
+                               "<body><tt>");
+       
+       /* 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, "&lt;"); break;
+               case '>' : g_string_append   (html, "&gt;"); break;
+               case '&' : g_string_append   (html, "&quot;"); break;
+               case '\n': g_string_append   (html, "<br>\n"); break;
+               default:
+                       if (kar == ' ') {
+                               g_string_append (html, first_space ? " " : "&nbsp;");
+                               first_space = FALSE;
+                       } else  if (kar == '\t')
+                               g_string_append (html, "&nbsp; &nbsp;&nbsp;");
+                       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, "</tt></body></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 = \
+               "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" \
+               "<html>\n" \
+               "<body>\n" \
+               "%s" \
+               "<blockquote type=\"cite\">\n%s\n</blockquote>\n" \
+               "</body>\n" \
+               "</html>\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,
-                               "<html>"
-                               "<head>"
-                               "<meta http-equiv=\"content-type\""
-                               " content=\"text/html; charset=utf8\">"
-                               "</head>"
-                               "<body><tt>");
-       
-       /* 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, "&lt;"); break;
-               case '>' : g_string_append   (html, "&gt;"); break;
-               case '&' : g_string_append   (html, "&quot;"); break;
-               case '\n': g_string_append   (html, "<br>\n"); break;
-               default:
-                       if (kar == ' ') {
-                               g_string_append (html, first_space ? " " : "&nbsp;");
-                               first_space = FALSE;
-                       } else  if (kar == '\t')
-                               g_string_append (html, "&nbsp; &nbsp;&nbsp;");
-                       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, "</tt></body></html>");
-       hyperlinkify_plain_text (html);
-
-       return g_string_free (html, FALSE);
-}
-
-
-
index f7da471..c3199f9 100644 (file)
 #include <time.h>
 
 /**
+ * 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
  * 
  * 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
index 442d69d..5baac6d 100644 (file)
@@ -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)
 {
index bed606a..ce0c62c 100644 (file)
 #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?
index d3be016..ffb3f42 100644 (file)
@@ -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
index 35f657c..d868806 100644 (file)
 #include <tny-store-account.h>
 #include <tny-folder.h>
 #include <tny-folder-store.h>
-#include <modest-tny-platform-factory.h>
 
-
-#include <modest-account-mgr.h>
-#include <modest-mail-operation.h>
+#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;
 }