aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-format.c
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2000-04-23 02:07:14 +0800
committerDan Winship <danw@src.gnome.org>2000-04-23 02:07:14 +0800
commitf5ec554c152ece6b2cac94f030760df4b53bb1c7 (patch)
treea4e616dba27372dadf0bdc2bcbe067161885d9f4 /mail/mail-format.c
parentee7f36f84b8f45356fae240c13dd68b0e8aee8d5 (diff)
downloadgsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.tar
gsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.tar.gz
gsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.tar.bz2
gsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.tar.lz
gsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.tar.xz
gsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.tar.zst
gsoc2013-evolution-f5ec554c152ece6b2cac94f030760df4b53bb1c7.zip
move msg_composer_cb and msg_composer_send_cb to mail-ops. Attach send,
* folder-browser-factory.c: move msg_composer_cb and msg_composer_send_cb to mail-ops. Attach send, reply, and "reply to all" buttons. * mail-ops.c (composer_send_cb, send): moved from folder-browser-factory.c. (reply_to_sender, reply_to_all): new functions to do replies. * mail-format.c (text_to_html): Add an "add_pre" flag, to make it wrap the output in <pre></pre>. (mail_generate_reply): New function to create a composer and build a reply in it. svn path=/trunk/; revision=2554
Diffstat (limited to 'mail/mail-format.c')
-rw-r--r--mail/mail-format.c251
1 files changed, 238 insertions, 13 deletions
diff --git a/mail/mail-format.c b/mail/mail-format.c
index 328f2af638..5fdf3b2d79 100644
--- a/mail/mail-format.c
+++ b/mail/mail-format.c
@@ -30,12 +30,6 @@
#include <ctype.h> /* for isprint */
#include <string.h> /* for strstr */
-/* We shouldn't be doing this, but I don't feel like fixing it right
- * now. (It's for gtk_html_stream_write.) When gtkhtml has nicer
- * interfaces, we can fix it.
- */
-#include <gtkhtml/gtkhtml-private.h>
-
static void handle_text_plain (CamelDataWrapper *wrapper,
GtkHTMLStreamHandle *stream,
CamelDataWrapper *root);
@@ -69,6 +63,7 @@ static void handle_unknown_type (CamelDataWrapper *wrapper,
static gchar *text_to_html (const guchar *input,
guint len,
guint *encoded_len_return,
+ gboolean add_pre,
gboolean convert_newlines_to_br);
/* writes the header info for a mime message into an html stream */
@@ -325,21 +320,21 @@ call_handler_function (CamelDataWrapper *wrapper,
/* Convert plain text in equivalent-looking valid HTML. */
static gchar *
text_to_html (const guchar *input, guint len,
- guint *encoded_len_return,
+ guint *encoded_len_return, gboolean add_pre,
gboolean convert_newlines_to_br)
{
const guchar *cur = input;
guchar *buffer = NULL;
guchar *out = NULL;
gint buffer_size = 0;
- guint count;
/* Allocate a translation buffer. */
- buffer_size = len * 2;
+ buffer_size = len * 2 + 5;
buffer = g_malloc (buffer_size);
out = buffer;
- count = 0;
+ if (add_pre)
+ out += sprintf (out, "<PRE>\n");
while (len--) {
if (out - buffer > buffer_size - 100) {
@@ -392,7 +387,10 @@ text_to_html (const guchar *input, guint len,
cur++;
}
- *out = '\0';
+ if (add_pre)
+ strcpy (out, "</PRE>");
+ else
+ *out = '\0';
if (encoded_len_return)
*encoded_len_return = out - buffer;
@@ -411,7 +409,7 @@ write_field_to_stream (const gchar *description, const gchar *value,
unsigned char *p;
encoded_value = text_to_html (value, strlen(value),
- NULL, TRUE);
+ NULL, FALSE, TRUE);
for (p = (unsigned char *)encoded_value; *p; p++) {
if (!isprint (*p))
*p = '?';
@@ -543,7 +541,7 @@ handle_text_plain (CamelDataWrapper *wrapper, GtkHTMLStreamHandle *stream,
text = text_to_html (tmp_buffer,
nb_bytes_read,
&returned_strlen,
- FALSE);
+ FALSE, FALSE);
mail_write_html (stream, text);
g_free (text);
}
@@ -835,3 +833,230 @@ mail_write_html (GtkHTMLStreamHandle *stream, const char *data)
{
gtk_html_stream_write (stream, data, strlen (data));
}
+
+static char *
+get_data_wrapper_text (CamelDataWrapper *data)
+{
+ CamelStream *memstream;
+ GByteArray *ba;
+ char *text;
+
+ ba = g_byte_array_new ();
+ memstream = camel_stream_mem_new_with_byte_array (ba, CAMEL_STREAM_MEM_WRITE);
+
+ camel_data_wrapper_write_to_stream (data, memstream);
+ text = g_malloc (ba->len + 1);
+ memcpy (text, ba->data, ba->len);
+ text[ba->len] = '\0';
+
+ camel_stream_close (memstream);
+ return text;
+}
+
+static char *
+reply_body (CamelDataWrapper *data, gboolean *html)
+{
+ CamelMultipart *mp;
+ CamelMimePart *subpart;
+ int i, nparts;
+ char *subtext, *old;
+ const char *boundary, *disp;
+ char *text = NULL;
+ GMimeContentField *mime_type;
+
+ /* We only include text, message, and multipart bodies. */
+ mime_type = camel_data_wrapper_get_mime_type_field (data);
+
+ if (strcasecmp (mime_type->type, "message") == 0)
+ return get_data_wrapper_text (data);
+
+ if (strcasecmp (mime_type->type, "text") == 0) {
+ *html = !strcasecmp (mime_type->subtype, "html");
+ return get_data_wrapper_text (data);
+ }
+
+ /* If it's not message and it's not text, and it's not
+ * multipart, we don't want to deal with it.
+ */
+ if (strcasecmp (mime_type->type, "multipart") != 0)
+ return NULL;
+
+ mp = CAMEL_MULTIPART (data);
+
+ if (strcasecmp (mime_type->subtype, "alternative") == 0) {
+ /* Pick our favorite alternative and reply to it. */
+
+ subpart = find_preferred_alternative (mp);
+ if (!subpart)
+ return NULL;
+
+ return reply_body (camel_medium_get_content_object (CAMEL_MEDIUM (subpart)), html);
+ }
+
+ nparts = camel_multipart_get_number (mp);
+
+ /* If any subpart is HTML, pull it out and reply to it by itself.
+ * (If we supported any other non-plain text types, we'd do the
+ * same for them here.)
+ */
+ for (i = 0; i < nparts; i++) {
+ subpart = CAMEL_MIME_PART (camel_multipart_get_part (mp, i));
+
+ if (strcasecmp (MIME_TYPE_SUB (subpart), "html") == 0)
+ return reply_body (camel_medium_get_content_object (CAMEL_MEDIUM (subpart)), html);
+ }
+
+ /* Otherwise, concatenate all the parts that:
+ * - are text/plain or message
+ * - are not explicitly tagged with non-inline disposition
+ */
+ boundary = camel_multipart_get_boundary (mp);
+ for (i = 0; i < nparts; i++) {
+ subpart = CAMEL_MIME_PART (camel_multipart_get_part (mp, i));
+
+ disp = camel_mime_part_get_disposition (subpart);
+ if (disp && strcasecmp (disp, "inline") != 0)
+ continue;
+
+ subtext = get_data_wrapper_text (data);
+ if (text) {
+ old = text;
+ text = g_strdup_printf ("%s\n--%s\n%s", text,
+ boundary, subtext);
+ g_free (subtext);
+ g_free (old);
+ } else
+ text = subtext;
+ }
+
+ if (!text)
+ return NULL;
+
+ old = text;
+ text = g_strdup_printf ("%s\n--%s--\n", text, boundary);
+ g_free (old);
+
+ return text;
+}
+
+EMsgComposer *
+mail_generate_reply (CamelMimeMessage *message, gboolean to_all)
+{
+ CamelDataWrapper *contents;
+ char *text, *subject;
+ EMsgComposer *composer;
+ gboolean html;
+ const char *repl_to, *message_id, *references;
+ GList *to, *cc;
+
+ contents = camel_medium_get_content_object (CAMEL_MEDIUM (message));
+ text = reply_body (contents, &html);
+
+ composer = E_MSG_COMPOSER (e_msg_composer_new ());
+
+ /* Set the quoted reply text. */
+ if (text) {
+ char *repl_text;
+
+ if (html) {
+ repl_text = g_strdup_printf ("<blockquote><i>\n%s\n"
+ "</i></blockquote>\n",
+ text);
+ } else {
+ char *s, *d, *quoted_text;
+ int 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++;
+ quoted_text = g_malloc (strlen (text) + lines * 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;
+ sprintf (d, "> %.*s\n", len, s);
+ s += len;
+ if (!*s++)
+ break;
+ d += len + 3;
+ }
+
+ /* Now convert that to HTML. */
+ repl_text = text_to_html (quoted_text,
+ strlen (quoted_text),
+ &len, TRUE, FALSE);
+ g_free (quoted_text);
+ }
+ e_msg_composer_set_body_text (composer, repl_text);
+ g_free (repl_text);
+ g_free (text);
+ }
+
+ /* Set the recipients */
+ repl_to = camel_mime_message_get_reply_to (message);
+ if (!repl_to)
+ repl_to = camel_mime_message_get_from (message);
+ to = g_list_append (NULL, repl_to);
+
+ if (to_all) {
+ const GList *recip;
+
+ recip = camel_mime_message_get_recipients (message,
+ CAMEL_RECIPIENT_TYPE_TO);
+ cc = g_list_copy (recip);
+
+ recip = camel_mime_message_get_recipients (message,
+ CAMEL_RECIPIENT_TYPE_CC);
+ while (recip) {
+ cc = g_list_append (cc, recip->data);
+ recip = recip->next;
+ }
+ } else
+ cc = NULL;
+
+ /* Set the subject of the new message. */
+ subject = camel_mime_message_get_subject (message);
+ if (!subject)
+ subject = g_strdup ("");
+ else if (!strncasecmp (subject, "Re: ", 4))
+ subject = g_strdup (subject);
+ else
+ subject = g_strdup_printf ("Re: %s", subject);
+
+ e_msg_composer_set_headers (composer, to, cc, NULL, subject);
+ g_list_free (to);
+ g_list_free (cc);
+ g_free (subject);
+
+ /* Add In-Reply-To and References. */
+ message_id = camel_medium_get_header (CAMEL_MEDIUM (message),
+ "Message-Id");
+ references = camel_medium_get_header (CAMEL_MEDIUM (message),
+ "References");
+ if (message_id) {
+ e_msg_composer_add_header (composer, "In-Reply-To",
+ message_id);
+ if (references) {
+ char *reply_refs;
+ reply_refs = g_strdup_printf ("%s %s", references,
+ message_id);
+ e_msg_composer_add_header (composer, "References",
+ reply_refs);
+ g_free (reply_refs);
+ }
+ } else if (references)
+ e_msg_composer_add_header (composer, "References", references);
+
+ return composer;
+}