aboutsummaryrefslogtreecommitdiffstats
path: root/modules/prefer-plain
diff options
context:
space:
mode:
Diffstat (limited to 'modules/prefer-plain')
-rw-r--r--modules/prefer-plain/Makefile.am28
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.c553
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.h30
-rw-r--r--modules/prefer-plain/evolution-module-prefer-plain.c73
-rw-r--r--modules/prefer-plain/plugin/Makefile.am28
-rw-r--r--modules/prefer-plain/plugin/config-ui.c192
-rw-r--r--modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml25
7 files changed, 929 insertions, 0 deletions
diff --git a/modules/prefer-plain/Makefile.am b/modules/prefer-plain/Makefile.am
new file mode 100644
index 0000000000..e4e6b56d02
--- /dev/null
+++ b/modules/prefer-plain/Makefile.am
@@ -0,0 +1,28 @@
+SUBDIRS=plugin
+
+module_LTLIBRARIES = module-prefer-plain.la
+
+module_prefer_plain_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ -DG_LOG_DOMAIN=\"evolution-module-prefer-plain\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+module_prefer_plain_la_SOURCES = \
+ e-mail-parser-prefer-plain.c \
+ e-mail-parser-prefer-plain.h \
+ evolution-module-prefer-plain.c
+
+module_prefer_plain_la_LIBADD = \
+ $(top_builddir)/mail/libevolution-mail.la \
+ $(top_builddir)/em-format/libemformat.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+module_prefer_plain_la_LDFLAGS = \
+ -avoid-version -module $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/prefer-plain/e-mail-parser-prefer-plain.c b/modules/prefer-plain/e-mail-parser-prefer-plain.c
new file mode 100644
index 0000000000..37da8d3a43
--- /dev/null
+++ b/modules/prefer-plain/e-mail-parser-prefer-plain.c
@@ -0,0 +1,553 @@
+/*
+ * 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/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "e-mail-parser-prefer-plain.h"
+
+#include <em-format/e-mail-extension-registry.h>
+#include <em-format/e-mail-parser-extension.h>
+#include <em-format/e-mail-part.h>
+#include <em-format/e-mail-part-utils.h>
+
+#include <libebackend/libebackend.h>
+
+#define d(x)
+
+typedef struct _EMailParserPreferPlain {
+ EExtension parent;
+
+ GSettings *settings;
+ gint mode;
+ gboolean show_suppressed;
+} EMailParserPreferPlain;
+
+typedef struct _EMailParserPreferPlainClass {
+ EExtensionClass parent_class;
+} EMailParserPreferPlainClass;
+
+GType e_mail_parser_prefer_plain_get_type (void);
+static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
+static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
+
+enum {
+ EPP_NORMAL,
+ EPP_PREFER,
+ EPP_TEXT
+};
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+ EMailParserPreferPlain,
+ e_mail_parser_prefer_plain,
+ E_TYPE_EXTENSION,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_EXTENSION,
+ e_mail_parser_mail_extension_interface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (
+ E_TYPE_MAIL_PARSER_EXTENSION,
+ e_mail_parser_parser_extension_interface_init));
+
+static const gchar* parser_mime_types[] = { "multipart/alternative",
+ "text/html",
+ NULL };
+
+static struct {
+ const gchar *key;
+ const gchar *label;
+ const gchar *description;
+} epp_options[] = {
+ { "normal",
+ N_("Show HTML if present"),
+ N_("Let Evolution choose the best part to show.") },
+
+ { "prefer_plain",
+ N_("Show plain text if present"),
+ N_("Show plain text part, if present, otherwise "
+ "let Evolution choose the best part to show.") },
+
+ { "only_plain",
+ N_("Only ever show plain text"),
+ N_("Always show plain text part and make attachments "
+ "from other parts, if requested.") },
+};
+
+enum {
+ PROP_0,
+ PROP_MODE,
+ PROP_SHOW_SUPPRESSED
+};
+
+static GSList *
+make_part_attachment (EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ gboolean force_html,
+ GCancellable *cancellable)
+{
+ GSList *parts;
+
+ if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
+ EMailPart *mail_part;
+ gint len;
+ /* always show HTML as attachments and not inline */
+ camel_mime_part_set_disposition (part, "attachment");
+
+ if (!camel_mime_part_get_filename (part)) {
+ gchar *str = g_strdup_printf ("%s.html", _("attachment"));
+ camel_mime_part_set_filename (part, str);
+ g_free (str);
+ }
+
+ len = part_id->len;
+ g_string_append (part_id, ".text_html");
+ mail_part = e_mail_part_new (part, part_id->str);
+ mail_part->mime_type = g_strdup ("text/html");
+ g_string_truncate (part_id, len);
+
+ parts = e_mail_parser_wrap_as_attachment (
+ parser, part, g_slist_append (NULL, mail_part),
+ part_id, cancellable);
+
+ } else if (force_html && CAMEL_IS_MIME_MESSAGE (part)) {
+ /* message was asked to be formatted as text/html;
+ * might be for cases where message itself is a text/html part */
+ CamelMimePart *new_part;
+ CamelDataWrapper *content;
+
+ content = camel_medium_get_content (CAMEL_MEDIUM (part));
+ g_return_val_if_fail (content != NULL, NULL);
+
+ new_part = camel_mime_part_new ();
+ camel_medium_set_content (CAMEL_MEDIUM (new_part), content);
+
+ parts = e_mail_parser_parse_part (
+ parser, new_part, part_id, cancellable);
+
+ g_object_unref (new_part);
+ } else {
+ parts = e_mail_parser_parse_part (
+ parser, part, part_id, cancellable);
+ }
+
+ return parts;
+}
+
+static GSList *
+export_as_attachments (CamelMultipart *mp,
+ EMailParser *parser,
+ CamelMimePart *except,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ gint i, nparts;
+ CamelMimePart *part;
+ gint len;
+ GSList *parts;
+
+ if (!mp || !CAMEL_IS_MULTIPART (mp))
+ return NULL;
+
+ len = part_id->len;
+ nparts = camel_multipart_get_number (mp);
+ parts = NULL;
+ for (i = 0; i < nparts; i++) {
+ part = camel_multipart_get_part (mp, i);
+
+ if (part != except) {
+ CamelMultipart *multipart = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
+
+ g_string_append_printf (part_id, ".aleternative-prefer-plain.%d", i);
+ if (CAMEL_IS_MULTIPART (multipart)) {
+ parts = g_slist_concat (parts,
+ export_as_attachments (
+ multipart, parser,
+ except, part_id,
+ cancellable));
+ } else {
+ parts = g_slist_concat (parts,
+ make_part_attachment (
+ parser, part, part_id,
+ FALSE, cancellable));
+ }
+ g_string_truncate (part_id, len);
+ }
+ }
+
+ return parts;
+}
+
+static GSList *
+empe_prefer_plain_parse (EMailParserExtension *extension,
+ EMailParser *parser,
+ CamelMimePart *part,
+ GString *part_id,
+ GCancellable *cancellable)
+{
+ EMailParserPreferPlain *emp_pp;
+ CamelMultipart *mp;
+ CamelMimePart *display_part = NULL, *calendar_part = NULL;
+ gint i, nparts, partidlen, displayid = 0, calendarid = 0;
+ GSList *parts;
+
+ emp_pp = (EMailParserPreferPlain *) extension;
+
+ /* We 'can' parse HTML as well!
+ * The reason simply is to convert the HTML part to attachment in some
+ * cases, otherwise we will return NULL and fallback to "normal" parser. */
+ if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) {
+ GQueue *extensions;
+ EMailExtensionRegistry *reg;
+
+ reg = e_mail_parser_get_extension_registry (parser);
+ extensions = e_mail_extension_registry_get_for_mime_type (
+ reg, "text/html");
+
+ if (emp_pp->mode != EPP_TEXT
+ || strstr (part_id->str, ".alternative-prefer-plain.") != NULL
+ || e_mail_part_is_inline (part, extensions)) {
+
+ return NULL;
+
+ } else if (emp_pp->show_suppressed) {
+ return make_part_attachment (
+ parser, part, part_id,
+ TRUE, cancellable);
+ }
+
+ /* Return an empty item. We MUST return something, otherwise
+ * the parser would think we have failed to parse the part
+ * and would let a fallback extension to parse it and we don't
+ * want that... */
+ /* FIXME: In theory we could parse it anyway and just set
+ * is_hidden to TRUE....? */
+ return g_slist_alloc ();
+ }
+
+ mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
+ partidlen = part_id->len;
+
+ parts = NULL;
+ if (emp_pp->mode == EPP_NORMAL) {
+ gboolean have_plain = FALSE;
+
+ /* Try to find text/html part even when not as last and force
+ * to show it. Old handler will show the last part of
+ * multipart/alternate, but if we can offer HTML, then
+ * offer it, regardless of position in multipart. But do
+ * this when have only text/plain and text/html parts,
+ * not more. */
+ nparts = camel_multipart_get_number (mp);
+ for (i = 0; i < nparts; i++) {
+ CamelContentType *content_type;
+
+ part = camel_multipart_get_part (mp, i);
+
+ if (!part)
+ continue;
+
+ content_type = camel_mime_part_get_content_type (part);
+
+ if (camel_content_type_is (content_type, "text", "html")) {
+ displayid = i;
+ display_part = part;
+
+ if (have_plain)
+ break;
+ } else if (camel_content_type_is (content_type, "text", "plain")) {
+ have_plain = TRUE;
+
+ if (display_part)
+ break;
+ }
+ }
+
+ if (display_part && have_plain && nparts == 2) {
+ g_string_append_printf (part_id, ".alternative-prefer-plain.%d", displayid);
+ /* FIXME Not passing a GCancellable here. */
+ parts = e_mail_parser_parse_part_as (
+ parser, display_part, part_id,
+ "text/html", cancellable);
+
+ g_string_truncate (part_id, partidlen);
+ } else {
+ /* Parser will automatically fallback to next extension */
+ return NULL;
+
+ }
+
+ return parts;
+
+ } else if (!CAMEL_IS_MULTIPART (mp)) {
+ return e_mail_parser_parse_part_as (
+ parser, part, part_id,
+ "application/vnd.evolution.source", cancellable);
+ }
+
+ nparts = camel_multipart_get_number (mp);
+ for (i = 0; i < nparts; i++) {
+ CamelContentType *ct;
+
+ part = camel_multipart_get_part (mp, i);
+
+ if (!part)
+ continue;
+
+ ct = camel_mime_part_get_content_type (part);
+ if (!display_part && camel_content_type_is (ct, "text", "plain")) {
+ displayid = i;
+ display_part = part;
+ } else if (!calendar_part && (camel_content_type_is (ct, "text", "calendar") || camel_content_type_is (ct, "text", "x-calendar"))) {
+ calendarid = i;
+ calendar_part = part;
+ }
+ }
+
+ /* if we found a text part, show it */
+ if (display_part) {
+ g_string_append_printf(part_id, ".alternative-prefer-plain.%d", displayid);
+ parts = g_slist_concat (parts,
+ e_mail_parser_parse_part_as (
+ parser, display_part, part_id,
+ "text/plain", cancellable));
+
+ g_string_truncate (part_id, partidlen);
+ }
+
+ /* all other parts are attachments */
+ if (emp_pp->show_suppressed) {
+ parts = g_slist_concat (parts,
+ export_as_attachments (
+ mp, parser, display_part, part_id,
+ cancellable));
+ } else if (calendar_part) {
+ g_string_append_printf(part_id, ".alternative-prefer-plain.%d", calendarid);
+ parts = g_slist_concat (parts,
+ make_part_attachment (
+ parser, calendar_part, part_id,
+ FALSE, NULL));
+ }
+
+ g_string_truncate (part_id, partidlen);
+
+ return parts;
+}
+
+static const gchar **
+empe_mime_types (EMailExtension *extension)
+{
+ return parser_mime_types;
+}
+
+void
+e_mail_parser_prefer_plain_type_register (GTypeModule *type_module)
+{
+ e_mail_parser_prefer_plain_register_type (type_module);
+}
+
+static void
+e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
+{
+ iface->mime_types = empe_mime_types;
+}
+
+static void
+e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
+{
+ iface->parse = empe_prefer_plain_parse;
+}
+
+static void
+e_mail_parser_prefer_plain_constructed (GObject *object)
+{
+ EExtensible *extensible;
+ EMailExtensionRegistry *reg;
+
+ extensible = e_extension_get_extensible (E_EXTENSION (object));
+ reg = E_MAIL_EXTENSION_REGISTRY (extensible);
+
+ e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
+}
+
+static void
+e_mail_parser_prefer_plain_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EMailParserPreferPlain *parser;
+
+ parser = (EMailParserPreferPlain *) object;
+
+ switch (property_id) {
+ case PROP_MODE:
+ g_value_set_int (value, parser->mode);
+ return;
+ case PROP_SHOW_SUPPRESSED:
+ g_value_set_boolean (value, parser->show_suppressed);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_mail_parser_prefer_plain_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EMailParserPreferPlain *parser;
+
+ parser = (EMailParserPreferPlain *) object;
+
+ switch (property_id) {
+ case PROP_MODE:
+ parser->mode = g_value_get_int (value);
+ return;
+ case PROP_SHOW_SUPPRESSED:
+ parser->show_suppressed = g_value_get_boolean (value);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_mail_parser_prefer_plain_finalize (GObject *object)
+{
+ EMailParserPreferPlain *parser;
+
+ parser = (EMailParserPreferPlain *) object;
+
+ g_clear_object (&parser->settings);
+
+ G_OBJECT_CLASS (e_mail_parser_prefer_plain_parent_class)->finalize (object);
+}
+
+static void
+e_mail_parser_prefer_plain_class_init (EMailParserPreferPlainClass *klass)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ e_mail_parser_prefer_plain_parent_class = g_type_class_peek_parent (klass);
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = e_mail_parser_prefer_plain_constructed;
+ object_class->get_property = e_mail_parser_prefer_plain_get_property;
+ object_class->set_property = e_mail_parser_prefer_plain_set_property;
+ object_class->finalize = e_mail_parser_prefer_plain_finalize;
+
+ extension_class = E_EXTENSION_CLASS (klass);
+ extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODE,
+ g_param_spec_int (
+ "mode",
+ "Mode",
+ NULL,
+ EPP_NORMAL,
+ EPP_TEXT,
+ EPP_NORMAL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_SUPPRESSED,
+ g_param_spec_boolean (
+ "show-suppressed",
+ "Show Suppressed",
+ NULL,
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+void
+e_mail_parser_prefer_plain_class_finalize (EMailParserPreferPlainClass *klass)
+{
+}
+
+static gboolean
+parser_mode_get_mapping (GValue *value,
+ GVariant *variant,
+ gpointer user_data)
+{
+ gint i;
+
+ const gchar *key = g_variant_get_string (variant, NULL);
+ if (key) {
+ for (i = 0; i < G_N_ELEMENTS (epp_options); i++) {
+ if (!strcmp (epp_options[i].key, key)) {
+ g_value_set_int (value, i);
+ return TRUE;
+ }
+ }
+ } else {
+ g_value_set_int (value, 0);
+ }
+
+ return TRUE;
+}
+
+static GVariant *
+parser_mode_set_mapping (const GValue *value,
+ const GVariantType *expected_type,
+ gpointer user_data)
+{
+ return g_variant_new_string (epp_options[g_value_get_int (value)].key);
+}
+
+static void
+e_mail_parser_prefer_plain_init (EMailParserPreferPlain *parser)
+{
+ gchar *key;
+ gint i;
+
+ parser->settings = g_settings_new ("org.gnome.evolution.plugin.prefer-plain");
+ g_settings_bind_with_mapping (
+ parser->settings, "mode",
+ parser, "mode", G_SETTINGS_BIND_DEFAULT,
+ parser_mode_get_mapping,
+ parser_mode_set_mapping,
+ NULL, NULL);
+ g_settings_bind (
+ parser->settings, "show-suppressed",
+ parser, "show-suppressed", G_SETTINGS_BIND_DEFAULT);
+
+ /* Initialize the settings */
+ key = g_settings_get_string (parser->settings, "mode");
+ if (key) {
+ for (i = 0; i < G_N_ELEMENTS (epp_options); i++) {
+ if (!strcmp (epp_options[i].key, key)) {
+ parser->mode = i;
+ break;
+ }
+ }
+ g_free (key);
+ } else {
+ parser->mode = 0;
+ }
+
+ parser->show_suppressed = g_settings_get_boolean (parser->settings, "show-suppressed");
+}
diff --git a/modules/prefer-plain/e-mail-parser-prefer-plain.h b/modules/prefer-plain/e-mail-parser-prefer-plain.h
new file mode 100644
index 0000000000..4cfb8226f9
--- /dev/null
+++ b/modules/prefer-plain/e-mail-parser-prefer-plain.h
@@ -0,0 +1,30 @@
+/*
+ * e-mail-parser-prefer-plain.h
+ *
+ * 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/>
+ *
+ */
+
+#ifndef E_MAIL_PARSER_PREFER_PLAIN_H
+#define E_MAIL_PARSER_PREFER_PLAIN_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void e_mail_parser_prefer_plain_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_PARSER_PREFER_PLAIN_H */
diff --git a/modules/prefer-plain/evolution-module-prefer-plain.c b/modules/prefer-plain/evolution-module-prefer-plain.c
new file mode 100644
index 0000000000..cb81932594
--- /dev/null
+++ b/modules/prefer-plain/evolution-module-prefer-plain.c
@@ -0,0 +1,73 @@
+/*
+ * evolution-module-prefer-plain.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-parser-prefer-plain.h"
+
+#include <gmodule.h>
+#include <gio/gio.h>
+
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+const gchar * g_module_check_init (GModule *module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+ GSettings *settings;
+ gchar **disabled_plugins;
+ gint i = 0;
+
+ settings = g_settings_new ("org.gnome.evolution");
+ disabled_plugins = g_settings_get_strv (settings, "disabled-eplugins");
+
+ for (i = 0; disabled_plugins && disabled_plugins[i] != NULL; i++) {
+
+ if (g_strcmp0 (
+ disabled_plugins[i],
+ "org.gnome.evolution.plugin.preferPlain") == 0) {
+
+ g_strfreev (disabled_plugins);
+ g_object_unref (settings);
+ return;
+ }
+
+ }
+
+ e_mail_parser_prefer_plain_type_register (type_module);
+
+ g_strfreev (disabled_plugins);
+ g_object_unref (settings);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init (GModule *module)
+{
+ /* FIXME Until mail is split into a module library and a
+ * reusable shared library, prevent the module from
+ * being unloaded. Unloading the module resets all
+ * static variables, which screws up foo_get_type()
+ * functions among other things. */
+ g_module_make_resident (module);
+
+ return NULL;
+}
diff --git a/modules/prefer-plain/plugin/Makefile.am b/modules/prefer-plain/plugin/Makefile.am
new file mode 100644
index 0000000000..3a0e16d29a
--- /dev/null
+++ b/modules/prefer-plain/plugin/Makefile.am
@@ -0,0 +1,28 @@
+@EVO_PLUGIN_RULE@
+
+plugin_DATA = org-gnome-prefer-plain.eplug
+plugin_LTLIBRARIES = liborg-gnome-prefer-plain.la
+
+liborg_gnome_prefer_plain_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/widgets \
+ -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+liborg_gnome_prefer_plain_la_SOURCES = \
+ config-ui.c
+
+liborg_gnome_prefer_plain_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+liborg_gnome_prefer_plain_la_LIBADD = \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+BUILT_SOURCES = $(plugin_DATA)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ org-gnome-prefer-plain.eplug.xml
diff --git a/modules/prefer-plain/plugin/config-ui.c b/modules/prefer-plain/plugin/config-ui.c
new file mode 100644
index 0000000000..29b81a60fe
--- /dev/null
+++ b/modules/prefer-plain/plugin/config-ui.c
@@ -0,0 +1,192 @@
+/*
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <mail/em-config.h>
+
+#include <libedataserverui/libedataserverui.h>
+
+GtkWidget *prefer_plain_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data);
+
+enum {
+ EPP_NORMAL,
+ EPP_PREFER,
+ EPP_TEXT
+};
+
+static GSettings *epp_settings = NULL;
+static gint epp_mode = -1;
+static gboolean epp_show_suppressed = TRUE;
+
+static struct {
+ const gchar *key;
+ const gchar *label;
+ const gchar *description;
+} epp_options[] = {
+ { "normal",
+ N_("Show HTML if present"),
+ N_("Let Evolution choose the best part to show.") },
+
+ { "prefer_plain",
+ N_("Show plain text if present"),
+ N_("Show plain text part, if present, otherwise "
+ "let Evolution choose the best part to show.") },
+
+ { "only_plain",
+ N_("Only ever show plain text"),
+ N_("Always show plain text part and make attachments "
+ "from other parts, if requested.") },
+};
+
+static void
+update_info_label (GtkWidget *info_label,
+ guint mode)
+{
+ gchar *str = g_strconcat ("<i>", _(epp_options[mode > 2 ? 0 : mode].description), "</i>", NULL);
+
+ gtk_label_set_markup (GTK_LABEL (info_label), str);
+
+ g_free (str);
+}
+
+static void
+epp_mode_changed (GtkComboBox *dropdown,
+ GtkWidget *info_label)
+{
+ epp_mode = gtk_combo_box_get_active (dropdown);
+ if (epp_mode > 2)
+ epp_mode = 0;
+
+ g_settings_set_string (epp_settings, "mode", epp_options[epp_mode].key);
+ update_info_label (info_label, epp_mode);
+}
+
+static void
+epp_show_suppressed_toggled (GtkToggleButton *check,
+ gpointer data)
+{
+ g_return_if_fail (check != NULL);
+
+ epp_show_suppressed = gtk_toggle_button_get_active (check);
+ g_settings_set_boolean (epp_settings, "show-suppressed", epp_show_suppressed);
+}
+
+GtkWidget *
+prefer_plain_page_factory (EPlugin *epl,
+ struct _EConfigHookItemFactoryData *data)
+{
+ GtkComboBox *dropdown;
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+ GtkWidget *dropdown_label, *info, *check;
+ guint i;
+ GtkTreeIter iter;
+
+ if (data->old)
+ return data->old;
+
+ check = gtk_check_button_new_with_mnemonic (_("Show s_uppressed HTML parts as attachments"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), epp_show_suppressed);
+ gtk_widget_show (check);
+ g_signal_connect (
+ check, "toggled",
+ G_CALLBACK (epp_show_suppressed_toggled), NULL);
+
+ dropdown = (GtkComboBox *) gtk_combo_box_new ();
+ cell = gtk_cell_renderer_text_new ();
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+ for (i = 0; i < G_N_ELEMENTS (epp_options); i++) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _(epp_options[i].label), -1);
+ }
+
+ gtk_cell_layout_pack_start ((GtkCellLayout *) dropdown, cell, TRUE);
+ gtk_cell_layout_set_attributes((GtkCellLayout *)dropdown, cell, "text", 0, NULL);
+ gtk_combo_box_set_model (dropdown, (GtkTreeModel *) store);
+ /*gtk_combo_box_set_active(dropdown, -1);*/
+ gtk_combo_box_set_active (dropdown, epp_mode);
+ gtk_widget_show ((GtkWidget *) dropdown);
+
+ dropdown_label = gtk_label_new_with_mnemonic (_("HTML _Mode"));
+ gtk_widget_show (dropdown_label);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (dropdown_label), (GtkWidget *) dropdown);
+
+ info = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (info), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (info), TRUE);
+
+ gtk_widget_show (info);
+ update_info_label (info, epp_mode);
+
+ g_signal_connect (
+ dropdown, "changed",
+ G_CALLBACK (epp_mode_changed), info);
+
+ g_object_get (data->parent, "n-rows", &i, NULL);
+ gtk_table_attach ((GtkTable *) data->parent, check, 0, 2, i, i + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_table_attach ((GtkTable *) data->parent, dropdown_label, 0, 1, i + 1, i + 2, 0, 0, 0, 0);
+ gtk_table_attach ((GtkTable *) data->parent, (GtkWidget *) dropdown, 1, 2, i + 1, i + 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_table_attach ((GtkTable *) data->parent, info, 1, 2, i + 2, i + 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+
+ /* since this isnt dynamic, we don't need to track each item */
+
+ return (GtkWidget *) dropdown;
+}
+
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
+
+gint
+e_plugin_lib_enable (EPlugin *ep,
+ gint enable)
+{
+ gchar *key;
+ gint i;
+
+ if (epp_settings || epp_mode != -1)
+ return 0;
+
+ if (enable) {
+
+ epp_settings = g_settings_new ("org.gnome.evolution.plugin.prefer-plain");
+ key = g_settings_get_string (epp_settings, "mode");
+ if (key) {
+ for (i = 0; i < G_N_ELEMENTS (epp_options); i++) {
+ if (!strcmp (epp_options[i].key, key)) {
+ epp_mode = i;
+ break;
+ }
+ }
+ g_free (key);
+ } else {
+ epp_mode = 0;
+ }
+
+ epp_show_suppressed = g_settings_get_boolean (epp_settings, "show-suppressed");
+ } else {
+ if (epp_settings) {
+ g_object_unref (epp_settings);
+ epp_settings = NULL;
+ }
+ }
+
+ return 0;
+}
diff --git a/modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml b/modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml
new file mode 100644
index 0000000000..43948e3a69
--- /dev/null
+++ b/modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<e-plugin-list>
+ <e-plugin
+ type="shlib"
+ id="org.gnome.evolution.plugin.preferPlain"
+ location="@PLUGINDIR@/liborg-gnome-prefer-plain@SOEXT@"
+ _name="Prefer Plain Text">
+
+
+ <_description>View mail messages as plain text, even if they contain HTML content.</_description>
+ <author name="Michael Zucchi" email="NotZed@Ximian.com"/>
+
+
+ <!-- hook into the 'html mail' preferences page -->
+ <hook class="org.gnome.evolution.mail.config:1.0">
+ <group target="prefs" id="org.gnome.evolution.mail.prefs">
+ <!-- we could also just insert our own items from a section factory, -->
+ <!-- but then we also need to create our own section frame -->
+ <item type="section_table" path="10.html/80.mode" _label="Plain Text Mode"/>
+ <item type="item_table" path="10.html/80.mode/00.mode" factory="prefer_plain_page_factory"/>
+ </group>
+ </hook>
+
+ </e-plugin>
+</e-plugin-list> \ No newline at end of file