aboutsummaryrefslogtreecommitdiffstats
path: root/composer
diff options
context:
space:
mode:
Diffstat (limited to 'composer')
-rw-r--r--composer/ChangeLog33
-rw-r--r--composer/e-msg-composer-attachment-bar.c39
-rw-r--r--composer/e-msg-composer-attachment-bar.h2
-rw-r--r--composer/e-msg-composer.c158
-rw-r--r--composer/e-msg-composer.h8
-rw-r--r--composer/listener.c68
6 files changed, 183 insertions, 125 deletions
diff --git a/composer/ChangeLog b/composer/ChangeLog
index ddf610712b..612082dfe4 100644
--- a/composer/ChangeLog
+++ b/composer/ChangeLog
@@ -1,3 +1,36 @@
+2001-10-21 Dan Winship <danw@frotz.mysterion.org>
+
+ 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.
+
2001-10-19 Jeffrey Stedfast <fejj@ximian.com>
* e-msg-composer.c (handle_multipart): Now takes a 'attach_all'
diff --git a/composer/e-msg-composer-attachment-bar.c b/composer/e-msg-composer-attachment-bar.c
index 6619a59597..71562e9692 100644
--- a/composer/e-msg-composer-attachment-bar.c
+++ b/composer/e-msg-composer-attachment-bar.c
@@ -816,42 +816,3 @@ e_msg_composer_attachment_bar_attach_mime_part (EMsgComposerAttachmentBar *bar,
add_from_mime_part (bar, part);
}
-
-CamelMimePart *
-e_msg_composer_attachment_bar_find_message (EMsgComposerAttachmentBar *bar, char *url)
-{
- EMsgComposerAttachmentBarPrivate *priv;
- GList *p;
- char *content_id = NULL;
-
- g_return_val_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar), NULL);
- g_return_val_if_fail (url != NULL, NULL);
-
- if (!strncmp ("cid:", url, 4))
- content_id = url + 4;
-
- priv = bar->priv;
-
- for (p = priv->attachments; p != NULL; p = p->next) {
- CamelMimePart *part;
- const char *part_id;
- const char *part_location;
-
- part = E_MSG_COMPOSER_ATTACHMENT (p->data)->body;
-
- part_id = camel_mime_part_get_content_id (part);
- g_warning ("content_id: %s, part_id: %s\n", content_id, part_id);
-
- if (content_id && part_id && !strcmp (part_id, content_id))
- return part;
-
- part_location = camel_mime_part_get_content_location (part);
- g_warning ("url: %s, part_id: %s\n", url, part_id);
-
- if (part_location && !strcmp (part_location, url))
- return part;
-
- }
-
- return NULL;
-}
diff --git a/composer/e-msg-composer-attachment-bar.h b/composer/e-msg-composer-attachment-bar.h
index 3dfe87ad80..15774bb2fe 100644
--- a/composer/e-msg-composer-attachment-bar.h
+++ b/composer/e-msg-composer-attachment-bar.h
@@ -68,8 +68,6 @@ void e_msg_composer_attachment_bar_to_multipart (EMsgComposerAttachmentBar *bar,
guint e_msg_composer_attachment_bar_get_num_attachments (EMsgComposerAttachmentBar *bar);
void e_msg_composer_attachment_bar_attach (EMsgComposerAttachmentBar *bar, const gchar *file_name);
void e_msg_composer_attachment_bar_attach_mime_part (EMsgComposerAttachmentBar *bar, CamelMimePart *part);
-CamelMimePart *e_msg_composer_attachment_bar_find_message (EMsgComposerAttachmentBar *bar,
- char *url);
#ifdef __cplusplus
}
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
*
diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h
index 0153fe3ccf..72cb00a673 100644
--- a/composer/e-msg-composer.h
+++ b/composer/e-msg-composer.h
@@ -70,7 +70,7 @@ struct _EMsgComposer {
Bonobo_PersistStream persist_stream_interface;
GNOME_GtkHTML_Editor_Engine editor_engine;
BonoboObject *editor_listener;
- GHashTable *inline_images;
+ GHashTable *inline_images, *inline_images_by_url;
Bonobo_ConfigDatabase config_db;
@@ -122,6 +122,10 @@ void e_msg_composer_add_header (EMsgComposer *compose
const char *value);
void e_msg_composer_attach (EMsgComposer *composer,
CamelMimePart *attachment);
+CamelMimePart *e_msg_composer_add_inline_image_from_file (EMsgComposer *composer,
+ const char *filename);
+void e_msg_composer_add_inline_image_from_mime_part (EMsgComposer *composer,
+ CamelMimePart *part);
CamelMimeMessage *e_msg_composer_get_message (EMsgComposer *composer);
CamelMimeMessage *e_msg_composer_get_message_draft (EMsgComposer *composer);
void e_msg_composer_show_sig_file (EMsgComposer *composer);
@@ -174,7 +178,7 @@ gchar * e_msg_composer_get_sig_file_content (const char *sigfi
void e_msg_composer_add_message_attachments (EMsgComposer *composer,
CamelMimeMessage *message,
gboolean settext,
- gboolean attach_all);
+ gboolean just_inlines);
#ifdef __cplusplus
}
diff --git a/composer/listener.c b/composer/listener.c
index 0b72407b88..228b1c2594 100644
--- a/composer/listener.c
+++ b/composer/listener.c
@@ -29,7 +29,6 @@
#include <bonobo/bonobo-stream-client.h>
#include "listener.h"
-#include "e-msg-composer-attachment-bar.h"
static BonoboObjectClass *listener_parent_class;
static POA_GNOME_GtkHTML_Editor_Listener__vepv listener_vepv;
@@ -54,23 +53,22 @@ get_any_null ()
static gchar *
resolve_image_url (EditorListener *l, gchar *url)
{
- gchar *cid = NULL;
+ CamelMimePart *part;
+ const char *cid;
- printf ("resolve_image_url %s\n", url);
-
- if (!strncmp (url, "file:", 5)) {
- gchar *id;
-
- id = (gchar *) g_hash_table_lookup (l->composer->inline_images, url + 5);
- if (!id) {
- id = header_msgid_generate ();
- g_hash_table_insert (l->composer->inline_images, g_strdup (url + 5), id);
- }
- cid = g_strconcat ("cid:", id, NULL);
- printf ("resolved to %s\n", cid);
+ part = g_hash_table_lookup (l->composer->inline_images_by_url, url);
+ if (!part && !strncmp (url, "file:", 5)) {
+ part = e_msg_composer_add_inline_image_from_file (l->composer,
+ url + 5);
}
+ if (!part)
+ return NULL;
+
+ cid = camel_mime_part_get_content_id (part);
+ if (!cid)
+ return NULL;
- return cid;
+ return g_strconcat ("cid:", cid, NULL);
}
static void
@@ -162,37 +160,31 @@ impl_event (PortableServer_Servant _servant,
}
} else if (!strcmp (name, "url_requested")) {
GNOME_GtkHTML_Editor_URLRequestEvent *e;
- CamelMimePart *part = NULL;
+ CamelMimePart *part;
+ GByteArray *ba;
+ CamelStream *cstream;
+ CamelDataWrapper *wrapper;
e = (GNOME_GtkHTML_Editor_URLRequestEvent *)arg->_value;
- g_warning ("url_requested = \"%s\"", e->url);
- if (e->url) {
- part = e_msg_composer_attachment_bar_find_message (
- E_MSG_COMPOSER_ATTACHMENT_BAR (l->composer->attachment_bar), e->url);
- }
+ if (!e->url || e->stream == CORBA_OBJECT_NIL)
+ return get_any_null ();
+ part = g_hash_table_lookup (l->composer->inline_images_by_url, e->url);
if (!part)
- printf ("url_requested: no part found\n");
- else
- printf ("url_requested: FOUND PART\n");
-
- if (part && e->stream != CORBA_OBJECT_NIL) {
- GByteArray *ba;
- CamelStream *cstream;
- CamelDataWrapper *wrapper;
-
- /* Write the data to a CamelStreamMem... */
- ba = g_byte_array_new ();
- cstream = camel_stream_mem_new_with_byte_array (ba);
- wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- camel_data_wrapper_write_to_stream (wrapper, cstream);
+ part = g_hash_table_lookup (l->composer->inline_images, e->url);
+ if (!part)
+ return get_any_null ();
- bonobo_stream_client_write (e->stream, ba->data, ba->len, ev);
+ /* Write the data to a CamelStreamMem... */
+ ba = g_byte_array_new ();
+ cstream = camel_stream_mem_new_with_byte_array (ba);
+ wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+ camel_data_wrapper_write_to_stream (wrapper, cstream);
- camel_object_unref (CAMEL_OBJECT (cstream));
- }
+ bonobo_stream_client_write (e->stream, ba->data, ba->len, ev);
+ camel_object_unref (CAMEL_OBJECT (cstream));
}
return rv ? rv : get_any_null ();