aboutsummaryrefslogtreecommitdiffstats
path: root/composer/e-msg-composer.c
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2001-10-22 03:08:07 +0800
committerDan Winship <danw@src.gnome.org>2001-10-22 03:08:07 +0800
commitb0ac33fbbe200997569e14574dd5aac746419bed (patch)
treec5573f27b274206769804d81262c0a90f1d85774 /composer/e-msg-composer.c
parente563157722c2dd8fe2cc157326e745142e850bcc (diff)
downloadgsoc2013-evolution-b0ac33fbbe200997569e14574dd5aac746419bed.tar.gz
gsoc2013-evolution-b0ac33fbbe200997569e14574dd5aac746419bed.tar.zst
gsoc2013-evolution-b0ac33fbbe200997569e14574dd5aac746419bed.zip
Make inline images used for replies not show up as
attachments. Also, I think this should make replies to HTML messages containing inline images referenced via Content-Location work, but that's not tested. * e-msg-composer.c (various): Keep two hash tables of inline image data: one mapping from cid: URLs to CamelMimeParts for all attachments, the other mapping from file: and Content-Location urls to CamelMimeParts (for those inline images that came from a file or have a Content-Location). (add_inlined_images): Simplify. Most of this code is in e_msg_composer_add_inline_image_from_file() now. (e_msg_composer_add_message_attachments, handle_multipart): Change "attach_all" arg to "just_inlines". If it is set, call e_msg_composer_add_inline_image_from_mime_part on any attachment with a Content-Id or Content-Location. (e_msg_composer_add_inline_image_from_file): Create a mime part from a file and add it to the inline images hash. (e_msg_composer_add_inline_image_from_mime_part): Add a mime part directly to the inline images hash. * listener.c (resolve_image_url): If asked to resolve a file: URL that isn't in the inline images hash, call e_msg_composer_add_inline_image_from_file to get a cid for it. (impl_event): Look up the URL in the inline_images and inline_images_by_url hashes. * e-msg-composer-attachment-bar.c (e_msg_composer_attachment_bar_find_message): Gone. No longer used. svn path=/trunk/; revision=13852
Diffstat (limited to 'composer/e-msg-composer.c')
-rw-r--r--composer/e-msg-composer.c158
1 files changed, 114 insertions, 44 deletions
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 1a8f525efa..aba81f2d6d 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -121,7 +121,7 @@ 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 attach_all, int depth);
+ gboolean just_inlines, int depth);
static void message_rfc822_dnd (EMsgComposer *composer, CamelStream *stream);
@@ -230,7 +230,15 @@ static gboolean
clear_inline_images (gpointer key, gpointer value, gpointer user_data)
{
g_free (key);
- g_free (value);
+ camel_object_unref (value);
+
+ return TRUE;
+}
+
+static gboolean
+clear_url (gpointer key, gpointer value, gpointer user_data)
+{
+ g_free (key);
return TRUE;
}
@@ -239,45 +247,13 @@ void
e_msg_composer_clear_inlined_table (EMsgComposer *composer)
{
g_hash_table_foreach_remove (composer->inline_images, clear_inline_images, NULL);
+ g_hash_table_foreach_remove (composer->inline_images_by_url, clear_url, NULL);
}
static void
-add_inlined_image (gpointer key, gpointer value, gpointer data)
+add_inlined_image (gpointer key, gpointer part, gpointer multipart)
{
- gchar *file_name = (gchar *) key;
- gchar *cid = (gchar *) value;
- gchar *mime_type;
- CamelMultipart *multipart = (CamelMultipart *) data;
- CamelStream *stream;
- CamelDataWrapper *wrapper;
- CamelMimePart *part;
- struct stat statbuf;
-
- /* check for regular file */
- if (stat (file_name, &statbuf) < 0 || !S_ISREG (statbuf.st_mode))
- return;
-
- if (!(stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0)))
- return;
-
- wrapper = camel_data_wrapper_new ();
- camel_data_wrapper_construct_from_stream (wrapper, stream);
- camel_object_unref (CAMEL_OBJECT (stream));
-
- mime_type = e_msg_composer_guess_mime_type (file_name);
- camel_data_wrapper_set_mime_type (wrapper, mime_type ? mime_type : "application/octet-stream");
- g_free (mime_type);
-
- part = camel_mime_part_new ();
- camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper);
- camel_object_unref (CAMEL_OBJECT (wrapper));
-
- camel_mime_part_set_content_id (part, cid);
- camel_mime_part_set_filename (part, g_basename (file_name));
- camel_mime_part_set_encoding (part, CAMEL_MIME_PART_ENCODING_BASE64);
-
camel_multipart_add_part (multipart, part);
- camel_object_unref (CAMEL_OBJECT (part));
}
static void
@@ -1961,6 +1937,7 @@ destroy (GtkObject *object)
e_msg_composer_clear_inlined_table (composer);
g_hash_table_destroy (composer->inline_images);
+ g_hash_table_destroy (composer->inline_images_by_url);
g_free (composer->charset);
@@ -2148,6 +2125,7 @@ init (EMsgComposer *composer)
composer->editor_engine = CORBA_OBJECT_NIL;
composer->inline_images = g_hash_table_new (g_str_hash, g_str_equal);
+ composer->inline_images_by_url = g_hash_table_new (g_str_hash, g_str_equal);
composer->attachment_bar_visible = FALSE;
composer->send_html = FALSE;
@@ -2492,7 +2470,7 @@ handle_multipart_alternative (EMsgComposer *composer, CamelMultipart *multipart)
}
static void
-handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean attach_all, int depth)
+handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean just_inlines, int depth)
{
int i, nparts;
@@ -2522,7 +2500,7 @@ handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean at
wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
mpart = CAMEL_MULTIPART (wrapper);
- handle_multipart (composer, mpart, attach_all, depth + 1);
+ handle_multipart (composer, mpart, just_inlines, depth + 1);
} else if (depth == 0 && i == 0) {
/* Since the first part is not multipart/alternative, then this must be the body */
CamelDataWrapper *contents;
@@ -2533,10 +2511,12 @@ handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, gboolean at
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 {
- /* this is a leaf of the tree, so attach it */
- if (attach_all || camel_mime_part_get_content_id (mime_part))
- e_msg_composer_attach (composer, mime_part);
+ e_msg_composer_attach (composer, mime_part);
}
}
}
@@ -2590,14 +2570,15 @@ is_special_header (const char *hdr_name)
* @composer: the composer to add the attachments to.
* @message: the source message to copy the attachments from.
* @settext: set the text of the composer
- * @attach_all: attach all attachments
+ * @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 attach_all)
+ gboolean settext, gboolean just_inlines)
{
CamelContentType *content_type;
@@ -2619,7 +2600,7 @@ e_msg_composer_add_message_attachments (EMsgComposer *composer, CamelMimeMessage
wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (message)));
multipart = CAMEL_MULTIPART (wrapper);
- handle_multipart (composer, multipart, attach_all, 0);
+ handle_multipart (composer, multipart, just_inlines, 0);
} else if (settext) {
/* We either have a text/plain or a text/html part */
CamelDataWrapper *contents;
@@ -3031,6 +3012,95 @@ e_msg_composer_attach (EMsgComposer *composer, CamelMimePart *attachment)
/**
+ * e_msg_composer_add_inline_image_from_file:
+ * @composer: a composer object
+ * @file_name: the name of the file containing the image
+ *
+ * This reads in the image in @file_name and adds it to @composer
+ * as an inline image, to be wrapped in a multipart/related.
+ *
+ * Return value: the newly-created CamelMimePart (which must be reffed
+ * if the caller wants to keep its own reference), or %NULL on error.
+ **/
+CamelMimePart *
+e_msg_composer_add_inline_image_from_file (EMsgComposer *composer,
+ const char *file_name)
+{
+ char *mime_type, *cid, *url;
+ CamelStream *stream;
+ CamelDataWrapper *wrapper;
+ CamelMimePart *part;
+ struct stat statbuf;
+
+ /* check for regular file */
+ if (stat (file_name, &statbuf) < 0 || !S_ISREG (statbuf.st_mode))
+ return NULL;
+
+ stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0);
+ if (!stream)
+ return NULL;
+
+ wrapper = camel_data_wrapper_new ();
+ camel_data_wrapper_construct_from_stream (wrapper, stream);
+ camel_object_unref (CAMEL_OBJECT (stream));
+
+ mime_type = e_msg_composer_guess_mime_type (file_name);
+ camel_data_wrapper_set_mime_type (wrapper, mime_type ? mime_type : "application/octet-stream");
+ g_free (mime_type);
+
+ part = camel_mime_part_new ();
+ camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper);
+ camel_object_unref (CAMEL_OBJECT (wrapper));
+
+ cid = header_msgid_generate ();
+ camel_mime_part_set_content_id (part, cid);
+ camel_mime_part_set_filename (part, g_basename (file_name));
+ camel_mime_part_set_encoding (part, CAMEL_MIME_PART_ENCODING_BASE64);
+
+ url = g_strdup_printf ("file:%s", file_name);
+ g_hash_table_insert (composer->inline_images_by_url, url, part);
+
+ url = g_strdup_printf ("cid:%s", cid);
+ g_hash_table_insert (composer->inline_images, url, part);
+ g_free (cid);
+
+ return part;
+}
+
+/**
+ * e_msg_composer_add_inline_image_from_mime_part:
+ * @composer: a composer object
+ * @part: a CamelMimePart containing image data
+ *
+ * This adds the mime part @part to @composer as an inline image, to
+ * be wrapped in a multipart/related.
+ **/
+void
+e_msg_composer_add_inline_image_from_mime_part (EMsgComposer *composer,
+ CamelMimePart *part)
+{
+ char *cid, *url;
+ const char *location;
+
+ cid = (char *)camel_mime_part_get_content_id (part);
+ if (!cid) {
+ cid = header_msgid_generate ();
+ camel_mime_part_set_content_id (part, cid);
+ g_free (cid);
+ }
+
+ url = g_strdup_printf ("cid:%s", cid);
+ g_hash_table_insert (composer->inline_images, url, part);
+ camel_object_ref (CAMEL_OBJECT (part));
+
+ location = camel_mime_part_get_content_location (part);
+ if (location) {
+ g_hash_table_insert (composer->inline_images_by_url,
+ g_strdup (location), part);
+ }
+}
+
+/**
* e_msg_composer_get_message:
* @composer: A message composer widget
*