aboutsummaryrefslogtreecommitdiffstats
path: root/mail/e-mail-reader-utils.c
diff options
context:
space:
mode:
authorDan Vrátil <dvratil@redhat.com>2012-06-18 19:44:58 +0800
committerDan Vrátil <dvratil@redhat.com>2012-06-18 19:44:58 +0800
commitfe59b10f04b794759f64d97281d907d7dce39972 (patch)
tree812d45440f6cfabe7681a03ad5fc2808306764ad /mail/e-mail-reader-utils.c
parent031c40a51791b2ebcd44f880c96860b987e1a00c (diff)
downloadgsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.tar
gsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.tar.gz
gsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.tar.bz2
gsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.tar.lz
gsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.tar.xz
gsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.tar.zst
gsoc2013-evolution-fe59b10f04b794759f64d97281d907d7dce39972.zip
Bug #677608 - Fails to open message which is not yet downloaded
Diffstat (limited to 'mail/e-mail-reader-utils.c')
-rw-r--r--mail/e-mail-reader-utils.c237
1 files changed, 111 insertions, 126 deletions
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index 2030350d1b..0f0d68ec9d 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -57,8 +57,6 @@
#define d(x)
-static GHashTable * mail_reader_get_mail_register (void);
-
typedef struct _AsyncContext AsyncContext;
struct _AsyncContext {
@@ -538,12 +536,15 @@ free_message_printing_context (struct _MessagePrintingContext *context)
}
static void
-mail_reader_do_print_message (EMailPartList *part_list,
+mail_reader_do_print_message (GObject *object,
+ GAsyncResult *result,
gpointer user_data)
{
+ EMailReader *reader = E_MAIL_READER (object);
EActivity *activity;
GCancellable *cancellable;
EMailPrinter *printer;
+ EMailPartList *part_list;
struct _MessagePrintingContext *context = user_data;
activity = e_mail_reader_new_activity (context->reader);
@@ -551,6 +552,8 @@ mail_reader_do_print_message (EMailPartList *part_list,
e_activity_set_state (activity, E_ACTIVITY_RUNNING);
cancellable = e_activity_get_cancellable (activity);
+ part_list = e_mail_reader_parse_message_finish (reader, result);
+
printer = e_mail_printer_new (part_list);
g_signal_connect (printer, "done",
G_CALLBACK (printing_done_cb), activity);
@@ -578,17 +581,15 @@ mail_reader_get_message_to_print_ready_cb (GObject *object,
e_mail_reader_parse_message (
context->reader, context->folder, context->message_uid,
- message, (GFunc) mail_reader_do_print_message, context);
+ message, mail_reader_do_print_message, context);
}
void
e_mail_reader_print (EMailReader *reader,
GtkPrintOperationAction action)
{
- EMailPartList *parts;
struct _MessagePrintingContext *context;
MessageList *message_list;
- gchar *uri;
context = g_new0 (struct _MessagePrintingContext, 1);
@@ -596,27 +597,15 @@ e_mail_reader_print (EMailReader *reader,
context->reader = g_object_ref (reader);
context->message_uid = g_strdup (message_list->cursor_uid);
context->folder = g_object_ref (e_mail_reader_get_folder (reader));
+ context->activity = e_mail_reader_new_activity (reader);
g_return_if_fail (E_IS_MAIL_READER (reader));
- uri = e_mail_part_build_uri (
- context->folder, context->message_uid, NULL, NULL);
- parts = e_mail_reader_lookup_part_list (reader, uri);
- if (!parts) {
- GCancellable *cancellable;
-
- context->activity = e_mail_reader_new_activity (reader);
- cancellable = e_activity_get_cancellable (context->activity);
-
- camel_folder_get_message (
- context->folder, context->message_uid,
- G_PRIORITY_DEFAULT, cancellable,
- (GAsyncReadyCallback) mail_reader_get_message_to_print_ready_cb,
- context);
-
- } else {
- mail_reader_do_print_message (parts, context);
- }
+ camel_folder_get_message (
+ context->folder, context->message_uid,
+ G_PRIORITY_DEFAULT, e_activity_get_cancellable (context->activity),
+ (GAsyncReadyCallback) mail_reader_get_message_to_print_ready_cb,
+ context);
}
static void
@@ -855,13 +844,18 @@ html_contains_nonwhitespace (const gchar *html,
}
static void
-mail_reader_reply_message_parsed (EMailPartList *part_list,
+mail_reader_reply_message_parsed (GObject *object,
+ GAsyncResult *result,
gpointer user_data)
{
EShell *shell;
EMailBackend *backend;
+ EMailReader *reader = E_MAIL_READER (object);
+ EMailPartList *part_list;
AsyncContext *context = user_data;
+ part_list = e_mail_reader_parse_message_finish (reader, result);
+
backend = e_mail_reader_get_backend (context->reader);
shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
@@ -907,8 +901,7 @@ mail_reader_get_message_ready_cb (CamelFolder *folder,
e_mail_reader_parse_message (context->reader, context->folder,
context->message_uid, message,
- (GFunc) mail_reader_reply_message_parsed,
- context);
+ mail_reader_reply_message_parsed, context);
}
void
@@ -932,7 +925,7 @@ e_mail_reader_reply_to_message (EMailReader *reader,
gchar *selection = NULL;
gint length;
gchar *mail_uri;
- GHashTable *mail_register;
+ CamelObjectBag *registry;
/* This handles quoting only selected text in the reply. If
* nothing is selected or only whitespace is selected, fall
@@ -982,9 +975,9 @@ e_mail_reader_reply_to_message (EMailReader *reader,
if (!gtk_widget_get_visible (GTK_WIDGET (web_view)))
goto whole_message;
- mail_register = mail_reader_get_mail_register ();
+ registry = e_mail_part_list_get_registry ();
mail_uri = e_mail_part_build_uri (folder, uid, NULL, NULL);
- part_list = g_hash_table_lookup (mail_register, mail_uri);
+ part_list = camel_object_bag_get (registry, mail_uri);
g_free (mail_uri);
if (!part_list)
@@ -995,7 +988,11 @@ e_mail_reader_reply_to_message (EMailReader *reader,
if (src_message != NULL)
g_object_ref (src_message);
+ g_object_unref (part_list);
+
g_return_if_fail (src_message != NULL);
+ } else {
+ g_object_unref (part_list);
}
if (!e_web_view_is_selection_active (web_view))
@@ -1535,98 +1532,63 @@ e_mail_reader_header_free (EMailReaderHeader *header)
g_free (header);
}
-static GHashTable *
-mail_reader_get_mail_register (void)
-{
- SoupSession *session;
- GHashTable *mails;
-
- session = webkit_get_default_session ();
- mails = g_object_get_data (G_OBJECT (session), "mails");
- if (!mails) {
- mails = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free, NULL);
- g_object_set_data_full (
- G_OBJECT (session), "mails", mails,
- (GDestroyNotify) g_hash_table_destroy);
- }
-
- return mails;
-}
-
-EMailPartList *
-e_mail_reader_lookup_part_list (EMailReader *reader,
- const gchar *uri)
-{
- GHashTable *mails;
-
- g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
- g_return_val_if_fail (uri && *uri, NULL);
-
- mails = mail_reader_get_mail_register ();
- return g_hash_table_lookup (mails, uri);
-}
+struct mail_reader_parse_message_run_data_ {
+ CamelFolder *folder;
+ CamelMimeMessage *message;
+ gchar *message_uid;
+ EActivity *activity;
-struct _formatter_weak_ref_closure {
- GHashTable *part_lists;
- gchar *mail_uri;
+ EMailPartList *part_list;
};
static void
-part_list_weak_ref_cb (gchar *mail_uri,
- EMailPartList *part_list)
+mail_reader_parse_message_run (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
{
- GHashTable *mails;
+ EMailReader *reader = E_MAIL_READER (object);
+ CamelObjectBag *registry;
+ EMailPartList *part_list;
+ gchar *mail_uri;
+ struct mail_reader_parse_message_run_data_ *data;
- mails = mail_reader_get_mail_register ();
+ data = g_object_get_data (G_OBJECT (simple), "evo-data");
- /* When this callback is called, the partslist is being finalized
- * so we only remove it from the parts list table. */
- g_hash_table_remove (mails, mail_uri);
+ registry = e_mail_part_list_get_registry ();
- d(printf("Destroying parts list %p (%s)\n", part_list, mail_uri));
+ mail_uri = e_mail_part_build_uri (
+ data->folder, data->message_uid, NULL, NULL);
- g_free (mail_uri);
-}
+ part_list = camel_object_bag_reserve (registry, mail_uri);
+ if (!part_list) {
+ EMailBackend *mail_backend;
+ EMailSession *mail_session;
+ EMailParser *parser;
-struct format_parser_async_closure_ {
- EActivity *activity;
- gchar *mail_uri;
+ mail_backend = e_mail_reader_get_backend (reader);
+ mail_session = e_mail_backend_get_session (mail_backend);
- GFunc user_callback;
- gpointer user_data;
-};
+ parser = e_mail_parser_new (CAMEL_SESSION (mail_session));
-static void
-format_parser_async_done_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- EMailParser *parser = E_MAIL_PARSER (source);
- EMailPartList *part_list;
- GHashTable *mails;
- struct format_parser_async_closure_ *closure = user_data;
-
- part_list = e_mail_parser_parse_finish (parser, result, NULL);
+ part_list = e_mail_parser_parse_sync (
+ parser, data->folder, data->message_uid,
+ data->message,
+ e_activity_get_cancellable (data->activity));
- /* When no EMailDisplay holds reference to the part list, then
- * the list can be destroyed. */
- g_object_weak_ref (G_OBJECT (part_list),
- (GWeakNotify) part_list_weak_ref_cb, g_strdup (closure->mail_uri));
+ g_object_unref (parser);
- mails = mail_reader_get_mail_register ();
- g_hash_table_insert (mails, g_strdup (closure->mail_uri), part_list);
- d(printf("Registered EMailPartList %s\n", closure->mail_uri));
-
- if (closure->user_callback)
- closure->user_callback (part_list, closure->user_data);
+ if (!part_list) {
+ camel_object_bag_abort (registry, mail_uri);
+ } else {
+ e_mail_part_list_registry_add (
+ registry, mail_uri, part_list);
+ g_object_ref (part_list);
+ }
+ }
- g_object_unref (closure->activity);
- g_free (closure->mail_uri);
- g_free (closure);
+ g_free (mail_uri);
- g_object_unref (result);
- g_object_unref (parser);
+ data->part_list = part_list;
}
void
@@ -1634,31 +1596,54 @@ e_mail_reader_parse_message (EMailReader *reader,
CamelFolder *folder,
const gchar *message_uid,
CamelMimeMessage *message,
- GFunc ready_callback,
+ GAsyncReadyCallback ready_callback,
gpointer user_data)
{
- EMailParser *parser;
- EMailBackend *mail_backend;
- EMailSession *mail_session;
- gchar *mail_uri;
- struct format_parser_async_closure_ *closure;
+ GSimpleAsyncResult *simple;
+ struct mail_reader_parse_message_run_data_ *data;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (ready_callback != NULL);
+
+ data = g_new0 (struct mail_reader_parse_message_run_data_, 1);
+ data->activity = e_mail_reader_new_activity (reader);
+ e_activity_set_text (data->activity, _("Parsing message"));
+ data->folder = g_object_ref (folder);
+ data->message = g_object_ref (message);
+ data->message_uid = g_strdup (message_uid);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (reader), ready_callback, user_data,
+ e_mail_reader_parse_message);
+ g_object_set_data (G_OBJECT (simple), "evo-data", data);
+
+ g_simple_async_result_run_in_thread (
+ simple, mail_reader_parse_message_run,
+ G_PRIORITY_DEFAULT,
+ e_activity_get_cancellable (data->activity));
+
+ g_object_unref (simple);
+}
+
+EMailPartList *
+e_mail_reader_parse_message_finish (EMailReader *reader,
+ GAsyncResult *result)
+{
+ struct mail_reader_parse_message_run_data_ *data;
+ EMailPartList *part_list;
- mail_uri = e_mail_part_build_uri (folder, message_uid, NULL, NULL);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
- mail_backend = e_mail_reader_get_backend (reader);
- mail_session = e_mail_backend_get_session (mail_backend);
+ data = g_object_get_data (G_OBJECT (result), "evo-data");
+ g_return_val_if_fail (data, NULL);
- closure = g_new0 (struct format_parser_async_closure_, 1);
- parser = e_mail_parser_new (CAMEL_SESSION (mail_session));
+ part_list = data->part_list;
- closure->activity = e_mail_reader_new_activity (reader);
- e_activity_set_text (closure->activity, _("Parsing message"));
- closure->mail_uri = mail_uri;
- closure->user_callback = ready_callback;
- closure->user_data = user_data;
+ g_clear_object (&data->folder);
+ g_clear_object (&data->message);
+ g_clear_object (&data->activity);
+ g_free (data->message_uid);
+ g_free (data);
- e_mail_parser_parse (parser, folder, message_uid,
- message, format_parser_async_done_cb,
- e_activity_get_cancellable (closure->activity),
- closure);
+ return part_list;
}