static gboolean
emfe_attachment_format (EMailFormatterExtension *extension,
                        EMailFormatter *formatter,
                        EMailFormatterContext *context,
                        EMailPart *part,
                        GOutputStream *stream,
                        GCancellable *cancellable)
{
	gchar *text, *html;
	gchar *button_id;
	EAttachmentStore *store;
	EMailExtensionRegistry *registry;
	GQueue *extensions;
	EMailPartAttachment *empa;
	CamelMimePart *mime_part;
	CamelMimeFilterToHTMLFlags flags;
	GString *buffer;
	const gchar *attachment_part_id;
	const gchar *part_id;

	g_return_val_if_fail (E_IS_MAIL_PART_ATTACHMENT (part), FALSE);

	empa = (EMailPartAttachment *) part;
	part_id = e_mail_part_get_id (part);

	if ((context->mode == E_MAIL_FORMATTER_MODE_NORMAL) ||
	    (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) ||
	    (context->mode == E_MAIL_FORMATTER_MODE_ALL_HEADERS)) {
		EAttachment *attachment;
		GList *head, *link;

		attachment = e_mail_part_attachment_ref_attachment (
			E_MAIL_PART_ATTACHMENT (part));

		head = g_queue_peek_head_link (&part->validities);

		for (link = head; link != NULL; link = g_list_next (link)) {
			EMailPartValidityPair *pair = link->data;

			if (pair == NULL)
				continue;

			if ((pair->validity_type & E_MAIL_PART_VALIDITY_SIGNED) != 0)
				e_attachment_set_signed (
					attachment,
					pair->validity->sign.status);

			if ((pair->validity_type & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0)
				e_attachment_set_encrypted (
					attachment,
					pair->validity->encrypt.status);
		}

		store = find_attachment_store (context->part_list, part);
		if (store) {
			GList *attachments = e_attachment_store_get_attachments (store);
			if (!g_list_find (attachments, attachment)) {
				e_attachment_store_add_attachment (
					store, attachment);
			}
			g_list_free (attachments);
		} else {
			g_warning ("Failed to locate attachment-bar for %s", part_id);
		}

		g_object_unref (attachment);
	}

	registry = e_mail_formatter_get_extension_registry (formatter);

	extensions = e_mail_extension_registry_get_for_mime_type (
		registry, empa->snoop_mime_type);
	if (extensions == NULL)
		extensions = e_mail_extension_registry_get_fallback (
			registry, empa->snoop_mime_type);

	/* If the attachment is requested as RAW, then call the
	 * handler directly and do not append any other code. */
	if ((context->mode == E_MAIL_FORMATTER_MODE_RAW) ||
	    (context->mode == E_MAIL_FORMATTER_MODE_PRINTING)) {
		GList *head, *link;
		gboolean success = FALSE;

		if (extensions == NULL)
			return FALSE;

		if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
			gchar *name;
			EAttachment *attachment;
			GFileInfo *file_info;
			const gchar *display_name;
			gchar *description;

			attachment = e_mail_part_attachment_ref_attachment (
				E_MAIL_PART_ATTACHMENT (part));

			file_info = e_attachment_ref_file_info (attachment);
			display_name = g_file_info_get_display_name (file_info);

			description = e_attachment_dup_description (attachment);
			if (description != NULL && *description != '\0') {
				name = g_strdup_printf (
					"<h2>Attachment: %s (%s)</h2>\n",
					description, display_name);
			} else {
				name = g_strdup_printf (
					"<h2>Attachment: %s</h2>\n",
					display_name);
			}

			g_output_stream_write_all (
				stream, name, strlen (name),
				NULL, cancellable, NULL);

			g_free (description);
			g_free (name);

			g_object_unref (attachment);
			g_object_unref (file_info);
		}

		head = g_queue_peek_head_link (extensions);

		for (link = head; link != NULL; link = g_list_next (link)) {
			success = e_mail_formatter_extension_format (
				E_MAIL_FORMATTER_EXTENSION (link->data),
				formatter, context, part, stream, cancellable);
			if (success)
				break;
		}

		return success;
	}

	/* E_MAIL_FORMATTER_MODE_NORMAL: */

	mime_part = e_mail_part_ref_mime_part (part);
	text = e_mail_part_describe (mime_part, empa->snoop_mime_type);
	flags = e_mail_formatter_get_text_format_flags (formatter);
	html = camel_text_to_html (
		text, flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
	g_free (text);
	g_object_unref (mime_part);

	if (empa->attachment_view_part_id)
		attachment_part_id = empa->attachment_view_part_id;
	else
		attachment_part_id = part_id;

	button_id = g_strconcat (attachment_part_id, ".attachment_button", NULL);

	/* XXX Wild guess at the initial size. */
	buffer = g_string_sized_new (8192);

	g_string_append_printf (
		buffer,
		"<div class=\"attachment\">"
		"<table width=\"100%%\" border=\"0\">"
		"<tr valign=\"middle\">"
		"<td align=\"left\" width=\"100\">"
		"<object type=\"application/vnd.evolution.widget.attachment-button\" "
		"height=\"20\" width=\"100\" data=\"%s\" id=\"%s\"></object>"
		"</td>"
		"<td align=\"left\">%s</td>"
		"</tr>", part_id, button_id, html);

	g_free (button_id);
	g_free (html);

	if (extensions != NULL) {
		GOutputStream *content_stream;
		gboolean success = FALSE;

		content_stream = g_memory_output_stream_new_resizable ();

		if (empa->attachment_view_part_id != NULL) {
			EMailPart *attachment_view_part;

			attachment_view_part = e_mail_part_list_ref_part (
				context->part_list,
				empa->attachment_view_part_id);

			/* Avoid recursion. */
			if (attachment_view_part == part)
				g_clear_object (&attachment_view_part);

			if (attachment_view_part != NULL) {
				success = e_mail_formatter_format_as (
					formatter, context,
					attachment_view_part,
					content_stream, NULL,
					cancellable);
				g_object_unref (attachment_view_part);
			}

		} else {
			GList *head, *link;

			head = g_queue_peek_head_link (extensions);

			for (link = head; link != NULL; link = g_list_next (link)) {
				success = e_mail_formatter_extension_format (
					E_MAIL_FORMATTER_EXTENSION (link->data),
					formatter, context,
					part, content_stream,
					cancellable);
				if (success)
					break;
			}
		}

		if (success) {
			gchar *wrapper_element_id;
			gconstpointer data;
			gsize size;

			wrapper_element_id = g_strconcat (
				attachment_part_id, ".wrapper", NULL);

			data = g_memory_output_stream_get_data (
				G_MEMORY_OUTPUT_STREAM (content_stream));
			size = g_memory_output_stream_get_data_size (
				G_MEMORY_OUTPUT_STREAM (content_stream));

			g_string_append_printf (
				buffer,
				"<tr><td colspan=\"2\">"
				"<div class=\"attachment-wrapper\" id=\"%s\">",
				wrapper_element_id);

			g_string_append_len (buffer, data, size);

			g_string_append (buffer, "</div></td></tr>");

			g_free (wrapper_element_id);
		}

		g_object_unref (content_stream);
	}

	g_string_append (buffer, "</table></div>");

	g_output_stream_write_all (
		stream, buffer->str, buffer->len, NULL, cancellable, NULL);

	g_string_free (buffer, TRUE);

	return TRUE;
}
static void
mail_formatter_print_run (EMailFormatter *formatter,
                          EMailFormatterContext *context,
                          GOutputStream *stream,
                          GCancellable *cancellable)
{
	GQueue queue = G_QUEUE_INIT;
	GQueue attachments = G_QUEUE_INIT;
	GList *head, *link;
	const gchar *string;

	context->mode = E_MAIL_FORMATTER_MODE_PRINTING;

	string =
		"<!DOCTYPE HTML>\n"
		"<html>\n"
		"<head>\n"
		"<meta name=\"generator\" content=\"Evolution Mail\" />\n"
		"<title>Evolution Mail Display</title>\n"
		"<link type=\"text/css\" rel=\"stylesheet\" "
		"      media=\"print\" href=\"" STYLESHEET_URI "/>\n"
		"</head>\n"
		"<body style=\"background: #FFF; color: #000;\">";

	g_output_stream_write_all (
		stream, string, strlen (string), NULL, cancellable, NULL);

	e_mail_part_list_queue_parts (context->part_list, NULL, &queue);

	head = g_queue_peek_head_link (&queue);

	for (link = head; link != NULL; link = g_list_next (link)) {
		EMailPart *part = E_MAIL_PART (link->data);
		const gchar *mime_type;
		gboolean ok;

		if (g_cancellable_is_cancelled (cancellable))
			break;

		if (part->is_hidden && !part->is_error) {
			if (e_mail_part_id_has_suffix (part, ".rfc822")) {
				link = e_mail_formatter_find_rfc822_end_iter (link);
			}

			continue;
		}

		mime_type = e_mail_part_get_mime_type (part);
		if (mime_type == NULL)
			continue;

		if (e_mail_part_get_is_attachment (part)) {
			if (e_mail_part_get_cid (part) != NULL)
				continue;

			g_queue_push_tail (&attachments, part);
		}

		ok = e_mail_formatter_format_as (
			formatter, context, part, stream,
			mime_type, cancellable);

		/* If the written part was message/rfc822 then
		 * jump to the end of the message, because content
		 * of the whole message has been formatted by
		 * message_rfc822 formatter */
		if (ok && e_mail_part_id_has_suffix (part, ".rfc822")) {
			link = e_mail_formatter_find_rfc822_end_iter (link);

			continue;
		}
	}

	while (!g_queue_is_empty (&queue))
		g_object_unref (g_queue_pop_head (&queue));

	/* This consumes the attachments queue. */
	if (!g_queue_is_empty (&attachments))
		mail_formatter_print_write_attachments (
			formatter, &attachments,
			stream, cancellable);

	string = "</body></html>";

	g_output_stream_write_all (
		stream, string, strlen (string),
		NULL, cancellable, NULL);
}
示例#3
0
static gboolean
emfe_message_rfc822_format (EMailFormatterExtension *extension,
                            EMailFormatter *formatter,
                            EMailFormatterContext *context,
                            EMailPart *part,
                            GOutputStream *stream,
                            GCancellable *cancellable)
{
	const gchar *part_id;

	part_id = e_mail_part_get_id (part);

	if (g_cancellable_is_cancelled (cancellable))
		return FALSE;

	if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
		GQueue queue = G_QUEUE_INIT;
		GList *head, *link;
		gchar *header, *end;
		const gchar *string;

		header = e_mail_formatter_get_html_header (formatter);
		g_output_stream_write_all (
			stream, header, strlen (header),
			NULL, cancellable, NULL);
		g_free (header);

		/* Print content of the message normally */
		context->mode = E_MAIL_FORMATTER_MODE_NORMAL;

		e_mail_part_list_queue_parts (
			context->part_list, part_id, &queue);

		/* Discard the first EMailPart. */
		if (!g_queue_is_empty (&queue))
			g_object_unref (g_queue_pop_head (&queue));

		head = g_queue_peek_head_link (&queue);

		end = g_strconcat (part_id, ".end", NULL);

		for (link = head; link != NULL; link = g_list_next (link)) {
			EMailPart *p = link->data;
			const gchar *p_id;

			p_id = e_mail_part_get_id (p);

			/* Check for nested rfc822 messages */
			if (e_mail_part_id_has_suffix (p, ".rfc822")) {
				gchar *sub_end = g_strconcat (p_id, ".end", NULL);

				while (link != NULL) {
					p = link->data;

					if (g_strcmp0 (p_id, sub_end) == 0)
						break;

					link = g_list_next (link);
				}
				g_free (sub_end);
				continue;
			}

			if ((g_strcmp0 (p_id, end) == 0))
				break;

			if (p->is_hidden)
				continue;

			e_mail_formatter_format_as (
				formatter, context, p,
				stream, NULL, cancellable);
		}

		g_free (end);

		while (!g_queue_is_empty (&queue))
			g_object_unref (g_queue_pop_head (&queue));

		context->mode = E_MAIL_FORMATTER_MODE_RAW;

		string = "</body></html>";

		g_output_stream_write_all (
			stream, string, strlen (string),
			NULL, cancellable, NULL);

	} else if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
		GQueue queue = G_QUEUE_INIT;
		GList *head, *link;
		gchar *end;

		/* Part is EMailPartAttachment */
		e_mail_part_list_queue_parts (
			context->part_list, part_id, &queue);

		/* Discard the first EMailPart. */
		if (!g_queue_is_empty (&queue))
			g_object_unref (g_queue_pop_head (&queue));

		if (g_queue_is_empty (&queue))
			return FALSE;

		part = g_queue_pop_head (&queue);
		end = g_strconcat (part_id, ".end", NULL);
		g_object_unref (part);

		head = g_queue_peek_head_link (&queue);

		for (link = head; link != NULL; link = g_list_next (link)) {
			EMailPart *p = link->data;
			const gchar *p_id;

			p_id = e_mail_part_get_id (p);

			/* Check for nested rfc822 messages */
			if (e_mail_part_id_has_suffix (p, ".rfc822")) {
				gchar *sub_end = g_strconcat (p_id, ".end", NULL);

				while (link != NULL) {
					p = link->data;

					if (g_strcmp0 (p_id, sub_end) == 0)
						break;

					link = g_list_next (link);
				}
				g_free (sub_end);
				continue;
			}

			if ((g_strcmp0 (p_id, end) == 0))
				break;

			if (p->is_hidden)
				continue;

			e_mail_formatter_format_as (
				formatter, context, p,
				stream, NULL, cancellable);
		}

		g_free (end);

		while (!g_queue_is_empty (&queue))
			g_object_unref (g_queue_pop_head (&queue));

	} else {
		EMailPart *p;
		CamelFolder *folder;
		const gchar *message_uid;
		const gchar *default_charset, *charset;
		gchar *str;
		gchar *uri;

		p = e_mail_part_list_ref_part (context->part_list, part_id);
		if (p == NULL)
			return FALSE;

		folder = e_mail_part_list_get_folder (context->part_list);
		message_uid = e_mail_part_list_get_message_uid (context->part_list);
		default_charset = e_mail_formatter_get_default_charset (formatter);
		charset = e_mail_formatter_get_charset (formatter);

		if (!default_charset)
			default_charset = "";
		if (!charset)
			charset = "";

		uri = e_mail_part_build_uri (
			folder, message_uid,
			"part_id", G_TYPE_STRING, e_mail_part_get_id (p),
			"mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
			"headers_collapsable", G_TYPE_INT, 0,
			"formatter_default_charset", G_TYPE_STRING, default_charset,
			"formatter_charset", G_TYPE_STRING, charset,
			NULL);

		str = g_strdup_printf (
			"<div class=\"part-container "
			"-e-mail-formatter-body-color\">\n"
			"<iframe width=\"100%%\" height=\"10\""
			" id=\"%s.iframe\" "
			" class=\"-e-mail-formatter-frame-color\""
			" frameborder=\"0\" src=\"%s\" name=\"%s\"></iframe>"
			"</div>",
			part_id, uri, part_id);

		g_output_stream_write_all (
			stream, str, strlen (str),
			NULL, cancellable, NULL);

		g_free (str);
		g_free (uri);

		g_object_unref (p);
	}

	return TRUE;
}
static void
mail_formatter_quote_run (EMailFormatter *formatter,
                          EMailFormatterContext *context,
                          GOutputStream *stream,
                          GCancellable *cancellable)
{
	EMailFormatterQuote *qf;
	EMailFormatterQuoteContext *qf_context;
	GQueue queue = G_QUEUE_INIT;
	GList *head, *link;
	const gchar *string;

	if (g_cancellable_is_cancelled (cancellable))
		return;

	qf = E_MAIL_FORMATTER_QUOTE (formatter);

	qf_context = (EMailFormatterQuoteContext *) context;
	qf_context->qf_flags = qf->priv->flags;

	g_seekable_seek (
		G_SEEKABLE (stream),
		0, G_SEEK_SET, NULL, NULL);

	e_mail_part_list_queue_parts (context->part_list, NULL, &queue);

	head = g_queue_peek_head_link (&queue);

	for (link = head; link != NULL; link = g_list_next (link)) {
		EMailPart *part = E_MAIL_PART (link->data);
		const gchar *mime_type;

		if (e_mail_part_id_has_suffix (part, ".headers") &&
		   !(qf_context->qf_flags & E_MAIL_FORMATTER_QUOTE_FLAG_HEADERS)) {
			continue;
		}

		if (e_mail_part_id_has_suffix (part, ".rfc822")) {
			link = e_mail_formatter_find_rfc822_end_iter (link);
			continue;
		}

		if (part->is_hidden)
			continue;

		if (e_mail_part_get_is_attachment (part))
			continue;

		mime_type = e_mail_part_get_mime_type (part);

		e_mail_formatter_format_as (
			formatter, context, part, stream,
			mime_type, cancellable);
	}

	while (!g_queue_is_empty (&queue))
		g_object_unref (g_queue_pop_head (&queue));

	/* Before we were inserting the BR elements and the credits in front of
	 * the actual HTML code of the message. But this was wrong as when WebKit
	 * was loading the given HTML code that looked like
	 * <br>CREDITS<html>MESSAGE_CODE</html> WebKit parsed it like
	 * <html><br>CREDITS</html><html>MESSAGE_CODE</html>. As no elements are
	 * allowed outside of the HTML root element WebKit wrapped them into
	 * another HTML root element. Afterwards the first root element was
	 * treated as the primary one and all the elements from the second's root
	 * HEAD and BODY elements were moved to the first one.
	 * Thus the HTML that was loaded into composer contained the i.e. META
	 * or STYLE definitions in the body.
	 * So if we want to put something into the message we have to put it into
	 * the special span element and it will be moved to body in EHTMLEditorView */
	if (qf->priv->credits && *qf->priv->credits) {
		gchar *credits = g_strdup_printf (
			"<span class=\"-x-evo-to-body\"><pre>%s</pre></span>", qf->priv->credits);
		g_output_stream_write_all (
			stream, credits, strlen (credits),
			NULL, cancellable, NULL);
		g_free (credits);
	}

	/* If we want to cite the message we have to append the special span element
	 * after the message and cite it in EHTMLEditorView because of reasons
	 * mentioned above */
	if (qf->priv->flags & E_MAIL_FORMATTER_QUOTE_FLAG_CITE) {
		string = "<span class=\"-x-evo-cite-body\"><span>";
		g_output_stream_write_all (
			stream, string, strlen (string),
			NULL, cancellable, NULL);
	}
}