diff options
author | Dan Winship <danw@src.gnome.org> | 2001-09-07 04:10:02 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2001-09-07 04:10:02 +0800 |
commit | e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60 (patch) | |
tree | 0a967cdf3e1ccf771ce74f4336238452d023d956 /mail | |
parent | 3f7f2d2f2e9d344dd102d245aed8e0af2a102f47 (diff) | |
download | gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.tar gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.tar.gz gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.tar.bz2 gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.tar.lz gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.tar.xz gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.tar.zst gsoc2013-evolution-e243f47a722dcbabbc1e82fa2cfeb8d4edcc0f60.zip |
Fix a bunch of replying/forwarding-related formatting bugs.
2749 - Message text not included in reply, but html attachment is
4294 - "forward inline" should quote the same headers as the
normal mail display
6100 - Reply to a forwarded email displays email headers
7255 - Replying to HTML message
7527 - replying to forwarded message w/ attachments does the wrong
thing
* mail-format.c (mail_get_message_rfc822): New function to get
message headers and body together, for inline forwards, or replies
containing attached messages.
(mail_get_message_body): Redo this to always return HTML, but keep
the "want_plain" flag, to decide whether to return HTML that looks
like HTML or HTML that looks like plain text. Use
mail_get_message_rfc822 to handle attached message/rfc822 parts.
Don't include the text of vcard or icalendar attachments. Don't
fail to include text parts just because we found an HTML part.
(Since we're always returning HTML now, this doesn't cause
problems any more.)
* mail-tools.c (mail_tool_quote_message): Simplify greatly.
mail_get_message_body always returns HTML now, and we let it take
care of prepending "> "s too. We then let GtkHTML deal with
converting the HTML to plain text if the user wants to reply in
plain text.
(mail_tool_forward_message): Simplify this a ton too: parts of it
are moved into mail_get_message_rfc822 and parts are now
unnecessary.
* mail-callbacks.c (do_forward_non_attached): Call
mail_tool_forward_message here always, and let it do the "> "
quoting in the "quoted" case, so that we get the headers too when
forwarding quoted. Related to bug #4294.
svn path=/trunk/; revision=12657
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 38 | ||||
-rw-r--r-- | mail/mail-callbacks.c | 11 | ||||
-rw-r--r-- | mail/mail-format.c | 189 | ||||
-rw-r--r-- | mail/mail-tools.c | 162 | ||||
-rw-r--r-- | mail/mail-tools.h | 2 | ||||
-rw-r--r-- | mail/mail.h | 3 |
6 files changed, 214 insertions, 191 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 683d509a64..91c2f773d2 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,41 @@ +2001-09-06 Dan Winship <danw@ximian.com> + + Fix a bunch of replying/forwarding-related formatting bugs. + + 2749 - Message text not included in reply, but html attachment is + 4294 - "forward inline" should quote the same headers as the + normal mail display + 6100 - Reply to a forwarded email displays email headers + 7255 - Replying to HTML message + 7527 - replying to forwarded message w/ attachments does the wrong + thing + + * mail-format.c (mail_get_message_rfc822): New function to get + message headers and body together, for inline forwards, or replies + containing attached messages. + (mail_get_message_body): Redo this to always return HTML, but keep + the "want_plain" flag, to decide whether to return HTML that looks + like HTML or HTML that looks like plain text. Use + mail_get_message_rfc822 to handle attached message/rfc822 parts. + Don't include the text of vcard or icalendar attachments. Don't + fail to include text parts just because we found an HTML part. + (Since we're always returning HTML now, this doesn't cause + problems any more.) + + * mail-tools.c (mail_tool_quote_message): Simplify greatly. + mail_get_message_body always returns HTML now, and we let it take + care of prepending "> "s too. We then let GtkHTML deal with + converting the HTML to plain text if the user wants to reply in + plain text. + (mail_tool_forward_message): Simplify this a ton too: parts of it + are moved into mail_get_message_rfc822 and parts are now + unnecessary. + + * mail-callbacks.c (do_forward_non_attached): Call + mail_tool_forward_message here always, and let it do the "> " + quoting in the "quoted" case, so that we get the headers too when + forwarding quoted. Related to bug #4294. + 2001-09-05 Dan Winship <danw@ximian.com> * mail-display.c (launch_cb): the "command" of a diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index f3378c2047..dc01bb0f78 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -922,19 +922,14 @@ forward_get_composer (CamelMimeMessage *message, const char *subject) static void do_forward_non_attached (CamelFolder *folder, char *uid, CamelMimeMessage *message, void *data) { - char *subject, *text, *title; + char *subject, *text; + MailConfigForwardStyle style = GPOINTER_TO_INT (data); if (!message) return; subject = mail_tool_generate_forward_subject (message); - if (GPOINTER_TO_INT (data) == MAIL_CONFIG_FORWARD_INLINE) { - text = mail_tool_forward_message (message); - } else { - title = e_utf8_from_locale_string (_("Forwarded message:\n")); - text = mail_tool_quote_message (message, title); - g_free (title); - } + text = mail_tool_forward_message (message, style == MAIL_CONFIG_FORWARD_QUOTED); if (text) { EMsgComposer *composer = forward_get_composer (message, subject); diff --git a/mail/mail-format.c b/mail/mail-format.c index 27f4506ad6..4e6dcd474a 100644 --- a/mail/mail-format.c +++ b/mail/mail-format.c @@ -1166,8 +1166,6 @@ handle_application_pgp (CamelMimePart *part, const char *mime_type, buffer = CAMEL_STREAM_MEM (plaintext)->buffer; - /* FIXME: uhm, pgp decrypted data doesn't have to be plaintext - * however this broken pgp method doesn't exactly tell us what it is */ camel_mime_part_set_content (mime_part, buffer->data, buffer->len, "text/plain"); camel_object_unref (CAMEL_OBJECT (plaintext)); } @@ -1292,7 +1290,6 @@ decode_pgp (CamelStream *ciphertext, CamelStream *plaintext, MailDisplay *md) camel_exception_init (&ex); /* FIXME: multipart parts */ - /* another FIXME: this doesn't have to return plaintext you realize... */ if (g_datalist_get_data (md->data, "show_pgp")) { CamelPgpContext *ctx; @@ -1359,9 +1356,6 @@ try_inline_pgp (char *start, MailDisplay *md) mail_html_write (md->html, md->stream, "<hr>"); - /* FIXME: uhm, pgp decrypted data doesn't have to be plaintext - * however, I suppose that since it was 'inline', it probably is */ - ciphertext = camel_stream_mem_new (); camel_stream_write (ciphertext, start, end - start); camel_stream_reset (ciphertext); @@ -2145,32 +2139,146 @@ handle_via_bonobo (CamelMimePart *part, const char *mime_type, return TRUE; } +/** + * mail_get_message_rfc822: + * @message: the message + * @want_plain: whether the caller prefers plain to html + * @cite: whether or not to cite the message text + * + * See mail_get_message_body() below for more details. + * + * Return value: an HTML string representing the text parts of @message. + **/ +static char * +mail_get_message_rfc822 (CamelMimeMessage *message, gboolean want_plain, gboolean cite) +{ + CamelDataWrapper *contents; + GString *retval; + const CamelInternetAddress *cia; + char *text, *citation, *buf, *html; + time_t date_val; + int offset; + + contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); + text = mail_get_message_body (contents, want_plain, cite); + if (!text) + text = g_strdup (""); + citation = cite ? "> " : ""; + retval = g_string_new (NULL); + + /* Kludge: if text starts with "<PRE>", wrap it around the + * headers too so we won't get a blank line between them for the + * <P> to <PRE> switch. + */ + if (!g_strncasecmp (text, "<pre>", 5)) + g_string_sprintfa (retval, "<PRE>"); + + /* create credits */ + cia = camel_mime_message_get_from (message); + buf = camel_address_format (CAMEL_ADDRESS (cia)); + if (buf) { + html = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); + g_string_sprintfa (retval, "%s<b>From:</b> %s<br>", + citation, html); + g_free (html); + g_free (buf); + } + + cia = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO); + buf = camel_address_format (CAMEL_ADDRESS (cia)); + if (buf) { + html = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); + g_string_sprintfa (retval, "%s<b>To:</b> %s<br>", + citation, html); + g_free (html); + g_free (buf); + } + + cia = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_CC); + buf = camel_address_format (CAMEL_ADDRESS (cia)); + if (buf) { + html = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); + g_string_sprintfa (retval, "%s<b>Cc:</b> %s<br>", + citation, html); + g_free (html); + g_free (buf); + } + + buf = (char *) camel_mime_message_get_subject (message); + if (buf) { + html = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); + g_string_sprintfa (retval, "%s<b>Subject:</b> %s<br>", + citation, html); + g_free (html); + } + + date_val = camel_mime_message_get_date (message, &offset); + buf = header_format_date (date_val, offset); + html = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); + g_string_sprintfa (retval, "%s<b>Date:</b> %s<br>", citation, html); + g_free (html); + + if (!g_strncasecmp (text, "<pre>", 5)) + g_string_sprintfa (retval, "%s<br>%s", citation, text + 5); + else + g_string_sprintfa (retval, "%s<br>%s", citation, text); + g_free (text); + + buf = retval->str; + g_string_free (retval, FALSE); + return buf; +} + +/** + * mail_get_message_body: + * @data: the message or mime part content + * @want_plain: whether the caller prefers plain to html + * @cite: whether or not to cite the message text + * + * This creates an HTML string representing @data. If @want_plain is %TRUE, + * it will be an HTML string that looks like a text/plain representation + * of @data (but it will still be HTML). + * + * If @cite is %TRUE, the message will be cited as a reply, using "> "s. + * + * Return value: the HTML string, which the caller must free, or + * %NULL if @data doesn't include any data which should be forwarded or + * replied to. + **/ char * -mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, gboolean *is_html) +mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, gboolean cite) { CamelMultipart *mp; CamelMimePart *subpart; int i, nparts; - char *subtext, *old; - const char *boundary; + char *subtext, *old, *div; char *text = NULL; CamelContentType *mime_type; - - /* We only include text, message, and multipart bodies. */ + mime_type = camel_data_wrapper_get_mime_type_field (data); - - /* FIXME: This is wrong. We don't want to include large - * images. But if we don't do it this way, we don't get - * the headers... + + /* If it is message/rfc822 or message/news, extract the + * important headers and recursively process the body. */ - if (header_content_type_is (mime_type, "message", "*")) { - *is_html = FALSE; - return get_data_wrapper_text (data); - } - - if (header_content_type_is (mime_type, "text", "*")) { - *is_html = header_content_type_is (mime_type, "text", "html"); - return get_data_wrapper_text (data); + if (header_content_type_is (mime_type, "message", "rfc822") || + header_content_type_is (mime_type, "message", "news")) + return mail_get_message_rfc822 (CAMEL_MIME_MESSAGE (data), want_plain, cite); + + /* If it's a vcard or icalendar, ignore it. */ + if (header_content_type_is (mime_type, "text", "x-vcard") || + header_content_type_is (mime_type, "text", "calendar")) + return NULL; + + /* Get the body data for other text/ or message/ types */ + if (header_content_type_is (mime_type, "text", "*") || + header_content_type_is (mime_type, "message", "*")) { + text = get_data_wrapper_text (data); + if (text && !header_content_type_is (mime_type, "text", "html")) { + char *html = e_text_to_html (text, E_TEXT_TO_HTML_PRE | (cite ? E_TEXT_TO_HTML_CITE : 0)); + g_free (text); + text = html; + } + return text; } /* If it's not message and it's not text, and it's not @@ -2188,38 +2296,31 @@ mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, gboolean *is if (!subpart) return NULL; - data = camel_medium_get_content_object ( - CAMEL_MEDIUM (subpart)); - return mail_get_message_body (data, want_plain, is_html); + data = camel_medium_get_content_object (CAMEL_MEDIUM (subpart)); + return mail_get_message_body (data, want_plain, cite); } + /* Otherwise, concatenate all the parts that we can. */ + if (want_plain) { + if (cite) + div = "<br>\n> ----<br>\n> <br>\n"; + else + div = "<br>\n----<br>\n<br>\n"; + } else + div = "<br><hr><br>"; + nparts = camel_multipart_get_number (mp); - - /* Otherwise, concatenate all the parts that we can. If we find - * an HTML part in there though, return just that: We don't want - * to deal with merging HTML and non-HTML parts. - */ - boundary = camel_multipart_get_boundary (mp); for (i = 0; i < nparts; i++) { subpart = camel_multipart_get_part (mp, i); - if (!mail_part_is_inline (subpart)) - continue; - - data = camel_medium_get_content_object ( - CAMEL_MEDIUM (subpart)); - subtext = mail_get_message_body (data, want_plain, is_html); + data = camel_medium_get_content_object (CAMEL_MEDIUM (subpart)); + subtext = mail_get_message_body (data, want_plain, cite); if (!subtext) continue; - if (*is_html) { - g_free (text); - return subtext; - } if (text) { old = text; - text = g_strdup_printf ("%s\n--%s\n%s", old, - boundary, subtext); + text = g_strdup_printf ("%s%s%s", old, div, subtext); g_free (subtext); g_free (old); } else diff --git a/mail/mail-tools.c b/mail/mail-tools.c index 56575ef4b1..45d5a45a5e 100644 --- a/mail/mail-tools.c +++ b/mail/mail-tools.c @@ -386,12 +386,15 @@ gchar * mail_tool_quote_message (CamelMimeMessage *message, const char *fmt, ...) { CamelDataWrapper *contents; - gboolean want_plain, is_html; + gboolean want_plain; gchar *text; want_plain = !mail_config_get_send_html (); contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); - text = mail_get_message_body (contents, want_plain, &is_html); + /* We pass "want_plain" for "cite", since if it's HTML, we'll + * do the citing ourself below. + */ + text = mail_get_message_body (contents, want_plain, want_plain); /* Set the quoted reply text. */ if (text) { @@ -406,68 +409,15 @@ mail_tool_quote_message (CamelMimeMessage *message, const char *fmt, ...) va_end (ap); } - if (is_html) { - ret_text = g_strdup_printf ("%s<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"orig\" value=\"1\">-->" - "<blockquote><i><font color=\"%06x\">\n%s\n" - "</font></i></blockquote>" - "<!--+GtkHTML:<DATA class=\"ClueFlow\" clear=\"orig\">-->", - credits ? credits : "", - mail_config_get_citation_color (), text); - } else { - gchar *s, *d, *quoted_text, *orig_text; - gint lines, len; - - /* Count the number of lines in the body. If - * the text ends with a \n, this will be one - * too high, but that's ok. Allocate enough - * space for the text and the "> "s. - */ - for (s = text, lines = 0; s; s = strchr (s + 1, '\n')) - lines++; - - /* offset is the size of the credits, strlen (text) - * covers the body, lines * 2 does the "> "s, and - * the last +2 covers the final "\0", plus an extra - * "\n" in case text doesn't end with one. - */ - quoted_text = g_malloc (strlen (text) + lines * 2 + 2); - - s = text; - d = quoted_text; - - /* Copy text to quoted_text line by line, - * prepending "> ". - */ - while (1) { - len = strcspn (s, "\n"); - if (len == 0 && !*s) - break; - if (!strncmp ("-- \n", s, 4)) - break; - sprintf (d, "> %.*s\n", len, s); - s += len; - if (!*s++) - break; - d += len + 3; - } - *d = '\0'; - - /* Now convert that to HTML. */ - orig_text = e_text_to_html_full (quoted_text, E_TEXT_TO_HTML_PRE - | (mail_config_get_citation_highlight () - ? E_TEXT_TO_HTML_MARK_CITATION : 0), - mail_config_get_citation_color ()); - g_free (quoted_text); - ret_text = g_strdup_printf ("%s<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"orig\" value=\"1\">-->" - "%s" - "<!--+GtkHTML:<DATA class=\"ClueFlow\" clear=\"orig\">-->", - credits ? credits : "", - orig_text); - g_free (orig_text); - } - + ret_text = g_strdup_printf ("%s<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"orig\" value=\"1\">-->" + "<font color=\"%06x\">\n%s%s%s</font>" + "<!--+GtkHTML:<DATA class=\"ClueFlow\" clear=\"orig\">-->", + credits ? credits : "", + mail_config_get_citation_color (), + want_plain ? "" : "<blockquote><i>", + text, + want_plain ? "" : "</i></blockquote>"); g_free (text); - return ret_text; } @@ -476,82 +426,22 @@ mail_tool_quote_message (CamelMimeMessage *message, const char *fmt, ...) /** * mail_tool_forward_message: - * @message: mime message to quote + * @message: mime message to forward + * @quoted: whether to forwarded it quoted (%TRUE) or inline (%FALSE) * * Returns an allocated buffer containing the forwarded message. */ gchar * -mail_tool_forward_message (CamelMimeMessage *message) +mail_tool_forward_message (CamelMimeMessage *message, gboolean quoted) { - CamelDataWrapper *contents; - gboolean want_plain, is_html; - XEvolution *xev; - gchar *text; - - xev = mail_tool_remove_xevolution_headers (message); - - want_plain = !mail_config_get_send_html (); - contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); - text = mail_get_message_body (contents, want_plain, &is_html); - - mail_tool_restore_xevolution_headers (message, xev); - mail_tool_destroy_xevolution (xev); - - /* Set the quoted reply text. */ - if (text) { - gchar *ret_text, *credits = NULL; - const CamelInternetAddress *cia; - char *buf, *from, *to, *subject; - char *title; - - /* create credits */ - cia = camel_mime_message_get_from (message); - buf = camel_address_format (CAMEL_ADDRESS (cia)); - if (buf) { - from = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); - g_free (buf); - } else - from = NULL; - - cia = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO); - buf = camel_address_format (CAMEL_ADDRESS (cia)); - if (buf) { - to = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); - g_free (buf); - } else - to = NULL; - - buf = (char *) camel_mime_message_get_subject (message); - if (buf) - subject = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS); - else - subject = ""; - - title = e_utf8_from_locale_string (_("Forwarded Message")); - credits = g_strdup_printf ("-----%s-----<br>" - "<b>From:</b> %s<br>" - "<b>To:</b> %s<br>" - "<b>Subject:</b> %s<br>", - title, from ? from : "", - to ? to : "", subject); - g_free (title); - g_free (from); - g_free (to); - - if (!is_html) { - /* Now convert that to HTML. */ - ret_text = e_text_to_html (text, E_TEXT_TO_HTML_PRE); - g_free (text); - text = ret_text; - } - - ret_text = g_strdup_printf ("%s<br>%s\n", credits, text); - - g_free (credits); - g_free (text); - - return ret_text; - } - - return NULL; + gchar *title, *body, *ret; + + body = mail_get_message_body (CAMEL_DATA_WRAPPER (message), + !mail_config_get_send_html (), + quoted); + title = e_utf8_from_locale_string (_("Forwarded Message")); + ret = g_strdup_printf ("-----%s-----<br>%s", title, body ? body : ""); + g_free (title); + g_free (body); + return ret; } diff --git a/mail/mail-tools.h b/mail/mail-tools.h index 98e68e6920..bcae822001 100644 --- a/mail/mail-tools.h +++ b/mail/mail-tools.h @@ -87,6 +87,6 @@ mail_lookup_url_table (CamelMimeMessage *mime_message); gchar *mail_tool_quote_message (CamelMimeMessage *message, const char *fmt, ...); -gchar *mail_tool_forward_message (CamelMimeMessage *message); +gchar *mail_tool_forward_message (CamelMimeMessage *message, gboolean quoted); #endif diff --git a/mail/mail.h b/mail/mail.h index b8f96739b1..6e13d84f66 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -61,8 +61,7 @@ gboolean mail_part_is_inline (CamelMimePart *part); gboolean mail_part_is_displayed_inline (CamelMimePart *part, MailDisplay *md); void mail_part_toggle_displayed (CamelMimePart *part, MailDisplay *md); -char *mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, - gboolean *is_html); +char *mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, gboolean cite); /* mail-identify */ char *mail_identify_mime_part (CamelMimePart *part, MailDisplay *md); |