aboutsummaryrefslogtreecommitdiffstats
path: root/modules/prefer-plain
diff options
context:
space:
mode:
authorDan Vrátil <dvratil@redhat.com>2012-06-06 21:29:38 +0800
committerDan Vrátil <dvratil@redhat.com>2012-06-06 21:29:38 +0800
commit931191474643164e96b5778c790e42cca517e729 (patch)
treeaec00f3303dbcd95a8a3f18ee324ac80594ff9b5 /modules/prefer-plain
parent5b8340563c271fb684a88c6e5bb6dd3bfb629058 (diff)
downloadgsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.tar
gsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.tar.gz
gsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.tar.bz2
gsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.tar.lz
gsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.tar.xz
gsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.tar.zst
gsoc2013-evolution-931191474643164e96b5778c790e42cca517e729.zip
Mail formatter rewrite - convert some plugins to modules
audio-inline, itip-formatter, prefer-plain, tnef-attachments and vcard-inline plugins were converted to modules so that they can fit into concept of the new formatter. Every module still installs .eplug file, because there is no suitable API at the moment to register plugins to the plugins dialog and to extend the Preferences dialog.
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