From 8ff61b81c5771badd0a695b8fab9b27a09570882 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 21 Apr 2000 05:12:05 +0000 Subject: deal with cid: URLs. (find_cid): helper routine for above. (This could be * mail-display.c (on_url_requested): deal with cid: URLs. (find_cid): helper routine for above. (This could be much better.) (mail_display_init): connect url_requested signal * mail-format.c (handle_multipart_related): Make this work. svn path=/trunk/; revision=2542 --- mail/ChangeLog | 6 ++++ mail/mail-display.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ mail/mail-format.c | 86 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 144 insertions(+), 21 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 2e4e787518..b7afba2070 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,5 +1,11 @@ 2000-04-21 Dan Winship + * mail-display.c (on_url_requested): deal with cid: URLs. + (find_cid): helper routine for above. (This could be much better.) + (mail_display_init): connect url_requested signal + + * mail-format.c (handle_multipart_related): Make this work. + * mail-display.c (mail_display_set_message): ref the message we display, since we're going to unref it when we remove it. Fixes a bug that showed up with the new camel code, but it's not obvious diff --git a/mail/mail-display.c b/mail/mail-display.c index 5a3b42a319..289b132a2a 100644 --- a/mail/mail-display.c +++ b/mail/mail-display.c @@ -219,6 +219,73 @@ on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, void *unused) g_string_free (camel_stream_gstr, TRUE); } +static CamelMimePart * +find_cid (const char *cid, CamelMimePart *part) +{ + const char *msg_cid; + CamelDataWrapper *content; + CamelMultipart *mp; + int i, nparts; + + msg_cid = camel_mime_part_get_content_id (part); + if (msg_cid && !strcmp (cid, msg_cid)) + return part; + + content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + if (!content) + return NULL; + + if (CAMEL_IS_MIME_PART (content)) + return find_cid (cid, CAMEL_MIME_PART (content)); + else if (!CAMEL_IS_MULTIPART (content)) + return NULL; + + mp = CAMEL_MULTIPART (content); + nparts = camel_multipart_get_number (mp); + for (i = 0; i < nparts; i++) { + CamelMimePart *found_part; + + part = CAMEL_MIME_PART (camel_multipart_get_part (mp, i)); + found_part = find_cid (cid, part); + if (found_part) + return found_part; + } + + return NULL; +} + +static void +on_url_requested (GtkHTML *html, const char *url, GtkHTMLStreamHandle handle, + gpointer user_data) +{ + char *cid, buf[1024]; + int nread; + CamelMimePart *part; + CamelDataWrapper *data; + CamelStream *output; + + if (strncmp (url, "cid:", 4)) + return; + + part = gtk_object_get_data (GTK_OBJECT (html), "message"); + g_return_if_fail (part != NULL); + + cid = g_strdup_printf ("<%s>", url + 4); + part = find_cid (cid, part); + g_free (cid); + + if (!part) + return; + + data = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + output = camel_data_wrapper_get_output_stream (data); + do { + nread = camel_stream_read (output, buf, sizeof (buf)); + if (nread > 0) + gtk_html_write (html, handle, buf, nread); + } while (!camel_stream_eos (output)); +} + /** * mail_display_set_message: @@ -283,6 +350,8 @@ mail_display_set_message (MailDisplay *mail_display, mail_format_mime_message (CAMEL_MIME_MESSAGE (medium), headers_stream, body_stream); + gtk_object_set_data (GTK_OBJECT (mail_display->body_html_widget), + "message", medium); mail_write_html (headers_stream, "\n\n\n\n"); mail_write_html (body_stream, "\n\n\n"); @@ -313,6 +382,10 @@ mail_display_init (GtkObject *object) "object_requested", GTK_SIGNAL_FUNC (on_object_requested), NULL); + gtk_signal_connect (GTK_OBJECT (mail_display->body_html_widget), + "url_requested", + GTK_SIGNAL_FUNC (on_url_requested), + NULL); gtk_widget_show (GTK_WIDGET (mail_display->body_html_widget)); /* various other initializations */ diff --git a/mail/mail-format.c b/mail/mail-format.c index 08c6e81073..328f2af638 100644 --- a/mail/mail-format.c +++ b/mail/mail-format.c @@ -402,7 +402,7 @@ text_to_html (const guchar *input, guint len, static void write_field_to_stream (const gchar *description, const gchar *value, - GtkHTMLStreamHandle *stream) + gboolean bold, GtkHTMLStreamHandle *stream) { gchar *s; gchar *encoded_value; @@ -419,8 +419,10 @@ write_field_to_stream (const gchar *description, const gchar *value, } else encoded_value = g_strdup (""); - s = g_strdup_printf ("%s" - "%s", description, encoded_value); + s = g_strdup_printf ("<%s align=right>%s" + "%s", bold ? "th" : "td", + description, bold ? "th" : "td", + encoded_value); mail_write_html (stream, s); g_free (encoded_value); g_free (s); @@ -428,7 +430,7 @@ write_field_to_stream (const gchar *description, const gchar *value, static void write_recipients_to_stream (const gchar *recipient_type, - const GList *recipients, + const GList *recipients, gboolean bold, GtkHTMLStreamHandle *stream) { gchar *recipients_string = NULL; @@ -445,7 +447,8 @@ write_recipients_to_stream (const gchar *recipient_type, recipients = recipients->next; } - write_field_to_stream (recipient_type, recipients_string, stream); + write_field_to_stream (recipient_type, recipients_string, + bold, stream); g_free (recipients_string); } @@ -455,7 +458,7 @@ static void write_header_info_to_stream (CamelMimeMessage *mime_message, GtkHTMLStreamHandle *stream) { - GList *recipients; + const GList *recipients; mail_write_html (stream, ""); @@ -466,29 +469,28 @@ write_header_info_to_stream (CamelMimeMessage *mime_message, write_field_to_stream ("From:", camel_mime_message_get_from (mime_message), - stream); + TRUE, stream); + + if (camel_mime_message_get_reply_to (mime_message)) { + write_field_to_stream ("Reply-To:", + camel_mime_message_get_reply_to (mime_message), + FALSE, stream); + } write_recipients_to_stream ("To:", camel_mime_message_get_recipients (mime_message, CAMEL_RECIPIENT_TYPE_TO), - stream); + TRUE, stream); recipients = camel_mime_message_get_recipients (mime_message, CAMEL_RECIPIENT_TYPE_CC); if (recipients) - write_recipients_to_stream ("Cc:", recipients, stream); + write_recipients_to_stream ("Cc:", recipients, TRUE, stream); write_field_to_stream ("Subject:", camel_mime_message_get_subject (mime_message), - stream); + TRUE, stream); mail_write_html (stream, "
"); } -/* case-insensitive string comparison */ -static gint -strcase_equal (gconstpointer v, gconstpointer v2) -{ - return g_strcasecmp ((const gchar*) v, (const gchar*)v2) == 0; -} - #define MIME_TYPE_WHOLE(a) (gmime_content_field_get_mime_type ( \ camel_mime_part_get_content_type (CAMEL_MIME_PART (a)))) #define MIME_TYPE_MAIN(a) ((camel_mime_part_get_content_type (CAMEL_MIME_PART (a)))->type) @@ -693,22 +695,64 @@ handle_multipart_mixed (CamelDataWrapper *wrapper, } } +/* As seen in RFC 2387! */ +/* FIXME: camel doesn't currently set CamelMultipart::parent, so we + * can use it here. + */ static void handle_multipart_related (CamelDataWrapper *wrapper, GtkHTMLStreamHandle *stream, CamelDataWrapper *root) { -// CamelMultipart* mp = CAMEL_MULTIPART (wrapper); + CamelMultipart *mp; + CamelMimeBodyPart *body_part; +#if 0 + GMimeContentField *parent_content_type; + const char *start, *cid; + int i, nparts; +#endif + + g_return_if_fail (CAMEL_IS_MULTIPART (wrapper)); + + mp = CAMEL_MULTIPART (wrapper); +#if 0 + parent_content_type = + camel_mime_part_get_content_type ( + camel_multipart_get_parent (mp)); + + start = gmime_content_field_get_parameter (parent_content_type, + "start"); + if (start) { + nparts = camel_multipart_get_number (mp); + for (i = 0; i < nparts; i++) { + CamelMimeBodyPart *body_part = + camel_multipart_get_part (mp, i); + + cid = camel_mime_part_get_content_id ( + CAMEL_MIME_PART (body_part)); + + if (!strcmp (cid, start)) { + display_camel_body_part (body_part, stream, + root); + return; + } + } + + /* Oops. Hrmph. */ + handle_multipart_mixed (wrapper, stream, root); + } +#endif - /* FIXME: read RFC, in terms of how a one message - may refer to another object */ + /* No start parameter, so it defaults to the first part. */ + body_part = camel_multipart_get_part (mp, 0); + display_camel_body_part (body_part, stream, root); } /* multipart/alternative helper function -- * Returns NULL if no displayable msg is found */ static CamelMimePart * -find_preferred_alternative (CamelMultipart* multipart) +find_preferred_alternative (CamelMultipart *multipart) { int i, nparts; CamelMimePart* html_part = NULL; -- cgit v1.2.3