This reverts commit bf30024dd7, because
it breaks EMailFormatter/Parser extensions, like the prefer-plain.
The thing is that the internal formatters/parsers (also extensions)
should be always added first, and only after then can be added extended
extensions, which are used before those internal. This constraint was not
satisfied with the reverted commit, the order of extension registration
was unpredictable, depended on GType.
1579 lines
40 KiB
C
1579 lines
40 KiB
C
/*
|
|
* e-mail-formatter.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.h"
|
|
|
|
#include "e-mail-formatter-extension.h"
|
|
#include "e-mail-formatter-utils.h"
|
|
#include "e-mail-part.h"
|
|
|
|
#include <e-util/e-util.h>
|
|
#include <libebackend/libebackend.h>
|
|
#include <gdk/gdk.h>
|
|
#include <glib/gi18n.h>
|
|
|
|
#define d(x)
|
|
|
|
/* internal formatter extensions */
|
|
GType e_mail_formatter_attachment_get_type (void);
|
|
GType e_mail_formatter_attachment_bar_get_type (void);
|
|
GType e_mail_formatter_error_get_type (void);
|
|
GType e_mail_formatter_headers_get_type (void);
|
|
GType e_mail_formatter_image_get_type (void);
|
|
GType e_mail_formatter_message_rfc822_get_type (void);
|
|
GType e_mail_formatter_secure_button_get_type (void);
|
|
GType e_mail_formatter_source_get_type (void);
|
|
GType e_mail_formatter_text_enriched_get_type (void);
|
|
GType e_mail_formatter_text_html_get_type (void);
|
|
GType e_mail_formatter_text_plain_get_type (void);
|
|
|
|
void e_mail_formatter_internal_extensions_load (EMailExtensionRegistry *ereg);
|
|
|
|
struct _EMailFormatterPrivate {
|
|
EMailImageLoadingPolicy image_loading_policy;
|
|
|
|
guint only_local_photos : 1;
|
|
guint show_sender_photo : 1;
|
|
guint show_real_date : 1;
|
|
guint animate_images : 1;
|
|
|
|
gchar *charset;
|
|
gchar *default_charset;
|
|
|
|
GQueue *header_list;
|
|
};
|
|
|
|
#define E_MAIL_FORMATTER_GET_PRIVATE(obj) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE \
|
|
((obj), E_TYPE_MAIL_FORMATTER, EMailFormatterPrivate))\
|
|
|
|
static gpointer e_mail_formatter_parent_class = 0;
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_BODY_COLOR,
|
|
PROP_CITATION_COLOR,
|
|
PROP_CONTENT_COLOR,
|
|
PROP_FRAME_COLOR,
|
|
PROP_HEADER_COLOR,
|
|
PROP_TEXT_COLOR,
|
|
PROP_IMAGE_LOADING_POLICY,
|
|
PROP_FORCE_IMAGE_LOADING,
|
|
PROP_MARK_CITATIONS,
|
|
PROP_ONLY_LOCAL_PHOTOS,
|
|
PROP_SHOW_SENDER_PHOTO,
|
|
PROP_SHOW_REAL_DATE,
|
|
PROP_ANIMATE_IMAGES,
|
|
PROP_CHARSET,
|
|
PROP_DEFAULT_CHARSET
|
|
};
|
|
|
|
enum {
|
|
NEED_REDRAW,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static gint signals[LAST_SIGNAL];
|
|
|
|
static EMailFormatterContext *
|
|
mail_formatter_create_context (EMailFormatter *formatter,
|
|
EMailPartList *part_list,
|
|
EMailFormatterMode mode,
|
|
EMailFormatterHeaderFlags flags)
|
|
{
|
|
EMailFormatterClass *class;
|
|
EMailFormatterContext *context;
|
|
|
|
class = E_MAIL_FORMATTER_GET_CLASS (formatter);
|
|
|
|
g_warn_if_fail (class->context_size >= sizeof (EMailFormatterContext));
|
|
|
|
context = g_malloc0 (class->context_size);
|
|
context->part_list = g_object_ref (part_list);
|
|
context->mode = mode;
|
|
context->flags = flags;
|
|
|
|
return context;
|
|
}
|
|
|
|
static void
|
|
mail_formatter_free_context (EMailFormatterContext *context)
|
|
{
|
|
if (context->part_list != NULL)
|
|
g_object_unref (context->part_list);
|
|
|
|
g_free (context);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
case PROP_BODY_COLOR:
|
|
e_mail_formatter_set_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_BODY,
|
|
g_value_get_boxed (value));
|
|
return;
|
|
|
|
case PROP_CITATION_COLOR:
|
|
e_mail_formatter_set_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_CITATION,
|
|
g_value_get_boxed (value));
|
|
return;
|
|
|
|
case PROP_CONTENT_COLOR:
|
|
e_mail_formatter_set_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_CONTENT,
|
|
g_value_get_boxed (value));
|
|
return;
|
|
|
|
case PROP_FRAME_COLOR:
|
|
e_mail_formatter_set_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_FRAME,
|
|
g_value_get_boxed (value));
|
|
return;
|
|
|
|
case PROP_HEADER_COLOR:
|
|
e_mail_formatter_set_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_HEADER,
|
|
g_value_get_boxed (value));
|
|
return;
|
|
|
|
case PROP_IMAGE_LOADING_POLICY:
|
|
e_mail_formatter_set_image_loading_policy (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_int (value));
|
|
return;
|
|
|
|
case PROP_MARK_CITATIONS:
|
|
e_mail_formatter_set_mark_citations (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_boolean (value));
|
|
return;
|
|
|
|
case PROP_ONLY_LOCAL_PHOTOS:
|
|
e_mail_formatter_set_only_local_photos (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_boolean (value));
|
|
return;
|
|
|
|
case PROP_SHOW_SENDER_PHOTO:
|
|
e_mail_formatter_set_show_sender_photo (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_boolean (value));
|
|
return;
|
|
|
|
case PROP_SHOW_REAL_DATE:
|
|
e_mail_formatter_set_show_real_date (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_boolean (value));
|
|
return;
|
|
|
|
case PROP_TEXT_COLOR:
|
|
e_mail_formatter_set_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_TEXT,
|
|
g_value_get_boxed (value));
|
|
return;
|
|
|
|
case PROP_ANIMATE_IMAGES:
|
|
e_mail_formatter_set_animate_images (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_boolean (value));
|
|
return;
|
|
|
|
case PROP_CHARSET:
|
|
e_mail_formatter_set_charset (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_string (value));
|
|
return;
|
|
|
|
case PROP_DEFAULT_CHARSET:
|
|
e_mail_formatter_set_default_charset (
|
|
E_MAIL_FORMATTER (object),
|
|
g_value_get_string (value));
|
|
return;
|
|
}
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
case PROP_BODY_COLOR:
|
|
g_value_set_boxed (
|
|
value,
|
|
e_mail_formatter_get_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_BODY));
|
|
return;
|
|
|
|
case PROP_CITATION_COLOR:
|
|
g_value_set_boxed (
|
|
value,
|
|
e_mail_formatter_get_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_CITATION));
|
|
return;
|
|
|
|
case PROP_CONTENT_COLOR:
|
|
g_value_set_boxed (
|
|
value,
|
|
e_mail_formatter_get_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_CONTENT));
|
|
return;
|
|
|
|
case PROP_FRAME_COLOR:
|
|
g_value_set_boxed (
|
|
value,
|
|
e_mail_formatter_get_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_FRAME));
|
|
return;
|
|
|
|
case PROP_HEADER_COLOR:
|
|
g_value_set_boxed (
|
|
value,
|
|
e_mail_formatter_get_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_HEADER));
|
|
return;
|
|
|
|
case PROP_IMAGE_LOADING_POLICY:
|
|
g_value_set_int (
|
|
value,
|
|
e_mail_formatter_get_image_loading_policy (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_MARK_CITATIONS:
|
|
g_value_set_boolean (
|
|
value,
|
|
e_mail_formatter_get_mark_citations (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_ONLY_LOCAL_PHOTOS:
|
|
g_value_set_boolean (
|
|
value,
|
|
e_mail_formatter_get_only_local_photos (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_SHOW_SENDER_PHOTO:
|
|
g_value_set_boolean (
|
|
value,
|
|
e_mail_formatter_get_show_sender_photo (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_SHOW_REAL_DATE:
|
|
g_value_set_boolean (
|
|
value,
|
|
e_mail_formatter_get_show_real_date (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_TEXT_COLOR:
|
|
g_value_set_boxed (
|
|
value,
|
|
e_mail_formatter_get_color (
|
|
E_MAIL_FORMATTER (object),
|
|
E_MAIL_FORMATTER_COLOR_TEXT));
|
|
return;
|
|
|
|
case PROP_ANIMATE_IMAGES:
|
|
g_value_set_boolean (
|
|
value,
|
|
e_mail_formatter_get_animate_images (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_CHARSET:
|
|
g_value_set_string (
|
|
value,
|
|
e_mail_formatter_get_charset (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
|
|
case PROP_DEFAULT_CHARSET:
|
|
g_value_set_string (
|
|
value,
|
|
e_mail_formatter_get_default_charset (
|
|
E_MAIL_FORMATTER (object)));
|
|
return;
|
|
}
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_finalize (GObject *object)
|
|
{
|
|
EMailFormatterPrivate *priv;
|
|
|
|
priv = E_MAIL_FORMATTER (object)->priv;
|
|
|
|
if (priv->charset) {
|
|
g_free (priv->charset);
|
|
priv->charset = NULL;
|
|
}
|
|
|
|
if (priv->default_charset) {
|
|
g_free (priv->default_charset);
|
|
priv->default_charset = NULL;
|
|
}
|
|
|
|
if (priv->header_list) {
|
|
e_mail_formatter_clear_headers (E_MAIL_FORMATTER (object));
|
|
g_queue_free (priv->header_list);
|
|
priv->header_list = NULL;
|
|
}
|
|
|
|
/* Chain up to parent's finalize() */
|
|
G_OBJECT_CLASS (e_mail_formatter_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_constructed (GObject *object)
|
|
{
|
|
G_OBJECT_CLASS (e_mail_formatter_parent_class)->constructed (object);
|
|
|
|
e_extensible_load_extensions (E_EXTENSIBLE (object));
|
|
}
|
|
|
|
static void
|
|
mail_formatter_run (EMailFormatter *formatter,
|
|
EMailFormatterContext *context,
|
|
CamelStream *stream,
|
|
GCancellable *cancellable)
|
|
{
|
|
GQueue queue = G_QUEUE_INIT;
|
|
GList *head, *link;
|
|
gchar *hdr;
|
|
|
|
hdr = e_mail_formatter_get_html_header (formatter);
|
|
camel_stream_write_string (stream, hdr, cancellable, NULL);
|
|
g_free (hdr);
|
|
|
|
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 = link->data;
|
|
gboolean ok;
|
|
|
|
if (g_cancellable_is_cancelled (cancellable))
|
|
break;
|
|
|
|
if (part->is_hidden && !part->is_error) {
|
|
if (g_str_has_suffix (part->id, ".rfc822")) {
|
|
link = e_mail_formatter_find_rfc822_end_iter (link);
|
|
}
|
|
|
|
if (link == NULL)
|
|
break;
|
|
|
|
continue;
|
|
}
|
|
|
|
/* Force formatting as source if needed */
|
|
if (context->mode != E_MAIL_FORMATTER_MODE_SOURCE) {
|
|
|
|
if (!part->mime_type)
|
|
continue;
|
|
|
|
ok = e_mail_formatter_format_as (
|
|
formatter, context, part, stream,
|
|
part->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 && g_str_has_suffix (part->id, ".rfc822")) {
|
|
link = e_mail_formatter_find_rfc822_end_iter (link);
|
|
|
|
if (link == NULL)
|
|
break;
|
|
|
|
continue;
|
|
}
|
|
|
|
} else {
|
|
ok = FALSE;
|
|
}
|
|
|
|
if (!ok) {
|
|
/* We don't want to source these */
|
|
if (g_str_has_suffix (part->id, ".headers") ||
|
|
g_str_has_suffix (part->id, "attachment-bar"))
|
|
continue;
|
|
|
|
e_mail_formatter_format_as (
|
|
formatter, context, part, stream,
|
|
"application/vnd.evolution.source", cancellable);
|
|
|
|
/* .message is the entire message. There's nothing more
|
|
* to be written. */
|
|
if (g_strcmp0 (part->id, ".message") == 0)
|
|
break;
|
|
|
|
/* If we just wrote source of a rfc822 message, then jump
|
|
* behind the message (otherwise source of all parts
|
|
* would be rendered twice) */
|
|
if (g_str_has_suffix (part->id, ".rfc822")) {
|
|
|
|
do {
|
|
part = link->data;
|
|
if (g_str_has_suffix (part->id, ".rfc822.end"))
|
|
break;
|
|
|
|
link = g_list_next (link);
|
|
} while (link != NULL);
|
|
|
|
if (link == NULL)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (!g_queue_is_empty (&queue))
|
|
e_mail_part_unref (g_queue_pop_head (&queue));
|
|
|
|
camel_stream_write_string (stream, "</body></html>", cancellable, NULL);
|
|
}
|
|
|
|
static void
|
|
mail_formatter_set_style (EMailFormatter *formatter,
|
|
GtkStyle *style,
|
|
GtkStateType state)
|
|
{
|
|
GdkColor *color;
|
|
EMailFormatterColorType type;
|
|
|
|
g_object_freeze_notify (G_OBJECT (formatter));
|
|
|
|
color = &style->bg[state];
|
|
type = E_MAIL_FORMATTER_COLOR_BODY;
|
|
e_mail_formatter_set_color (formatter, type, color);
|
|
|
|
color = &style->base[GTK_STATE_NORMAL];
|
|
type = E_MAIL_FORMATTER_COLOR_CONTENT;
|
|
e_mail_formatter_set_color (formatter, type, color);
|
|
|
|
color = &style->dark[state];
|
|
type = E_MAIL_FORMATTER_COLOR_FRAME;
|
|
e_mail_formatter_set_color (formatter, type, color);
|
|
|
|
color = &style->fg[state];
|
|
type = E_MAIL_FORMATTER_COLOR_HEADER;
|
|
e_mail_formatter_set_color (formatter, type, color);
|
|
|
|
color = &style->text[state];
|
|
type = E_MAIL_FORMATTER_COLOR_TEXT;
|
|
e_mail_formatter_set_color (formatter, type, color);
|
|
|
|
g_object_thaw_notify (G_OBJECT (formatter));
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_base_init (EMailFormatterClass *class)
|
|
{
|
|
/* Register internal extensions. */
|
|
g_type_ensure (e_mail_formatter_attachment_get_type ());
|
|
g_type_ensure (e_mail_formatter_attachment_bar_get_type ());
|
|
g_type_ensure (e_mail_formatter_error_get_type ());
|
|
g_type_ensure (e_mail_formatter_headers_get_type ());
|
|
g_type_ensure (e_mail_formatter_image_get_type ());
|
|
g_type_ensure (e_mail_formatter_message_rfc822_get_type ());
|
|
g_type_ensure (e_mail_formatter_secure_button_get_type ());
|
|
g_type_ensure (e_mail_formatter_source_get_type ());
|
|
g_type_ensure (e_mail_formatter_text_enriched_get_type ());
|
|
g_type_ensure (e_mail_formatter_text_html_get_type ());
|
|
g_type_ensure (e_mail_formatter_text_plain_get_type ());
|
|
|
|
class->extension_registry = g_object_new (
|
|
E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY, NULL);
|
|
|
|
e_mail_formatter_internal_extensions_load (
|
|
E_MAIL_EXTENSION_REGISTRY (class->extension_registry));
|
|
|
|
e_extensible_load_extensions (
|
|
E_EXTENSIBLE (class->extension_registry));
|
|
|
|
class->text_html_flags =
|
|
CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
|
|
CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
|
|
CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
|
|
CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES |
|
|
CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_base_finalize (EMailFormatterClass *class)
|
|
{
|
|
g_object_unref (class->extension_registry);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_class_init (EMailFormatterClass *class)
|
|
{
|
|
GObjectClass *object_class;
|
|
GdkColor *color;
|
|
|
|
e_mail_formatter_parent_class = g_type_class_peek_parent (class);
|
|
g_type_class_add_private (class, sizeof (EMailFormatterPrivate));
|
|
|
|
object_class = G_OBJECT_CLASS (class);
|
|
object_class->set_property = e_mail_formatter_set_property;
|
|
object_class->get_property = e_mail_formatter_get_property;
|
|
object_class->finalize = e_mail_formatter_finalize;
|
|
object_class->constructed = e_mail_formatter_constructed;
|
|
|
|
class->context_size = sizeof (EMailFormatterContext);
|
|
class->run = mail_formatter_run;
|
|
class->set_style = mail_formatter_set_style;
|
|
|
|
color = &class->colors[E_MAIL_FORMATTER_COLOR_BODY];
|
|
gdk_color_parse ("#eeeeee", color);
|
|
|
|
color = &class->colors[E_MAIL_FORMATTER_COLOR_CONTENT];
|
|
gdk_color_parse ("#ffffff", color);
|
|
|
|
color = &class->colors[E_MAIL_FORMATTER_COLOR_FRAME];
|
|
gdk_color_parse ("#3f3f3f", color);
|
|
|
|
color = &class->colors[E_MAIL_FORMATTER_COLOR_HEADER];
|
|
gdk_color_parse ("#eeeeee", color);
|
|
|
|
color = &class->colors[E_MAIL_FORMATTER_COLOR_TEXT];
|
|
gdk_color_parse ("#000000", color);
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_BODY_COLOR,
|
|
g_param_spec_boxed (
|
|
"body-color",
|
|
"Body Color",
|
|
NULL,
|
|
GDK_TYPE_COLOR,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_CITATION_COLOR,
|
|
g_param_spec_boxed (
|
|
"citation-color",
|
|
"Citation Color",
|
|
NULL,
|
|
GDK_TYPE_COLOR,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_CONTENT_COLOR,
|
|
g_param_spec_boxed (
|
|
"content-color",
|
|
"Content Color",
|
|
NULL,
|
|
GDK_TYPE_COLOR,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_FRAME_COLOR,
|
|
g_param_spec_boxed (
|
|
"frame-color",
|
|
"Frame Color",
|
|
NULL,
|
|
GDK_TYPE_COLOR,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_HEADER_COLOR,
|
|
g_param_spec_boxed (
|
|
"header-color",
|
|
"Header Color",
|
|
NULL,
|
|
GDK_TYPE_COLOR,
|
|
G_PARAM_READWRITE));
|
|
|
|
/* FIXME Make this a proper enum property. */
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_IMAGE_LOADING_POLICY,
|
|
g_param_spec_int (
|
|
"image-loading-policy",
|
|
"Image Loading Policy",
|
|
NULL,
|
|
E_MAIL_IMAGE_LOADING_POLICY_NEVER,
|
|
E_MAIL_IMAGE_LOADING_POLICY_ALWAYS,
|
|
E_MAIL_IMAGE_LOADING_POLICY_NEVER,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_MARK_CITATIONS,
|
|
g_param_spec_boolean (
|
|
"mark-citations",
|
|
"Mark Citations",
|
|
NULL,
|
|
TRUE,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_ONLY_LOCAL_PHOTOS,
|
|
g_param_spec_boolean (
|
|
"only-local-photos",
|
|
"Only Local Photos",
|
|
NULL,
|
|
TRUE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_SHOW_SENDER_PHOTO,
|
|
g_param_spec_boolean (
|
|
"show-sender-photo",
|
|
"Show Sender Photo",
|
|
NULL,
|
|
FALSE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_SHOW_REAL_DATE,
|
|
g_param_spec_boolean (
|
|
"show-real-date",
|
|
"Show real Date header value",
|
|
NULL,
|
|
TRUE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_TEXT_COLOR,
|
|
g_param_spec_boxed (
|
|
"text-color",
|
|
"Text Color",
|
|
NULL,
|
|
GDK_TYPE_COLOR,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_ANIMATE_IMAGES,
|
|
g_param_spec_boolean (
|
|
"animate-images",
|
|
"Animate images",
|
|
NULL,
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_CHARSET,
|
|
g_param_spec_string (
|
|
"charset",
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property (
|
|
object_class,
|
|
PROP_DEFAULT_CHARSET,
|
|
g_param_spec_string (
|
|
"default-charset",
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
|
|
signals[NEED_REDRAW] = g_signal_new (
|
|
"need-redraw",
|
|
E_TYPE_MAIL_FORMATTER,
|
|
G_SIGNAL_RUN_FIRST,
|
|
G_STRUCT_OFFSET (EMailFormatterClass, need_redraw),
|
|
NULL,
|
|
NULL,
|
|
g_cclosure_marshal_VOID__VOID,
|
|
G_TYPE_NONE, 0, NULL);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_init (EMailFormatter *formatter)
|
|
{
|
|
formatter->priv = E_MAIL_FORMATTER_GET_PRIVATE (formatter);
|
|
|
|
formatter->priv->header_list = g_queue_new ();
|
|
e_mail_formatter_set_default_headers (formatter);
|
|
}
|
|
|
|
static void
|
|
e_mail_formatter_extensible_interface_init (EExtensibleInterface *interface)
|
|
{
|
|
|
|
}
|
|
|
|
EMailFormatter *
|
|
e_mail_formatter_new (void)
|
|
{
|
|
return g_object_new (E_TYPE_MAIL_FORMATTER, NULL);
|
|
}
|
|
|
|
GType
|
|
e_mail_formatter_get_type (void)
|
|
{
|
|
static GType type = 0;
|
|
|
|
if (G_UNLIKELY (type == 0)) {
|
|
const GTypeInfo type_info = {
|
|
sizeof (EMailFormatterClass),
|
|
(GBaseInitFunc) e_mail_formatter_base_init,
|
|
(GBaseFinalizeFunc) e_mail_formatter_base_finalize,
|
|
(GClassInitFunc) e_mail_formatter_class_init,
|
|
(GClassFinalizeFunc) NULL,
|
|
NULL, /* class_data */
|
|
sizeof (EMailFormatter),
|
|
0, /* n_preallocs */
|
|
(GInstanceInitFunc) e_mail_formatter_init,
|
|
NULL /* value_table */
|
|
};
|
|
|
|
const GInterfaceInfo e_extensible_interface_info = {
|
|
(GInterfaceInitFunc) e_mail_formatter_extensible_interface_init
|
|
};
|
|
|
|
type = g_type_register_static (
|
|
G_TYPE_OBJECT,
|
|
"EMailFormatter", &type_info, 0);
|
|
|
|
g_type_add_interface_static (
|
|
type, E_TYPE_EXTENSIBLE, &e_extensible_interface_info);
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_format_sync (EMailFormatter *formatter,
|
|
EMailPartList *parts,
|
|
CamelStream *stream,
|
|
EMailFormatterHeaderFlags flags,
|
|
EMailFormatterMode mode,
|
|
GCancellable *cancellable)
|
|
{
|
|
EMailFormatterContext *context;
|
|
EMailFormatterClass *formatter_class;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (CAMEL_IS_STREAM (stream));
|
|
|
|
formatter_class = E_MAIL_FORMATTER_GET_CLASS (formatter);
|
|
g_return_if_fail (formatter_class->run != NULL);
|
|
|
|
context = mail_formatter_create_context (
|
|
formatter, parts, mode, flags);
|
|
|
|
formatter_class->run (
|
|
formatter, context, stream, cancellable);
|
|
|
|
mail_formatter_free_context (context);
|
|
}
|
|
|
|
static void
|
|
mail_format_async_prepare (GSimpleAsyncResult *result,
|
|
GObject *object,
|
|
GCancellable *cancellable)
|
|
{
|
|
EMailFormatterContext *context;
|
|
EMailFormatterClass *formatter_class;
|
|
CamelStream *stream;
|
|
|
|
context = g_object_get_data (G_OBJECT (result), "context");
|
|
stream = g_object_get_data (G_OBJECT (result), "stream");
|
|
|
|
formatter_class = E_MAIL_FORMATTER_GET_CLASS (object);
|
|
formatter_class->run (
|
|
E_MAIL_FORMATTER (object), context, stream, cancellable);
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_format (EMailFormatter *formatter,
|
|
EMailPartList *parts,
|
|
CamelStream *stream,
|
|
EMailFormatterHeaderFlags flags,
|
|
EMailFormatterMode mode,
|
|
GAsyncReadyCallback callback,
|
|
GCancellable *cancellable,
|
|
gpointer user_data)
|
|
{
|
|
GSimpleAsyncResult *simple;
|
|
EMailFormatterContext *context;
|
|
EMailFormatterClass *formatter_class;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (CAMEL_IS_STREAM (stream));
|
|
|
|
formatter_class = E_MAIL_FORMATTER_GET_CLASS (formatter);
|
|
g_return_if_fail (formatter_class->run != NULL);
|
|
|
|
simple = g_simple_async_result_new (
|
|
G_OBJECT (formatter), callback,
|
|
user_data, e_mail_formatter_format);
|
|
|
|
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
|
|
|
if (!parts) {
|
|
if (callback)
|
|
callback (G_OBJECT (formatter), G_ASYNC_RESULT (simple), user_data);
|
|
g_object_unref (simple);
|
|
return;
|
|
}
|
|
|
|
context = mail_formatter_create_context (
|
|
formatter, parts, mode, flags);
|
|
|
|
g_object_set_data (G_OBJECT (simple), "context", context);
|
|
g_object_set_data (G_OBJECT (simple), "stream", stream);
|
|
|
|
g_simple_async_result_run_in_thread (
|
|
simple, mail_format_async_prepare,
|
|
G_PRIORITY_DEFAULT, cancellable);
|
|
|
|
g_object_unref (simple);
|
|
}
|
|
|
|
CamelStream *
|
|
e_mail_formatter_format_finished (EMailFormatter *formatter,
|
|
GAsyncResult *result,
|
|
GError *error)
|
|
{
|
|
EMailFormatterContext *context;
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
|
|
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
|
|
|
|
context = g_object_get_data (G_OBJECT (result), "context");
|
|
|
|
mail_formatter_free_context (context);
|
|
|
|
return g_object_get_data (G_OBJECT (result), "stream");
|
|
}
|
|
|
|
/**
|
|
* e_mail_formatter_format_as:
|
|
* @formatter: an #EMailFormatter
|
|
* @context: an #EMailFormatterContext
|
|
* @part: an #EMailPart
|
|
* @stream: a #CamelStream
|
|
* @as_mime_type: (allow-none) mime-type to use for formatting, or %NULL
|
|
* @cancellable: (allow-none) an optional #GCancellable
|
|
*
|
|
* Formats given @part using a @formatter extension for given mime type. When
|
|
* the mime type is %NULL, the function will try to lookup the best formatter
|
|
* for given @part by it's default mime type.
|
|
*
|
|
* Return Value: %TRUE on success, %FALSE when no suitable formatter is found or
|
|
* when it fails to format the part.
|
|
*/
|
|
gboolean
|
|
e_mail_formatter_format_as (EMailFormatter *formatter,
|
|
EMailFormatterContext *context,
|
|
EMailPart *part,
|
|
CamelStream *stream,
|
|
const gchar *as_mime_type,
|
|
GCancellable *cancellable)
|
|
{
|
|
EMailExtensionRegistry *reg;
|
|
GQueue *formatters;
|
|
GList *iter;
|
|
gboolean ok;
|
|
d (
|
|
gint _call_i;
|
|
static gint _call = 0;
|
|
G_LOCK_DEFINE_STATIC (_call);
|
|
G_LOCK (_call);
|
|
_call++;
|
|
_call_i = _call;
|
|
G_UNLOCK (_call)
|
|
);
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), FALSE);
|
|
g_return_val_if_fail (part, FALSE);
|
|
g_return_val_if_fail (CAMEL_IS_STREAM (stream), FALSE);
|
|
|
|
if (!as_mime_type || !*as_mime_type)
|
|
as_mime_type = part->mime_type;
|
|
|
|
if (!as_mime_type || !*as_mime_type)
|
|
return FALSE;
|
|
|
|
reg = e_mail_formatter_get_extension_registry (formatter);
|
|
formatters = e_mail_extension_registry_get_for_mime_type (
|
|
reg, as_mime_type);
|
|
if (!formatters) {
|
|
formatters = e_mail_extension_registry_get_fallback (
|
|
reg, as_mime_type);
|
|
}
|
|
|
|
ok = FALSE;
|
|
|
|
d (
|
|
printf ("(%d) Formatting for part %s of type %s (found %d formatters)\n",
|
|
_call_i, part->id, as_mime_type,
|
|
formatters ? g_queue_get_length (formatters) : 0));
|
|
|
|
if (formatters) {
|
|
for (iter = formatters->head; iter; iter = iter->next) {
|
|
|
|
EMailFormatterExtension *extension;
|
|
|
|
extension = iter->data;
|
|
if (!extension)
|
|
continue;
|
|
|
|
ok = e_mail_formatter_extension_format (
|
|
extension, formatter, context,
|
|
part, stream, cancellable);
|
|
|
|
d (
|
|
printf (
|
|
"\t(%d) trying %s...%s\n", _call_i,
|
|
G_OBJECT_TYPE_NAME (extension),
|
|
ok ? "OK" : "failed"));
|
|
|
|
if (ok)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
/**
|
|
* em_format_format_text:
|
|
* @part: an #EMailPart to decode
|
|
* @formatter: an #EMailFormatter
|
|
* @stream: Where to write the converted text
|
|
* @cancellable: optional #GCancellable object, or %NULL
|
|
*
|
|
* Decode/output a part's content to @stream.
|
|
**/
|
|
void
|
|
e_mail_formatter_format_text (EMailFormatter *formatter,
|
|
EMailPart *part,
|
|
CamelStream *stream,
|
|
GCancellable *cancellable)
|
|
{
|
|
CamelStream *filter_stream;
|
|
CamelMimeFilter *filter;
|
|
const gchar *charset = NULL;
|
|
CamelMimeFilterWindows *windows = NULL;
|
|
CamelStream *mem_stream = NULL;
|
|
CamelDataWrapper *dw;
|
|
|
|
if (g_cancellable_is_cancelled (cancellable))
|
|
return;
|
|
|
|
dw = CAMEL_DATA_WRAPPER (part->part);
|
|
|
|
if (formatter->priv->charset) {
|
|
charset = formatter->priv->charset;
|
|
} else if (dw->mime_type
|
|
&& (charset = camel_content_type_param (dw->mime_type, "charset"))
|
|
&& g_ascii_strncasecmp (charset, "iso-8859-", 9) == 0) {
|
|
CamelStream *null;
|
|
|
|
/* Since a few Windows mailers like to claim they sent
|
|
* out iso-8859-# encoded text when they really sent
|
|
* out windows-cp125#, do some simple sanity checking
|
|
* before we move on... */
|
|
|
|
null = camel_stream_null_new ();
|
|
filter_stream = camel_stream_filter_new (null);
|
|
g_object_unref (null);
|
|
|
|
windows = (CamelMimeFilterWindows *) camel_mime_filter_windows_new (charset);
|
|
camel_stream_filter_add (
|
|
CAMEL_STREAM_FILTER (filter_stream),
|
|
CAMEL_MIME_FILTER (windows));
|
|
|
|
camel_data_wrapper_decode_to_stream_sync (
|
|
dw, (CamelStream *) filter_stream, cancellable, NULL);
|
|
camel_stream_flush ((CamelStream *) filter_stream, cancellable, NULL);
|
|
g_object_unref (filter_stream);
|
|
|
|
charset = camel_mime_filter_windows_real_charset (windows);
|
|
} else if (charset == NULL) {
|
|
charset = formatter->priv->default_charset;
|
|
}
|
|
|
|
mem_stream = (CamelStream *) camel_stream_mem_new ();
|
|
filter_stream = camel_stream_filter_new (mem_stream);
|
|
|
|
if ((filter = camel_mime_filter_charset_new (charset, "UTF-8"))) {
|
|
camel_stream_filter_add (
|
|
CAMEL_STREAM_FILTER (filter_stream),
|
|
CAMEL_MIME_FILTER (filter));
|
|
g_object_unref (filter);
|
|
}
|
|
|
|
camel_data_wrapper_decode_to_stream_sync (
|
|
camel_medium_get_content ((CamelMedium *) dw),
|
|
(CamelStream *) filter_stream, cancellable, NULL);
|
|
camel_stream_flush ((CamelStream *) filter_stream, cancellable, NULL);
|
|
g_object_unref (filter_stream);
|
|
|
|
g_seekable_seek (G_SEEKABLE (mem_stream), 0, G_SEEK_SET, NULL, NULL);
|
|
|
|
camel_stream_write_to_stream (
|
|
mem_stream, (CamelStream *) stream, cancellable, NULL);
|
|
camel_stream_flush ((CamelStream *) mem_stream, cancellable, NULL);
|
|
|
|
if (windows) {
|
|
g_object_unref (windows);
|
|
}
|
|
|
|
g_object_unref (mem_stream);
|
|
}
|
|
|
|
gchar *
|
|
e_mail_formatter_get_html_header (EMailFormatter *formatter)
|
|
{
|
|
return g_strdup_printf (
|
|
"<!DOCTYPE HTML>\n<html>\n"
|
|
"<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\" />\n"
|
|
"<title>Evolution Mail Display</title>\n"
|
|
"<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\" />\n"
|
|
"<style type=\"text/css\">\n"
|
|
" table th { color: #%06x; font-weight: bold; }\n"
|
|
"</style>\n"
|
|
"</head><body bgcolor=\"#%06x\" text=\"#%06x\">",
|
|
e_color_to_value ((GdkColor *)
|
|
e_mail_formatter_get_color (
|
|
formatter, E_MAIL_FORMATTER_COLOR_HEADER)),
|
|
e_color_to_value ((GdkColor *)
|
|
e_mail_formatter_get_color (
|
|
formatter, E_MAIL_FORMATTER_COLOR_BODY)),
|
|
e_color_to_value ((GdkColor *)
|
|
e_mail_formatter_get_color (
|
|
formatter, E_MAIL_FORMATTER_COLOR_TEXT)));
|
|
}
|
|
|
|
EMailExtensionRegistry *
|
|
e_mail_formatter_get_extension_registry (EMailFormatter *formatter)
|
|
{
|
|
EMailFormatterClass * formatter_class;
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
|
|
|
|
formatter_class = E_MAIL_FORMATTER_GET_CLASS (formatter);
|
|
return E_MAIL_EXTENSION_REGISTRY (formatter_class->extension_registry);
|
|
}
|
|
|
|
guint32
|
|
e_mail_formatter_get_text_format_flags (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), 0);
|
|
|
|
return E_MAIL_FORMATTER_GET_CLASS (formatter)->text_html_flags;
|
|
}
|
|
|
|
const GdkColor *
|
|
e_mail_formatter_get_color (EMailFormatter *formatter,
|
|
EMailFormatterColorType type)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
|
|
g_return_val_if_fail (type < E_MAIL_FORMATTER_NUM_COLOR_TYPES, NULL);
|
|
|
|
return &E_MAIL_FORMATTER_GET_CLASS (formatter)->colors[type];
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_color (EMailFormatter *formatter,
|
|
EMailFormatterColorType type,
|
|
const GdkColor *color)
|
|
{
|
|
GdkColor *format_color;
|
|
const gchar *property_name;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (type < E_MAIL_FORMATTER_NUM_COLOR_TYPES);
|
|
g_return_if_fail (color != NULL);
|
|
|
|
format_color = &E_MAIL_FORMATTER_GET_CLASS (formatter)->colors[type];
|
|
|
|
if (gdk_color_equal (color, format_color))
|
|
return;
|
|
|
|
format_color->red = color->red;
|
|
format_color->green = color->green;
|
|
format_color->blue = color->blue;
|
|
|
|
switch (type) {
|
|
case E_MAIL_FORMATTER_COLOR_BODY:
|
|
property_name = "body-color";
|
|
break;
|
|
case E_MAIL_FORMATTER_COLOR_CITATION:
|
|
property_name = "citation-color";
|
|
break;
|
|
case E_MAIL_FORMATTER_COLOR_CONTENT:
|
|
property_name = "content-color";
|
|
break;
|
|
case E_MAIL_FORMATTER_COLOR_FRAME:
|
|
property_name = "frame-color";
|
|
break;
|
|
case E_MAIL_FORMATTER_COLOR_HEADER:
|
|
property_name = "header-color";
|
|
break;
|
|
case E_MAIL_FORMATTER_COLOR_TEXT:
|
|
property_name = "text-color";
|
|
break;
|
|
default:
|
|
g_return_if_reached ();
|
|
}
|
|
|
|
g_object_notify (G_OBJECT (formatter), property_name);
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_style (EMailFormatter *formatter,
|
|
GtkStyle *style,
|
|
GtkStateType state)
|
|
{
|
|
EMailFormatterClass *formatter_class;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (GTK_IS_STYLE (style));
|
|
|
|
formatter_class = E_MAIL_FORMATTER_GET_CLASS (formatter);
|
|
g_return_if_fail (formatter_class->set_style != NULL);
|
|
|
|
formatter_class->set_style (formatter, style, state);
|
|
}
|
|
|
|
EMailImageLoadingPolicy
|
|
e_mail_formatter_get_image_loading_policy (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), 0);
|
|
|
|
return formatter->priv->image_loading_policy;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_image_loading_policy (EMailFormatter *formatter,
|
|
EMailImageLoadingPolicy policy)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (policy == formatter->priv->image_loading_policy)
|
|
return;
|
|
|
|
formatter->priv->image_loading_policy = policy;
|
|
|
|
g_object_notify (G_OBJECT (formatter), "image-loading-policy");
|
|
}
|
|
|
|
gboolean
|
|
e_mail_formatter_get_mark_citations (EMailFormatter *formatter)
|
|
{
|
|
guint32 flags;
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), FALSE);
|
|
|
|
flags = E_MAIL_FORMATTER_GET_CLASS (formatter)->text_html_flags;
|
|
|
|
return ((flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION) != 0);
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_mark_citations (EMailFormatter *formatter,
|
|
gboolean mark_citations)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (mark_citations)
|
|
E_MAIL_FORMATTER_GET_CLASS (formatter)->text_html_flags |=
|
|
CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
|
|
else
|
|
E_MAIL_FORMATTER_GET_CLASS (formatter)->text_html_flags &=
|
|
~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
|
|
|
|
g_object_notify (G_OBJECT (formatter), "mark-citations");
|
|
}
|
|
|
|
gboolean
|
|
e_mail_formatter_get_only_local_photos (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), FALSE);
|
|
|
|
return formatter->priv->only_local_photos;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_only_local_photos (EMailFormatter *formatter,
|
|
gboolean only_local_photos)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (formatter->priv->only_local_photos == only_local_photos)
|
|
return;
|
|
|
|
formatter->priv->only_local_photos = only_local_photos;
|
|
|
|
g_object_notify (G_OBJECT (formatter), "only-local-photos");
|
|
}
|
|
|
|
gboolean
|
|
e_mail_formatter_get_show_sender_photo (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), FALSE);
|
|
|
|
return formatter->priv->show_sender_photo;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_show_sender_photo (EMailFormatter *formatter,
|
|
gboolean show_sender_photo)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (formatter->priv->show_sender_photo == show_sender_photo)
|
|
return;
|
|
|
|
formatter->priv->show_sender_photo = show_sender_photo;
|
|
|
|
g_object_notify (G_OBJECT (formatter), "show-sender-photo");
|
|
}
|
|
|
|
gboolean
|
|
e_mail_formatter_get_show_real_date (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), FALSE);
|
|
|
|
return formatter->priv->show_real_date;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_show_real_date (EMailFormatter *formatter,
|
|
gboolean show_real_date)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (formatter->priv->show_real_date == show_real_date)
|
|
return;
|
|
|
|
formatter->priv->show_real_date = show_real_date;
|
|
|
|
g_object_notify (G_OBJECT (formatter), "show-real-date");
|
|
}
|
|
|
|
gboolean
|
|
e_mail_formatter_get_animate_images (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), FALSE);
|
|
|
|
return formatter->priv->animate_images;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_animate_images (EMailFormatter *formatter,
|
|
gboolean animate_images)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (formatter->priv->animate_images == animate_images)
|
|
return;
|
|
|
|
formatter->priv->animate_images = animate_images;
|
|
|
|
g_object_notify (G_OBJECT (formatter), "animate-images");
|
|
}
|
|
|
|
const gchar *
|
|
e_mail_formatter_get_charset (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
|
|
|
|
return formatter->priv->charset;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_charset (EMailFormatter *formatter,
|
|
const gchar *charset)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
if (g_strcmp0 (formatter->priv->charset, charset) == 0)
|
|
return;
|
|
|
|
g_free (formatter->priv->charset);
|
|
|
|
if (!charset) {
|
|
formatter->priv->charset = NULL;
|
|
} else {
|
|
formatter->priv->charset = g_strdup (charset);
|
|
}
|
|
|
|
g_object_notify (G_OBJECT (formatter), "charset");
|
|
}
|
|
|
|
const gchar *
|
|
e_mail_formatter_get_default_charset (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
|
|
|
|
return formatter->priv->default_charset;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_set_default_charset (EMailFormatter *formatter,
|
|
const gchar *default_charset)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (default_charset && *default_charset);
|
|
|
|
if (g_strcmp0 (formatter->priv->default_charset, default_charset) == 0)
|
|
return;
|
|
|
|
g_free (formatter->priv->default_charset);
|
|
formatter->priv->default_charset = g_strdup (default_charset);
|
|
|
|
g_object_notify (G_OBJECT (formatter), "default-charset");
|
|
}
|
|
|
|
/* note: also copied in em-mailer-prefs.c */
|
|
static const struct {
|
|
const gchar *name;
|
|
guint32 flags;
|
|
} default_headers[] = {
|
|
{ N_("From"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Reply-To"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("To"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Cc"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Bcc"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Subject"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Date"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Newsgroups"), E_MAIL_FORMATTER_HEADER_FLAG_BOLD },
|
|
{ N_("Face"), 0 },
|
|
};
|
|
|
|
/**
|
|
* e_mail_formatter_get_headers:
|
|
* @formatter: an #EMailFormatter
|
|
*
|
|
* Returns list of currently set headers.
|
|
*
|
|
* Return Value: A #GQueue of headers which you should not modify or unref
|
|
*/
|
|
const GQueue *
|
|
e_mail_formatter_get_headers (EMailFormatter *formatter)
|
|
{
|
|
g_return_val_if_fail (E_IS_MAIL_FORMATTER (formatter), NULL);
|
|
|
|
return formatter->priv->header_list;
|
|
}
|
|
|
|
/**
|
|
* e_mail_formatter_clear_headers:
|
|
* @formatter: an #EMailFormatter
|
|
*
|
|
* Clear the list of headers to be displayed. This will force all headers to
|
|
* be shown.
|
|
**/
|
|
void
|
|
e_mail_formatter_clear_headers (EMailFormatter *formatter)
|
|
{
|
|
EMailFormatterHeader *header;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
while ((header = g_queue_pop_head (formatter->priv->header_list)) != NULL) {
|
|
e_mail_formatter_header_free (header);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* e_mail_formatter_set_default_headers:
|
|
* @formatter: an #EMailFormatter
|
|
*
|
|
* Clear the list of headers and sets the default ones, e.g. "To", "From", "Cc"
|
|
* "Subject", etc...
|
|
*/
|
|
void
|
|
e_mail_formatter_set_default_headers (EMailFormatter *formatter)
|
|
{
|
|
gint ii;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
|
|
/* Set the default headers */
|
|
e_mail_formatter_clear_headers (formatter);
|
|
for (ii = 0; ii < G_N_ELEMENTS (default_headers); ii++) {
|
|
e_mail_formatter_add_header (
|
|
formatter, default_headers[ii].name, NULL,
|
|
default_headers[ii].flags);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* e_mail_formatter_add_header:
|
|
* @formatter:
|
|
* @name: The name of the header, as it will appear during output.
|
|
* @value: Value of the header. Can be %NULL.
|
|
* @flags: a set of #EMailFormatterHeaderFlags to control display attributes.
|
|
*
|
|
* Add a specific header to show. If any headers are set, they will
|
|
* be displayed in the order set by this function. Certain known
|
|
* headers included in this list will be shown using special
|
|
* formatting routines.
|
|
**/
|
|
void
|
|
e_mail_formatter_add_header (EMailFormatter *formatter,
|
|
const gchar *name,
|
|
const gchar *value,
|
|
EMailFormatterHeaderFlags flags)
|
|
{
|
|
EMailFormatterHeader *h;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (name && *name);
|
|
|
|
h = e_mail_formatter_header_new (name, value);
|
|
h->flags = flags;
|
|
g_queue_push_tail (formatter->priv->header_list, h);
|
|
|
|
g_signal_emit (formatter, signals[NEED_REDRAW], 0, NULL);
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_add_header_struct (EMailFormatter *formatter,
|
|
const EMailFormatterHeader *header)
|
|
{
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (header && header->name);
|
|
|
|
e_mail_formatter_add_header (formatter, header->name, header->value, header->flags);
|
|
}
|
|
|
|
void e_mail_formatter_remove_header (EMailFormatter *formatter,
|
|
const gchar *name,
|
|
const gchar *value)
|
|
{
|
|
GList *iter = NULL;
|
|
|
|
g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
|
|
g_return_if_fail (name && *name);
|
|
|
|
iter = g_queue_peek_head_link (formatter->priv->header_list);
|
|
while (iter) {
|
|
EMailFormatterHeader *header = iter->data;
|
|
|
|
if (!header->value || !*header->value) {
|
|
GList *next = iter->next;
|
|
if (g_strcmp0 (name, header->name) == 0)
|
|
g_queue_delete_link (formatter->priv->header_list, iter);
|
|
|
|
iter = next;
|
|
continue;
|
|
}
|
|
|
|
if (value && *value) {
|
|
if ((g_strcmp0 (name, header->name) == 0) &&
|
|
(g_strcmp0 (value, header->value) == 0))
|
|
break;
|
|
} else {
|
|
if (g_strcmp0 (name, header->name) == 0)
|
|
break;
|
|
}
|
|
|
|
iter = iter->next;
|
|
}
|
|
|
|
if (iter) {
|
|
e_mail_formatter_header_free (iter->data);
|
|
g_queue_delete_link (formatter->priv->header_list, iter);
|
|
}
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_remove_header_struct (EMailFormatter *formatter,
|
|
const EMailFormatterHeader *header)
|
|
{
|
|
g_return_if_fail (header != NULL);
|
|
|
|
e_mail_formatter_remove_header (formatter, header->name, header->value);
|
|
}
|
|
|
|
EMailFormatterHeader *
|
|
e_mail_formatter_header_new (const gchar *name,
|
|
const gchar *value)
|
|
{
|
|
EMailFormatterHeader *header;
|
|
|
|
g_return_val_if_fail (name && *name, NULL);
|
|
|
|
header = g_new0 (EMailFormatterHeader, 1);
|
|
header->name = g_strdup (name);
|
|
if (value && *value)
|
|
header->value = g_strdup (value);
|
|
|
|
return header;
|
|
}
|
|
|
|
void
|
|
e_mail_formatter_header_free (EMailFormatterHeader *header)
|
|
{
|
|
g_return_if_fail (header);
|
|
|
|
if (header->name) {
|
|
g_free (header->name);
|
|
header->name = NULL;
|
|
}
|
|
|
|
if (header->value) {
|
|
g_free (header->value);
|
|
header->value = NULL;
|
|
}
|
|
|
|
g_free (header);
|
|
}
|