diff options
Diffstat (limited to 'composer/e-msg-composer.c')
-rw-r--r-- | composer/e-msg-composer.c | 334 |
1 files changed, 214 insertions, 120 deletions
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index 9b2d859c1a..758728b257 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -120,10 +120,20 @@ static GnomeAppClass *parent_class = NULL; /* local prototypes */ static GList *add_recipients (GList *list, const char *recips, gboolean decode); -static void handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, - gboolean just_inlines, int depth); + static void message_rfc822_dnd (EMsgComposer *composer, CamelStream *stream); +/* used by e_msg_composer_add_message_attachments() */ +static void add_attachments_from_multipart (EMsgComposer *composer, CamelMultipart *multipart, + gboolean just_inlines, int depth); + +/* used by e_msg_composer_new_with_message() */ +static void handle_multipart_alternative (EMsgComposer *composer, CamelMultipart *multipart, int depth); + +static void handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, int depth); + + + static GByteArray * get_text (Bonobo_PersistStream persist, char *format) @@ -2414,11 +2424,56 @@ e_msg_composer_new (void) return new; } + +/* FIXME: are there any other headers?? */ +/* This is a list of headers that we DO NOT want to append to the + * extra_hdr_* arrays. + * + * Note: a '*' char can be used for a simple wilcard match. + * is_special_header() will use g_strNcasecmp() with the first '*' + * char being the end of the match string. If no '*' is present, then + * it will be assumed that the header must be an exact match. + */ +static char *special_headers[] = { + "Subject", + "Date", + "From", + "To", + "Cc", + "Bcc", + "Received", + "Message-Id", + "X-Evolution*", + "Content-*", + "MIME-Version", + NULL +}; + +static gboolean +is_special_header (const char *hdr_name) +{ + int i; + + for (i = 0; special_headers[i]; i++) { + char *p; + + if ((p = strchr (special_headers[i], '*'))) { + if (!g_strncasecmp (special_headers[i], hdr_name, p - special_headers[i])) + return TRUE; + } else { + if (!g_strcasecmp (special_headers[i], hdr_name)) + return TRUE; + } + } + + return FALSE; +} + static void e_msg_composer_set_pending_body (EMsgComposer *composer, char *text) { char *old; - + old = gtk_object_get_data (GTK_OBJECT (composer), "body:text"); g_free (old); gtk_object_set_data (GTK_OBJECT (composer), "body:text", text); @@ -2433,16 +2488,89 @@ e_msg_composer_flush_pending_body (EMsgComposer *composer, gboolean apply) if (body) { if (apply) e_msg_composer_set_body_text (composer, body); - + gtk_object_set_data (GTK_OBJECT (composer), "body:text", NULL); g_free (body); } } + +static void +add_attachments_from_multipart (EMsgComposer *composer, CamelMultipart *multipart, + gboolean just_inlines, int depth) +{ + /* find appropriate message attachments to add to the composer */ + int i, nparts; + + nparts = camel_multipart_get_number (multipart); + + for (i = 0; i < nparts; i++) { + CamelContentType *content_type; + CamelMimePart *mime_part; + + mime_part = camel_multipart_get_part (multipart, i); + content_type = camel_mime_part_get_content_type (mime_part); + if (header_content_type_is (content_type, "multipart", "*")) { + /* another layer of multipartness... */ + CamelDataWrapper *wrapper; + CamelMultipart *mpart; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + mpart = CAMEL_MULTIPART (wrapper); + + add_attachments_from_multipart (composer, mpart, just_inlines, depth + 1); + } else if (header_content_type_is (content_type, "text", "*")) { + /* do nothing */ + } else if (header_content_type_is (content_type, "message", "*")) { + /* do nothing */ + } else if (just_inlines) { + if (camel_mime_part_get_content_id (mime_part) || + camel_mime_part_get_content_location (mime_part)) + e_msg_composer_add_inline_image_from_mime_part (composer, mime_part); + } else { + e_msg_composer_attach (composer, mime_part); + } + } +} + + +/** + * e_msg_composer_add_message_attachments: + * @composer: the composer to add the attachments to. + * @message: the source message to copy the attachments from. + * @just_inlines: whether to attach all attachments or just add + * inline images. + * + * Walk through all the mime parts in @message and add them to the composer + * specified in @composer. + */ +void +e_msg_composer_add_message_attachments (EMsgComposer *composer, CamelMimeMessage *message, + gboolean just_inlines) +{ + CamelContentType *content_type; + + content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (message)); + if (header_content_type_is (content_type, "multipart", "*")) { + /* there must be attachments... */ + CamelDataWrapper *wrapper; + CamelMultipart *multipart; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (message))); + multipart = CAMEL_MULTIPART (wrapper); + + add_attachments_from_multipart (composer, multipart, just_inlines, 0); + } else { + /* do nothing... */ + } +} + + static void -handle_multipart_alternative (EMsgComposer *composer, CamelMultipart *multipart) +handle_multipart_alternative (EMsgComposer *composer, CamelMultipart *multipart, int depth) { /* Find the text/html part and set the composer body to it's contents */ + CamelMimePart *text_part = NULL; int i, nparts; nparts = camel_multipart_get_number (multipart); @@ -2454,23 +2582,44 @@ handle_multipart_alternative (EMsgComposer *composer, CamelMultipart *multipart) mime_part = camel_multipart_get_part (multipart, i); content_type = camel_mime_part_get_content_type (mime_part); - if (header_content_type_is (content_type, "text", "html")) { - CamelDataWrapper *contents; - char *text; - - contents = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - text = mail_get_message_body (contents, FALSE, FALSE); + if (header_content_type_is (content_type, "multipart", "*")) { + /* another layer of multipartness... */ + CamelDataWrapper *wrapper; + CamelMultipart *mpart; - if (text) - e_msg_composer_set_pending_body (composer, text); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + mpart = CAMEL_MULTIPART (wrapper); - return; + /* depth doesn't matter so long as we don't pass 0 */ + handle_multipart (composer, mpart, depth + 1); + } else if (header_content_type_is (content_type, "text", "html")) { + /* text/html is preferable, so once we find it we're done... */ + text_part = mime_part; + break; + } else if (header_content_type_is (content_type, "text", "*")) { + /* anyt text part not text/html is second rate so the first + text part we find isn't necessarily the one we'll use. */ + if (!text_part) + text_part = mime_part; + } else { + e_msg_composer_attach (composer, mime_part); } } + + if (text_part) { + CamelDataWrapper *contents; + char *text; + + contents = camel_medium_get_content_object (CAMEL_MEDIUM (text_part)); + text = mail_get_message_body (contents, FALSE, FALSE); + + if (text) + e_msg_composer_set_pending_body (composer, text); + } } static void -handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean just_inlines, int depth) +handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, int depth) { int i, nparts; @@ -2491,7 +2640,7 @@ handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean ju wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); mpart = CAMEL_MULTIPART (wrapper); - handle_multipart_alternative (composer, mpart); + handle_multipart_alternative (composer, mpart, depth + 1); } else if (header_content_type_is (content_type, "multipart", "*")) { /* another layer of multipartness... */ CamelDataWrapper *wrapper; @@ -2500,7 +2649,7 @@ handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean ju wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); mpart = CAMEL_MULTIPART (wrapper); - handle_multipart (composer, mpart, just_inlines, depth + 1); + handle_multipart (composer, mpart, depth + 1); } else if (depth == 0 && i == 0) { /* Since the first part is not multipart/alternative, then this must be the body */ CamelDataWrapper *contents; @@ -2511,120 +2660,26 @@ handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean ju if (text) e_msg_composer_set_pending_body (composer, text); - } else if (just_inlines) { - if (camel_mime_part_get_content_id (mime_part) || - camel_mime_part_get_content_location (mime_part)) - e_msg_composer_add_inline_image_from_mime_part (composer, mime_part); + } else if (camel_mime_part_get_content_id (mime_part) || + camel_mime_part_get_content_location (mime_part)) { + /* special in-line attachment */ + e_msg_composer_add_inline_image_from_mime_part (composer, mime_part); } else { + /* normal attachment */ e_msg_composer_attach (composer, mime_part); } } } -/* FIXME: are there any other headers?? */ -/* This is a list of headers that we DO NOT want to append to the - * extra_hdr_* arrays. - * - * Note: a '*' char can be used for a simple wilcard match. - * is_special_header() will use g_strNcasecmp() with the first '*' - * char being the end of the match string. If no '*' is present, then - * it will be assumed that the header must be an exact match. - */ -static char *special_headers[] = { - "Subject", - "Date", - "From", - "To", - "Cc", - "Bcc", - "Received", - "Message-Id", - "X-Evolution*", - "Content-*", - "MIME-Version", - NULL -}; - -static gboolean -is_special_header (const char *hdr_name) -{ - int i; - - for (i = 0; special_headers[i]; i++) { - char *p; - - if ((p = strchr (special_headers[i], '*'))) { - if (!g_strncasecmp (special_headers[i], hdr_name, p - special_headers[i])) - return TRUE; - } else { - if (!g_strcasecmp (special_headers[i], hdr_name)) - return TRUE; - } - } - - return FALSE; -} /** - * e_msg_composer_add_message_attachments: - * @composer: the composer to add the attachments to. - * @message: the source message to copy the attachments from. - * @settext: set the text of the composer - * @just_inlines: whether to attach all attachments or just add - * inline images. - * - * Walk through all the mime parts in @message and add them to the composer - * specified in @composer. - */ -void -e_msg_composer_add_message_attachments (EMsgComposer *composer, CamelMimeMessage *message, - gboolean settext, gboolean just_inlines) -{ - CamelContentType *content_type; - - content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (message)); - if (header_content_type_is (content_type, "multipart", "alternative")) { - /* this contains the text/plain and text/html versions of the message body */ - CamelDataWrapper *wrapper; - CamelMultipart *multipart; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (message))); - multipart = CAMEL_MULTIPART (wrapper); - - handle_multipart_alternative (composer, multipart); - } else if (header_content_type_is (content_type, "multipart", "*")) { - /* there must be attachments... */ - CamelDataWrapper *wrapper; - CamelMultipart *multipart; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (message))); - multipart = CAMEL_MULTIPART (wrapper); - - handle_multipart (composer, multipart, just_inlines, 0); - } else if (settext) { - /* We either have a text/plain or a text/html part */ - CamelDataWrapper *contents; - char *text; - - contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); - text = mail_get_message_body (contents, FALSE, FALSE); - - if (text) - e_msg_composer_set_pending_body (composer, text); - } - - /* We wait until now to set the body text because we need to ensure that - * the attachment bar has all the attachments, before we request them. - */ - e_msg_composer_flush_pending_body (composer, settext); -} - -/** * e_msg_composer_new_with_message: * @message: The message to use as the source * * Create a new message composer widget. - * + * + * Note: Designed to work only for messages constructed using Evolution. + * * Return value: A pointer to the newly created widget **/ EMsgComposer * @@ -2634,6 +2689,7 @@ e_msg_composer_new_with_message (CamelMimeMessage *message) GList *To = NULL, *Cc = NULL, *Bcc = NULL; EDestination **Tov, **Ccv, **Bccv; const char *format, *subject, *account_name; + CamelContentType *content_type; struct _header_raw *headers; EMsgComposer *new; XEvolution *xev; @@ -2737,7 +2793,42 @@ e_msg_composer_new_with_message (CamelMimeMessage *message) headers = headers->next; } - e_msg_composer_add_message_attachments (new, message, TRUE, TRUE); + /* Restore the attachments and body text */ + content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (message)); + if (header_content_type_is (content_type, "multipart", "alternative")) { + /* this contains the text/plain and text/html versions of the message body */ + CamelDataWrapper *wrapper; + CamelMultipart *multipart; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (message))); + multipart = CAMEL_MULTIPART (wrapper); + + handle_multipart_alternative (new, multipart, 0); + } else if (header_content_type_is (content_type, "multipart", "*")) { + /* there must be attachments... */ + CamelDataWrapper *wrapper; + CamelMultipart *multipart; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (message))); + multipart = CAMEL_MULTIPART (wrapper); + + handle_multipart (new, multipart, 0); + } else { + /* We either have a text/plain or a text/html part */ + CamelDataWrapper *contents; + char *text; + + contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); + text = mail_get_message_body (contents, FALSE, FALSE); + + if (text) + e_msg_composer_set_pending_body (new, text); + } + + /* We wait until now to set the body text because we need to ensure that + * the attachment bar has all the attachments, before we request them. + */ + e_msg_composer_flush_pending_body (new, TRUE); return new; } @@ -2964,6 +3055,9 @@ e_msg_composer_set_body_text (EMsgComposer *composer, const char *text) { g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + printf ("setting as body text:\n-----\n%s\n-----\n", text); + fflush (stdout); + set_editor_text (composer, text); } |