From a952dca522c1e1e9f7d883dfb67d5b444d4dd649 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 23 Oct 2009 22:28:56 +0200 Subject: Bug #575208 - Use complete template message with all attachments --- mail/em-composer-utils.c | 263 +++++++++++++++++++++--------------------- plugins/templates/templates.c | 70 ++--------- 2 files changed, 143 insertions(+), 190 deletions(-) diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c index b3bb7e6b59..b2083b78d3 100644 --- a/mail/em-composer-utils.c +++ b/mail/em-composer-utils.c @@ -763,160 +763,165 @@ em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri return composer; } -/* Editing messages... */ - -static GtkWidget * -edit_message (CamelMimeMessage *message, CamelFolder *drafts, const gchar *uid) +static gboolean +replace_variables (GSList *clues, CamelMimeMessage *message, gchar **pstr) { - EMsgComposer *composer; + gint i; + gboolean string_changed = FALSE, count1 = FALSE; + gchar *str; + + g_return_val_if_fail (pstr != NULL, FALSE); + g_return_val_if_fail (*pstr != NULL, FALSE); + g_return_val_if_fail (message != NULL, FALSE); + + str = *pstr; + + for (i = 0; i < strlen (str); i++) { + const gchar *cur = str + i; + if (!g_ascii_strncasecmp (cur, "$", 1)) { + const gchar *end = cur + 1; + gchar *out; + gchar **temp_str; + GSList *list; + + while (*end && (g_unichar_isalnum (*end) || *end == '_')) + end++; + + out = g_strndup ((const gchar *) cur, end - cur); + + temp_str = g_strsplit (str, out, 2); + + for (list = clues; list; list = g_slist_next (list)) { + gchar **temp = g_strsplit (list->data, "=", 2); + if (!g_ascii_strcasecmp (temp[0], out+1)) { + g_free (str); + str = g_strconcat (temp_str[0], temp[1], temp_str[1], NULL); + count1 = TRUE; + string_changed = TRUE; + } else + count1 = FALSE; + g_strfreev(temp); + } - /* Template specific code follows. */ - if (em_utils_folder_is_templates(drafts, NULL) == TRUE) { - /* retrieve the message from the CamelFolder */ - CamelDataWrapper *content; - CamelStream *mem; - CamelContentType *type; - CamelMimePart *mime_part = CAMEL_MIME_PART (message); - CamelDataWrapper *mail_text; - CamelMultipart *body = camel_multipart_new (); - CamelStream *stream; - CamelMimePart *part; - gint count1 = 0, string_changed = 0; - gint i; - GConfClient *gconf; - GSList *clue_list = NULL, *list; + if (!count1) { + if (getenv (out+1)) { + g_free (str); + str = g_strconcat (temp_str[0], getenv (out + 1), temp_str[1], NULL); + count1 = TRUE; + string_changed = TRUE; + } else + count1 = FALSE; + } - gchar *str; - gint count = 2; + if (!count1) { + const CamelInternetAddress *to; + const gchar *name, *addr; + + to = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO); + if (!camel_internet_address_get (to, 0, &name, &addr)) + continue; + + if (name && g_ascii_strcasecmp ("sender_name", out + 1) == 0) { + g_free (str); + str = g_strconcat (temp_str[0], name, temp_str[1], NULL); + count1 = TRUE; + string_changed = TRUE; + } else if (addr && g_ascii_strcasecmp ("sender_email", out + 1) == 0) { + g_free (str); + str = g_strconcat (temp_str[0], addr, temp_str[1], NULL); + count1 = TRUE; + string_changed = TRUE; + } + } - content = camel_medium_get_content_object ((CamelMedium *) message); - if (!content) - return NULL; - - /* - * Get non-multipart content from multipart message. - */ - while (CAMEL_IS_MULTIPART (content) && count > 0) - { - mime_part = camel_multipart_get_part (CAMEL_MULTIPART (content), 0); - content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - count--; + g_strfreev (temp_str); + g_free (out); } + } - if (!mime_part) - return NULL; + *pstr = str; - type = camel_mime_part_get_content_type (mime_part); - if (!camel_content_type_is (type, "text", "plain")) - return NULL; + return string_changed; +} - mem = camel_stream_mem_new (); - camel_data_wrapper_decode_to_stream (content, mem); +static void +traverse_parts (GSList *clues, CamelMimeMessage *message, CamelDataWrapper *content) +{ + g_return_if_fail (message != NULL); - str = g_strndup ((const gchar *)((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len); - camel_object_unref (mem); + if (!content) + return; - gconf = gconf_client_get_default (); - /* Get the list from gconf */ - clue_list = gconf_client_get_list ( gconf, GCONF_KEY_TEMPLATE_PLACEHOLDERS, GCONF_VALUE_STRING, NULL ); - g_object_unref (gconf); + if (CAMEL_IS_MULTIPART (content)) { + guint i, n; + CamelMultipart *multipart = CAMEL_MULTIPART (content); + CamelMimePart *part; - for (i = 0; i < strlen (str); i++) { - const gchar *cur = str + i; - if (!g_ascii_strncasecmp (cur, "$", 1)) { - const gchar *end = cur + 1; - gchar *out; - gchar **temp_str; - - while (*end && (g_unichar_isalnum (*end) || *end == '_')) - end++; - - out = g_strndup ((const gchar *) cur, end - cur); - - temp_str = g_strsplit (str, out, 2); - - for (list = clue_list; list; list = g_slist_next (list)) { - gchar **temp = g_strsplit (list->data, "=", 2); - if (!g_ascii_strcasecmp(temp[0], out+1)) { - g_free (str); - str = g_strconcat (temp_str[0], temp[1], temp_str[1], NULL); - count1 = 1; - string_changed = 1; - } else - count1 = 0; - g_strfreev(temp); - } + n = camel_multipart_get_number (multipart); + for (i = 0; i < n; i++) { + part = camel_multipart_get_part (multipart, i); + if (!part) + continue; - if (!count1) { - if (getenv (out+1)) { - g_free (str); - str = g_strconcat (temp_str[0], getenv (out + 1), temp_str[1], NULL); - count1 = 1; - string_changed = 1; - } else - count1 = 0; - } + traverse_parts (clues, message, CAMEL_DATA_WRAPPER (part)); + } + } else if (CAMEL_IS_MIME_PART (content)) { + CamelMimePart *part = CAMEL_MIME_PART (content); + CamelContentType *type; + CamelStream *mem; + gchar *str; - if (!count1) { - const CamelInternetAddress *to; - const gchar *name, *addr; - - to = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO); - if (!camel_internet_address_get (to, 0, &name, &addr)) - continue; - - if (name && g_ascii_strcasecmp ("sender_name", out + 1) == 0) { - g_free (str); - str = g_strconcat (temp_str[0], name, temp_str[1], NULL); - count1 = 1; - string_changed = 1; - } else if (addr && g_ascii_strcasecmp ("sender_email", out + 1) == 0) { - g_free (str); - str = g_strconcat (temp_str[0], addr, temp_str[1], NULL); - count1 = 1; - string_changed = 1; - } - } + content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + if (!content) + return; - g_strfreev (temp_str); - g_free (out); - } + if (CAMEL_IS_MULTIPART (content)) { + traverse_parts (clues, message, CAMEL_DATA_WRAPPER (content)); + return; } - if (clue_list) { - g_slist_foreach (clue_list, (GFunc) g_free, NULL); - g_slist_free (clue_list); - } + type = camel_mime_part_get_content_type (part); + if (!camel_content_type_is (type, "text", "*")) + return; - if (string_changed) { + mem = camel_stream_mem_new (); + camel_data_wrapper_decode_to_stream (content, mem); - /* Create toplevel container */ - camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (body), - "multipart/alternative;"); - camel_multipart_set_boundary (body, NULL); + str = g_strndup ((const gchar *)((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len); + camel_object_unref (mem); - stream = camel_stream_mem_new (); + if (replace_variables (clues, message, &str)) { + mem = camel_stream_mem_new_with_buffer (str, strlen (str)); + camel_stream_reset (mem); + camel_data_wrapper_construct_from_stream (content, mem); + camel_object_unref (mem); + } - mail_text = camel_data_wrapper_new (); - camel_data_wrapper_set_mime_type_field (mail_text, type); + g_free (str); + } +} + +/* Editing messages... */ - camel_stream_printf (stream, "%s", str); +static GtkWidget * +edit_message (CamelMimeMessage *message, CamelFolder *drafts, const gchar *uid) +{ + EMsgComposer *composer; - camel_data_wrapper_construct_from_stream (mail_text, stream); - camel_object_unref (stream); + /* Template specific code follows. */ + if (em_utils_folder_is_templates (drafts, NULL) == TRUE) { + GConfClient *gconf; + GSList *clue_list = NULL; - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), mail_text); - camel_object_unref (mail_text); - camel_multipart_add_part (body, part); - camel_object_unref (part); + gconf = gconf_client_get_default (); + /* Get the list from gconf */ + clue_list = gconf_client_get_list ( gconf, GCONF_KEY_TEMPLATE_PLACEHOLDERS, GCONF_VALUE_STRING, NULL ); + g_object_unref (gconf); - /* Finish creating the message */ - camel_medium_set_content_object (CAMEL_MEDIUM (message), CAMEL_DATA_WRAPPER(body)); - camel_object_unref (body); - } + traverse_parts (clue_list, message, camel_medium_get_content_object (CAMEL_MEDIUM (message))); - g_free (str); + g_slist_foreach (clue_list, (GFunc) g_free, NULL); + g_slist_free (clue_list); } composer = e_msg_composer_new_with_message (message); diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index f6832695d7..9e95b4f9dc 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -432,65 +432,13 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) return hbox; } -/* borrowed from plugins/mail-to-task/ */ -static gchar * -get_content (CamelMimeMessage *message) -{ - CamelDataWrapper *content; - CamelStream *mem; - CamelContentType *type; - CamelMimePart *mime_part = CAMEL_MIME_PART (message); - gchar *str, *convert_str = NULL; - gsize bytes_read, bytes_written; - gint count = 2; - - content = camel_medium_get_content_object ((CamelMedium *) message); - if (!content) - return NULL; - - /* Get non-multipart content from multipart message. */ - while (CAMEL_IS_MULTIPART (content) && count > 0) { - mime_part = camel_multipart_get_part (CAMEL_MULTIPART (content), 0); - content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); - count--; - } - - if (!mime_part) - return NULL; - - type = camel_mime_part_get_content_type (mime_part); - if (!camel_content_type_is (type, "text", "plain")) - return NULL; - - mem = camel_stream_mem_new (); - camel_data_wrapper_decode_to_stream (content, mem); - - str = g_strndup ((const gchar *)((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len); - camel_object_unref (mem); - - /* convert to UTF-8 string */ - if (str && content->mime_type->params && content->mime_type->params->value) { - convert_str = g_convert (str, strlen (str), - "UTF-8", content->mime_type->params->value, - &bytes_read, &bytes_written, NULL); - } - - if (convert_str) { - g_free (str); - return convert_str; - } - else - return str; - -} - static void create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, gpointer data) { GtkAction *action = data; CamelMimeMessage *new, *template; struct _camel_header_raw *header; - gchar *cont; + CamelStream *mem; g_return_if_fail (data != NULL); g_return_if_fail (message != NULL); @@ -501,6 +449,14 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes /* The new message we are creating */ new = camel_mime_message_new(); + /* make the exact copy of the template message, with all + its attachments and message structure */ + mem = camel_stream_mem_new (); + camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (template), mem); + camel_stream_reset (mem); + camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (new), mem); + camel_object_unref (mem); + /* Add the headers from the message we are replying to, so CC and that * stuff is preserved. */ header = ((CamelMimePart *)message)->headers; @@ -513,11 +469,6 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes header = header->next; } - camel_mime_part_set_encoding((CamelMimePart *) new, CAMEL_TRANSFER_ENCODING_8BIT); - - /* Get the template content. */ - cont = get_content (template); - /* Set the To: field to the same To: field of the message we are replying to. */ camel_mime_message_set_recipients (new, CAMEL_RECIPIENT_TYPE_TO, camel_mime_message_get_from (message)); @@ -529,9 +480,6 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes camel_mime_message_set_recipients (new, CAMEL_RECIPIENT_TYPE_BCC, camel_mime_message_get_recipients (template, CAMEL_RECIPIENT_TYPE_BCC)); - camel_mime_part_set_content((CamelMimePart *)new, - cont, (gint) g_utf8_strlen(cont, -1), "text"); - /* Create the composer */ em_utils_edit_message (new, folder); -- cgit v1.2.3