/*
* e-mail-formatter-print.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include "e-mail-formatter-print.h"
#include "e-mail-part-attachment.h"
#include "e-mail-formatter-extension.h"
#include "e-mail-formatter-utils.h"
#include "e-mail-part.h"
#include <gdk/gdk.h>
#include <glib/gi18n.h>
#define STYLESHEET_URI \
"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview-print.css"
/* internal formatter extensions */
GType e_mail_formatter_print_headers_get_type (void);
void e_mail_formatter_print_internal_extensions_load (EMailExtensionRegistry *ereg);
static gpointer e_mail_formatter_print_parent_class = 0;
static void
mail_formatter_print_write_attachments (EMailFormatter *formatter,
GQueue *attachments,
CamelStream *stream,
GCancellable *cancellable)
{
GString *str;
str = g_string_new (
"<table border=\"0\" cellspacing=\"5\" cellpadding=\"0\" "
"class=\"attachments-list\" >\n");
g_string_append_printf (
str,
"<tr><th colspan=\"2\"><h1>%s</h1></td></tr>\n"
"<tr><th>%s</th><th>%s</th></tr>\n",
_("Attachments"), _("Name"), _("Size"));
while (!g_queue_is_empty (attachments)) {
EMailPartAttachment *part;
EAttachment *attachment;
GFileInfo *file_info;
gchar *name, *size;
const gchar *description;
const gchar *display_name;
part = g_queue_pop_head (attachments);
attachment = e_mail_part_attachment_ref_attachment (part);
file_info = e_attachment_get_file_info (attachment);
if (file_info == NULL) {
g_object_unref (attachment);
continue;
}
description = e_attachment_get_description (attachment);
display_name = g_file_info_get_display_name (file_info);
if (description != NULL && *description != '\0') {
name = g_strdup_printf (
"%s (%s)", description, display_name);
} else {
name = g_strdup (display_name);
}
size = g_format_size (g_file_info_get_size (file_info));
g_string_append_printf (
str, "<tr><td>%s</td><td>%s</td></tr>\n",
name, size);
g_free (name);
g_free (size);
g_object_unref (attachment);
}
g_string_append (str, "</table>\n");
camel_stream_write_string (stream, str->str, cancellable, NULL);
g_string_free (str, TRUE);
}
static void
mail_formatter_print_run (EMailFormatter *formatter,
EMailFormatterContext *context,
CamelStream *stream,
GCancellable *cancellable)
{
GQueue queue = G_QUEUE_INIT;
GQueue attachments = G_QUEUE_INIT;
GList *head, *link;
context->mode = E_MAIL_FORMATTER_MODE_PRINTING;
camel_stream_write_string (
stream,
"<!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;\">",
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))
e_mail_part_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);
camel_stream_write_string (stream, "</body></html>", cancellable, NULL);
}
static void
mail_formatter_update_style (EMailFormatter *formatter,
GtkStateFlags state)
{
/* White background */
GdkRGBA body_color = { 1.0, 1.0, 1.0, 1.0 };
/* Black text */
GdkRGBA text_color = { 0.0, 0.0, 0.0, 0.0 };
g_object_freeze_notify (G_OBJECT (formatter));
/* Chain up to parent's update_style() method. */
E_MAIL_FORMATTER_CLASS (e_mail_formatter_print_parent_class)->
update_style (formatter, state);
e_mail_formatter_set_color (
formatter, E_MAIL_FORMATTER_COLOR_FRAME, &body_color);
e_mail_formatter_set_color (
formatter, E_MAIL_FORMATTER_COLOR_CONTENT, &body_color);
e_mail_formatter_set_color (
formatter, E_MAIL_FORMATTER_COLOR_TEXT, &text_color);
g_object_thaw_notify (G_OBJECT (formatter));
}
static void
e_mail_formatter_print_init (EMailFormatterPrint *formatter)
{
}
static void
e_mail_formatter_print_class_init (EMailFormatterPrintClass *class)
{
EMailFormatterClass *formatter_class;
e_mail_formatter_print_parent_class = g_type_class_peek_parent (class);
formatter_class = E_MAIL_FORMATTER_CLASS (class);
formatter_class->run = mail_formatter_print_run;
formatter_class->update_style = mail_formatter_update_style;
}
static void
e_mail_formatter_print_base_init (EMailFormatterPrintClass *class)
{
/* Register internal extensions. */
g_type_ensure (e_mail_formatter_print_headers_get_type ());
e_mail_formatter_extension_registry_load (
E_MAIL_FORMATTER_CLASS (class)->extension_registry,
E_TYPE_MAIL_FORMATTER_PRINT_EXTENSION);
E_MAIL_FORMATTER_CLASS (class)->text_html_flags =
CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
}
EMailFormatter *
e_mail_formatter_print_new (void)
{
return g_object_new (E_TYPE_MAIL_FORMATTER_PRINT, NULL);
}
GType
e_mail_formatter_print_get_type (void)
{
static GType type = 0;
if (G_UNLIKELY (type == 0)) {
const GTypeInfo type_info = {
sizeof (EMailFormatterClass),
(GBaseInitFunc) e_mail_formatter_print_base_init,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) e_mail_formatter_print_class_init,
(GClassFinalizeFunc) NULL,
NULL, /* class_data */
sizeof (EMailFormatterPrint),
0, /* n_preallocs */
(GInstanceInitFunc) e_mail_formatter_print_init,
NULL /* value_table */
};
type = g_type_register_static (
E_TYPE_MAIL_FORMATTER,
"EMailFormatterPrint", &type_info, 0);
}
return type;
}
/* ------------------------------------------------------------------------- */
G_DEFINE_ABSTRACT_TYPE (
EMailFormatterPrintExtension,
e_mail_formatter_print_extension,
E_TYPE_MAIL_FORMATTER_EXTENSION)
static void
e_mail_formatter_print_extension_class_init (EMailFormatterPrintExtensionClass *class)
{
}
static void
e_mail_formatter_print_extension_init (EMailFormatterPrintExtension *extension)
{
}