aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog38
-rw-r--r--mail/mail-callbacks.c11
-rw-r--r--mail/mail-format.c189
-rw-r--r--mail/mail-tools.c162
-rw-r--r--mail/mail-tools.h2
-rw-r--r--mail/mail.h3
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 ? "&gt; " : "";
+ 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&gt; ----<br>\n&gt; <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);