aboutsummaryrefslogblamecommitdiffstats
path: root/em-format/e-mail-formatter-quote.c
blob: b402eda29c6467f878a2e448ca3b0603cdb26e51 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11


                           


                                                                           
  



                                                                             
  

                                                                           






                                   
                                   







                                    



                                                                         




                                       








                                                                                    


                                                        


                                                         
                                                



                                                    

                                    
                            












                                                            
                                                                        
 
                                               
 
                                                                    
                                                           
                                       
 
                                                                   



                                                                                   
                                                                  
                                                                            


                                 


                                    
                                                         

                                 

                                                             

                                                         
                                                

         
                                          
                                                           
 
























                                                                                                  
                                                                 
                                                                   


                                                        
















                                                                                
                                                                  
 







                                                                          


                                                                   
 
                                                         





                                                           
                                                                   



                                             

                                                                               
 
                                                         
                                                                            
                                                        
 
                                              





















                                                                           


                                                              
















                                                                     

















                                                                                      
/*
 * e-mail-formatter-quote.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.
 *
 * 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 General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "e-mail-formatter-quote.h"

#include <camel/camel.h>

#include "e-mail-formatter-utils.h"
#include "e-mail-part.h"
#include "e-mail-part-attachment.h"
#include "e-mail-part-utils.h"

#include <libebackend/libebackend.h>
#include <gdk/gdk.h>
#include <glib/gi18n.h>

#define E_MAIL_FORMATTER_QUOTE_GET_PRIVATE(obj) \
    (G_TYPE_INSTANCE_GET_PRIVATE \
    ((obj), E_TYPE_MAIL_FORMATTER_QUOTE, EMailFormatterQuotePrivate))

struct _EMailFormatterQuotePrivate {
    gchar *credits;
    EMailFormatterQuoteFlags flags;
};

/* internal formatter extensions */
GType e_mail_formatter_quote_attachment_get_type (void);
GType e_mail_formatter_quote_headers_get_type (void);
GType e_mail_formatter_quote_message_rfc822_get_type (void);
GType e_mail_formatter_quote_text_enriched_get_type (void);
GType e_mail_formatter_quote_text_html_get_type (void);
GType e_mail_formatter_quote_text_plain_get_type (void);

void e_mail_formatter_quote_internal_extensions_load (EMailExtensionRegistry *ereg);

static gpointer e_mail_formatter_quote_parent_class = 0;

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);
    }
}

static void
e_mail_formatter_quote_init (EMailFormatterQuote *formatter)
{
    formatter->priv = E_MAIL_FORMATTER_QUOTE_GET_PRIVATE (formatter);
}

static void
e_mail_formatter_quote_finalize (GObject *object)
{
    /* Chain up to parent's finalize() */
    G_OBJECT_CLASS (e_mail_formatter_quote_parent_class)->finalize (object);
}

static void
e_mail_formatter_quote_base_init (EMailFormatterQuoteClass *class)
{
    /* Register internal extensions. */
    g_type_ensure (e_mail_formatter_quote_attachment_get_type ());
    g_type_ensure (e_mail_formatter_quote_headers_get_type ());
    g_type_ensure (e_mail_formatter_quote_message_rfc822_get_type ());
    g_type_ensure (e_mail_formatter_quote_text_enriched_get_type ());
    g_type_ensure (e_mail_formatter_quote_text_html_get_type ());
    g_type_ensure (e_mail_formatter_quote_text_plain_get_type ());

    e_mail_formatter_extension_registry_load (
        E_MAIL_FORMATTER_CLASS (class)->extension_registry,
        E_TYPE_MAIL_FORMATTER_QUOTE_EXTENSION);

    E_MAIL_FORMATTER_CLASS (class)->text_html_flags =
        CAMEL_MIME_FILTER_TOHTML_PRE |
        CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
        CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
}

static void
e_mail_formatter_quote_class_init (EMailFormatterQuoteClass *class)
{
    GObjectClass *object_class;
    EMailFormatterClass *formatter_class;

    e_mail_formatter_quote_parent_class = g_type_class_peek_parent (class);
    g_type_class_add_private (class, sizeof (EMailFormatterQuotePrivate));

    formatter_class = E_MAIL_FORMATTER_CLASS (class);
    formatter_class->context_size = sizeof (EMailFormatterQuoteContext);
    formatter_class->run = mail_formatter_quote_run;

    object_class = G_OBJECT_CLASS (class);
    object_class->finalize = e_mail_formatter_quote_finalize;
}

GType
e_mail_formatter_quote_get_type (void)
{
    static GType type = 0;

    if (G_UNLIKELY (type == 0)) {
        const GTypeInfo type_info = {
            sizeof (EMailFormatterClass),
            (GBaseInitFunc) e_mail_formatter_quote_base_init,
            (GBaseFinalizeFunc) NULL,
            (GClassInitFunc) e_mail_formatter_quote_class_init,
            (GClassFinalizeFunc) NULL,
            NULL,   /* class_data */
            sizeof (EMailFormatterQuote),
            0,  /* n_preallocs */
            (GInstanceInitFunc) e_mail_formatter_quote_init,
            NULL    /* value_table */
        };

        type = g_type_register_static (
            E_TYPE_MAIL_FORMATTER,
            "EMailFormatterQuote", &type_info, 0);
    }

    return type;
}

EMailFormatter *
e_mail_formatter_quote_new (const gchar *credits,
                            EMailFormatterQuoteFlags flags)
{
    EMailFormatterQuote *formatter;
    formatter = g_object_new (E_TYPE_MAIL_FORMATTER_QUOTE, NULL);

    formatter->priv->credits = g_strdup (credits);
    formatter->priv->flags = flags;

    return (EMailFormatter *) formatter;
}

/* ------------------------------------------------------------------------- */

G_DEFINE_ABSTRACT_TYPE (
    EMailFormatterQuoteExtension,
    e_mail_formatter_quote_extension,
    E_TYPE_MAIL_FORMATTER_EXTENSION)

static void
e_mail_formatter_quote_extension_class_init (EMailFormatterQuoteExtensionClass *class)
{
}

static void
e_mail_formatter_quote_extension_init (EMailFormatterQuoteExtension *extension)
{
}