コード例 #1
0
void
e_mail_formatter_format_text_header (EMailFormatter *formatter,
                                     GString *buffer,
                                     const gchar *label,
                                     const gchar *value,
                                     guint32 flags)
{
	GtkTextDirection direction;
	const gchar *fmt, *html;
	const gchar *display;
	gchar *mhtml = NULL;

	g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
	g_return_if_fail (buffer != NULL);
	g_return_if_fail (label != NULL);

	if (value == NULL)
		return;

	while (*value == ' ')
		value++;

	if (!(flags & E_MAIL_FORMATTER_HEADER_FLAG_HTML)) {
		CamelMimeFilterToHTMLFlags text_format_flags;

		text_format_flags =
			e_mail_formatter_get_text_format_flags (formatter);
		html = mhtml = camel_text_to_html (
			value, text_format_flags, 0);
	} else {
		html = value;
	}

	direction = gtk_widget_get_default_direction ();

	if (flags & E_MAIL_FORMATTER_HEADER_FLAG_NOCOLUMNS) {
		if (flags & E_MAIL_FORMATTER_HEADER_FLAG_BOLD) {
			fmt = "<tr style=\"display: %s\">"
				"<td><b>%s:</b> %s</td></tr>";
		} else {
			fmt = "<tr style=\"display: %s\">"
				"<td>%s: %s</td></tr>";
		}
	} else if (flags & E_MAIL_FORMATTER_HEADER_FLAG_NODEC) {
		if (direction == GTK_TEXT_DIR_RTL)
			fmt = "<tr class=\"header\" style=\"display: %s\">"
				"<th class=\"header rtl\">%s</th>"
				"<td class=\"header rtl\">%s</td>"
				"</tr>";
		else
			fmt = "<tr class=\"header\" style=\"display: %s\">"
				"<th class=\"header ltr\">%s</th>"
				"<td class=\"header ltr\">%s</td>"
				"</tr>";
	} else {
		if (direction == GTK_TEXT_DIR_RTL)
			fmt = "<tr class=\"header\" style=\"display: %s\">"
				"<th class=\"header rtl\">%s:</th>"
				"<td class=\"header rtl\">%s</td>"
				"</tr>";
		else
			fmt = "<tr class=\"header\" style=\"display: %s\">"
				"<th class=\"header ltr\">%s:</th>"
				"<td class=\"header ltr\">%s</td>"
				"</tr>";
	}

	if (flags & E_MAIL_FORMATTER_HEADER_FLAG_HIDDEN)
		display = "none";
	else
		display = "table-row";

	g_string_append_printf (buffer, fmt, display, label, html);

	g_free (mhtml);
}
コード例 #2
0
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;
}
コード例 #3
0
void
e_mail_formatter_format_header (EMailFormatter *formatter,
                                GString *buffer,
                                const gchar *header_name,
                                const gchar *header_value,
                                guint32 flags,
                                const gchar *charset)
{
	gchar *canon_name, *buf, *value = NULL;
	const gchar *label, *txt;
	gboolean addrspec = FALSE;
	gchar *str_field = NULL;
	gint i;

	g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
	g_return_if_fail (buffer != NULL);
	g_return_if_fail (header_name != NULL);
	g_return_if_fail (header_value != NULL);

	canon_name = g_alloca (strlen (header_name) + 1);
	strcpy (canon_name, header_name);
	e_mail_formatter_canon_header_name (canon_name);

	for (i = 0; addrspec_hdrs[i]; i++) {
		if (g_ascii_strcasecmp (canon_name, addrspec_hdrs[i]) == 0) {
			addrspec = TRUE;
			break;
		}
	}

	label = _(canon_name);

	if (addrspec) {
		struct _camel_header_address *addrs;
		GString *html;
		gchar *img;
		gchar *charset;

		charset = e_mail_formatter_dup_charset (formatter);
		if (charset == NULL)
			charset = e_mail_formatter_dup_default_charset (formatter);

		buf = camel_header_unfold (header_value);
		addrs = camel_header_address_decode (buf, charset);
		if (addrs == NULL) {
			g_free (charset);
			g_free (buf);
			return;
		}

		g_free (charset);
		g_free (buf);

		html = g_string_new ("");
		img = e_mail_formatter_format_address (
			formatter, html, addrs, label,
			(flags & E_MAIL_FORMATTER_HEADER_FLAG_NOLINKS),
			!(flags & E_MAIL_FORMATTER_HEADER_FLAG_NOELIPSIZE));

		if (img != NULL) {
			str_field = g_strdup_printf ("%s: %s", label, img);
			label = str_field;
			flags |= E_MAIL_FORMATTER_HEADER_FLAG_NODEC;
			g_free (img);
		}

		camel_header_address_list_clear (&addrs);
		txt = value = html->str;
		g_string_free (html, FALSE);

		flags |= E_MAIL_FORMATTER_HEADER_FLAG_HTML;
		flags |= E_MAIL_FORMATTER_HEADER_FLAG_BOLD;

	} else if (g_str_equal (canon_name, "Subject")) {
		buf = camel_header_unfold (header_value);
		txt = value = camel_header_decode_string (buf, charset);
		g_free (buf);

		flags |= E_MAIL_FORMATTER_HEADER_FLAG_BOLD;

	} else if (g_str_equal (canon_name, "X-Evolution-Mailer")) {
		/* pseudo-header */
		label = _("Mailer");
		txt = value = camel_header_format_ctext (header_value, charset);
		flags |= E_MAIL_FORMATTER_HEADER_FLAG_BOLD;

	} else if (g_str_equal (canon_name, "Date") ||
		   g_str_equal (canon_name, "Resent-Date")) {
		CamelMimeFilterToHTMLFlags text_format_flags;
		gint msg_offset, local_tz;
		time_t msg_date;
		struct tm local;
		gchar *html;
		gboolean hide_real_date;

		hide_real_date = !e_mail_formatter_get_show_real_date (formatter);

		txt = header_value;
		while (*txt == ' ' || *txt == '\t')
			txt++;

		text_format_flags =
			e_mail_formatter_get_text_format_flags (formatter);

		html = camel_text_to_html (txt, text_format_flags, 0);

		msg_date = camel_header_decode_date (txt, &msg_offset);
		e_localtime_with_offset (msg_date, &local, &local_tz);

		/* Convert message offset to minutes (e.g. -0400 --> -240) */
		msg_offset = ((msg_offset / 100) * 60) + (msg_offset % 100);
		/* Turn into offset from localtime, not UTC */
		msg_offset -= local_tz / 60;

		/* value will be freed at the end */
		if (!hide_real_date && !msg_offset) {
			/* No timezone difference; just
			 * show the real Date: header. */
			txt = value = html;
		} else {
			gchar *date_str;

			date_str = e_datetime_format_format (
				"mail", "header",
				DTFormatKindDateTime, msg_date);

			if (hide_real_date) {
				/* Show only the local-formatted date, losing
				 * all timezone information like Outlook does.
				 * Should we attempt to show it somehow? */
				txt = value = date_str;
			} else {
				txt = value = g_strdup_printf (
					"%s (<I>%s</I>)", html, date_str);
				g_free (date_str);
			}
			g_free (html);
		}

		flags |= E_MAIL_FORMATTER_HEADER_FLAG_HTML;
		flags |= E_MAIL_FORMATTER_HEADER_FLAG_BOLD;

	} else if (g_str_equal (canon_name, "Newsgroups")) {
		GSList *ng, *scan;
		GString *html;

		buf = camel_header_unfold (header_value);

		if (!(ng = camel_header_newsgroups_decode (buf))) {
			g_free (buf);
			return;
		}

		g_free (buf);

		html = g_string_new ("");
		scan = ng;
		while (scan) {
			const gchar *newsgroup = scan->data;

			if (flags & E_MAIL_FORMATTER_HEADER_FLAG_NOLINKS)
				g_string_append_printf (
					html, "%s", newsgroup);
			else
				g_string_append_printf (
					html, "<a href=\"news:%s\">%s</a>",
					newsgroup, newsgroup);
			scan = g_slist_next (scan);
			if (scan)
				g_string_append_printf (html, ", ");
		}

		g_slist_free_full (ng, g_free);

		txt = html->str;
		value = g_string_free (html, FALSE);

		flags |= E_MAIL_FORMATTER_HEADER_FLAG_HTML;
		flags |= E_MAIL_FORMATTER_HEADER_FLAG_BOLD;

	} else if (g_str_equal (canon_name, "Received") ||
		   g_str_has_prefix (canon_name, "X-")) {
		/* don't unfold Received nor extension headers */
		txt = value = camel_header_decode_string (header_value, charset);

	} else {
		/* don't unfold Received nor extension headers */
		buf = camel_header_unfold (header_value);
		txt = value = camel_header_decode_string (buf, charset);
		g_free (buf);
	}

	e_mail_formatter_format_text_header (
		formatter, buffer, label, txt, flags);

	g_free (value);
	g_free (str_field);
}