diff options
Diffstat (limited to 'modules/prefer-plain')
-rw-r--r-- | modules/prefer-plain/Makefile.am | 28 | ||||
-rw-r--r-- | modules/prefer-plain/e-mail-parser-prefer-plain.c | 553 | ||||
-rw-r--r-- | modules/prefer-plain/e-mail-parser-prefer-plain.h | 30 | ||||
-rw-r--r-- | modules/prefer-plain/evolution-module-prefer-plain.c | 73 | ||||
-rw-r--r-- | modules/prefer-plain/plugin/Makefile.am | 28 | ||||
-rw-r--r-- | modules/prefer-plain/plugin/config-ui.c | 192 | ||||
-rw-r--r-- | modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml | 25 |
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 |