diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/e-mail-attachment-bar.c | 64 | ||||
-rw-r--r-- | mail/e-mail-browser.c | 8 | ||||
-rw-r--r-- | mail/e-mail-reader.c | 56 | ||||
-rw-r--r-- | mail/em-format-html.c | 2 | ||||
-rw-r--r-- | mail/em-inline-filter.c | 81 | ||||
-rw-r--r-- | mail/message-list.c | 3 |
6 files changed, 116 insertions, 98 deletions
diff --git a/mail/e-mail-attachment-bar.c b/mail/e-mail-attachment-bar.c index 88198438b7..aa5abd09fb 100644 --- a/mail/e-mail-attachment-bar.c +++ b/mail/e-mail-attachment-bar.c @@ -64,36 +64,6 @@ enum { static gpointer parent_class; static void -mail_attachment_bar_sync_icon_view (EMailAttachmentBar *bar) -{ - EAttachmentView *source; - EAttachmentView *target; - - source = E_ATTACHMENT_VIEW (bar->priv->tree_view); - target = E_ATTACHMENT_VIEW (bar->priv->icon_view); - - /* Only sync if the tree view is active. This prevents the - * two views from endlessly trying to sync with each other. */ - if (e_mail_attachment_bar_get_active_view (bar) == 1) - e_attachment_view_sync_selection (source, target); -} - -static void -mail_attachment_bar_sync_tree_view (EMailAttachmentBar *bar) -{ - EAttachmentView *source; - EAttachmentView *target; - - source = E_ATTACHMENT_VIEW (bar->priv->icon_view); - target = E_ATTACHMENT_VIEW (bar->priv->tree_view); - - /* Only sync if the icon view is active. This prevents the - * two views from endlessly trying to sync with each other. */ - if (e_mail_attachment_bar_get_active_view (bar) == 0) - e_attachment_view_sync_selection (source, target); -} - -static void mail_attachment_bar_update_status (EMailAttachmentBar *bar) { EAttachmentView *view; @@ -516,7 +486,6 @@ static void mail_attachment_bar_init (EMailAttachmentBar *bar) { EAttachmentView *view; - GtkTreeSelection *selection; GtkSizeGroup *size_group; GtkWidget *container; GtkWidget *widget; @@ -562,7 +531,7 @@ mail_attachment_bar_init (EMailAttachmentBar *bar) gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); bar->priv->tree_frame = g_object_ref (widget); - gtk_widget_show (widget); + gtk_widget_hide (widget); container = widget; @@ -645,17 +614,6 @@ mail_attachment_bar_init (EMailAttachmentBar *bar) bar->priv->status_label = g_object_ref (widget); gtk_widget_show (widget); - selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (bar->priv->tree_view)); - - g_signal_connect_swapped ( - selection, "changed", - G_CALLBACK (mail_attachment_bar_sync_icon_view), bar); - - g_signal_connect_swapped ( - bar->priv->icon_view, "selection-changed", - G_CALLBACK (mail_attachment_bar_sync_tree_view), bar); - g_signal_connect_swapped ( bar->priv->model, "notify::num-attachments", G_CALLBACK (mail_attachment_bar_update_status), bar); @@ -722,9 +680,15 @@ void e_mail_attachment_bar_set_active_view (EMailAttachmentBar *bar, gint active_view) { + EAttachmentView *source; + EAttachmentView *target; + g_return_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar)); g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS); + if (active_view == bar->priv->active_view) + return; + bar->priv->active_view = active_view; if (active_view == 0) { @@ -735,6 +699,20 @@ e_mail_attachment_bar_set_active_view (EMailAttachmentBar *bar, gtk_widget_show (bar->priv->tree_frame); } + /* Synchronize the item selection of the view we're + * switching TO with the view we're switching FROM. */ + if (active_view == 0) { + /* from tree view to icon view */ + source = E_ATTACHMENT_VIEW (bar->priv->tree_view); + target = E_ATTACHMENT_VIEW (bar->priv->icon_view); + } else { + /* from icon view to tree view */ + source = E_ATTACHMENT_VIEW (bar->priv->icon_view); + target = E_ATTACHMENT_VIEW (bar->priv->tree_view); + } + + e_attachment_view_sync_selection (source, target); + g_object_notify (G_OBJECT (bar), "active-view"); } diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c index aaf4f789d6..cd7ecd32fd 100644 --- a/mail/e-mail-browser.c +++ b/mail/e-mail-browser.c @@ -280,11 +280,10 @@ close_on_idle_cb (gpointer browser) } static void -mail_browser_message_list_built_cb (EMailBrowser *browser, MessageList *message_list) +mail_browser_message_list_built_cb (EMailBrowser *browser, + MessageList *message_list) { - g_return_if_fail (browser != NULL); g_return_if_fail (E_IS_MAIL_BROWSER (browser)); - g_return_if_fail (message_list != NULL); g_return_if_fail (IS_MESSAGE_LIST (message_list)); if (!message_list_count (message_list)) @@ -446,7 +445,8 @@ mail_browser_dispose (GObject *object) } if (priv->message_list != NULL) { - g_object_unref (priv->message_list); + /* This will cancel a regen operation. */ + gtk_widget_destroy (priv->message_list); priv->message_list = NULL; } diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index 6b1fa7df09..10f1864497 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -52,7 +52,8 @@ #include "mail/message-list.h" #define E_MAIL_READER_GET_PRIVATE(obj) \ - (mail_reader_get_private (G_OBJECT (obj))) + ((EMailReaderPrivate *) g_object_get_qdata \ + (G_OBJECT (obj), quark_private)) typedef struct _EMailReaderPrivate EMailReaderPrivate; @@ -92,31 +93,24 @@ static GQuark quark_private; static guint signals[LAST_SIGNAL]; static void -mail_reader_finalize (EMailReaderPrivate *priv) +mail_reader_destroy (GObject *object) { - if (priv->message_selected_timeout_id > 0) - g_source_remove (priv->message_selected_timeout_id); - - g_free (priv->mark_read_message_uid); - - g_slice_free (EMailReaderPrivate, priv); + /* This will free the private struct. */ + g_object_set_qdata (object, quark_private, NULL); } -static EMailReaderPrivate * -mail_reader_get_private (GObject *object) +static void +mail_reader_private_free (EMailReaderPrivate *priv) { - EMailReaderPrivate *priv; + if (priv->message_selected_timeout_id > 0) + g_source_remove (priv->message_selected_timeout_id); - priv = g_object_get_qdata (object, quark_private); + if (priv->retrieving_message_operation_id > 0) + mail_msg_cancel (priv->retrieving_message_operation_id); - if (G_UNLIKELY (priv == NULL)) { - priv = g_slice_new0 (EMailReaderPrivate); - g_object_set_qdata_full ( - object, quark_private, priv, - (GDestroyNotify) mail_reader_finalize); - } + g_free (priv->mark_read_message_uid); - return priv; + g_slice_free (EMailReaderPrivate, priv); } static void @@ -1809,6 +1803,14 @@ mail_reader_message_loaded_cb (CamelFolder *folder, priv = E_MAIL_READER_GET_PRIVATE (reader); + /* If the private struct is NULL, the EMailReader was destroyed + * while we were loading the message and we're likely holding the + * last reference. Nothing to do but drop the reference. */ + if (priv == NULL) { + g_object_unref (reader); + return; + } + html_display = e_mail_reader_get_html_display (reader); message_list = e_mail_reader_get_message_list (reader); @@ -2537,7 +2539,7 @@ e_mail_reader_get_type (void) type = g_type_register_static ( G_TYPE_INTERFACE, "EMailReader", &type_info, 0); - g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); + g_type_interface_add_prerequisite (type, GTK_TYPE_OBJECT); } return type; @@ -2590,6 +2592,7 @@ e_mail_reader_init (EMailReader *reader) /* Add the other actions the normal way. */ + gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); gtk_action_group_add_actions ( action_group, mail_reader_entries, G_N_ELEMENTS (mail_reader_entries), reader); @@ -2686,6 +2689,19 @@ e_mail_reader_init (EMailReader *reader) g_signal_connect_swapped ( message_list, "selection-change", G_CALLBACK (e_mail_reader_changed), reader); + + /* Install a private struct for storing things like flags and + * timeout and asynchronous operation IDs. We delete it when + * the EMailReader is destroyed rather than finalized so that + * asynchronous callbacks holding a reference can detect that + * the reader has been destroyed and drop their reference. */ + g_object_set_qdata_full ( + G_OBJECT (reader), quark_private, + g_slice_new0 (EMailReaderPrivate), + (GDestroyNotify) mail_reader_private_free); + g_signal_connect ( + reader, "destroy", + G_CALLBACK (mail_reader_destroy), NULL); } void diff --git a/mail/em-format-html.c b/mail/em-format-html.c index 62e190f4b2..db03a6a9d0 100644 --- a/mail/em-format-html.c +++ b/mail/em-format-html.c @@ -1694,7 +1694,7 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo camel_object_unref(null); inline_filter = em_inline_filter_new(camel_mime_part_get_encoding(part), ct); camel_stream_filter_add(filtered_stream, (CamelMimeFilter *)inline_filter); - camel_data_wrapper_write_to_stream(dw, (CamelStream *)filtered_stream); + camel_data_wrapper_decode_to_stream (dw, (CamelStream *)filtered_stream); camel_stream_close((CamelStream *)filtered_stream); camel_object_unref(filtered_stream); diff --git a/mail/em-inline-filter.c b/mail/em-inline-filter.c index 1959b0b7f8..43dee1f97e 100644 --- a/mail/em-inline-filter.c +++ b/mail/em-inline-filter.c @@ -30,6 +30,8 @@ #include <camel/camel-mime-part.h> #include <camel/camel-multipart.h> #include <camel/camel-stream-mem.h> +#include <camel/camel-mime-filter-basic.h> +#include <camel/camel-stream-filter.h> #include "em-utils.h" #include "em-format/em-format.h" @@ -140,11 +142,26 @@ emif_add_part(EMInlineFilter *emif, const gchar *data, gint len) if (emif->data->len <= 0) { return; } - mem = camel_stream_mem_new_with_byte_array(emif->data); + + mem = camel_stream_mem_new_with_byte_array (emif->data); emif->data = g_byte_array_new(); dw = camel_data_wrapper_new(); - camel_data_wrapper_construct_from_stream(dw, mem); + if (encoding == emif->base_encoding && (encoding == CAMEL_TRANSFER_ENCODING_BASE64 || encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE)) { + CamelMimeFilterBasic *enc_filter = camel_mime_filter_basic_new_type (encoding == CAMEL_TRANSFER_ENCODING_BASE64 ? CAMEL_MIME_FILTER_BASIC_BASE64_ENC : CAMEL_MIME_FILTER_BASIC_QP_ENC); + CamelStreamFilter *filter_stream; + + filter_stream = camel_stream_filter_new_with_stream (mem); + camel_stream_filter_add (filter_stream, CAMEL_MIME_FILTER (enc_filter)); + + /* properly encode content */ + camel_data_wrapper_construct_from_stream (dw, CAMEL_STREAM (filter_stream)); + + camel_object_unref (enc_filter); + camel_object_unref (filter_stream); + } else { + camel_data_wrapper_construct_from_stream (dw, mem); + } camel_object_unref(mem); if (emif_types[emif->state].plain && emif->base_type) { @@ -199,12 +216,14 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) gchar *start; while (inptr < inend) { + gint rest_len; + start = inptr; while (inptr < inend && *inptr != '\n') inptr++; - if (inptr == inend) { + if (inptr == inend && start == inptr) { if (!final) { camel_mime_filter_backup(f, start, inend-start); inend = start; @@ -212,22 +231,26 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) break; } - *inptr++ = 0; + rest_len = inend - start; + if (inptr < inend) + *inptr++ = 0; + + #define restore_inptr() G_STMT_START { if (inptr < inend) inptr[-1] = '\n'; } G_STMT_END switch (emif->state) { case EMIF_PLAIN: - /* This could use some funky plugin shit, but this'll do for now */ - if (strncmp(start, "begin ", 6) == 0 + /* This could use some funky plugin, but this'll do for now */ + if (rest_len > 6 && strncmp (start, "begin ", 6) == 0 && start[6] >= '0' && start[6] <= '7') { gint i = 7; gchar *name; - while (start[i] >='0' && start[i] <='7') + while (i < rest_len && start[i] >='0' && start[i] <='7') i++; - inptr[-1] = '\n'; + restore_inptr (); - if (start[i++] != ' ') + if (i >= rest_len || start[i++] != ' ') break; emif_add_part(emif, data_start, start-data_start); @@ -237,23 +260,23 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) g_free(name); data_start = start; emif->state = EMIF_UUENC; - } else if (strncmp(start, "(This file must be converted with BinHex 4.0)", 45) == 0) { - inptr[-1] = '\n'; + } else if (rest_len >= 45 && strncmp (start, "(This file must be converted with BinHex 4.0)", 45) == 0) { + restore_inptr (); emif_add_part(emif, data_start, start-data_start); data_start = start; emif->state = EMIF_BINHEX; - } else if (strncmp(start, "%!PS-Adobe-", 11) == 0) { - inptr[-1] = '\n'; + } else if (rest_len >= 11 && strncmp (start, "%!PS-Adobe-", 11) == 0) { + restore_inptr (); emif_add_part(emif, data_start, start-data_start); data_start = start; emif->state = EMIF_POSTSCRIPT; - } else if (strncmp(start, "-----BEGIN PGP SIGNED MESSAGE-----", 34) == 0) { - inptr[-1] = '\n'; + } else if (rest_len >= 34 && strncmp (start, "-----BEGIN PGP SIGNED MESSAGE-----", 34) == 0) { + restore_inptr (); emif_add_part(emif, data_start, start-data_start); data_start = start; emif->state = EMIF_PGPSIGNED; - } else if (strncmp(start, "-----BEGIN PGP MESSAGE-----", 27) == 0) { - inptr[-1] = '\n'; + } else if (rest_len >= 27 && strncmp (start, "-----BEGIN PGP MESSAGE-----", 27) == 0) { + restore_inptr (); emif_add_part(emif, data_start, start-data_start); data_start = start; emif->state = EMIF_PGPENCRYPTED; @@ -261,8 +284,8 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) break; case EMIF_UUENC: - if (strcmp(start, "end") == 0) { - inptr[-1] = '\n'; + if (rest_len >= 3 && strncmp (start, "end", 3) == 0) { + restore_inptr (); emif_add_part(emif, data_start, inptr-data_start); data_start = inptr; emif->state = EMIF_PLAIN; @@ -278,7 +301,7 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) linelen /= 4; linelen *= 3; if (!(len == linelen || len == linelen-1 || len == linelen-2)) { - inptr[-1] = '\n'; + restore_inptr (); emif_add_part(emif, data_start, start-data_start); data_start = start; inptr = start; @@ -289,31 +312,31 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) break; case EMIF_BINHEX: if (inptr > (start+1) && inptr[-2] == ':') { - inptr[-1] = '\n'; + restore_inptr (); emif_add_part(emif, data_start, inptr-data_start); data_start = inptr; emif->state = EMIF_PLAIN; } break; case EMIF_POSTSCRIPT: - if (strcmp(start, "%%EOF") == 0) { - inptr[-1] = '\n'; + if (rest_len >= 5 && strncmp (start, "%%EOF", 5) == 0) { + restore_inptr (); emif_add_part(emif, data_start, inptr-data_start); data_start = inptr; emif->state = EMIF_PLAIN; } break; case EMIF_PGPSIGNED: - if (strcmp(start, "-----END PGP SIGNATURE-----") == 0) { - inptr[-1] = '\n'; + if (rest_len >= 27 && strncmp (start, "-----END PGP SIGNATURE-----", 27) == 0) { + restore_inptr (); emif_add_part(emif, data_start, inptr-data_start); data_start = inptr; emif->state = EMIF_PLAIN; } break; case EMIF_PGPENCRYPTED: - if (strcmp(start, "-----END PGP MESSAGE-----") == 0) { - inptr[-1] = '\n'; + if (rest_len >= 25 && strncmp (start, "-----END PGP MESSAGE-----", 25) == 0) { + restore_inptr (); emif_add_part(emif, data_start, inptr-data_start); data_start = inptr; emif->state = EMIF_PLAIN; @@ -321,7 +344,9 @@ emif_scan(CamelMimeFilter *f, gchar *in, gsize len, gint final) break; } - inptr[-1] = '\n'; + restore_inptr (); + + #undef restore_inptr } if (final) { diff --git a/mail/message-list.c b/mail/message-list.c index ed1236524c..c7361087b8 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -4900,7 +4900,7 @@ mail_regen_list (MessageList *ml, const gchar *search, const gchar *hideexpr, Ca #endif m = mail_msg_new (®en_list_info); - m->ml = ml; + m->ml = g_object_ref (ml); m->search = g_strdup (search); m->hideexpr = g_strdup (hideexpr); m->changes = changes; @@ -4908,7 +4908,6 @@ mail_regen_list (MessageList *ml, const gchar *search, const gchar *hideexpr, Ca m->hidedel = ml->hidedeleted; m->hidejunk = ml->hidejunk; m->thread_subject = gconf_client_get_bool (gconf, "/apps/evolution/mail/display/thread_subject", NULL); - g_object_ref(ml); m->folder = ml->folder; camel_object_ref(m->folder); m->last_row = -1; |