aboutsummaryrefslogblamecommitdiffstats
path: root/em-format/e-mail-formatter-print.c
blob: a855ebc102c5cdcd88b6f8b79905d51f3a56b49f (plain) (tree)



















                                                                             







                                       


                                                                      




                                                                                    


                                                        



                                                                  

                     


                                                                          


                                                  



                                                               

                                                 
                                        
                                     
                                   

                                          
 
                                                      
                                                                          
 
                                                                    

                                                    
                                 
                 
 



                                                                        
                                                
                                                                      
                        
                                                       

                 
                                                                        
 

                                                                 



                                    

                                            




                                                                        
 








                                                         
                                    
                                          
                           


                                                       

                                   



                                                                          
                                                         

                                                                     



                                                                  



                                                                        
                                                                    

                                                           




                                                             
                                                         
                                                                          
                                                                                    




                                 
                                                             
                                      

                                 
                                                           
                                                               

                                         
                                                               



                                                         
                                                




                                                                  
                                                                        
                                                                            




                                 


                                                              




                                                        
 



                                                                                
                                                       
                                                 
 
                              
                                                    
                        
                                                    


                                                      


                                                                      













                                                                        


           
                                                                   
 

                                             
                                                                               
 
                                                         
                                                        
                                                                    


           
                                                                  
 


                                                                   


                                                                   
 
                                                         





























                                                                           


                                                              




                    
















                                                                                      
/*
 * 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)
{
}