diff options
33 files changed, 6423 insertions, 5627 deletions
diff --git a/configure.ac b/configure.ac index 474d20b449..8ba00a265e 100644 --- a/configure.ac +++ b/configure.ac @@ -198,8 +198,6 @@ case "$host" in os_win32=yes NO_UNDEFINED='-no-undefined' SOEXT='.dll' - SA_JUNK_PLUGIN='' - BF_JUNK_PLUGIN='' DL_LIB='' SOFTOKN3_LIB='' CHAMPLAIN_REQUIREMENT='' @@ -218,8 +216,6 @@ case "$host" in os_win32=no NO_UNDEFINED='-no-undefined' SOEXT='.so' - SA_JUNK_PLUGIN=sa-junk-plugin - BF_JUNK_PLUGIN=bogo-junk-plugin DL_LIB='-ldl' SOFTOKN3_LIB='-lsoftokn3' ;; @@ -1437,8 +1433,8 @@ AC_ARG_ENABLE([plugins], dnl Add any new plugins here plugins_base_always="calendar-file calendar-http itip-formatter default-source addressbook-file mark-all-read publish-calendar caldav imap-features google-account-setup webdav-account-setup" -plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN" -dist_plugins_base="$plugins_base_always calendar-weather sa-junk-plugin bogo-junk-plugin" +plugins_base="$plugins_base_always" +dist_plugins_base="$plugins_base_always calendar-weather" plugins_standard_always="bbdb save-calendar mail-to-task mailing-list-actions prefer-plain mail-notification attachment-reminder backup-restore email-custom-header face templates vcard-inline dbx-import" @@ -1754,6 +1750,7 @@ mail/importers/Makefile maint/Makefile modules/Makefile modules/addressbook/Makefile +modules/bogofilter/Makefile modules/calendar/Makefile modules/mail/Makefile modules/composer-autosave/Makefile @@ -1766,6 +1763,7 @@ modules/plugin-lib/Makefile modules/plugin-manager/Makefile modules/plugin-mono/Makefile modules/plugin-python/Makefile +modules/spamassassin/Makefile modules/startup-wizard/Makefile modules/windows-sens/Makefile plugins/Makefile @@ -1774,7 +1772,6 @@ plugins/attachment-reminder/Makefile plugins/audio-inline/Makefile plugins/backup-restore/Makefile plugins/bbdb/Makefile -plugins/bogo-junk-plugin/Makefile plugins/caldav/Makefile plugins/calendar-file/Makefile plugins/calendar-http/Makefile @@ -1795,7 +1792,6 @@ plugins/mark-all-read/Makefile plugins/prefer-plain/Makefile plugins/pst-import/Makefile plugins/publish-calendar/Makefile -plugins/sa-junk-plugin/Makefile plugins/save-calendar/Makefile plugins/templates/Makefile plugins/tnef-attachments/Makefile diff --git a/mail/Makefile.am b/mail/Makefile.am index 520e6876cd..0d2864d59f 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -56,6 +56,8 @@ mailinclude_HEADERS = \ e-mail-enums.h \ e-mail-enumtypes.h \ e-mail-folder-utils.h \ + e-mail-junk-filter.h \ + e-mail-junk-options.h \ e-mail-label-action.h \ e-mail-label-dialog.h \ e-mail-label-list-store.h \ @@ -91,7 +93,6 @@ mailinclude_HEADERS = \ em-format-html-display.h \ em-format-html-print.h \ em-html-stream.h \ - em-junk.h \ em-search-context.h \ em-subscription-editor.h \ em-sync-stream.h \ @@ -128,6 +129,8 @@ libevolution_mail_la_SOURCES = \ e-mail-display.c \ e-mail-enumtypes.c \ e-mail-folder-utils.c \ + e-mail-junk-filter.c \ + e-mail-junk-options.c \ e-mail-label-action.c \ e-mail-label-dialog.c \ e-mail-label-list-store.c \ @@ -163,7 +166,6 @@ libevolution_mail_la_SOURCES = \ em-format-html-display.c \ em-format-html-print.c \ em-html-stream.c \ - em-junk.c \ em-search-context.c \ em-subscription-editor.c \ em-sync-stream.c \ diff --git a/mail/e-mail-junk-filter.c b/mail/e-mail-junk-filter.c new file mode 100644 index 0000000000..71128013ad --- /dev/null +++ b/mail/e-mail-junk-filter.c @@ -0,0 +1,82 @@ +/* + * e-mail-junk-filter.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-junk-filter.h" + +#include <mail/e-mail-session.h> + +G_DEFINE_ABSTRACT_TYPE ( + EMailJunkFilter, + e_mail_junk_filter, + E_TYPE_EXTENSION) + +static void +e_mail_junk_filter_class_init (EMailJunkFilterClass *class) +{ + EExtensionClass *extension_class; + + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_MAIL_SESSION; +} + +static void +e_mail_junk_filter_init (EMailJunkFilter *junk_filter) +{ +} + +gboolean +e_mail_junk_filter_available (EMailJunkFilter *junk_filter) +{ + EMailJunkFilterClass *class; + + g_return_val_if_fail (E_IS_MAIL_JUNK_FILTER (junk_filter), FALSE); + + class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); + g_return_val_if_fail (class->available != NULL, FALSE); + + return class->available (junk_filter); +} + +GtkWidget * +e_mail_junk_filter_new_config_widget (EMailJunkFilter *junk_filter) +{ + EMailJunkFilterClass *class; + GtkWidget *widget = NULL; + + g_return_val_if_fail (E_IS_MAIL_JUNK_FILTER (junk_filter), NULL); + + class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); + + if (class->new_config_widget != NULL) + widget = class->new_config_widget (junk_filter); + + return widget; +} + +gint +e_mail_junk_filter_compare (EMailJunkFilter *junk_filter_a, + EMailJunkFilter *junk_filter_b) +{ + EMailJunkFilterClass *class_a; + EMailJunkFilterClass *class_b; + + class_a = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter_a); + class_b = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter_b); + + return g_utf8_collate (class_a->display_name, class_b->display_name); +} diff --git a/mail/e-mail-junk-filter.h b/mail/e-mail-junk-filter.h new file mode 100644 index 0000000000..34d95e56c7 --- /dev/null +++ b/mail/e-mail-junk-filter.h @@ -0,0 +1,74 @@ +/* + * e-mail-junk-filter.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_JUNK_FILTER_H +#define E_MAIL_JUNK_FILTER_H + +#include <gtk/gtk.h> +#include <e-util/e-extension.h> + +/* Standard GObject macros */ +#define E_TYPE_MAIL_JUNK_FILTER \ + (e_mail_junk_filter_get_type ()) +#define E_MAIL_JUNK_FILTER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MAIL_JUNK_FILTER, EMailJunkFilter)) +#define E_MAIL_JUNK_FILTER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MAIL_JUNK_FILTER, EMailJunkFilterClass)) +#define E_IS_MAIL_JUNK_FILTER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MAIL_JUNK_FILTER)) +#define E_IS_MAIL_JUNK_FILTER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MAIL_JUNK_FILTER)) +#define E_MAIL_JUNK_FILTER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MAIL_JUNK_FILTER, EMailJunkFilterClass)) + +G_BEGIN_DECLS + +typedef struct _EMailJunkFilter EMailJunkFilter; +typedef struct _EMailJunkFilterClass EMailJunkFilterClass; +typedef struct _EMailJunkFilterPrivate EMailJunkFilterPrivate; + +struct _EMailJunkFilter { + EExtension parent; + EMailJunkFilterPrivate *priv; +}; + +struct _EMailJunkFilterClass { + EExtensionClass parent_class; + + const gchar *filter_name; + const gchar *display_name; + + gboolean (*available) (EMailJunkFilter *junk_filter); + GtkWidget * (*new_config_widget) (EMailJunkFilter *junk_filter); +}; + +GType e_mail_junk_filter_get_type (void) G_GNUC_CONST; +gboolean e_mail_junk_filter_available (EMailJunkFilter *junk_filter); +GtkWidget * e_mail_junk_filter_new_config_widget + (EMailJunkFilter *junk_filter); +gint e_mail_junk_filter_compare (EMailJunkFilter *junk_filter_a, + EMailJunkFilter *junk_filter_b); + +G_END_DECLS + +#endif /* E_MAIL_JUNK_FILTER_H */ diff --git a/mail/e-mail-junk-options.c b/mail/e-mail-junk-options.c new file mode 100644 index 0000000000..d57e1d6dc6 --- /dev/null +++ b/mail/e-mail-junk-options.c @@ -0,0 +1,372 @@ +/* + * e-mail-junk-options.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-junk-options.h" + +#include <config.h> +#include <glib/gi18n-lib.h> + +#include <mail/e-mail-junk-filter.h> + +#define E_MAIL_JUNK_OPTIONS_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MAIL_JUNK_OPTIONS, EMailJunkOptionsPrivate)) + +G_DEFINE_TYPE ( + EMailJunkOptions, + e_mail_junk_options, + GTK_TYPE_GRID) + +struct _EMailJunkOptionsPrivate { + EMailSession *session; + + GtkWidget *label; /* not referenced */ + GtkWidget *combo_box; /* not referenced */ + GtkWidget *option_box; /* not referenced */ + GPtrArray *widgets; /* not referenced */ + + GBinding *active_id_binding; +}; + +enum { + PROP_0, + PROP_SESSION +}; + +enum { + COLUMN_FILTER_NAME, + COLUMN_DISPLAY_NAME +}; + +static void +mail_junk_options_combo_box_changed_cb (GtkComboBox *combo_box, + EMailJunkOptions *options) +{ + GPtrArray *array; + gint active; + guint ii; + + array = options->priv->widgets; + active = gtk_combo_box_get_active (combo_box); + + for (ii = 0; ii < array->len; ii++) { + GtkWidget *widget = GTK_WIDGET (array->pdata[ii]); + gtk_widget_set_visible (widget, ii == active); + } +} + +static void +mail_junk_options_rebuild (EMailJunkOptions *options) +{ + EMailSession *session; + GtkComboBox *combo_box; + GtkTreeModel *model; + GtkBox *option_box; + GList *list = NULL; + GList *link; + guint n_filters; + + session = e_mail_junk_options_get_session (options); + combo_box = GTK_COMBO_BOX (options->priv->combo_box); + option_box = GTK_BOX (options->priv->option_box); + + /* Remove the GtkComboBox:active-id binding so it doesn't + * affect EMailSession:junk-filter-name when we clear the + * combo box's list model. */ + if (options->priv->active_id_binding != NULL) { + g_object_unref (options->priv->active_id_binding); + options->priv->active_id_binding = NULL; + } + + model = gtk_combo_box_get_model (combo_box); + gtk_list_store_clear (GTK_LIST_STORE (model)); + + g_ptr_array_foreach ( + options->priv->widgets, + (GFunc) gtk_widget_destroy, NULL); + g_ptr_array_set_size (options->priv->widgets, 0); + + if (session != NULL) + list = e_mail_session_get_available_junk_filters (session); + + for (link = list; link != NULL; link = g_list_next (link)) { + EMailJunkFilter *junk_filter; + EMailJunkFilterClass *class; + GtkWidget *widget; + GtkTreeIter iter; + + junk_filter = E_MAIL_JUNK_FILTER (link->data); + class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + COLUMN_FILTER_NAME, class->filter_name, + COLUMN_DISPLAY_NAME, class->display_name, + -1); + + /* Create a configuration widget for this junk filter, + * or else just create an empty placeholder widget. */ + widget = e_mail_junk_filter_new_config_widget (junk_filter); + if (widget == NULL) + widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + + g_ptr_array_add (options->priv->widgets, widget); + + /* Set extra padding to 12px, since only one child of + * 'option_box' is visible at a time, and we still want + * the extra padding if the first grid row is invisible. */ + gtk_box_pack_start (option_box, widget, FALSE, FALSE, 12); + } + + /* Synchronize the combo box with the active junk filter. */ + if (session != NULL) { + GBinding *binding; + + binding = g_object_bind_property ( + session, "junk-filter-name", + combo_box, "active-id", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + options->priv->active_id_binding = binding; + } + + /* Select the first combo box item if we need to. If there's + * no first item to select, this will silently do nothing. */ + if (gtk_combo_box_get_active (combo_box) < 0) + gtk_combo_box_set_active (combo_box, 0); + + /* Update visibility of widgets. */ + n_filters = g_list_length (list); + gtk_widget_set_visible (GTK_WIDGET (options), n_filters > 0); + gtk_widget_set_visible (options->priv->label, n_filters > 1); + gtk_widget_set_visible (options->priv->combo_box, n_filters > 1); + + g_list_free (list); +} + +static void +mail_junk_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SESSION: + e_mail_junk_options_set_session ( + E_MAIL_JUNK_OPTIONS (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_junk_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SESSION: + g_value_set_object ( + value, + e_mail_junk_options_get_session ( + E_MAIL_JUNK_OPTIONS (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_junk_options_dispose (GObject *object) +{ + EMailJunkOptionsPrivate *priv; + + priv = E_MAIL_JUNK_OPTIONS_GET_PRIVATE (object); + + if (priv->session != NULL) { + g_object_unref (priv->session); + priv->session = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_mail_junk_options_parent_class)->dispose (object); +} + +static void +mail_junk_options_finalize (GObject *object) +{ + EMailJunkOptionsPrivate *priv; + + priv = E_MAIL_JUNK_OPTIONS_GET_PRIVATE (object); + + g_ptr_array_free (priv->widgets, TRUE); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_mail_junk_options_parent_class)->finalize (object); +} + +static void +mail_junk_options_constructed (GObject *object) +{ + EMailJunkOptionsPrivate *priv; + GtkCellRenderer *cell_renderer; + GtkCellLayout *cell_layout; + GtkListStore *list_store; + GtkWidget *widget; + + priv = E_MAIL_JUNK_OPTIONS_GET_PRIVATE (object); + + /* XXX The margins we're using here are tailored to its + * placement in the Junk tab of Mail Preferences. + * EMailJunkOptions is not really reusable as is. */ + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_mail_junk_options_parent_class)->constructed (object); + + gtk_grid_set_column_spacing (GTK_GRID (object), 6); + + list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + + /* Label + combo box has a 12px left margin so it's + * aligned with the junk mail options above it. */ + widget = gtk_label_new (_("Junk filtering software:")); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_widget_set_margin_left (widget, 12); + gtk_grid_attach (GTK_GRID (object), widget, 0, 0, 1, 1); + priv->label = widget; /* not referenced */ + gtk_widget_show (widget); + + widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (list_store)); + gtk_combo_box_set_id_column ( + GTK_COMBO_BOX (widget), COLUMN_FILTER_NAME); + gtk_grid_attach (GTK_GRID (object), widget, 1, 0, 1, 1); + priv->combo_box = widget; /* not referenced */ + gtk_widget_show (widget); + + g_signal_connect ( + widget, "changed", + G_CALLBACK (mail_junk_options_combo_box_changed_cb), object); + + /* The config widgets that come from EMailJunkFilter have no + * left margin, since they usually include a bold header and + * interactive widgets with their own left margin. */ + widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_grid_attach (GTK_GRID (object), widget, 0, 1, 2, 1); + priv->option_box = widget; /* not referenced */ + gtk_widget_show (widget); + + cell_layout = GTK_CELL_LAYOUT (priv->combo_box); + cell_renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (cell_layout, cell_renderer, FALSE); + + gtk_cell_layout_add_attribute ( + cell_layout, cell_renderer, + "text", COLUMN_DISPLAY_NAME); + + g_object_unref (list_store); +} + +static void +mail_junk_options_map (GtkWidget *widget) +{ + /* Chain up to parent's map() method. */ + GTK_WIDGET_CLASS (e_mail_junk_options_parent_class)->map (widget); + + mail_junk_options_rebuild (E_MAIL_JUNK_OPTIONS (widget)); +} + +static void +e_mail_junk_options_class_init (EMailJunkOptionsClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + g_type_class_add_private (class, sizeof (EMailJunkOptionsPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = mail_junk_options_set_property; + object_class->get_property = mail_junk_options_get_property; + object_class->dispose = mail_junk_options_dispose; + object_class->finalize = mail_junk_options_finalize; + object_class->constructed = mail_junk_options_constructed; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->map = mail_junk_options_map; + + g_object_class_install_property ( + object_class, + PROP_SESSION, + g_param_spec_object ( + "session", + NULL, + NULL, + E_TYPE_MAIL_SESSION, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_mail_junk_options_init (EMailJunkOptions *options) +{ + options->priv = E_MAIL_JUNK_OPTIONS_GET_PRIVATE (options); + + options->priv->widgets = g_ptr_array_new (); +} + +GtkWidget * +e_mail_junk_options_new (EMailSession *session) +{ + g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); + + return g_object_new ( + E_TYPE_MAIL_JUNK_OPTIONS, "session", session, NULL); +} + +EMailSession * +e_mail_junk_options_get_session (EMailJunkOptions *options) +{ + g_return_val_if_fail (E_IS_MAIL_JUNK_OPTIONS (options), NULL); + + return options->priv->session; +} + +void +e_mail_junk_options_set_session (EMailJunkOptions *options, + EMailSession *session) +{ + g_return_if_fail (E_IS_MAIL_JUNK_OPTIONS (options)); + + if (session != NULL) { + g_return_if_fail (E_IS_MAIL_SESSION (session)); + g_object_ref (session); + } + + if (options->priv->session != NULL) + g_object_unref (options->priv->session); + + options->priv->session = session; + + g_object_notify (G_OBJECT (options), "session"); + + mail_junk_options_rebuild (options); +} diff --git a/mail/e-mail-junk-options.h b/mail/e-mail-junk-options.h new file mode 100644 index 0000000000..5e2c99faf7 --- /dev/null +++ b/mail/e-mail-junk-options.h @@ -0,0 +1,67 @@ +/* + * e-mail-junk-options.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_JUNK_OPTIONS_H +#define E_MAIL_JUNK_OPTIONS_H + +#include <gtk/gtk.h> +#include <mail/e-mail-session.h> + +/* Standard GObject macros */ +#define E_TYPE_MAIL_JUNK_OPTIONS \ + (e_mail_junk_options_get_type ()) +#define E_MAIL_JUNK_OPTIONS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MAIL_JUNK_OPTIONS, EMailJunkOptions)) +#define E_MAIL_JUNK_OPTIONS_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MAIL_JUNK_OPTIONS, EMailJunkOptionsClass)) +#define E_IS_MAIL_JUNK_OPTIONS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MAIL_JUNK_OPTIONS)) +#define E_IS_MAIL_JUNK_OPTIONS_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MAIL_JUNK_OPTIONS)) +#define E_MAIL_JUNK_OPTIONS_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MAIL_JUNK_OPTIONS, EMailJunkOptionsClass)) + +G_BEGIN_DECLS + +typedef struct _EMailJunkOptions EMailJunkOptions; +typedef struct _EMailJunkOptionsClass EMailJunkOptionsClass; +typedef struct _EMailJunkOptionsPrivate EMailJunkOptionsPrivate; + +struct _EMailJunkOptions { + GtkGrid parent; + EMailJunkOptionsPrivate *priv; +}; + +struct _EMailJunkOptionsClass { + GtkGridClass parent_class; +}; + +GType e_mail_junk_options_get_type (void); +GtkWidget * e_mail_junk_options_new (EMailSession *session); +EMailSession * e_mail_junk_options_get_session (EMailJunkOptions *options); +void e_mail_junk_options_set_session (EMailJunkOptions *options, + EMailSession *session); + +G_END_DECLS + +#endif /* E_MAIL_JUNK_OPTIONS_H */ diff --git a/mail/e-mail-session.c b/mail/e-mail-session.c index 44bbd8d0aa..8a3072447a 100644 --- a/mail/e-mail-session.c +++ b/mail/e-mail-session.c @@ -50,9 +50,12 @@ #include "e-util/e-util.h" #include "e-util/e-account-utils.h" #include "e-util/e-alert-dialog.h" +#include "e-util/e-extensible.h" #include "e-util/e-util-private.h" +#include "e-util/gconf-bridge.h" #include "e-mail-folder-utils.h" +#include "e-mail-junk-filter.h" #include "e-mail-local.h" #include "e-mail-session.h" #include "em-composer-utils.h" @@ -78,7 +81,7 @@ struct _EMailSessionPrivate { MailFolderCache *folder_cache; FILE *filter_logfile; - GList *junk_plugins; + GHashTable *junk_filters; }; struct _AsyncContext { @@ -93,7 +96,8 @@ struct _AsyncContext { enum { PROP_0, - PROP_FOLDER_CACHE + PROP_FOLDER_CACHE, + PROP_JUNK_FILTER_NAME }; static gchar *mail_data_dir; @@ -103,10 +107,11 @@ static gchar *mail_config_dir; static MailMsgInfo ms_thread_info_dummy = { sizeof (MailMsg) }; #endif -G_DEFINE_TYPE ( +G_DEFINE_TYPE_WITH_CODE ( EMailSession, e_mail_session, - CAMEL_TYPE_SESSION) + CAMEL_TYPE_SESSION, + G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL)) /* Support for CamelSession.alert_user() *************************************/ @@ -546,6 +551,84 @@ mail_session_check_junk_notify (GConfClient *gconf, } } +static const gchar * +mail_session_get_junk_filter_name (EMailSession *session) +{ + CamelJunkFilter *junk_filter; + GHashTableIter iter; + gpointer key, value; + + /* XXX This property can be removed once Evolution moves to + * GSettings and can use transform functions when binding + * properties to settings. That's why this is private. */ + + g_hash_table_iter_init (&iter, session->priv->junk_filters); + junk_filter = camel_session_get_junk_filter (CAMEL_SESSION (session)); + + while (g_hash_table_iter_next (&iter, &key, &value)) { + if (junk_filter == CAMEL_JUNK_FILTER (value)) + return (const gchar *) key; + } + + if (junk_filter != NULL) + g_warning ( + "Camel is using a junk filter " + "unknown to Evolution of type %s", + G_OBJECT_TYPE_NAME (junk_filter)); + + return ""; /* GConfBridge doesn't like NULL strings */ +} + +static void +mail_session_set_junk_filter_name (EMailSession *session, + const gchar *junk_filter_name) +{ + CamelJunkFilter *junk_filter = NULL; + + /* XXX This property can be removed once Evolution moves to + * GSettings and can use transform functions when binding + * properties to settings. That's why this is private. */ + + /* An empty string is equivalent to a NULL string. */ + if (junk_filter_name != NULL && *junk_filter_name == '\0') + junk_filter_name = NULL; + + if (junk_filter_name != NULL) { + junk_filter = g_hash_table_lookup ( + session->priv->junk_filters, junk_filter_name); + if (junk_filter != NULL) { + if (!e_mail_junk_filter_available ( + E_MAIL_JUNK_FILTER (junk_filter))) + junk_filter = NULL; + } else { + g_warning ( + "Unrecognized junk filter name " + "'%s' in GConf", junk_filter_name); + } + } + + camel_session_set_junk_filter (CAMEL_SESSION (session), junk_filter); + + /* XXX We emit the "notify" signal in mail_session_notify(). */ +} + +static void +mail_session_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_JUNK_FILTER_NAME: + mail_session_set_junk_filter_name ( + E_MAIL_SESSION (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + static void mail_session_get_property (GObject *object, guint property_id, @@ -559,6 +642,13 @@ mail_session_get_property (GObject *object, e_mail_session_get_folder_cache ( E_MAIL_SESSION (object))); return; + + case PROP_JUNK_FILTER_NAME: + g_value_set_string ( + value, + mail_session_get_junk_filter_name ( + E_MAIL_SESSION (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -583,8 +673,13 @@ mail_session_dispose (GObject *object) static void mail_session_finalize (GObject *object) { + EMailSessionPrivate *priv; GConfClient *client; + priv = E_MAIL_SESSION_GET_PRIVATE (object); + + g_hash_table_destroy (priv->junk_filters); + client = gconf_client_get_default (); if (session_check_junk_notify_id != 0) { @@ -606,6 +701,87 @@ mail_session_finalize (GObject *object) G_OBJECT_CLASS (e_mail_session_parent_class)->finalize (object); } +static void +mail_session_notify (GObject *object, + GParamSpec *pspec) +{ + /* GObject does not implement this method; do not chain up. */ + + /* XXX Delete this once Evolution moves to GSettings and + * we're able to get rid of PROP_JUNK_FILTER_NAME. */ + if (g_strcmp0 (pspec->name, "junk-filter") == 0) + g_object_notify (object, "junk-filter-name"); +} + +static void +mail_session_constructed (GObject *object) +{ + EMailSessionPrivate *priv; + EExtensible *extensible; + GType extension_type; + GList *list, *iter; + + priv = E_MAIL_SESSION_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_mail_session_parent_class)->constructed (object); + + extensible = E_EXTENSIBLE (object); + e_extensible_load_extensions (extensible); + + /* Add junk filter extensions to an internal hash table. */ + + extension_type = E_TYPE_MAIL_JUNK_FILTER; + list = e_extensible_list_extensions (extensible, extension_type); + + for (iter = list; iter != NULL; iter = g_list_next (iter)) { + EMailJunkFilter *junk_filter; + EMailJunkFilterClass *class; + + junk_filter = E_MAIL_JUNK_FILTER (iter->data); + class = E_MAIL_JUNK_FILTER_GET_CLASS (junk_filter); + + if (!CAMEL_IS_JUNK_FILTER (junk_filter)) { + g_warning ( + "Skipping %s: Does not implement " + "CamelJunkFilterInterface", + G_OBJECT_TYPE_NAME (junk_filter)); + continue; + } + + if (class->filter_name == NULL) { + g_warning ( + "Skipping %s: filter_name unset", + G_OBJECT_TYPE_NAME (junk_filter)); + continue; + } + + if (class->display_name == NULL) { + g_warning ( + "Skipping %s: display_name unset", + G_OBJECT_TYPE_NAME (junk_filter)); + continue; + } + + /* No need to reference the EMailJunkFilter since + * EMailSession owns the reference to it already. */ + g_hash_table_insert ( + priv->junk_filters, + (gpointer) class->filter_name, + junk_filter); + } + + g_list_free (list); + + /* Bind the "/apps/evolution/mail/junk/default_plugin" + * GConf key to our "junk-filter-name" property. */ + + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/default_plugin", + object, "junk-filter-name"); +} + static gchar * mail_session_get_password (CamelSession *session, CamelService *service, @@ -928,9 +1104,12 @@ e_mail_session_class_init (EMailSessionClass *class) g_type_class_add_private (class, sizeof (EMailSessionPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = mail_session_set_property; object_class->get_property = mail_session_get_property; object_class->dispose = mail_session_dispose; object_class->finalize = mail_session_finalize; + object_class->notify = mail_session_notify; + object_class->constructed = mail_session_constructed; session_class = CAMEL_SESSION_CLASS (class); session_class->get_password = mail_session_get_password; @@ -948,7 +1127,22 @@ e_mail_session_class_init (EMailSessionClass *class) NULL, NULL, MAIL_TYPE_FOLDER_CACHE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* XXX This property can be removed once Evolution moves to + * GSettings and can use transform functions when binding + * properties to settings. */ + g_object_class_install_property ( + object_class, + PROP_JUNK_FILTER_NAME, + g_param_spec_string ( + "junk-filter-name", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } static void @@ -958,6 +1152,8 @@ e_mail_session_init (EMailSession *session) session->priv = E_MAIL_SESSION_GET_PRIVATE (session); session->priv->folder_cache = mail_folder_cache_new (); + session->priv->junk_filters = g_hash_table_new ( + (GHashFunc) g_str_hash, (GEqualFunc) g_str_equal); /* Initialize the EAccount setup. */ e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD); @@ -974,7 +1170,6 @@ e_mail_session_init (EMailSession *session) client, "/apps/evolution/mail/junk", (GConfClientNotifyFunc) mail_session_check_junk_notify, session, NULL, NULL); - CAMEL_SESSION (session)->junk_plugin = NULL; mail_config_reload_junk_headers (session); @@ -1003,6 +1198,36 @@ e_mail_session_get_folder_cache (EMailSession *session) return session->priv->folder_cache; } +GList * +e_mail_session_get_available_junk_filters (EMailSession *session) +{ + GList *list, *link; + GQueue trash = G_QUEUE_INIT; + + g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); + + list = g_hash_table_get_values (session->priv->junk_filters); + + /* Discard unavailable junk filters. (e.g. Junk filter + * requires Bogofilter but Bogofilter is not installed, + * hence the junk filter is unavailable.) */ + + for (link = list; link != NULL; link = g_list_next (link)) { + EMailJunkFilter *junk_filter; + + junk_filter = E_MAIL_JUNK_FILTER (link->data); + if (!e_mail_junk_filter_available (junk_filter)) + g_queue_push_tail (&trash, link); + } + + while ((link = g_queue_pop_head (&trash)) != NULL) + list = g_list_delete_link (list, link); + + /* Sort the remaining junk filters by display name. */ + + return g_list_sort (list, (GCompareFunc) e_mail_junk_filter_compare); +} + static void mail_session_get_inbox_thread (GSimpleAsyncResult *simple, EMailSession *session, @@ -1327,42 +1552,6 @@ mail_session_flush_filter_log (EMailSession *session) fflush (session->priv->filter_logfile); } -void -mail_session_add_junk_plugin (EMailSession *session, - const gchar *plugin_name, - CamelJunkPlugin *junk_plugin) -{ - GConfClient *client; - gchar *def_plugin; - const gchar *key; - - g_return_if_fail (E_IS_MAIL_SESSION (session)); - - client = gconf_client_get_default (); - key = "/apps/evolution/mail/junk/default_plugin"; - def_plugin = gconf_client_get_string (client, key, NULL); - g_object_unref (client); - - session->priv->junk_plugins = g_list_append ( - session->priv->junk_plugins, junk_plugin); - if (def_plugin && plugin_name) { - if (!strcmp (def_plugin, plugin_name)) { - CAMEL_SESSION (session)->junk_plugin = junk_plugin; - camel_junk_plugin_init (junk_plugin); - } - } - - g_free (def_plugin); -} - -const GList * -mail_session_get_junk_plugins (EMailSession *session) -{ - g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL); - - return session->priv->junk_plugins; -} - const gchar * mail_session_get_data_dir (void) { diff --git a/mail/e-mail-session.h b/mail/e-mail-session.h index 5cc6b8976e..653404ca7a 100644 --- a/mail/e-mail-session.h +++ b/mail/e-mail-session.h @@ -66,6 +66,8 @@ GType e_mail_session_get_type (void); EMailSession * e_mail_session_new (void); MailFolderCache * e_mail_session_get_folder_cache (EMailSession *session); +GList * e_mail_session_get_available_junk_filters + (EMailSession *session); CamelFolder * e_mail_session_get_inbox_sync (EMailSession *session, const gchar *service_uid, GCancellable *cancellable, @@ -113,10 +115,6 @@ CamelFolder * e_mail_session_uri_to_folder_finish /*** Legacy API ***/ void mail_session_flush_filter_log (EMailSession *session); -void mail_session_add_junk_plugin (EMailSession *session, - const gchar *plugin_name, - CamelJunkPlugin *junk_plugin); -const GList * mail_session_get_junk_plugins (EMailSession *session); const gchar * mail_session_get_data_dir (void); const gchar * mail_session_get_config_dir (void); diff --git a/mail/em-junk.c b/mail/em-junk.c deleted file mode 100644 index 1026e4d76a..0000000000 --- a/mail/em-junk.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * em-junk.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/> - * - * - * Authors: - * Vivek Jain <jvivek@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "em-junk.h" - -GQuark -em_junk_error_quark (void) -{ - return g_quark_from_static_string ("em-junk-error-quark"); -} diff --git a/mail/em-junk.h b/mail/em-junk.h deleted file mode 100644 index 978f5ece7d..0000000000 --- a/mail/em-junk.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * em-junk.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/> - * - * - * Authors: - * Vivek Jain <jvivek@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef EM_JUNK_H -#define EM_JUNK_H - -#include <camel/camel.h> -#include <e-util/e-plugin.h> - -#define EM_JUNK_ERROR (em_junk_error_quark ()) - -G_BEGIN_DECLS - -typedef struct _EMJunkTarget EMJunkTarget; -typedef struct _EMJunkInterface EMJunkInterface; - -typedef void (*EMJunkHookFunc) (EPlugin *plugin, EMJunkTarget *data); - -struct _EMJunkTarget { - CamelMimeMessage *m; - GError *error; -}; - -struct _EMJunkInterface { - CamelJunkPlugin camel; - - /* The hook forwards calls from Camel to the EPlugin. */ - EPluginHook *hook; - - /* These are symbol names in the EPlugin. */ - gchar *check_junk; - gchar *report_junk; - gchar *report_notjunk; - gchar *commit_reports; - gchar *validate_binary; - - gchar *plugin_name; -}; - -GQuark em_junk_error_quark (void); - -G_END_DECLS - -#endif /* EM_JUNK_H */ diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in index cb697b5aff..3261788016 100644 --- a/mail/evolution-mail.schemas.in +++ b/mail/evolution-mail.schemas.in @@ -1434,34 +1434,6 @@ </schema> <schema> - <key>/schemas/apps/evolution/mail/junk/sa/local_only</key> - <applyto>/apps/evolution/mail/junk/sa/local_only</applyto> - <owner>evolution-mail</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Use only local spam tests.</short> - <long> - Use only the local spam tests (no DNS). - </long> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/mail/junk/sa/use_daemon</key> - <applyto>/apps/evolution/mail/junk/sa/use_daemon</applyto> - <owner>evolution-mail</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Use SpamAssassin daemon and client</short> - <long> - Use SpamAssassin daemon and client (spamc/spamd). - </long> - </locale> - </schema> - - <schema> <key>/schemas/apps/evolution/mail/junk/lookup_addressbook</key> <applyto>/apps/evolution/mail/junk/lookup_addressbook</applyto> <owner>evolution-mail</owner> diff --git a/mail/mail-config.ui b/mail/mail-config.ui index d2e5d8dd34..213f397660 100644 --- a/mail/mail-config.ui +++ b/mail/mail-config.ui @@ -1,187 +1,185 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8"?> <interface> - <requires lib="gtk+" version="2.16"/> <!-- interface-requires evolution 0.0 --> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkAdjustment" id="adjustment1"> - <property name="value">1.5</property> - <property name="upper">10</property> - <property name="step_increment">1</property> - <property name="page_increment">1</property> - </object> - <object class="GtkAdjustment" id="adjustment2"> - <property name="upper">30000</property> - <property name="step_increment">1</property> - <property name="page_increment">10</property> - </object> - <object class="GtkAdjustment" id="adjustment3"> - <property name="value">5</property> - <property name="lower">1</property> - <property name="upper">100</property> - <property name="step_increment">1</property> - <property name="page_increment">10</property> - </object> - <object class="GtkAdjustment" id="adjustment4"> - <property name="upper">65535</property> - <property name="step_increment">1</property> - <property name="page_increment">10</property> - </object> - <object class="GtkAdjustment" id="adjustment5"> - <property name="upper">65535</property> - <property name="step_increment">1</property> - <property name="page_increment">10</property> - </object> - <object class="GtkListStore" id="model1"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">a</col> - </row> - <row> - <col id="0" translatable="yes">b</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model2"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">a</col> - </row> - <row> - <col id="0" translatable="yes">b</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model3"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Attachment</col> - </row> - <row> - <col id="0" translatable="yes">Inline (Outlook style)</col> - </row> - <row> - <col id="0" translatable="yes">Quoted</col> - </row> - <row> - <col id="0" translatable="yes">Do not quote</col> - </row> - </data> - </object> - <object class="GtkListStore" id="model4"> - <columns> - <!-- column-name gchararray --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Attachment</col> - </row> - <row> - <col id="0" translatable="yes">Inline</col> - </row> - <row> - <col id="0" translatable="yes">Quoted</col> - </row> - </data> - </object> - <object class="GtkListStore" id="hash_algo_model"> - <columns> - <!-- column-name Hash --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">Default</col> - </row> - <row> - <col id="0" translatable="yes">SHA1</col> - </row> - <row> - <col id="0" translatable="yes">SHA256</col> - </row> - <row> - <col id="0" translatable="yes">SHA384</col> - </row> - <row> - <col id="0" translatable="yes">SHA512</col> - </row> - </data> - </object> - <object class="GtkVBox" id="vboxIdentityBorder"> - <property name="visible">True</property> + <requires lib="gtk+" version="2.16"/> + <object class="GtkDialog" id="add-custom-junk-header"> + <property name="width_request">400</property> + <property name="can_focus">False</property> <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child> - <object class="GtkVBox" id="management-section"> + <property name="title" translatable="yes">Set custom junk header</property> + <property name="resizable">False</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="inner-vbox"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="management-header"> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="junk_header_hbutton_box"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Account Information</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="junk-header-cancel"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="junk-header-ok"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkAlignment" id="management-alignment"> + <object class="GtkLabel" id="junk_header_info"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">All new emails with header that matches given content will be automatically filtered as junk</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkTable" id="junk_header_table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">2</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> <child> - <object class="GtkTable" id="management-table"> + <object class="GtkLabel" id="junk_header_label1"> <property name="visible">True</property> - <property name="column_spacing">6</property> - <property name="row_spacing">2</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Header name</property> + <property name="mnemonic_widget">junk-header-name</property> + </object> + <packing> + <property name="x_options">GTK_SHRINK</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="junk_header_label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Header content</property> + <property name="mnemonic_widget">junk-header-content</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_SHRINK</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="junk-header-name"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="junk-header-content"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-6">junk-header-cancel</action-widget> + <action-widget response="-3">junk-header-ok</action-widget> + </action-widgets> + </object> + <object class="GtkDialog" id="add_script_signature"> + <property name="can_focus">False</property> + <property name="type_hint">normal</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button_add_script_add"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <child> - <object class="GtkVBox" id="account_vbox"> + <object class="GtkAlignment" id="alignment30"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="management_description_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Type the name by which you would like to refer to this account. -For example: "Work" or "Personal"</property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xscale">0</property> + <property name="yscale">0</property> <child> - <object class="GtkHBox" id="hboxIdentityName"> + <object class="GtkHBox" id="hbox221"> <property name="visible">True</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> <child> - <object class="GtkLabel" id="management_name_label"> + <object class="GtkImage" id="image5"> <property name="visible">True</property> - <property name="label" translatable="yes">_Name:</property> - <property name="use_underline">True</property> - <property name="justify">right</property> - <property name="mnemonic_widget">management_name</property> + <property name="can_focus">False</property> + <property name="stock">gtk-add</property> </object> <packing> <property name="expand">False</property> @@ -190,609 +188,276 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkEntry" id="management_name"> + <object class="GtkLabel" id="label547"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Add Signature</property> + <property name="use_underline">True</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> </child> </object> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="identity-required-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="identity-required-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Required Information</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="identity-required-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> <child> - <object class="GtkTable" id="identity-required-table"> + <object class="GtkButton" id="button_add_script_cancel"> + <property name="label">gtk-cancel</property> <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkEntry" id="identity_address"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <accessibility> - <relation type="labelled-by" target="identity_address_label"/> - <relation type="labelled-by" target="identity-required-header"/> - </accessibility> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="identity_address_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Email _Address:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">identity_address</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="identity_full_name_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Full Nam_e:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">identity_full_name</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="identity_full_name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <accessibility> - <relation type="labelled-by" target="identity-required-header"/> - <relation type="labelled-by" target="identity_full_name_label"/> - </accessibility> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_stock">True</property> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> </child> </object> <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="identity-optional-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="identity-optional-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Optional Information</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkAlignment" id="identity-optional-alignment"> + <object class="GtkVBox" id="vbox160"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> <child> - <object class="GtkTable" id="identity-optional-table"> + <object class="GtkVBox" id="vbox_add_script_signature"> <property name="visible">True</property> - <property name="n_rows">4</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="sigLabel"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Signat_ure:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">signature_dropdown</property> - </object> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">6</property> <child> - <object class="GtkHBox" id="hbox169"> + <object class="GtkHBox" id="hboxImageAndHelp"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkComboBox" id="signature_dropdown"> + <object class="GtkImage" id="pixmap1"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="yalign">0</property> + <property name="stock">gtk-dialog-info</property> + <property name="icon-size">6</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkButton" id="sigAddNew"> - <property name="label" translatable="yes">Add Ne_w Signature...</property> + <object class="GtkLabel" id="label456"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="sigAddNewClicked"/> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">The output of this script will be used as your +signature. The name you specify will be used +for display purposes only. </property> + <property name="wrap">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="pack_type">end</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="identity_organization"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <accessibility> - <relation type="labelled-by" target="identity_organization_label"/> - <relation type="labelled-by" target="identity-optional-header"/> - </accessibility> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="identity_organization_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Or_ganization:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">identity_organization</property> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="identity_reply_to"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <accessibility> - <relation type="labelled-by" target="identity-optional-header"/> - <relation type="labelled-by" target="reply_to_label"/> - </accessibility> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="reply_to_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Re_ply-To:</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">identity_reply_to</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkCheckButton" id="management_default"> - <property name="label" translatable="yes">_Make this my default account</property> + <object class="GtkTable" id="tblNameScript"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="label459"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Name:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + <property name="mnemonic_widget">entry_add_script_name</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label460"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Script:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + <property name="mnemonic_widget">filechooserbutton_add_script</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_add_script_name"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkFileChooserButton" id="filechooserbutton_add_script"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="title" translatable="yes"></property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> </object> <packing> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> </child> + <action-widgets> + <action-widget response="0">button_add_script_add</action-widget> + <action-widget response="0">button_add_script_cancel</action-widget> + </action-widgets> </object> - <object class="GtkVBox" id="vboxSourceBorder"> + <object class="GtkAdjustment" id="adjustment1"> + <property name="upper">10</property> + <property name="value">1.5</property> + <property name="step_increment">1</property> + <property name="page_increment">1</property> + </object> + <object class="GtkAdjustment" id="adjustment2"> + <property name="upper">30000</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment3"> + <property name="lower">1</property> + <property name="upper">100</property> + <property name="value">5</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment4"> + <property name="upper">65535</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment5"> + <property name="upper">65535</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkNotebook" id="composer_toplevel"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child> - <object class="GtkTable" id="source-type-table"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">3</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="source_type_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Server _Type:</property> - <property name="use_underline">True</property> - <property name="justify">right</property> - <property name="mnemonic_widget">source_type_dropdown</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label442"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">Description:</property> - <property name="justify">center</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="source_description"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">description</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="source_type_dropdown"> - <property name="visible">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHSeparator" id="source-separator"> - <property name="visible">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> + <property name="can_focus">True</property> <child> - <object class="GtkVBox" id="source-config-section"> + <object class="GtkVBox" id="vboxComposerGeneral"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> <property name="spacing">6</property> <child> - <object class="GtkLabel" id="source-config-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Configuration</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="source-config-alignment"> + <object class="GtkVBox" id="default-behavior-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkTable" id="source-config-table"> + <object class="GtkLabel" id="default-behavior-header"> <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="source_host_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Server:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">source_host</property> - </object> - <packing> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="left_attach">0</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="source_port_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label">_Port:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">source_port</property> - </object> - <packing> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="left_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="source_user_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">User _Name:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">source_user</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="source_host"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="EPortEntry" type-func="e_port_entry_get_type" id="source_port"> - <property name="visible">True</property> - <property name="has-entry">True</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="top_attach">0</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="source_user"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">4</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="source_path_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Path:</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkFileChooserButton" id="source_path_entry"> - <property name="visible">True</property> - <property name="title" translatable="yes">Mailbox location</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options"></property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Default Behavior</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="source-security-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="source-security-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Security</property> - <property name="mnemonic_widget">source_auth_dropdown</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="source-security-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="source-security-vbox"> + <object class="GtkAlignment" id="default-behavior-alignment"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkHBox" id="source_ssl_hbox"> + <object class="GtkVBox" id="default-behavior-vbox"> <property name="visible">True</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="spacing">8</property> <child> - <object class="GtkLabel" id="lblSourceUseSSL"> + <object class="GtkCheckButton" id="chkSendHTML"> + <property name="label" translatable="yes">Format messages in _HTML</property> <property name="visible">True</property> - <property name="label" translatable="yes">_Use Secure Connection:</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">source_use_ssl</property> + <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> @@ -801,15 +466,14 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkComboBox" id="source_use_ssl"> + <object class="GtkCheckButton" id="chkAutoSmileys"> + <property name="label" translatable="yes">Automatically insert _emoticon images</property> <property name="visible">True</property> - <property name="model">use_ssl_model</property> - <child> - <object class="GtkCellRendererText" id="source_use_ssl_renderer"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> @@ -817,574 +481,587 @@ For example: "Work" or "Personal"</property> <property name="position">1</property> </packing> </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="source_ssl_disabled"> - <property name="visible">True</property> - <property name="spacing">6</property> <child> - <object class="GtkImage" id="image2"> + <object class="GtkCheckButton" id="chkRequestReceipt"> + <property name="label" translatable="yes">Always request rea_d receipt</property> <property name="visible">True</property> - <property name="stock">gtk-dialog-warning</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">0</property> + <property name="position">2</property> </packing> </child> <child> - <object class="GtkLabel" id="label514"> + <object class="GtkCheckButton" id="chkOutlookFilenames"> + <property name="label" translatable="yes">Encode file names in an Outlook/GMail way</property> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">SSL is not supported in this build of Evolution</property> - <property name="justify">center</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">1</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hboxComposerCharset"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="lblCharset"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">C_haracter set:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> </packing> </child> </object> - <packing> - <property name="position">1</property> - </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> </child> </object> <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="source-auth-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="source-auth-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Authentication Type</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">source_auth_dropdown</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkAlignment" id="source-auth-alignment"> + <object class="GtkVBox" id="replies-and-forwards-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkVBox" id="source-auth-vbox"> + <object class="GtkLabel" id="replies-and-forwards-label"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Replies and Forwards</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="replies-and-forwards-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkHBox" id="hbox199"> + <object class="GtkTable" id="replies-and-forwards-table"> <property name="visible">True</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="n_rows">6</property> + <property name="n_columns">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> <child> - <object class="GtkComboBox" id="source_auth_dropdown"> + <object class="GtkLabel" id="lblReplyStyle"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Reply style:</property> + <property name="use_underline">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkButton" id="source_check_supported"> - <property name="label" translatable="yes">Ch_eck for Supported Types</property> + <object class="GtkLabel" id="lblForwardStyle"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Forward style:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chkReplyStartBottom"> + <property name="label" translatable="yes">Start _typing at the bottom on replying</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chkTopSignature"> + <property name="label" translatable="yes">_Keep signature above the original message on replying</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chkIgnoreListReplyTo"> + <property name="label" translatable="yes">Ignore Reply-To: for mailing lists</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chkGroupReplyToList"> + <property name="label" translatable="yes">Group Reply goes only to mailing list, if possible</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">2</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="reply-style-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xscale">0</property> + <child> + <object class="GtkComboBox" id="comboboxReplyStyle"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">model3</property> + <child> + <object class="GtkCellRendererText" id="renderer3"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="forward-style-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xscale">0</property> + <child> + <object class="GtkComboBox" id="comboboxForwardStyle"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">model4</property> + <child> + <object class="GtkCellRendererText" id="renderer4"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> </packing> </child> </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="source_remember_password"> - <property name="label" translatable="yes">Re_member password</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> - </packing> </child> - </object> - <object class="GtkVBox" id="vboxTransportBorder"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child> - <object class="GtkTable" id="transport-type-table"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">3</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="transport_type_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">Server _Type:</property> - <property name="use_underline">True</property> - <property name="justify">right</property> - <property name="mnemonic_widget">transport_type_dropdown</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label50"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">Description:</property> - <property name="justify">right</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="transport_type_dropdown"> - <property name="visible">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="transport_description"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">description</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHSeparator" id="transport-separator"> + <child type="tab"> + <object class="GtkLabel" id="lblComposerGeneral"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">General</property> + <property name="use_underline">True</property> + <property name="justify">center</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="tab_fill">False</property> </packing> </child> <child> - <object class="GtkVBox" id="transport-server-section"> + <object class="GtkVBox" id="vboxSignatures"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> <child> - <object class="GtkLabel" id="transport-server-header"> + <object class="GtkVBox" id="signature-section"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Server Configuration</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="signature-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Sig_natures</property> + <property name="use_underline">True</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="signature-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkAlignment" id="transport-server-alignment"> + <object class="GtkVBox" id="signature-preview-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkTable" id="transport-server-table"> + <object class="GtkLabel" id="signature-preview-header"> <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="transport_host_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Server:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">transport_host</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="transport_port_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Port:</property> - <property name="use_underline">True</property> - <property name="justify">right</property> - <property name="mnemonic_widget">transport_port</property> - </object> - <packing> - <property name="left-attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="transport_host"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="EPortEntry" type-func="e_port_entry_get_type" id="transport_port"> - <property name="visible">True</property> - <property name="has-entry">True</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Preview</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="signature-preview-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkCheckButton" id="transport_needs_auth"> - <property name="label" translatable="yes">Ser_ver requires authentication</property> + <object class="GtkScrolledWindow" id="signature-preview-scrolled-window"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="shadow_type">in</property> + <child> + <placeholder/> + </child> </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - </packing> </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> + <property name="position">1</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="lblSignatures"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Signatures</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + </object> + <packing> + <property name="position">1</property> + <property name="tab_fill">False</property> </packing> </child> <child> - <object class="GtkVBox" id="transport-security-section"> + <object class="GtkVBox" id="vboxSpellChecking"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="transport-security-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Security</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> <child> - <object class="GtkAlignment" id="transport-security-alignment"> + <object class="GtkVBox" id="languages-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkTable" id="transport-security-table"> + <object class="GtkLabel" id="languages-header"> <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="row_spacing">6</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Languages</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">listSpellCheckLanguage</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="languages-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkHBox" id="transport_ssl_disabled"> + <object class="GtkTable" id="languages-table"> <property name="visible">True</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> <child> - <object class="GtkImage" id="image1"> + <object class="GtkImage" id="pixmapSpellInfo"> <property name="visible">True</property> - <property name="stock">gtk-dialog-warning</property> + <property name="can_focus">False</property> + <property name="yalign">0</property> + <property name="stock">gtk-dialog-info</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options"></property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkLabel" id="transport_ssl_disabled_label"> + <object class="GtkLabel" id="languages-label"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> - <property name="label" translatable="yes">SSL is not supported in this build of Evolution</property> - <property name="justify">center</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="transport_ssl_hbox"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="lblTransportUseSSL"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Use Secure Connection:</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">transport_use_ssl</property> + <property name="label" translatable="yes">The list of languages here reflects only the languages for which you have a dictionary installed.</property> + <property name="wrap">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkComboBox" id="transport_use_ssl"> + <object class="GtkScrolledWindow" id="languages-scrolled-window"> <property name="visible">True</property> - <property name="model">use_ssl_model</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> <child> - <object class="GtkCellRendererText" id="transport_use_ssl_renderer"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> + <object class="GtkTreeView" id="listSpellCheckLanguage"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <child internal-child="accessible"> + <object class="AtkObject" id="listSpellCheckLanguage-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Languages Table</property> + </object> + </child> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection3"/> + </child> + </object> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="right_attach">2</property> </packing> </child> </object> </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> </object> <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="transport-auth-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="transport-auth-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Authentication</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkAlignment" id="transport-auth-alignment"> + <object class="GtkVBox" id="spell-options-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkTable" id="transport-auth-table"> + <object class="GtkLabel" id="spell-options-header"> <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="transport_auth_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">T_ype:</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">transport_auth_dropdown</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="transport_user_label"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">User _Name:</property> - <property name="use_underline">True</property> - <property name="justify">right</property> - <property name="mnemonic_widget">transport_user</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="transport_user"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="transport_remember_password"> - <property name="label" translatable="yes">Remember _password</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Options</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="spell-options-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkAlignment" id="alignment1"> + <object class="GtkVBox" id="spell-options-vbox"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xscale">0</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkHBox" id="hbox195"> + <object class="GtkCheckButton" id="chkEnableSpellChecking"> + <property name="label" translatable="yes">Check spelling while I _type</property> <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hboxSpellCheckColor"> + <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkComboBox" id="transport_auth_dropdown"> + <object class="GtkLabel" id="lblSpellCheckColor"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Color for _misspelled words:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + <property name="mnemonic_widget">colorButtonSpellCheckColor</property> </object> <packing> <property name="expand">False</property> @@ -1393,12 +1070,13 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkButton" id="transport_check_supported"> - <property name="label" translatable="yes">Ch_eck for Supported Types</property> + <object class="GtkColorButton" id="colorButtonSpellCheckColor"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <property name="use_underline">True</property> + <property name="use_action_appearance">False</property> + <property name="title" translatable="yes">Pick a color</property> + <property name="color">#000000000000</property> </object> <packing> <property name="expand">False</property> @@ -1407,49 +1085,59 @@ For example: "Work" or "Personal"</property> </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> </child> </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - </packing> - </child> - <child> - <placeholder/> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> + <property name="position">2</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="lblSpellChecking"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Spell Checking</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + </object> + <packing> + <property name="position">2</property> + <property name="tab_fill">False</property> </packing> </child> - </object> - <object class="GtkVBox" id="vboxFoldersBorder"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> <child> - <object class="GtkVBox" id="special-folders-section"> + <object class="GtkVBox" id="confirmation-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> <child> - <object class="GtkLabel" id="special-folders-header"> + <object class="GtkLabel" id="confirmation-label"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> - <property name="label" translatable="yes">Special Folders</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> + <property name="label" translatable="yes">To help avoid email accidents and embarrassments, ask for confirmation before taking the following checkmarked actions:</property> + <property name="wrap">True</property> </object> <packing> <property name="expand">False</property> @@ -1458,1007 +1146,646 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkAlignment" id="special-folders-alignment"> + <object class="GtkAlignment" id="confirmation-alignment"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xscale">0</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> - <object class="GtkTable" id="special-folders-table"> + <object class="GtkVBox" id="confirmation-vbox"> <property name="visible">True</property> - <property name="n_rows">5</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="drafts_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Drafts _Folder:</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="sent_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Sent _Messages Folder:</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkCheckButton" id="trash_folder_check"> - <property name="label" translatable="yes">_Trash Folder:</property> + <object class="GtkCheckButton" id="chkPromptEmptySubject"> + <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a message with an _empty subject line</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkCheckButton" id="junk_folder_check"> - <property name="label" translatable="yes">_Junk Folder:</property> + <object class="GtkCheckButton" id="chkPromptBccOnly"> + <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a message with only _Bcc recipients defined</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="revert-button-alignment"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xscale">0</property> - <child> - <object class="GtkButton" id="default_folders_button"> - <property name="label">gtk-revert-to-saved</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> - </object> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - </packing> - </child> - <child> - <object class="EMFolderSelectionButton" id="drafts_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - </packing> - </child> - <child> - <object class="EMFolderSelectionButton" id="sent_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> <child> - <object class="EMFolderSelectionButton" id="trash_folder_butt"> + <object class="GtkCheckButton" id="chkPromptPrivateListReply"> + <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a _private reply to a mailing list message</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> </packing> </child> <child> - <object class="EMFolderSelectionButton" id="junk_folder_butt"> + <object class="GtkCheckButton" id="chkPromptReplyManyRecips"> + <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a reply to a large _number of recipients</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="composing-messages-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="composing-messages-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Composing Messages</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="composing-messages-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkTable" id="composing-messages-table"> - <property name="visible">True</property> - <property name="n_rows">4</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkAlignment" id="always-bcc-alignment"> - <property name="visible">True</property> - <property name="left_padding">18</property> - <child> - <object class="GtkEntry" id="bcc_addrs"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - </child> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> </packing> </child> <child> - <object class="GtkCheckButton" id="always_bcc"> - <property name="label" translatable="yes">Always _blind carbon-copy (bcc) to:</property> + <object class="GtkCheckButton" id="chkPromptListReplyTo"> + <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Allowing a _mailing list to redirect a private reply to the list</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="always-cc-alignment"> - <property name="visible">True</property> - <property name="left_padding">18</property> - <child> - <object class="GtkEntry" id="cc_addrs"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - </child> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> </packing> </child> <child> - <object class="GtkCheckButton" id="always_cc"> - <property name="label" translatable="yes">Alway_s carbon-copy (cc) to:</property> + <object class="GtkCheckButton" id="chkPromptSendInvalidRecip"> + <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a message with _recipients not entered as mail addresses</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">5</property> + </packing> </child> </object> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="position">3</property> </packing> </child> - <child> - <object class="GtkVBox" id="message-receipts-section"> + <child type="tab"> + <object class="GtkLabel" id="lblConfirmation"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="message-receipts-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Message Receipts</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="message-receipts-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkHBox" id="message-receipts-hbox"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="label583"> - <property name="visible">True</property> - <property name="label" translatable="yes">S_end message receipts:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">receipt_policy_dropdown</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="receipt_policy_dropdown"> - <property name="visible">True</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Confirmations</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> + <property name="position">3</property> + <property name="tab_fill">False</property> </packing> </child> </object> - <object class="GtkVBox" id="vboxSecurityBorder"> + <object class="GtkListStore" id="hash_algo_model"> + <columns> + <!-- column-name Hash --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Default</col> + </row> + <row> + <col id="0" translatable="yes">SHA1</col> + </row> + <row> + <col id="0" translatable="yes">SHA256</col> + </row> + <row> + <col id="0" translatable="yes">SHA384</col> + </row> + <row> + <col id="0" translatable="yes">SHA512</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model1"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">a</col> + </row> + <row> + <col id="0" translatable="yes">b</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model2"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">a</col> + </row> + <row> + <col id="0" translatable="yes">b</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model3"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Attachment</col> + </row> + <row> + <col id="0" translatable="yes">Inline (Outlook style)</col> + </row> + <row> + <col id="0" translatable="yes">Quoted</col> + </row> + <row> + <col id="0" translatable="yes">Do not quote</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model4"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Attachment</col> + </row> + <row> + <col id="0" translatable="yes">Inline</col> + </row> + <row> + <col id="0" translatable="yes">Quoted</col> + </row> + </data> + </object> + <object class="GtkNotebook" id="network_preferences_toplevel"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="can_focus">True</property> <child> - <object class="GtkVBox" id="security-general-section"> + <object class="GtkVBox" id="vboxNetworkGeneral"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="security-general-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">General</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> <child> - <object class="GtkAlignment" id="security-general-alignment"> + <object class="GtkVBox" id="proxy-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkCheckButton" id="pgp_no_imip_sign"> - <property name="label" translatable="yes">_Do not sign meeting requests (for Outlook compatibility)</property> + <object class="GtkLabel" id="proxy-header"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Proxy Settings</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="pgp-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="pgp-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Pretty Good Privacy (PGP/GPG)</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="pgp-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> <child> - <object class="GtkTable" id="pgp-table"> + <object class="GtkAlignment" id="proxy-alignment"> <property name="visible">True</property> - <property name="column_spacing">6</property> - <property name="row_spacing">2</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="vboxPGP"> + <object class="GtkVBox" id="proxy-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkHBox" id="hbox63"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="pgp_key_id_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">PGP/GPG _Key ID:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">pgp_key</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="pgp_key"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox4"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="pgp_hash_algo_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Si_gning algorithm:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">pgp_hash_algo</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="pgp_hash_algo"> - <property name="visible">True</property> - <property name="model">hash_algo_model</property> - <child> - <object class="GtkCellRendererText" id="pgp_hash_algo_renderer"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="pgp_always_sign"> - <property name="label" translatable="yes">Al_ways sign outgoing messages when using this account</property> + <object class="GtkRadioButton" id="rdoSysSettings"> + <property name="label" translatable="yes">_Use system defaults</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> + <property name="active">True</property> <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">2</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkCheckButton" id="pgp_encrypt_to_self"> - <property name="label" translatable="yes">Always encrypt to _myself when sending encrypted messages</property> + <object class="GtkRadioButton" id="rdoNoProxy"> + <property name="label" translatable="yes">_Direct connection to the Internet</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> - <property name="active">True</property> <property name="draw_indicator">True</property> + <property name="group">rdoSysSettings</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">3</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkCheckButton" id="pgp_always_trust"> - <property name="label" translatable="yes">Always _trust keys in my keyring when encrypting</property> + <object class="GtkRadioButton" id="rdoManualProxy"> + <property name="label" translatable="yes">_Manual proxy configuration:</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> + <property name="group">rdoSysSettings</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">4</property> + <property name="position">2</property> </packing> </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="smime-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="smime-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Secure MIME (S/MIME)</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="smime-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <object class="GtkTable" id="smime_table"> - <property name="visible">True</property> - <property name="n_rows">7</property> - <property name="n_columns">3</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkEntry" id="smime_sign_key"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="smime_encrypt_key"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">6</property> - <property name="bottom_attach">7</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="smime_encrypt_to_self"> - <property name="label" translatable="yes">Also encrypt to sel_f when sending encrypted messages</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="right_attach">3</property> - <property name="top_attach">5</property> - <property name="bottom_attach">6</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="smime_encrypt_default"> - <property name="label" translatable="yes">Encrypt out_going messages (by default)</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="right_attach">3</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="smime_sign_default"> - <property name="label" translatable="yes">Digitally sign o_utgoing messages (by default)</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkHSeparator" id="hseparator1"> - <property name="visible">True</property> - </object> - <packing> - <property name="right_attach">3</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - <property name="y_padding">6</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Encry_ption certificate:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">smime_encrypt_key</property> - </object> - <packing> - <property name="top_attach">6</property> - <property name="bottom_attach">7</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label469"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Sig_ning certificate:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">smime_sign_key</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox208"> - <property name="visible">True</property> - <property name="spacing">6</property> <child> - <object class="GtkButton" id="smime_encrypt_key_select"> + <object class="GtkAlignment" id="alignment27"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> + <property name="can_focus">False</property> + <property name="left_padding">24</property> <child> - <object class="GtkAlignment" id="alignment28"> + <object class="GtkVBox" id="vbox18"> <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkHBox" id="hbox1"> + <object class="GtkTable" id="table9"> <property name="visible">True</property> - <property name="spacing">2</property> + <property name="can_focus">False</property> + <property name="n_rows">4</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> <child> - <object class="GtkImage" id="image3"> + <object class="GtkLabel" id="lblHttpHost"> <property name="visible">True</property> - <property name="stock">gtk-open</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">H_TTP Proxy:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">txtHttpHost</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkLabel" id="button98"> + <object class="GtkLabel" id="lblHttpsHost"> <property name="visible">True</property> - <property name="label" translatable="yes">S_elect...</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Secure HTTP Proxy:</property> <property name="use_underline">True</property> + <property name="mnemonic_widget">txtHttpsHost</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="smime_encrypt_key_clear"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <child> - <object class="GtkAlignment" id="alignment35"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox230"> - <property name="visible">True</property> - <property name="spacing">2</property> <child> - <object class="GtkImage" id="image10"> + <object class="GtkLabel" id="lblIgnoreHosts"> <property name="visible">True</property> - <property name="stock">gtk-clear</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">No _Proxy for:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">txtIgnoreHosts</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkLabel" id="label577"> + <object class="GtkEntry" id="txtHttpHost"> <property name="visible">True</property> - <property name="label" translatable="yes">Clea_r</property> - <property name="use_underline">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="txtHttpsHost"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="lblHttpPort"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Port:</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="lblHttpsPort"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Port:</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spnHttpPort"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + <property name="adjustment">adjustment4</property> + <property name="climb_rate">1</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spnHttpsPort"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + <property name="adjustment">adjustment5</property> + <property name="climb_rate">1</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> </packing> </child> + <child> + <object class="GtkEntry" id="txtIgnoreHosts"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">4</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">6</property> - <property name="bottom_attach">7</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="smime_hash_algo_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Signing _algorithm:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">smime_hash_algo</property> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="smime_hash_algo_alignment"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xscale">0</property> - <child> - <object class="GtkComboBox" id="smime_hash_algo"> - <property name="visible">True</property> - <property name="model">hash_algo_model</property> - <child> - <object class="GtkCellRendererText" id="smime_hash_algo_renderer"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment4"> - <property name="visible">True</property> - <property name="yalign">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox209"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkButton" id="smime_sign_key_select"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> <child> - <object class="GtkAlignment" id="alignment29"> + <object class="GtkCheckButton" id="chkUseAuth"> + <property name="label" translatable="yes">Use Authe_ntication</property> <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment26"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">24</property> <child> - <object class="GtkHBox" id="hbox2"> + <object class="GtkTable" id="table11"> <property name="visible">True</property> - <property name="spacing">2</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">3</property> <child> - <object class="GtkImage" id="image4"> + <object class="GtkLabel" id="lblAuthUser"> <property name="visible">True</property> - <property name="stock">gtk-open</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Us_ername:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">txtAuthUser</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkLabel" id="label2"> + <object class="GtkLabel" id="lblAuthPwd"> <property name="visible">True</property> - <property name="label" translatable="yes">_Select...</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Pass_word:</property> <property name="use_underline">True</property> + <property name="mnemonic_widget">txtAuthPwd</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="smime_sign_key_clear"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <child> - <object class="GtkAlignment" id="alignment34"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox229"> - <property name="visible">True</property> - <property name="spacing">2</property> <child> - <object class="GtkImage" id="image9"> + <object class="GtkEntry" id="txtAuthUser"> <property name="visible">True</property> - <property name="stock">gtk-clear</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options">GTK_FILL</property> </packing> </child> <child> - <object class="GtkLabel" id="label576"> + <object class="GtkEntry" id="txtAuthPwd"> <property name="visible">True</property> - <property name="label" translatable="yes">Cle_ar</property> - <property name="use_underline">True</property> + <property name="can_focus">True</property> + <property name="visibility">False</property> + <property name="invisible_char">â—</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> </packing> </child> </object> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> </child> </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">3</property> - </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="proxy-padding"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <placeholder/> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> + </child> + <child type="tab"> + <object class="GtkLabel" id="lblNetworkGeneral"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">General</property> + </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> + <property name="tab_fill">False</property> </packing> </child> </object> - <object class="GtkListStore" id="use_ssl_model"> - <columns> - <!-- column-name Label --> - <column type="gchararray"/> - <!-- column-name Value --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">No encryption</col> - <col id="1">never</col> - </row> - <row> - <col id="0" translatable="yes">TLS encryption</col> - <col id="1">when-possible</col> - </row> - <row> - <col id="0" translatable="yes">SSL encryption</col> - <col id="1">always</col> - </row> - </data> - </object> <object class="GtkNotebook" id="preferences_toplevel"> <property name="visible">True</property> <property name="can_focus">True</property> @@ -2466,17 +1793,18 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="vboxMailGeneral"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">12</property> - <property name="orientation">vertical</property> <property name="spacing">12</property> <child> <object class="GtkVBox" id="start-up-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="start-up-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Start up</property> <attributes> @@ -2492,15 +1820,17 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="start-up-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkVBox" id="start-up-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkHBox" id="start-up-hbox1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">4</property> <child> <object class="GtkCheckButton" id="chkCheckMailOnStart"> @@ -2508,6 +1838,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -2527,6 +1858,7 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkHBox" id="start-up-hbox2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">4</property> <child> <object class="GtkCheckButton" id="chkCheckMailInAllOnStart"> @@ -2534,6 +1866,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -2569,11 +1902,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="message-display-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="message-display-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Message Display</property> <attributes> @@ -2589,11 +1923,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="message-display-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkVBox" id="message-display-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="radFontUseSame"> @@ -2601,6 +1936,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -2613,10 +1949,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="custom-font-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">24</property> <child> <object class="GtkTable" id="tblScreen"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">2</property> <property name="n_columns">2</property> <property name="column_spacing">6</property> @@ -2624,6 +1962,7 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkLabel" id="lblScreenVariable"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">1</property> <property name="label" translatable="yes">S_tandard Font:</property> <property name="use_underline">True</property> @@ -2640,8 +1979,9 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <property name="title" translatable="yes">Select HTML fixed width font</property> - <signal name="font_set" handler="changed"/> + <signal name="font-set" handler="changed" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -2657,8 +1997,9 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <property name="title" translatable="yes">Select HTML variable width font</property> - <signal name="font_set" handler="changed"/> + <signal name="font-set" handler="changed" swapped="no"/> </object> <packing> <property name="left_attach">1</property> @@ -2670,6 +2011,7 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkLabel" id="label444"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">1</property> <property name="label" translatable="yes">Fix_ed Width Font:</property> <property name="use_underline">True</property> @@ -2687,12 +2029,15 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkHBox" id="hboxHighlightColor"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="chkHighlightCitations"> @@ -2700,6 +2045,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="active">True</property> <property name="draw_indicator">True</property> @@ -2715,6 +2061,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <property name="title" translatable="yes">Pick a color</property> <property name="color">#000000000000</property> </object> @@ -2727,6 +2074,7 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkLabel" id="lblColor"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">color</property> <property name="justify">center</property> </object> @@ -2738,16 +2086,20 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkHBox" id="hboxDefaultCharset"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="lblDefaultCharset"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Default character e_ncoding:</property> <property name="use_underline">True</property> <property name="justify">center</property> @@ -2763,6 +2115,8 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">3</property> </packing> </child> @@ -2772,10 +2126,13 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">4</property> </packing> </child> @@ -2785,10 +2142,13 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">5</property> </packing> </child> @@ -2796,6 +2156,8 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2809,11 +2171,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="delete-mail-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="delete-mail-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Delete Mail</property> <attributes> @@ -2829,15 +2192,17 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="delete-mail-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkVBox" id="delete-mail-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkHBox" id="hbox220"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">4</property> <child> <object class="GtkCheckButton" id="chkEmptyTrashOnExit"> @@ -2845,6 +2210,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -2857,6 +2223,7 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkComboBox" id="comboboxEmptyTrashDays"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="model">model1</property> <child> <object class="GtkCellRendererText" id="renderer1"/> @@ -2884,6 +2251,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -2897,6 +2265,8 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -2915,6 +2285,7 @@ For example: "Work" or "Personal"</property> <child type="tab"> <object class="GtkLabel" id="lblMailGeneral"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">General</property> <property name="use_underline">True</property> <property name="justify">center</property> @@ -2926,17 +2297,18 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="vboxHtmlMail"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">12</property> - <property name="orientation">vertical</property> <property name="spacing">12</property> <child> <object class="GtkVBox" id="html-general-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="html-general-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">General</property> <attributes> @@ -2952,11 +2324,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="html-general-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkVBox" id="html-general-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="chkShowAnimatedImages"> @@ -2964,6 +2337,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -2979,6 +2353,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -3007,11 +2382,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="loading-images-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="loading-images-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Loading Images</property> <attributes> @@ -3027,11 +2403,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="loading-images-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkVBox" id="loading-images-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkRadioButton" id="radImagesNever"> @@ -3039,6 +2416,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="active">True</property> <property name="draw_indicator">True</property> @@ -3055,6 +2433,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="active">True</property> <property name="draw_indicator">True</property> @@ -3072,6 +2451,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="active">True</property> <property name="draw_indicator">True</property> @@ -3087,9 +2467,9 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> - <property name="position">1</property> <property name="expand">False</property> <property name="fill">False</property> + <property name="position">1</property> </packing> </child> </object> @@ -3108,6 +2488,7 @@ For example: "Work" or "Personal"</property> <child type="tab"> <object class="GtkLabel" id="lblHtmlMail"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">HTML Messages</property> <property name="use_underline">True</property> <property name="justify">center</property> @@ -3120,12 +2501,13 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="frameColours"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">12</property> - <property name="orientation">vertical</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="labels-section"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Labels</property> <attributes> @@ -3141,12 +2523,15 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="labels-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <placeholder/> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -3158,6 +2543,7 @@ For example: "Work" or "Personal"</property> <child type="tab"> <object class="GtkLabel" id="lblColours"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Labels</property> <property name="use_underline">True</property> <property name="justify">center</property> @@ -3170,17 +2556,18 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="vboxHeaderTab"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">12</property> - <property name="orientation">vertical</property> <property name="spacing">12</property> <child> <object class="GtkVBox" id="photograph-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="photograph-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Sender Photograph</property> <attributes> @@ -3196,11 +2583,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="photograph-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkVBox" id="photograph-vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="photo_show"> @@ -3208,6 +2596,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -3223,6 +2612,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> @@ -3251,11 +2641,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="message-headers-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="message-headers-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Displayed Message Headers</property> <property name="use_underline">True</property> @@ -3273,21 +2664,23 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="message-headers-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkHBox" id="message-headers-hbox"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkVBox" id="vbox199"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">12</property> <child> <object class="GtkEntry" id="txtHeaders"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> + <property name="invisible_char">â—</property> </object> <packing> <property name="expand">False</property> @@ -3299,8 +2692,6 @@ For example: "Work" or "Personal"</property> <object class="GtkScrolledWindow" id="scrolledwindow49"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> <property name="shadow_type">in</property> <child> <object class="GtkTreeView" id="treeHeaders"> @@ -3312,24 +2703,29 @@ For example: "Work" or "Personal"</property> <property name="AtkObject::accessible-name" translatable="yes">Mail Headers Table</property> </object> </child> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> </object> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="position">0</property> <property name="expand">True</property> <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> <object class="GtkVBox" id="vbox200"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkButton" id="cmdHeadersAdd"> @@ -3338,6 +2734,7 @@ For example: "Work" or "Personal"</property> <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <property name="use_stock">True</property> </object> <packing> @@ -3352,6 +2749,7 @@ For example: "Work" or "Personal"</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <property name="use_stock">True</property> </object> <packing> @@ -3371,6 +2769,8 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -3384,11 +2784,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkVBox" id="datetime-format-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> <object class="GtkLabel" id="datetime-format-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="label" translatable="yes">Date/Time Format</property> <property name="use_underline">True</property> @@ -3406,10 +2807,12 @@ For example: "Work" or "Personal"</property> <child> <object class="GtkAlignment" id="datetime-format-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> <object class="GtkTable" id="datetime-format-table"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_columns">3</property> <child> <placeholder/> @@ -3424,9 +2827,9 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> - <property name="position">1</property> <property name="expand">False</property> <property name="fill">False</property> + <property name="position">1</property> </packing> </child> </object> @@ -3445,6 +2848,7 @@ For example: "Work" or "Personal"</property> <child type="tab"> <object class="GtkLabel" id="lblHeaders"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Headers</property> <property name="use_underline">True</property> </object> @@ -3454,236 +2858,272 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkVBox" id="vboxJunk"> + <object class="GtkAlignment" id="junk-alignment"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="yalign">0</property> + <property name="yscale">0</property> <child> - <object class="GtkVBox" id="junk-general-section"> + <object class="GtkVBox" id="vboxJunk"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="junk-general-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">General</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="resize_mode">immediate</property> + <property name="spacing">12</property> <child> - <object class="GtkAlignment" id="junk-general-alignment"> + <object class="GtkVBox" id="junk-general-section"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkTable" id="junk-general-table"> + <object class="GtkLabel" id="junk-general-header"> <property name="visible">True</property> - <property name="n_rows">9</property> - <property name="row_spacing">3</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">General</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="junk-general-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkHBox" id="hbox235"> + <object class="GtkTable" id="junk-general-table"> <property name="visible">True</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="n_rows">8</property> + <property name="row_spacing">3</property> <child> - <object class="GtkLabel" id="label586"> + <object class="GtkCheckButton" id="chkCheckIncomingMail"> + <property name="label" translatable="yes">Check incoming _messages for junk</property> <property name="visible">True</property> - <property name="label" translatable="yes">_Default junk plugin:</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">default_junk_plugin</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="padding">6</property> - <property name="position">0</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + <property name="x_padding">4</property> </packing> </child> <child> - <object class="GtkComboBox" id="default_junk_plugin"> + <object class="GtkHBox" id="hbox237"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">4</property> + <child> + <object class="GtkCheckButton" id="junk_empty_check"> + <property name="label" translatable="yes">Delete junk messages on e_xit</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="junk_empty_combobox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">model2</property> + <child> + <object class="GtkCellRendererText" id="renderer2"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">4</property> </packing> </child> - </object> - <packing> - <property name="top_attach">7</property> - <property name="bottom_attach">8</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="chkCheckIncomingMail"> - <property name="label" translatable="yes">Check incoming _messages for junk</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - <property name="x_padding">4</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox236"> - <property name="visible">True</property> - <property name="spacing">3</property> <child> - <object class="GtkImage" id="plugin_image"> + <object class="GtkCheckButton" id="junk_header_check"> + <property name="label" translatable="yes">Check cu_stom headers for junk</property> <property name="visible">True</property> - <property name="icon_name">gtk-info</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + <property name="x_padding">4</property> </packing> </child> <child> - <object class="GtkLabel" id="plugin_status"> + <object class="GtkHBox" id="hbox243"> <property name="visible">True</property> - <property name="use_markup">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow51"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="junk_header_tree"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection"/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVButtonBox" id="vbuttonbox26"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <property name="layout_style">start</property> + <child> + <object class="GtkButton" id="junk_header_add"> + <property name="label">gtk-add</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="junk_header_remove"> + <property name="label">gtk-remove</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_padding">22</property> </packing> </child> - </object> - <packing> - <property name="top_attach">8</property> - <property name="bottom_attach">9</property> - <property name="x_options">GTK_FILL</property> - <property name="x_padding">15</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox237"> - <property name="visible">True</property> - <property name="spacing">4</property> <child> - <object class="GtkCheckButton" id="junk_empty_check"> - <property name="label" translatable="yes">Delete junk messages on e_xit</property> + <object class="GtkCheckButton" id="lookup_book"> + <property name="label" translatable="yes">Do not mar_k messages as junk if sender is in my address book</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="junk_empty_combobox"> - <property name="visible">True</property> - <property name="model">model2</property> - <child> - <object class="GtkCellRendererText" id="renderer2"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + <property name="x_padding">4</property> </packing> </child> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="x_padding">4</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="junk_header_check"> - <property name="label" translatable="yes">Check cu_stom headers for junk</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - <property name="x_padding">4</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox243"> - <property name="visible">True</property> - <property name="spacing">6</property> <child> - <object class="GtkScrolledWindow" id="scrolledwindow51"> + <object class="GtkCheckButton" id="junk_lookup_local_only"> + <property name="label" translatable="yes">_Lookup in local address book only</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTreeView" id="junk_header_tree"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </object> - </child> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="position">0</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + <property name="x_padding">25</property> </packing> </child> <child> - <object class="GtkVButtonBox" id="vbuttonbox26"> + <object class="GtkHBox" id="hbox244"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> - <property name="layout_style">start</property> <child> - <object class="GtkButton" id="junk_header_add"> - <property name="label">gtk-add</property> + <object class="GtkImage" id="image11"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-info</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkButton" id="junk_header_remove"> - <property name="label">gtk-remove</property> + <object class="GtkLabel" id="label590"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Option is ignored if a match for custom junk headers is found.</property> </object> <packing> <property name="expand">False</property> @@ -3693,96 +3133,56 @@ For example: "Work" or "Personal"</property> </child> </object> <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_padding">22</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="lookup_book"> - <property name="label" translatable="yes">Do not mar_k messages as junk if sender is in my address book</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - <property name="x_padding">4</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="junk_lookup_local_only"> - <property name="label" translatable="yes">_Lookup in local address book only</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="top_attach">5</property> - <property name="bottom_attach">6</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - <property name="x_padding">25</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox244"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkImage" id="image11"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="x_options">GTK_FILL</property> </packing> </child> <child> - <object class="GtkLabel" id="label590"> + <object class="EMailJunkOptions" id="junk-module-options"> <property name="visible">True</property> - <property name="label" translatable="yes">Option is ignored if a match for custom junk headers is found.</property> + <property name="can_focus">False</property> + <property name="row_spacing">12</property> + <property name="column_spacing">6</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="top_attach">7</property> + <property name="bottom_attach">8</property> + <property name="y_options">GTK_FILL</property> </packing> </child> </object> - <packing> - <property name="top_attach">6</property> - <property name="bottom_attach">7</property> - <property name="x_options">GTK_FILL</property> - </packing> </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> </object> <packing> - <property name="position">1</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> </child> </object> <packing> @@ -3792,6 +3192,7 @@ For example: "Work" or "Personal"</property> <child type="tab"> <object class="GtkLabel" id="lblJunk"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Junk</property> <property name="use_underline">True</property> </object> @@ -3801,115 +3202,481 @@ For example: "Work" or "Personal"</property> </packing> </child> </object> - <object class="GtkNotebook" id="composer_toplevel"> + <object class="GtkListStore" id="use_ssl_model"> + <columns> + <!-- column-name Label --> + <column type="gchararray"/> + <!-- column-name Value --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">No encryption</col> + <col id="1">never</col> + </row> + <row> + <col id="0" translatable="yes">TLS encryption</col> + <col id="1">when-possible</col> + </row> + <row> + <col id="0" translatable="yes">SSL encryption</col> + <col id="1">always</col> + </row> + </data> + </object> + <object class="GtkVBox" id="vboxFoldersBorder"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> <child> - <object class="GtkVBox" id="vboxComposerGeneral"> + <object class="GtkVBox" id="special-folders-section"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkVBox" id="default-behavior-section"> + <object class="GtkLabel" id="special-folders-header"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="default-behavior-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Default Behavior</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Special Folders</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="special-folders-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xscale">0</property> + <property name="left_padding">12</property> <child> - <object class="GtkAlignment" id="default-behavior-alignment"> + <object class="GtkTable" id="special-folders-table"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="n_rows">5</property> + <property name="n_columns">2</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> <child> - <object class="GtkVBox" id="default-behavior-vbox"> + <object class="GtkLabel" id="drafts_label"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">8</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Drafts _Folder:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="sent_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Sent _Messages Folder:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="trash_folder_check"> + <property name="label" translatable="yes">_Trash Folder:</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="junk_folder_check"> + <property name="label" translatable="yes">_Junk Folder:</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="revert-button-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xscale">0</property> <child> - <object class="GtkCheckButton" id="chkSendHTML"> - <property name="label" translatable="yes">Format messages in _HTML</property> + <object class="GtkButton" id="default_folders_button"> + <property name="label">gtk-revert-to-saved</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_stock">True</property> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + </packing> + </child> + <child> + <object class="EMFolderSelectionButton" id="drafts_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <object class="EMFolderSelectionButton" id="sent_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <object class="EMFolderSelectionButton" id="trash_folder_butt"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + </packing> + </child> + <child> + <object class="EMFolderSelectionButton" id="junk_folder_butt"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="composing-messages-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="composing-messages-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Composing Messages</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="composing-messages-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkTable" id="composing-messages-table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">4</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkAlignment" id="always-bcc-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">18</property> <child> - <object class="GtkCheckButton" id="chkAutoSmileys"> - <property name="label" translatable="yes">Automatically insert _emoticon images</property> + <object class="GtkEntry" id="bcc_addrs"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="invisible_char">â—</property> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="always_bcc"> + <property name="label" translatable="yes">Always _blind carbon-copy (bcc) to:</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="always-cc-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">18</property> <child> - <object class="GtkCheckButton" id="chkRequestReceipt"> - <property name="label" translatable="yes">Always request rea_d receipt</property> + <object class="GtkEntry" id="cc_addrs"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="invisible_char">â—</property> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> </child> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="always_cc"> + <property name="label" translatable="yes">Alway_s carbon-copy (cc) to:</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="message-receipts-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="message-receipts-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Message Receipts</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="message-receipts-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkHBox" id="message-receipts-hbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="label583"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">S_end message receipts:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">receipt_policy_dropdown</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="receipt_policy_dropdown"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + <object class="GtkVBox" id="vboxIdentityBorder"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> + <child> + <object class="GtkVBox" id="management-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="management-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Account Information</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="management-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkTable" id="management-table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="column_spacing">6</property> + <property name="row_spacing">2</property> + <child> + <object class="GtkVBox" id="account_vbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkCheckButton" id="chkOutlookFilenames"> - <property name="label" translatable="yes">Encode file names in an Outlook/GMail way</property> + <object class="GtkLabel" id="management_description_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Type the name by which you would like to refer to this account. +For example: "Work" or "Personal"</property> + <property name="use_markup">True</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkHBox" id="hboxComposerCharset"> + <object class="GtkHBox" id="hboxIdentityName"> <property name="visible">True</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> <child> - <object class="GtkLabel" id="lblCharset"> + <object class="GtkLabel" id="management_name_label"> <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">C_haracter set:</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Name:</property> <property name="use_underline">True</property> - <property name="justify">center</property> + <property name="justify">right</property> + <property name="mnemonic_widget">management_name</property> </object> <packing> <property name="expand">False</property> @@ -3918,506 +3685,978 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <placeholder/> + <object class="GtkEntry" id="management_name"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> </object> <packing> - <property name="position">4</property> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> </child> </object> - <packing> - <property name="position">1</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="identity-required-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="identity-required-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Required Information</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkVBox" id="replies-and-forwards-section"> + <object class="GtkAlignment" id="identity-required-alignment"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkLabel" id="replies-and-forwards-label"> + <object class="GtkTable" id="identity-required-table"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Replies and Forwards</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">2</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkEntry" id="identity_address"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + <accessibility> + <relation type="labelled-by" target="identity_address_label"/> + <relation type="labelled-by" target="identity-required-header"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="identity_address_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Email _Address:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">identity_address</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="identity_full_name_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Full Nam_e:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">identity_full_name</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="identity_full_name"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + <accessibility> + <relation type="labelled-by" target="identity-required-header"/> + <relation type="labelled-by" target="identity_full_name_label"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> </object> - <packing> - <property name="position">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="identity-optional-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="identity-optional-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Optional Information</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="identity-optional-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkAlignment" id="replies-and-forwards-alignment"> + <object class="GtkTable" id="identity-optional-table"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="n_rows">4</property> + <property name="n_columns">2</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> <child> - <object class="GtkTable" id="replies-and-forwards-table"> + <object class="GtkLabel" id="sigLabel"> <property name="visible">True</property> - <property name="n_rows">6</property> - <property name="n_columns">2</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Signat_ure:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">signature_dropdown</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox169"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkLabel" id="lblReplyStyle"> + <object class="GtkComboBox" id="signature_dropdown"> <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Reply style:</property> - <property name="use_underline">True</property> + <property name="can_focus">False</property> </object> <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkLabel" id="lblForwardStyle"> + <object class="GtkButton" id="sigAddNew"> + <property name="label" translatable="yes">Add Ne_w Signature...</property> <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">_Forward style:</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> + <signal name="clicked" handler="sigAddNewClicked" swapped="no"/> </object> <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="pack_type">end</property> + <property name="position">1</property> </packing> </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="identity_organization"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + <accessibility> + <relation type="labelled-by" target="identity_organization_label"/> + <relation type="labelled-by" target="identity-optional-header"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="identity_organization_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Or_ganization:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">identity_organization</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="identity_reply_to"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + <accessibility> + <relation type="labelled-by" target="identity-optional-header"/> + <relation type="labelled-by" target="reply_to_label"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="reply_to_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Re_ply-To:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + <property name="mnemonic_widget">identity_reply_to</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="management_default"> + <property name="label" translatable="yes">_Make this my default account</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + <object class="GtkVBox" id="vboxSecurityBorder"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> + <child> + <object class="GtkVBox" id="security-general-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="security-general-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">General</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="security-general-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkCheckButton" id="pgp_no_imip_sign"> + <property name="label" translatable="yes">_Do not sign meeting requests (for Outlook compatibility)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="pgp-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="pgp-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Pretty Good Privacy (PGP/GPG)</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="pgp-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkTable" id="pgp-table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="column_spacing">6</property> + <property name="row_spacing">2</property> + <child> + <object class="GtkVBox" id="vboxPGP"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkCheckButton" id="chkReplyStartBottom"> - <property name="label" translatable="yes">Start _typing at the bottom on replying</property> + <object class="GtkHBox" id="hbox63"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="pgp_key_id_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">PGP/GPG _Key ID:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">pgp_key</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="pgp_key"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkTopSignature"> - <property name="label" translatable="yes">_Keep signature above the original message on replying</property> + <object class="GtkHBox" id="hbox4"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="pgp_hash_algo_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Si_gning algorithm:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">pgp_hash_algo</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="pgp_hash_algo"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">hash_algo_model</property> + <child> + <object class="GtkCellRendererText" id="pgp_hash_algo_renderer"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> </object> <packing> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options"></property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkIgnoreListReplyTo"> - <property name="label" translatable="yes">Ignore Reply-To: for mailing lists</property> + <object class="GtkCheckButton" id="pgp_always_sign"> + <property name="label" translatable="yes">Al_ways sign outgoing messages when using this account</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> - <property name="right_attach">2</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkGroupReplyToList"> - <property name="label" translatable="yes">Group Reply goes only to mailing list, if possible</property> + <object class="GtkCheckButton" id="pgp_encrypt_to_self"> + <property name="label" translatable="yes">Always encrypt to _myself when sending encrypted messages</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> <property name="use_underline">True</property> + <property name="active">True</property> <property name="draw_indicator">True</property> </object> <packing> - <property name="right_attach">2</property> - <property name="top_attach">5</property> - <property name="bottom_attach">6</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="reply-style-alignment"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xscale">0</property> - <child> - <object class="GtkComboBox" id="comboboxReplyStyle"> - <property name="visible">True</property> - <property name="model">model3</property> - <child> - <object class="GtkCellRendererText" id="renderer3"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> </packing> </child> <child> - <object class="GtkAlignment" id="forward-style-alignment"> + <object class="GtkCheckButton" id="pgp_always_trust"> + <property name="label" translatable="yes">Always _trust keys in my keyring when encrypting</property> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="xscale">0</property> - <child> - <object class="GtkComboBox" id="comboboxForwardStyle"> - <property name="visible">True</property> - <property name="model">model4</property> - <child> - <object class="GtkCellRendererText" id="renderer4"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> </packing> </child> </object> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="lblComposerGeneral"> - <property name="visible">True</property> - <property name="label" translatable="yes">General</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - </object> <packing> - <property name="tab_fill">False</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkVBox" id="vboxSignatures"> + <object class="GtkVBox" id="smime-section"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkVBox" id="signature-section"> + <object class="GtkLabel" id="smime-header"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="signature-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Sig_natures</property> - <property name="use_underline">True</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="signature-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">1</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Secure MIME (S/MIME)</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">0</property> - <property name="expand">True</property> - <property name="fill">True</property> </packing> </child> <child> - <object class="GtkVBox" id="signature-preview-section"> + <object class="GtkAlignment" id="smime-alignment"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="signature-preview-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Preview</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkAlignment" id="signature-preview-alignment"> + <object class="GtkTable" id="smime_table"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="n_rows">7</property> + <property name="n_columns">3</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> <child> - <object class="GtkScrolledWindow" id="signature-preview-scrolled-window"> + <object class="GtkEntry" id="smime_sign_key"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <placeholder/> - </child> + <property name="invisible_char">â—</property> </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> </child> - </object> - <packing> - <property name="position">1</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="lblSignatures"> - <property name="visible">True</property> - <property name="label" translatable="yes">Signatures</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - </object> - <packing> - <property name="position">1</property> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vboxSpellChecking"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child> - <object class="GtkVBox" id="languages-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="languages-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Languages</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">listSpellCheckLanguage</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="languages-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> <child> - <object class="GtkTable" id="languages-table"> + <object class="GtkEntry" id="smime_encrypt_key"> <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkImage" id="pixmapSpellInfo"> - <property name="visible">True</property> - <property name="yalign">0</property> - <property name="stock">gtk-dialog-info</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> - </child> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="smime_encrypt_to_self"> + <property name="label" translatable="yes">Also encrypt to sel_f when sending encrypted messages</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">3</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="smime_encrypt_default"> + <property name="label" translatable="yes">Encrypt out_going messages (by default)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">3</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="smime_sign_default"> + <property name="label" translatable="yes">Digitally sign o_utgoing messages (by default)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkHSeparator" id="hseparator1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="right_attach">3</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + <property name="y_padding">6</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Encry_ption certificate:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">smime_encrypt_key</property> + </object> + <packing> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label469"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Sig_ning certificate:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">smime_sign_key</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox208"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkLabel" id="languages-label"> + <object class="GtkButton" id="smime_encrypt_key_select"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">The list of languages here reflects only the languages for which you have a dictionary installed.</property> - <property name="wrap">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <child> + <object class="GtkAlignment" id="alignment28"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> + <object class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child> + <object class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-open</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="button98"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">S_elect...</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="languages-scrolled-window"> + <object class="GtkButton" id="smime_encrypt_key_clear"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> <child> - <object class="GtkTreeView" id="listSpellCheckLanguage"> + <object class="GtkAlignment" id="alignment35"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - <child internal-child="accessible"> - <object class="AtkObject" id="listSpellCheckLanguage-atkobject"> - <property name="AtkObject::accessible-name" translatable="yes">Languages Table</property> + <property name="can_focus">False</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> + <object class="GtkHBox" id="hbox230"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child> + <object class="GtkImage" id="image10"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-clear</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label577"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Clea_r</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> </object> </child> </object> </child> </object> <packing> - <property name="right_attach">2</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> </child> - </object> - <packing> - <property name="position">1</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="spell-options-section"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="spell-options-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Options</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="spell-options-alignment"> - <property name="visible">True</property> - <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="spell-options-vbox"> + <object class="GtkLabel" id="smime_hash_algo_label"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Signing _algorithm:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">smime_hash_algo</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="smime_hash_algo_alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xscale">0</property> <child> - <object class="GtkCheckButton" id="chkEnableSpellChecking"> - <property name="label" translatable="yes">Check spelling while I _type</property> + <object class="GtkComboBox" id="smime_hash_algo"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="model">hash_algo_model</property> + <child> + <object class="GtkCellRendererText" id="smime_hash_algo_renderer"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="yalign">0</property> + <property name="yscale">0</property> <child> - <object class="GtkHBox" id="hboxSpellCheckColor"> + <object class="GtkHBox" id="hbox209"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkLabel" id="lblSpellCheckColor"> + <object class="GtkButton" id="smime_sign_key_select"> <property name="visible">True</property> - <property name="label" translatable="yes">Color for _misspelled words:</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">colorButtonSpellCheckColor</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <child> + <object class="GtkAlignment" id="alignment29"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> + <object class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child> + <object class="GtkImage" id="image4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-open</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Select...</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> </object> <packing> <property name="expand">False</property> @@ -4426,12 +4665,51 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkColorButton" id="colorButtonSpellCheckColor"> + <object class="GtkButton" id="smime_sign_key_clear"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> - <property name="title" translatable="yes">Pick a color</property> - <property name="color">#000000000000</property> + <property name="use_action_appearance">False</property> + <child> + <object class="GtkAlignment" id="alignment34"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> + <object class="GtkHBox" id="hbox229"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child> + <object class="GtkImage" id="image9"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-clear</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label576"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Cle_ar</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> </object> <packing> <property name="expand">False</property> @@ -4440,57 +4718,138 @@ For example: "Work" or "Personal"</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">3</property> + </packing> </child> </object> - <packing> - <property name="position">1</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">2</property> </packing> </child> - <child type="tab"> - <object class="GtkLabel" id="lblSpellChecking"> + </object> + <object class="GtkVBox" id="vboxSourceBorder"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> + <child> + <object class="GtkTable" id="source-type-table"> <property name="visible">True</property> - <property name="label" translatable="yes">Spell Checking</property> - <property name="use_underline">True</property> - <property name="justify">center</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">3</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="source_type_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Server _Type:</property> + <property name="use_underline">True</property> + <property name="justify">right</property> + <property name="mnemonic_widget">source_type_dropdown</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label442"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">Description:</property> + <property name="justify">center</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="source_description"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">description</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="source_type_dropdown"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> </object> <packing> - <property name="position">2</property> - <property name="tab_fill">False</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkVBox" id="confirmation-section"> + <object class="GtkHSeparator" id="source-separator"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="source-config-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkLabel" id="confirmation-label"> + <object class="GtkLabel" id="source-config-header"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> - <property name="label" translatable="yes">To help avoid email accidents and embarrassments, ask for confirmation before taking the following checkmarked actions:</property> - <property name="wrap">True</property> + <property name="label" translatable="yes">Configuration</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> <packing> <property name="expand">False</property> @@ -4499,167 +4858,217 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkAlignment" id="confirmation-alignment"> + <object class="GtkAlignment" id="source-config-alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="confirmation-vbox"> + <object class="GtkTable" id="source-config-table"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="n_rows">3</property> + <property name="n_columns">4</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> <child> - <object class="GtkCheckButton" id="chkPromptEmptySubject"> - <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a message with an _empty subject line</property> + <object class="GtkLabel" id="source_host_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Server:</property> <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="mnemonic_widget">source_host</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkPromptBccOnly"> - <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a message with only _Bcc recipients defined</property> + <object class="GtkLabel" id="source_port_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label">_Port:</property> <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="mnemonic_widget">source_port</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> + <property name="left_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkPromptPrivateListReply"> - <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a _private reply to a mailing list message</property> + <object class="GtkLabel" id="source_user_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">User _Name:</property> <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="mnemonic_widget">source_user</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> + <property name="top_attach">1</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkPromptReplyManyRecips"> - <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a reply to a large _number of recipients</property> + <object class="GtkEntry" id="source_host"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="invisible_char">â—</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> + <property name="left_attach">1</property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkPromptListReplyTo"> - <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Allowing a _mailing list to redirect a private reply to the list</property> + <object class="EPortEntry" id="source_port" type-func="e_port_entry_get_type"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="has_entry">True</property> + <child internal-child="entry"> + <object class="GtkEntry" id="port-entry-entry2"> + <property name="can_focus">False</property> + </object> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> + <property name="left_attach">3</property> + <property name="x_options"></property> + <property name="y_options"></property> </packing> </child> <child> - <object class="GtkCheckButton" id="chkPromptSendInvalidRecip"> - <property name="label" translatable="yes" comments="This is in the context of: Ask for confirmation before...">Sending a message with _recipients not entered as mail addresses</property> + <object class="GtkEntry" id="source_user"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="receives_default">False</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="source_path_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Path:</property> <property name="use_underline">True</property> - <property name="draw_indicator">True</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">5</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkFileChooserButton" id="source_path_entry"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="title" translatable="yes">Mailbox location</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> </packing> </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> - <property name="position">3</property> - </packing> - </child> - <child type="tab"> - <object class="GtkLabel" id="lblConfirmation"> - <property name="visible">True</property> - <property name="label" translatable="yes">Confirmations</property> - </object> - <packing> - <property name="position">3</property> - <property name="tab_fill">False</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> </packing> </child> - </object> - <object class="GtkDialog" id="add_script_signature"> - <property name="type_hint">normal</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox1"> + <child> + <object class="GtkVBox" id="source-security-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkVBox" id="vbox160"> + <object class="GtkLabel" id="source-security-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Security</property> + <property name="mnemonic_widget">source_auth_dropdown</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="source-security-alignment"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="vbox_add_script_signature"> + <object class="GtkVBox" id="source-security-vbox"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkHBox" id="hboxImageAndHelp"> + <object class="GtkHBox" id="source_ssl_hbox"> <property name="visible">True</property> - <property name="spacing">6</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> <child> - <object class="GtkImage" id="pixmap1"> + <object class="GtkLabel" id="lblSourceUseSSL"> <property name="visible">True</property> - <property name="yalign">0</property> - <property name="stock">gtk-dialog-info</property> - <property name="icon-size">6</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Use Secure Connection:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + <property name="mnemonic_widget">source_use_ssl</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkLabel" id="label456"> + <object class="GtkComboBox" id="source_use_ssl"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">The output of this script will be used as your -signature. The name you specify will be used -for display purposes only. </property> - <property name="wrap">True</property> + <property name="can_focus">False</property> + <property name="model">use_ssl_model</property> + <child> + <object class="GtkCellRendererText" id="source_use_ssl_renderer"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> </object> <packing> <property name="expand">False</property> @@ -4675,685 +5084,687 @@ for display purposes only. </property> </packing> </child> <child> - <object class="GtkTable" id="tblNameScript"> + <object class="GtkHBox" id="source_ssl_disabled"> <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkLabel" id="label459"> + <object class="GtkImage" id="image2"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Name:</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">entry_add_script_name</property> + <property name="can_focus">False</property> + <property name="stock">gtk-dialog-warning</property> </object> <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkLabel" id="label460"> + <object class="GtkLabel" id="label514"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> - <property name="label" translatable="yes">_Script:</property> - <property name="use_underline">True</property> + <property name="label" translatable="yes">SSL is not supported in this build of Evolution</property> <property name="justify">center</property> - <property name="mnemonic_widget">filechooserbutton_add_script</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="source-auth-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="source-auth-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Authentication Type</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">source_auth_dropdown</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="source-auth-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkVBox" id="source-auth-vbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkHBox" id="hbox199"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkEntry" id="entry_add_script_name"> + <object class="GtkComboBox" id="source_auth_dropdown"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can_focus">False</property> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkFileChooserButton" id="filechooserbutton_add_script"> + <object class="GtkButton" id="source_check_supported"> + <property name="label" translatable="yes">Ch_eck for Supported Types</property> <property name="visible">True</property> - <property name="title" translatable="yes"></property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="source_remember_password"> + <property name="label" translatable="yes">Re_member password</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> <property name="position">1</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> + </packing> + </child> + </object> + <object class="GtkVBox" id="vboxTransportBorder"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">12</property> + <child> + <object class="GtkTable" id="transport-type-table"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">3</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="transport_type_label"> <property name="visible">True</property> - <property name="layout_style">end</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">Server _Type:</property> + <property name="use_underline">True</property> + <property name="justify">right</property> + <property name="mnemonic_widget">transport_type_dropdown</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label50"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">Description:</property> + <property name="justify">right</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="transport_type_dropdown"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="transport_description"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">description</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHSeparator" id="transport-separator"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="transport-server-section"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="transport-server-header"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Server Configuration</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="transport-server-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkButton" id="button_add_script_add"> + <object class="GtkTable" id="transport-server-table"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="n_columns">4</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> <child> - <object class="GtkAlignment" id="alignment30"> + <object class="GtkLabel" id="transport_host_label"> <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <object class="GtkHBox" id="hbox221"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkImage" id="image5"> - <property name="visible">True</property> - <property name="stock">gtk-add</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label547"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Add Signature</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Server:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">transport_host</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="transport_port_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Port:</property> + <property name="use_underline">True</property> + <property name="justify">right</property> + <property name="mnemonic_widget">transport_port</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="transport_host"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="EPortEntry" id="transport_port" type-func="e_port_entry_get_type"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_entry">True</property> + <child internal-child="entry"> + <object class="GtkEntry" id="port-entry-entry4"> + <property name="can_focus">False</property> </object> </child> </object> + <packing> + <property name="left_attach">3</property> + <property name="x_options"></property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="transport_needs_auth"> + <property name="label" translatable="yes">Ser_ver requires authentication</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button_add_script_cancel"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> </child> - <action-widgets> - <action-widget response="0">button_add_script_add</action-widget> - <action-widget response="0">button_add_script_cancel</action-widget> - </action-widgets> - </object> - <object class="GtkNotebook" id="network_preferences_toplevel"> - <property name="visible">True</property> - <property name="can_focus">True</property> <child> - <object class="GtkVBox" id="vboxNetworkGeneral"> + <object class="GtkVBox" id="transport-security-section"> <property name="visible">True</property> - <property name="border_width">12</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkVBox" id="proxy-section"> + <object class="GtkLabel" id="transport-security-header"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="proxy-header"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Proxy Settings</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="position">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Security</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="transport-security-alignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkAlignment" id="proxy-alignment"> + <object class="GtkTable" id="transport-security-table"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> + <property name="n_rows">2</property> + <property name="row_spacing">6</property> <child> - <object class="GtkVBox" id="proxy-vbox"> + <object class="GtkHBox" id="transport_ssl_disabled"> <property name="visible">True</property> - <property name="orientation">vertical</property> + <property name="can_focus">False</property> <property name="spacing">6</property> <child> - <object class="GtkRadioButton" id="rdoSysSettings"> - <property name="label" translatable="yes">_Use system defaults</property> + <object class="GtkImage" id="image1"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-dialog-warning</property> </object> <packing> - <property name="position">0</property> <property name="expand">False</property> <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkRadioButton" id="rdoNoProxy"> - <property name="label" translatable="yes">_Direct connection to the Internet</property> + <object class="GtkLabel" id="transport_ssl_disabled_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">rdoSysSettings</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">SSL is not supported in this build of Evolution</property> + <property name="justify">center</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> <packing> - <property name="position">1</property> <property name="expand">False</property> <property name="fill">False</property> + <property name="position">1</property> </packing> </child> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="transport_ssl_hbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> <child> - <object class="GtkRadioButton" id="rdoManualProxy"> - <property name="label" translatable="yes">_Manual proxy configuration:</property> + <object class="GtkLabel" id="lblTransportUseSSL"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Use Secure Connection:</property> <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">rdoSysSettings</property> + <property name="justify">center</property> + <property name="mnemonic_widget">transport_use_ssl</property> </object> <packing> - <property name="position">2</property> <property name="expand">False</property> <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkAlignment" id="alignment27"> + <object class="GtkComboBox" id="transport_use_ssl"> <property name="visible">True</property> - <property name="left_padding">24</property> + <property name="can_focus">False</property> + <property name="model">use_ssl_model</property> <child> - <object class="GtkVBox" id="vbox18"> - <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkTable" id="table9"> - <property name="visible">True</property> - <property name="n_rows">4</property> - <property name="n_columns">4</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="lblHttpHost"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">H_TTP Proxy:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">txtHttpHost</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="lblHttpsHost"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Secure HTTP Proxy:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">txtHttpsHost</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="lblIgnoreHosts"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">No _Proxy for:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">txtIgnoreHosts</property> - </object> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="txtHttpHost"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="txtHttpsHost"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="lblHttpPort"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Port:</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="lblHttpsPort"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Port:</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkSpinButton" id="spnHttpPort"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <property name="adjustment">adjustment4</property> - <property name="climb_rate">1</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkSpinButton" id="spnHttpsPort"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <property name="adjustment">adjustment5</property> - <property name="climb_rate">1</property> - </object> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="txtIgnoreHosts"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">4</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="chkUseAuth"> - <property name="label" translatable="yes">Use Authe_ntication</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment26"> - <property name="visible">True</property> - <property name="left_padding">24</property> - <child> - <object class="GtkTable" id="table11"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="column_spacing">6</property> - <property name="row_spacing">3</property> - <child> - <object class="GtkLabel" id="lblAuthUser"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Us_ername:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">txtAuthUser</property> - </object> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkLabel" id="lblAuthPwd"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Pass_word:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">txtAuthPwd</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <object class="GtkEntry" id="txtAuthUser"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="txtAuthPwd"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="visibility">False</property> - <property name="invisible_char">●</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> + <object class="GtkCellRendererText" id="transport_use_ssl_renderer"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> </child> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">3</property> + <property name="position">1</property> </packing> </child> </object> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="proxy-padding"> - <property name="visible">True</property> - <child> - <placeholder/> </child> </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> - </child> - <child type="tab"> - <object class="GtkLabel" id="lblNetworkGeneral"> - <property name="visible">True</property> - <property name="label" translatable="yes">General</property> - </object> <packing> - <property name="tab_fill">False</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> </packing> </child> - </object> - <object class="GtkDialog" id="add-custom-junk-header"> - <property name="type_hint">dialog</property> - <property name="title" translatable="yes">Set custom junk header</property> - <property name="border-width">12</property> - <property name="width-request">400</property> - <property name="resizable">FALSE</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="inner-vbox"> + <child> + <object class="GtkVBox" id="transport-auth-section"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <property name="border-width">12</property> - <property name="spacing">12</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> - <object class="GtkLabel" id="junk_header_info"> + <object class="GtkLabel" id="transport-auth-header"> <property name="visible">True</property> - <property name="wrap">True</property> - <property name="label" translatable="yes">All new emails with header that matches given content will be automatically filtered as junk</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Authentication</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> </child> - <child> - <object class="GtkTable" id="junk_header_table"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <object class="GtkLabel" id="junk_header_label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Header name</property> - <property name="mnemonic_widget">junk-header-name</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="x_options">GTK_SHRINK</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="junk_header_label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Header content</property> - <property name="mnemonic_widget">junk-header-content</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_SHRINK</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="junk-header-name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="junk-header-content"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2></property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - </packing> - </child> - </object> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="junk_header_hbutton_box"> + <child> + <object class="GtkAlignment" id="transport-auth-alignment"> <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="junk-header-cancel"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="use_stock">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> - <object class="GtkButton" id="junk-header-ok"> - <property name="label" translatable="yes">gtk-ok</property> + <object class="GtkTable" id="transport-auth-table"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="use_stock">True</property> - <property name="use_underline">True</property> + <property name="can_focus">False</property> + <property name="n_rows">3</property> + <property name="n_columns">2</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="transport_auth_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">T_ype:</property> + <property name="use_underline">True</property> + <property name="justify">center</property> + <property name="mnemonic_widget">transport_auth_dropdown</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="transport_user_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">User _Name:</property> + <property name="use_underline">True</property> + <property name="justify">right</property> + <property name="mnemonic_widget">transport_user</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="transport_user"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">â—</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="transport_remember_password"> + <property name="label" translatable="yes">Remember _password</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xscale">0</property> + <child> + <object class="GtkHBox" id="hbox195"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkComboBox" id="transport_auth_dropdown"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="transport_check_supported"> + <property name="label" translatable="yes">Ch_eck for Supported Types</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <placeholder/> + </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">4</property> + </packing> </child> - <action-widgets> - <action-widget response="-6">junk-header-cancel</action-widget> - <action-widget response="-3">junk-header-ok</action-widget> - </action-widgets> + </object> + <object class="GtkSizeGroup" id="composer-combo-box-size-group"> + <widgets> + <widget name="comboboxReplyStyle"/> + <widget name="comboboxForwardStyle"/> + </widgets> </object> <object class="GtkSizeGroup" id="composer-label-size-group"> <widgets> @@ -5362,10 +5773,4 @@ for display purposes only. </property> <widget name="lblForwardStyle"/> </widgets> </object> - <object class="GtkSizeGroup" id="composer-combo-box-size-group"> - <widgets> - <widget name="comboboxReplyStyle"/> - <widget name="comboboxForwardStyle"/> - </widgets> - </object> </interface> diff --git a/maint/evolution.xml b/maint/evolution.xml index 8f48229dd1..c072734164 100644 --- a/maint/evolution.xml +++ b/maint/evolution.xml @@ -17,12 +17,14 @@ <property id="icon-name"/> </glade-widget-class> + <glade-widget-class name="EMailJunkOptions" generic-name="junk-options" title="Junk Mail Options" get-type-function="e_mail_junk_options_get_type"/> + <glade-widget-class name="EMFolderSelectionButton" generic-name="folder-selection-button" title="Folder Selection Button" get-type-function="em_folder_selection_button_get_type"> <property id="caption"/> <property id="title"/> </glade-widget-class> - <glade-widget-class name="EPortEntry" generic-name="port-entry" title="Port Entry"/> + <glade-widget-class name="EPortEntry" generic-name="port-entry" title="Port Entry" get-type-function="e_port_entry_get_type"/> <glade-widget-class name="ESourceComboBox" generic-name="source-combo-box" title="Source Combo Box"> <property id="source-list"/> @@ -39,6 +41,7 @@ <glade-widget-group name="evolution-widgets" title="Evolution"> <glade-widget-class-ref name="EDateEdit"/> <glade-widget-class-ref name="EImageChooser"/> + <glade-widget-class-ref name="EMailJunkOptions"/> <glade-widget-class-ref name="EMFolderSelectionButton"/> <glade-widget-class-ref name="EPortEntry"/> <glade-widget-class-ref name="ESourceComboBox"/> diff --git a/modules/Makefile.am b/modules/Makefile.am index 9a32c72ebc..dd363d27a3 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -24,6 +24,7 @@ endif SUBDIRS = \ addressbook \ + bogofilter \ calendar \ mail \ composer-autosave \ @@ -31,6 +32,7 @@ SUBDIRS = \ offline-alert \ plugin-lib \ plugin-manager \ + spamassassin \ startup-wizard \ $(MONO_DIR) \ $(PYTHON_DIR) \ diff --git a/modules/bogofilter/Makefile.am b/modules/bogofilter/Makefile.am new file mode 100644 index 0000000000..7803267836 --- /dev/null +++ b/modules/bogofilter/Makefile.am @@ -0,0 +1,57 @@ +module_LTLIBRARIES = libevolution-module-bogofilter.la + +libevolution_module_bogofilter_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-bogofilter\" \ + -DWELCOME_MESSAGE=\""$(privdatadir)/default/C/mail/local/Inbox"\" \ + $(GNOME_PLATFORM_CFLAGS) \ + $(EVOLUTION_MAIL_CFLAGS) + +libevolution_module_bogofilter_la_SOURCES = \ + evolution-bogofilter.c + +libevolution_module_bogofilter_la_LIBADD = \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/mail/libevolution-mail.la \ + $(GNOME_PLATFORM_LIBS) \ + $(EVOLUTION_MAIL_LIBS) + +libevolution_module_bogofilter_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +schemadir = $(GCONF_SCHEMA_FILE_DIR) +schema_in_files = evolution-bogofilter.schemas.in +schema_DATA = $(schema_in_files:.schemas.in=.schemas) + +@INTLTOOL_SCHEMAS_RULE@ + +if GCONF_SCHEMAS_INSTALL + +if OS_WIN32 +install-data-local: + if test -z "$(DESTDIR)" ; then \ + for p in $(schema_DATA) ; do \ + (echo set GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE); \ + echo $(GCONFTOOL) --makefile-install-rule $$p) >_temp.bat; \ + cmd /c _temp.bat; \ + rm _temp.bat; \ + done \ + fi +else +install-data-local: + if test -z "$(DESTDIR)" ; then \ + for p in $(schema_DATA) ; do \ + GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) \ + $(GCONFTOOL) --makefile-install-rule $$p; \ + done \ + fi +endif + +endif + +DISTCLEANFILES = $(schema_DATA) + +EXTRA_DIST = $(schema_in_files) + +-include $(top_srcdir)/git.mk diff --git a/modules/bogofilter/evolution-bogofilter.c b/modules/bogofilter/evolution-bogofilter.c new file mode 100644 index 0000000000..2cc7a64359 --- /dev/null +++ b/modules/bogofilter/evolution-bogofilter.c @@ -0,0 +1,524 @@ +/* + * evolution-bogofilter.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 <config.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <glib/gi18n-lib.h> + +#include <camel/camel.h> + +#include <e-util/gconf-bridge.h> +#include <mail/e-mail-junk-filter.h> + +/* Standard GObject macros */ +#define E_TYPE_BOGOFILTER \ + (e_bogofilter_get_type ()) +#define E_BOGOFILTER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_BOGOFILTER, EBogofilter)) + +#ifndef BOGOFILTER_BINARY +#define BOGOFILTER_BINARY "/usr/bin/bogofilter" +#endif + +#define BOGOFILTER_EXIT_STATUS_SPAM 0 +#define BOGOFILTER_EXIT_STATUS_HAM 1 +#define BOGOFILTER_EXIT_STATUS_UNSURE 2 +#define BOGOFILTER_EXIT_STATUS_ERROR 3 + +typedef struct _EBogofilter EBogofilter; +typedef struct _EBogofilterClass EBogofilterClass; + +struct _EBogofilter { + EMailJunkFilter parent; + gboolean convert_to_unicode; +}; + +struct _EBogofilterClass { + EMailJunkFilterClass parent_class; +}; + +enum { + PROP_0, + PROP_CONVERT_TO_UNICODE +}; + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +/* Forward Declarations */ +GType e_bogofilter_get_type (void); +static void e_bogofilter_interface_init (CamelJunkFilterInterface *interface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED ( + EBogofilter, + e_bogofilter, + E_TYPE_MAIL_JUNK_FILTER, 0, + G_IMPLEMENT_INTERFACE_DYNAMIC ( + CAMEL_TYPE_JUNK_FILTER, + e_bogofilter_interface_init)) + +#ifdef G_OS_UNIX +static void +bogofilter_cancelled_cb (GCancellable *cancellable, + GPid *pid) +{ + /* XXX On UNIX-like systems we can safely assume a GPid is the + * process ID and use it to terminate the process via signal. */ + kill (*pid, SIGTERM); +} +#endif + +static void +bogofilter_exited_cb (GPid *pid, + gint status, + gpointer user_data) +{ + struct { + GMainLoop *loop; + gint exit_code; + } *source_data = user_data; + + if (WIFEXITED (status)) + source_data->exit_code = WEXITSTATUS (status); + else + source_data->exit_code = BOGOFILTER_EXIT_STATUS_ERROR; + + g_main_loop_quit (source_data->loop); +} + +static gint +bogofilter_command (const gchar **argv, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error) +{ + CamelStream *stream; + GMainContext *context; + GSource *source; + GPid child_pid; + gssize bytes_written; + gint standard_input; + gulong handler_id = 0; + gboolean success; + + struct { + GMainLoop *loop; + gint exit_code; + } source_data; + + /* Spawn Bogofilter with an open stdin pipe. */ + success = g_spawn_async_with_pipes ( + NULL, + (gchar **) argv, + NULL, + G_SPAWN_DO_NOT_REAP_CHILD | + G_SPAWN_STDOUT_TO_DEV_NULL, + NULL, NULL, + &child_pid, + &standard_input, + NULL, + NULL, + error); + + if (!success) { + gchar *command_line; + + command_line = g_strjoinv (" ", (gchar **) argv); + g_prefix_error ( + error, _("Failed to spawn Bogofilter (%s): "), + command_line); + g_free (command_line); + + return BOGOFILTER_EXIT_STATUS_ERROR; + } + + /* Stream the CamelMimeMessage to Bogofilter. */ + stream = camel_stream_fs_new_with_fd (standard_input); + bytes_written = camel_data_wrapper_write_to_stream_sync ( + CAMEL_DATA_WRAPPER (message), stream, cancellable, error); + success = (bytes_written >= 0) && + (camel_stream_close (stream, cancellable, error) == 0); + g_object_unref (stream); + + if (!success) { + g_spawn_close_pid (child_pid); + g_prefix_error ( + error, _("Failed to stream mail " + "message content to Bogofilter: ")); + return BOGOFILTER_EXIT_STATUS_ERROR; + } + + /* Wait for the Bogofilter process to terminate + * using GLib's main loop for better portability. */ + + context = g_main_context_new (); + + source = g_child_watch_source_new (child_pid); + g_source_set_callback ( + source, (GSourceFunc) + bogofilter_exited_cb, + &source_data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + source_data.loop = g_main_loop_new (context, TRUE); + source_data.exit_code = 0; + +#ifdef G_OS_UNIX + if (G_IS_CANCELLABLE (cancellable)) + handler_id = g_cancellable_connect ( + cancellable, + G_CALLBACK (bogofilter_cancelled_cb), + &child_pid, (GDestroyNotify) NULL); +#endif + + g_main_loop_run (source_data.loop); + + if (handler_id > 0) + g_cancellable_disconnect (cancellable, handler_id); + + g_main_loop_unref (source_data.loop); + source_data.loop = NULL; + + g_main_context_unref (context); + + /* Clean up. */ + + g_spawn_close_pid (child_pid); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + source_data.exit_code = BOGOFILTER_EXIT_STATUS_ERROR; + + else if (source_data.exit_code == BOGOFILTER_EXIT_STATUS_ERROR) + g_set_error_literal ( + error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, + _("Bogofilter either crashed or " + "failed to process a mail message")); + + return source_data.exit_code; +} + +static void +bogofilter_init_wordlist (EBogofilter *extension) +{ + CamelStream *stream; + CamelMimeParser *parser; + CamelMimeMessage *message; + + /* Initialize the Bogofilter database with a welcome message. */ + + parser = camel_mime_parser_new (); + message = camel_mime_message_new (); + + stream = camel_stream_fs_new_with_name ( + WELCOME_MESSAGE, O_RDONLY, 0, NULL); + camel_mime_parser_init_with_stream (parser, stream, NULL); + camel_mime_parser_scan_from (parser, FALSE); + g_object_unref (stream); + + camel_mime_part_construct_from_parser_sync ( + CAMEL_MIME_PART (message), parser, NULL, NULL); + + camel_junk_filter_learn_not_junk ( + CAMEL_JUNK_FILTER (extension), message, NULL, NULL); + + g_object_unref (message); + g_object_unref (parser); +} + +static gboolean +bogofilter_get_convert_to_unicode (EBogofilter *extension) +{ + return extension->convert_to_unicode; +} + +static void +bogofilter_set_convert_to_unicode (EBogofilter *extension, + gboolean convert_to_unicode) +{ + extension->convert_to_unicode = convert_to_unicode; + + g_object_notify (G_OBJECT (extension), "convert-to-unicode"); +} + +static void +bogofilter_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CONVERT_TO_UNICODE: + bogofilter_set_convert_to_unicode ( + E_BOGOFILTER (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +bogofilter_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CONVERT_TO_UNICODE: + g_value_set_boolean ( + value, bogofilter_get_convert_to_unicode ( + E_BOGOFILTER (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static gboolean +bogofilter_available (EMailJunkFilter *junk_filter) +{ + return g_file_test (BOGOFILTER_BINARY, G_FILE_TEST_IS_EXECUTABLE); +} + +static GtkWidget * +bogofilter_new_config_widget (EMailJunkFilter *junk_filter) +{ + GtkWidget *box; + GtkWidget *widget; + gchar *markup; + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + + markup = g_markup_printf_escaped ( + "<b>%s</b>", _("Bogofilter Options")); + widget = gtk_label_new (markup); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + g_free (markup); + + widget = gtk_check_button_new_with_mnemonic ( + _("Convert message text to _Unicode")); + gtk_widget_set_margin_left (widget, 12); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_object_bind_property ( + junk_filter, "convert-to-unicode", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE); + + return box; +} + +static gboolean +bogofilter_classify (CamelJunkFilter *junk_filter, + CamelMimeMessage *message, + CamelJunkStatus *status, + GCancellable *cancellable, + GError **error) +{ + EBogofilter *extension = E_BOGOFILTER (junk_filter); + static gboolean wordlist_initialized = FALSE; + gint exit_code; + + const gchar *argv[] = { + BOGOFILTER_BINARY, + NULL, /* leave room for unicode option */ + NULL + }; + + if (bogofilter_get_convert_to_unicode (extension)) + argv[1] = "--unicode=yes"; + +retry: + exit_code = bogofilter_command (argv, message, cancellable, error); + + switch (exit_code) { + case BOGOFILTER_EXIT_STATUS_SPAM: + *status = CAMEL_JUNK_STATUS_MESSAGE_IS_JUNK; + break; + + case BOGOFILTER_EXIT_STATUS_HAM: + *status = CAMEL_JUNK_STATUS_MESSAGE_IS_NOT_JUNK; + break; + + case BOGOFILTER_EXIT_STATUS_UNSURE: + *status = CAMEL_JUNK_STATUS_INCONCLUSIVE; + break; + + case BOGOFILTER_EXIT_STATUS_ERROR: + if (!wordlist_initialized) { + wordlist_initialized = TRUE; + bogofilter_init_wordlist (extension); + goto retry; + } + break; + + default: + g_warning ( + "Bogofilter: Unexpected exit code (%d) " + "while classifying message", exit_code); + break; + } + + /* Check that the return value and GError agree. */ + if (exit_code != BOGOFILTER_EXIT_STATUS_ERROR) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + return (exit_code != BOGOFILTER_EXIT_STATUS_ERROR); +} + +static gboolean +bogofilter_learn_junk (CamelJunkFilter *junk_filter, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error) +{ + EBogofilter *extension = E_BOGOFILTER (junk_filter); + gint exit_code; + + const gchar *argv[] = { + BOGOFILTER_BINARY, + "--register-spam", + NULL, /* leave room for unicode option */ + NULL + }; + + if (bogofilter_get_convert_to_unicode (extension)) + argv[2] = "--unicode=yes"; + + exit_code = bogofilter_command (argv, message, cancellable, error); + + if (exit_code != 0) + g_warning ( + "Bogofilter: Unexpected exit code (%d) " + "while registering spam", exit_code); + + /* Check that the return value and GError agree. */ + if (exit_code != BOGOFILTER_EXIT_STATUS_ERROR) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + return (exit_code != BOGOFILTER_EXIT_STATUS_ERROR); +} + +static gboolean +bogofilter_learn_not_junk (CamelJunkFilter *junk_filter, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error) +{ + EBogofilter *extension = E_BOGOFILTER (junk_filter); + gint exit_code; + + const gchar *argv[] = { + BOGOFILTER_BINARY, + "--register-ham", + NULL, /* leave room for unicode option */ + NULL + }; + + if (bogofilter_get_convert_to_unicode (extension)) + argv[2] = "--unicode=yes"; + + exit_code = bogofilter_command (argv, message, cancellable, error); + + if (exit_code != 0) + g_warning ( + "Bogofilter: Unexpected exit code (%d) " + "while registering ham", exit_code); + + /* Check that the return value and GError agree. */ + if (exit_code != BOGOFILTER_EXIT_STATUS_ERROR) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + return (exit_code != BOGOFILTER_EXIT_STATUS_ERROR); +} + +static void +e_bogofilter_class_init (EBogofilterClass *class) +{ + GObjectClass *object_class; + EMailJunkFilterClass *junk_filter_class; + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = bogofilter_set_property; + object_class->get_property = bogofilter_get_property; + + junk_filter_class = E_MAIL_JUNK_FILTER_CLASS (class); + junk_filter_class->filter_name = "Bogofilter"; + junk_filter_class->display_name = _("Bogofilter"); + junk_filter_class->available = bogofilter_available; + junk_filter_class->new_config_widget = bogofilter_new_config_widget; + + g_object_class_install_property ( + object_class, + PROP_CONVERT_TO_UNICODE, + g_param_spec_boolean ( + "convert-to-unicode", + "Convert to Unicode", + "Convert message text to Unicode", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_bogofilter_class_finalize (EBogofilterClass *class) +{ +} + +static void +e_bogofilter_interface_init (CamelJunkFilterInterface *interface) +{ + interface->classify = bogofilter_classify; + interface->learn_junk = bogofilter_learn_junk; + interface->learn_not_junk = bogofilter_learn_not_junk; +} + +static void +e_bogofilter_init (EBogofilter *extension) +{ + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/bogofilter/unicode", + G_OBJECT (extension), "convert-to-unicode"); +} + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_bogofilter_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} diff --git a/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in b/modules/bogofilter/evolution-bogofilter.schemas.in index d4bfbb5b70..e313eb9ffc 100644 --- a/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in +++ b/modules/bogofilter/evolution-bogofilter.schemas.in @@ -1,9 +1,10 @@ <gconfschemafile> <schemalist> + <schema> <key>/schemas/apps/evolution/mail/junk/bogofilter/unicode</key> <applyto>/apps/evolution/mail/junk/bogofilter/unicode</applyto> - <owner>bf-eplugin</owner> + <owner>evolution-bogofilter</owner> <type>bool</type> <default>true</default> <locale name="C"> @@ -14,5 +15,6 @@ </long> </locale> </schema> + </schemalist> </gconfschemafile> diff --git a/modules/mail/Makefile.am b/modules/mail/Makefile.am index 884d050d78..0bea9ac1a2 100644 --- a/modules/mail/Makefile.am +++ b/modules/mail/Makefile.am @@ -27,8 +27,6 @@ libevolution_module_mail_la_SOURCES = \ e-mail-config-web-view.h \ e-mail-event-hook.c \ e-mail-event-hook.h \ - e-mail-junk-hook.c \ - e-mail-junk-hook.h \ e-mail-shell-backend.c \ e-mail-shell-backend.h \ e-mail-shell-content.c \ diff --git a/modules/mail/e-mail-junk-hook.c b/modules/mail/e-mail-junk-hook.c deleted file mode 100644 index 4ccc404e8d..0000000000 --- a/modules/mail/e-mail-junk-hook.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * e-mail-junk-hook.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/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-mail-junk-hook.h" - -#include <glib/gi18n.h> - -#include "e-util/e-alert-dialog.h" -#include "shell/e-shell.h" - -#include "mail/em-junk.h" -#include "mail/em-utils.h" -#include "mail/e-mail-backend.h" -#include "mail/e-mail-session.h" - -struct _EMailJunkHookPrivate { - EMJunkInterface interface; -}; - -struct ErrorData { - const gchar *error_message; - GError *error; -}; - -static gpointer parent_class; -static GType mail_junk_hook_type; - -static gboolean -mail_junk_hook_idle_cb (struct ErrorData *data) -{ - EShell *shell; - EShellBackend *shell_backend; - - shell = e_shell_get_default (); - shell_backend = e_shell_get_backend_by_name (shell, "mail"); - - e_mail_backend_submit_alert ( - E_MAIL_BACKEND (shell_backend), - data->error_message, data->error->message, NULL); - - g_error_free (data->error); - g_slice_free (struct ErrorData, data); - - return FALSE; -} - -static void -mail_junk_hook_error (const gchar *error_message, - GError *error) -{ - struct ErrorData *data; - - g_return_if_fail (error != NULL); - - data = g_slice_new (struct ErrorData); - data->error_message = error_message; - data->error = error; - - g_idle_add ((GSourceFunc) mail_junk_hook_idle_cb, data); -} - -static const gchar * -mail_junk_hook_get_name (CamelJunkPlugin *junk_plugin) -{ - EMJunkInterface *interface; - - interface = (EMJunkInterface *) junk_plugin; - - if (!interface->hook->plugin->enabled) { - /* Translators: "None" for a junk hook name, - * when the junk plugin is not enabled. */ - return C_("mail-junk-hook", "None"); - } - - return interface->hook->plugin->name; -} - -static void -mail_junk_hook_plugin_init (CamelJunkPlugin *junk_plugin) -{ - EMJunkInterface *interface; - EPluginClass *class; - - interface = (EMJunkInterface *) junk_plugin; - - class = E_PLUGIN_GET_CLASS (interface->hook->plugin); - g_return_if_fail (class->enable != NULL); - - class->enable (interface->hook->plugin, 1); -} - -static gboolean -mail_junk_hook_check_junk (CamelJunkPlugin *junk_plugin, - CamelMimeMessage *mime_message) -{ - EMJunkTarget target = { mime_message, NULL }; - EMJunkInterface *interface; - gpointer result; - - interface = (EMJunkInterface *) junk_plugin; - - if (!interface->hook->plugin->enabled) - return FALSE; - - result = e_plugin_invoke ( - interface->hook->plugin, - interface->check_junk, &target); - - if (target.error != NULL) - mail_junk_hook_error ("mail:junk-check-error", target.error); - - return (result != NULL); -} - -static void -mail_junk_hook_report_junk (CamelJunkPlugin *junk_plugin, - CamelMimeMessage *mime_message) -{ - EMJunkTarget target = { mime_message, NULL }; - EMJunkInterface *interface; - - interface = (EMJunkInterface *) junk_plugin; - - if (!interface->hook->plugin->enabled) - return; - - e_plugin_invoke ( - interface->hook->plugin, - interface->report_junk, &target); - - if (target.error != NULL) - mail_junk_hook_error ("mail:junk-report-error", target.error); -} - -static void -mail_junk_hook_report_notjunk (CamelJunkPlugin *junk_plugin, - CamelMimeMessage *mime_message) -{ - EMJunkTarget target = { mime_message, NULL }; - EMJunkInterface *interface; - - interface = (EMJunkInterface *) junk_plugin; - - if (!interface->hook->plugin->enabled) - return; - - e_plugin_invoke ( - interface->hook->plugin, - interface->report_notjunk, &target); - - if (target.error != NULL) - mail_junk_hook_error ( - "mail:junk-not-report-error", target.error); -} - -static void -mail_junk_hook_commit_reports (CamelJunkPlugin *junk_plugin) -{ - EMJunkInterface *interface; - - interface = (EMJunkInterface *) junk_plugin; - - if (!interface->hook->plugin->enabled) - return; - - e_plugin_invoke ( - interface->hook->plugin, - interface->commit_reports, NULL); -} - -static void -mail_junk_hook_finalize (GObject *object) -{ - EMailJunkHookPrivate *priv; - - priv = E_MAIL_JUNK_HOOK (object)->priv; - - g_free (priv->interface.check_junk); - g_free (priv->interface.report_junk); - g_free (priv->interface.report_notjunk); - g_free (priv->interface.commit_reports); - g_free (priv->interface.validate_binary); - g_free (priv->interface.plugin_name); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gint -mail_junk_hook_construct (EPluginHook *hook, - EPlugin *plugin, - xmlNodePtr node) -{ - EMailJunkHookPrivate *priv; - EShell *shell; - EShellBackend *shell_backend; - EMailBackend *backend; - EMailSession *session; - gchar *property; - - priv = E_MAIL_JUNK_HOOK (hook)->priv; - - /* Chain up to parent's construct() method. */ - if (E_PLUGIN_HOOK_CLASS (parent_class)->construct (hook, plugin, node) == -1) - return -1; - - if (!plugin->enabled) - return -1; - - node = xmlFirstElementChild (node); - - if (node == NULL) - return -1; - - if (g_strcmp0 ((gchar *) node->name, "interface") != 0) - return -1; - - property = e_plugin_xml_prop (node, "check_junk"); - priv->interface.check_junk = property; - - property = e_plugin_xml_prop (node, "report_junk"); - priv->interface.report_junk = property; - - property = e_plugin_xml_prop (node, "report_non_junk"); - priv->interface.report_notjunk = property; - - property = e_plugin_xml_prop (node, "commit_reports"); - priv->interface.commit_reports = property; - - property = e_plugin_xml_prop (node, "validate_binary"); - priv->interface.validate_binary = property; - - property = e_plugin_xml_prop (node, "name"); - priv->interface.plugin_name = property; - - if (priv->interface.check_junk == NULL) - return -1; - - if (priv->interface.report_junk == NULL) - return -1; - - if (priv->interface.report_notjunk == NULL) - return -1; - - if (priv->interface.commit_reports == NULL) - return -1; - - shell = e_shell_get_default (); - shell_backend = e_shell_get_backend_by_name (shell, "mail"); - - backend = E_MAIL_BACKEND (shell_backend); - session = e_mail_backend_get_session (backend); - - mail_session_add_junk_plugin ( - session, priv->interface.plugin_name, - &priv->interface.camel); - - return 0; -} - -static void -mail_junk_hook_class_init (EMailJunkHookClass *class) -{ - GObjectClass *object_class; - EPluginHookClass *plugin_hook_class; - - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EMailJunkHookPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = mail_junk_hook_finalize; - - plugin_hook_class = E_PLUGIN_HOOK_CLASS (class); - plugin_hook_class->construct = mail_junk_hook_construct; - plugin_hook_class->id = "org.gnome.evolution.mail.junk:1.0"; -} - -static void -mail_junk_hook_init (EMailJunkHook *mail_junk_hook) -{ - EMJunkInterface *interface; - - mail_junk_hook->priv = G_TYPE_INSTANCE_GET_PRIVATE ( - mail_junk_hook, E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookPrivate); - - interface = &mail_junk_hook->priv->interface; - interface->camel.get_name = mail_junk_hook_get_name; - interface->camel.api_version = 1; - interface->camel.check_junk = mail_junk_hook_check_junk; - interface->camel.report_junk = mail_junk_hook_report_junk; - interface->camel.report_notjunk = mail_junk_hook_report_notjunk; - interface->camel.commit_reports = mail_junk_hook_commit_reports; - interface->camel.init = mail_junk_hook_plugin_init; - interface->hook = E_PLUGIN_HOOK (mail_junk_hook); -} - -GType -e_mail_junk_hook_get_type (void) -{ - return mail_junk_hook_type; -} - -void -e_mail_junk_hook_register_type (GTypeModule *type_module) -{ - const GTypeInfo type_info = { - sizeof (EMailJunkHookClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) mail_junk_hook_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EMailJunkHook), - 0, /* n_preallocs */ - (GInstanceInitFunc) mail_junk_hook_init, - NULL /* value_table */ - }; - - mail_junk_hook_type = g_type_module_register_type ( - type_module, E_TYPE_PLUGIN_HOOK, - "EMailJunkHook", &type_info, 0); -} diff --git a/modules/mail/e-mail-junk-hook.h b/modules/mail/e-mail-junk-hook.h deleted file mode 100644 index f5882e66b3..0000000000 --- a/modules/mail/e-mail-junk-hook.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * e-mail-junk-hook.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/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef E_MAIL_JUNK_HOOK_H -#define E_MAIL_JUNK_HOOK_H - -#include <e-util/e-plugin.h> - -/* Standard GObject macros */ -#define E_TYPE_MAIL_JUNK_HOOK \ - (e_mail_junk_hook_get_type ()) -#define E_MAIL_JUNK_HOOK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHook)) -#define E_MAIL_JUNK_HOOK_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookClass)) -#define E_IS_MAIL_JUNK_HOOK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_MAIL_JUNK_HOOK)) -#define E_IS_MAIL_JUNK_HOOK_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_MAIL_JUNK_HOOK)) -#define E_MAIL_JUNK_HOOK_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookClass)) - -G_BEGIN_DECLS - -typedef struct _EMailJunkHook EMailJunkHook; -typedef struct _EMailJunkHookClass EMailJunkHookClass; -typedef struct _EMailJunkHookPrivate EMailJunkHookPrivate; - -struct _EMailJunkHook { - EPluginHook parent; - EMailJunkHookPrivate *priv; -}; - -struct _EMailJunkHookClass { - EPluginHookClass parent_class; -}; - -GType e_mail_junk_hook_get_type (void); -void e_mail_junk_hook_register_type (GTypeModule *type_module); - -G_END_DECLS - -#endif /* E_MAIL_JUNK_HOOK_H */ diff --git a/modules/mail/em-mailer-prefs.c b/modules/mail/em-mailer-prefs.c index 8e2688e615..bbf65e36b5 100644 --- a/modules/mail/em-mailer-prefs.c +++ b/modules/mail/em-mailer-prefs.c @@ -37,18 +37,20 @@ #include "libedataserverui/e-cell-renderer-color.h" -#include "e-util/e-util.h" -#include "e-util/e-datetime-format.h" -#include "e-util/e-util-private.h" -#include "widgets/misc/e-charset-combo-box.h" -#include "shell/e-shell-utils.h" - -#include "e-mail-backend.h" -#include "e-mail-label-manager.h" -#include "e-mail-reader-utils.h" -#include "em-folder-selection-button.h" -#include "em-junk.h" -#include "em-config.h" +#include <e-util/e-util.h> +#include <e-util/e-datetime-format.h> +#include <e-util/e-util-private.h> + +#include <misc/e-charset-combo-box.h> +#include <misc/e-port-entry.h> +#include <shell/e-shell-utils.h> + +#include <mail/e-mail-backend.h> +#include <mail/e-mail-junk-options.h> +#include <mail/e-mail-label-manager.h> +#include <mail/e-mail-reader-utils.h> +#include <mail/em-folder-selection-button.h> +#include <mail/em-config.h> enum { HEADER_LIST_NAME_COLUMN, /* displayable name of the header (may be a translation) */ @@ -102,7 +104,6 @@ em_mailer_prefs_finalize (GObject *object) { EMMailerPrefs *prefs = (EMMailerPrefs *) object; - g_object_unref (prefs->session); g_object_unref (prefs->builder); if (prefs->labels_change_notify_id) { @@ -676,131 +677,8 @@ emmp_free (EConfig *ec, GSList *items, gpointer data) } static void -junk_plugin_changed (GtkWidget *combo, EMMailerPrefs *prefs) -{ - gchar *def_plugin; - const GList *plugins = mail_session_get_junk_plugins (prefs->session); - GtkTreeIter iter; - - g_return_if_fail (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)); - - def_plugin = NULL; - gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (combo)), &iter, 0, &def_plugin, -1); - - gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/junk/default_plugin", def_plugin, NULL); - while (plugins) { - EMJunkInterface *iface = plugins->data; - - if (iface->plugin_name && def_plugin && !strcmp (iface->plugin_name, def_plugin)) { - gboolean status; - - CAMEL_SESSION (prefs->session)->junk_plugin = - CAMEL_JUNK_PLUGIN (&iface->camel); - status = e_plugin_invoke (iface->hook->plugin, iface->validate_binary, NULL) != NULL; - if ((gboolean) status == TRUE) { - gchar *text, *html; - gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU); - text = g_strdup_printf (_("%s plugin is available and the binary is installed."), iface->plugin_name); - html = g_strdup_printf ("<i>%s</i>", text); - gtk_label_set_markup (prefs->plugin_status, html); - g_free (html); - g_free (text); - } else { - gchar *text, *html; - gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU); - text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), iface->plugin_name); - html = g_strdup_printf ("<i>%s</i>", text); - gtk_label_set_markup (prefs->plugin_status, html); - g_free (html); - g_free (text); - } - break; - } - plugins = plugins->next; - } - - g_free (def_plugin); -} - -static void -junk_plugin_setup (GtkComboBox *combo_box, EMMailerPrefs *prefs) -{ - GtkListStore *store; - GtkCellRenderer *cell; - gint index = 0; - gboolean def_set = FALSE; - const GList *plugins = mail_session_get_junk_plugins (prefs->session); - gchar *pdefault = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/junk/default_plugin", NULL); - - store = gtk_list_store_new (1, G_TYPE_STRING); - gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (store)); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell, - "text", 0, - NULL); - - if (!plugins || !g_list_length ((GList *) plugins)) { - GtkTreeIter iter; - - gtk_list_store_append (store, &iter); - gtk_list_store_set ( - store, &iter, 0, _("No junk plugin available"), -1); - gtk_combo_box_set_active (combo_box, 0); - gtk_widget_set_sensitive (GTK_WIDGET (combo_box), FALSE); - gtk_widget_hide (GTK_WIDGET (prefs->plugin_image)); - gtk_widget_hide (GTK_WIDGET (prefs->plugin_status)); - gtk_image_set_from_stock (prefs->plugin_image, NULL, 0); - g_free (pdefault); - - return; - } - - while (plugins) { - EMJunkInterface *iface = plugins->data; - GtkTreeIter iter; - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, iface->plugin_name, -1); - if (!def_set && pdefault && iface->plugin_name && !strcmp (pdefault, iface->plugin_name)) { - gboolean status; - - def_set = TRUE; - gtk_combo_box_set_active (combo_box, index); - status = e_plugin_invoke (iface->hook->plugin, iface->validate_binary, NULL) != NULL; - if (status) { - gchar *text, *html; - gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU); - /* May be a better text */ - text = g_strdup_printf (_("%s plugin is available and the binary is installed."), iface->plugin_name); - html = g_strdup_printf ("<i>%s</i>", text); - gtk_label_set_markup (prefs->plugin_status, html); - g_free (html); - g_free (text); - } else { - gchar *text, *html; - gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU); - /* May be a better text */ - text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), iface->plugin_name); - html = g_strdup_printf ("<i>%s</i>", text); - gtk_label_set_markup (prefs->plugin_status, html); - g_free (html); - g_free (text); - } - } - plugins = plugins->next; - index++; - } - - g_signal_connect ( - combo_box, "changed", - G_CALLBACK (junk_plugin_changed), prefs); - g_free (pdefault); -} - -static void em_mailer_prefs_construct (EMMailerPrefs *prefs, + EMailSession *session, EShell *shell) { GSList *header_config_list, *header_add_list, *p; @@ -823,6 +701,7 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs, /* Make sure our custom widget classes are registered with * GType before we load the GtkBuilder definition file. */ + E_TYPE_MAIL_JUNK_OPTIONS; EM_TYPE_FOLDER_SELECTION_BUTTON; prefs->builder = gtk_builder_new (); @@ -1182,10 +1061,8 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs, G_BINDING_SYNC_CREATE); emmp_empty_junk_init (prefs, GTK_COMBO_BOX (widget)); - prefs->default_junk_plugin = GTK_COMBO_BOX (e_builder_get_widget (prefs->builder, "default_junk_plugin")); - prefs->plugin_status = GTK_LABEL (e_builder_get_widget (prefs->builder, "plugin_status")); - prefs->plugin_image = GTK_IMAGE (e_builder_get_widget (prefs->builder, "plugin_image")); - junk_plugin_setup (prefs->default_junk_plugin, prefs); + widget = e_builder_get_widget (prefs->builder, "junk-module-options"); + e_mail_junk_options_set_session (E_MAIL_JUNK_OPTIONS (widget), session); prefs->junk_header_check = (GtkToggleButton *)e_builder_get_widget (prefs->builder, "junk_header_check"); prefs->junk_header_tree = (GtkTreeView *)e_builder_get_widget (prefs->builder, "junk_header_tree"); @@ -1238,11 +1115,8 @@ em_mailer_prefs_new (EPreferencesWindow *window) new = g_object_new (EM_TYPE_MAILER_PREFS, NULL); - /* FIXME This should be a constructor property. */ - new->session = g_object_ref (session); - /* FIXME Kill this function. */ - em_mailer_prefs_construct (new, shell); + em_mailer_prefs_construct (new, session, shell); return GTK_WIDGET (new); } diff --git a/modules/mail/em-mailer-prefs.h b/modules/mail/em-mailer-prefs.h index d28fd5f5e4..35ebec3bf7 100644 --- a/modules/mail/em-mailer-prefs.h +++ b/modules/mail/em-mailer-prefs.h @@ -26,7 +26,6 @@ #include <gtk/gtk.h> #include <gconf/gconf-client.h> #include <shell/e-shell.h> -#include <mail/e-mail-session.h> #include <widgets/misc/e-preferences-window.h> /* Standard GObject macros */ @@ -56,8 +55,6 @@ typedef struct _EMMailerPrefsClass EMMailerPrefsClass; struct _EMMailerPrefs { GtkVBox parent_object; - EMailSession *session; - GtkBuilder *builder; GConfClient *gconf; @@ -95,9 +92,6 @@ struct _EMMailerPrefs { GtkToggleButton *sa_local_tests_only; GtkToggleButton *sa_use_daemon; - GtkComboBox *default_junk_plugin; - GtkLabel *plugin_status; - GtkImage *plugin_image; GtkToggleButton *junk_header_check; GtkTreeView *junk_header_tree; diff --git a/modules/mail/evolution-module-mail.c b/modules/mail/evolution-module-mail.c index ddb9d8996b..bda0db5d95 100644 --- a/modules/mail/evolution-module-mail.c +++ b/modules/mail/evolution-module-mail.c @@ -27,7 +27,6 @@ #include "e-mail-config-hook.h" #include "e-mail-event-hook.h" -#include "e-mail-junk-hook.h" #include "e-mail-shell-backend.h" #include "e-mail-shell-content.h" @@ -52,7 +51,6 @@ e_module_load (GTypeModule *type_module) e_mail_config_hook_register_type (type_module); e_mail_event_hook_register_type (type_module); - e_mail_junk_hook_register_type (type_module); e_mail_shell_backend_register_type (type_module); e_mail_shell_content_register_type (type_module); diff --git a/modules/spamassassin/Makefile.am b/modules/spamassassin/Makefile.am new file mode 100644 index 0000000000..8bce85214b --- /dev/null +++ b/modules/spamassassin/Makefile.am @@ -0,0 +1,56 @@ +module_LTLIBRARIES = libevolution-module-spamassassin.la + +libevolution_module_spamassassin_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-spamassassin\" \ + $(GNOME_PLATFORM_CFLAGS) \ + $(EVOLUTION_MAIL_CFLAGS) + +libevolution_module_spamassassin_la_SOURCES = \ + evolution-spamassassin.c + +libevolution_module_spamassassin_la_LIBADD = \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/mail/libevolution-mail.la \ + $(GNOME_PLATFORM_LIBS) \ + $(EVOLUTION_MAIL_LIBS) + +libevolution_module_spamassassin_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +schemadir = $(GCONF_SCHEMA_FILE_DIR) +schema_in_files = evolution-spamassassin.schemas.in +schema_DATA = $(schema_in_files:.schemas.in=.schemas) + +@INTLTOOL_SCHEMAS_RULE@ + +if GCONF_SCHEMAS_INSTALL + +if OS_WIN32 +install-data-local: + if test -z "$(DESTDIR)" ; then \ + for p in $(schema_DATA) ; do \ + (echo set GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE); \ + echo $(GCONFTOOL) --makefile-install-rule $$p) >_temp.bat; \ + cmd /c _temp.bat; \ + rm _temp.bat; \ + done \ + fi +else +install-data-local: + if test -z "$(DESTDIR)" ; then \ + for p in $(schema_DATA) ; do \ + GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) \ + $(GCONFTOOL) --makefile-install-rule $$p; \ + done \ + fi +endif + +endif + +DISTCLEANFILES = $(schema_DATA) + +EXTRA_DIST = $(schema_in_files) + +-include $(top_srcdir)/git.mk diff --git a/modules/spamassassin/evolution-spamassassin.c b/modules/spamassassin/evolution-spamassassin.c new file mode 100644 index 0000000000..6107694713 --- /dev/null +++ b/modules/spamassassin/evolution-spamassassin.c @@ -0,0 +1,1177 @@ +/* + * evolution-spamassassin.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 <config.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <glib/gi18n-lib.h> + +#include <camel/camel.h> + +#include <e-util/e-mktemp.h> +#include <e-util/gconf-bridge.h> +#include <mail/e-mail-junk-filter.h> + +/* Standard GObject macros */ +#define E_TYPE_SPAM_ASSASSIN \ + (e_spam_assassin_get_type ()) +#define E_SPAM_ASSASSIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SPAM_ASSASSIN, ESpamAssassin)) + +#ifndef SPAMASSASSIN_BINARY +#define SPAMASSASSIN_BINARY "/usr/bin/spamassassin" +#endif + +#ifndef SA_LEARN_BINARY +#define SA_LEARN_BINARY "/usr/bin/sa-learn" +#endif + +#ifndef SPAMC_BINARY +#define SPAMC_BINARY "/usr/bin/spamc" +#endif + +#ifndef SPAMD_BINARY +#define SPAMD_BINARY "/usr/bin/spamd" +#endif + +/* For starting our own daemon. */ +#define DAEMON_MAX_RETRIES 100 +#define DAEMON_RETRY_DELAY 0.05 /* seconds */ + +#define SPAM_ASSASSIN_EXIT_STATUS_SUCCESS 0 +#define SPAM_ASSASSIN_EXIT_STATUS_ERROR -1 + +typedef struct _ESpamAssassin ESpamAssassin; +typedef struct _ESpamAssassinClass ESpamAssassinClass; + +struct _ESpamAssassin { + EMailJunkFilter parent; + + GMutex *socket_path_mutex; + + gchar *pid_file; + gchar *socket_path; + gchar *spamc_binary; + gchar *spamd_binary; + gint version; + + gboolean local_only; + gboolean use_daemon; + gboolean version_set; + + /* spamc/spamd state */ + gboolean spamd_tested; + gboolean spamd_using_allow_tell; + gboolean system_spamd_available; + gboolean use_spamc; +}; + +struct _ESpamAssassinClass { + EMailJunkFilterClass parent_class; +}; + +enum { + PROP_0, + PROP_LOCAL_ONLY, + PROP_SPAMC_BINARY, + PROP_SPAMD_BINARY, + PROP_SOCKET_PATH, + PROP_USE_DAEMON +}; + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +/* Forward Declarations */ +GType e_spam_assassin_get_type (void); +static void e_spam_assassin_interface_init (CamelJunkFilterInterface *interface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED ( + ESpamAssassin, + e_spam_assassin, + E_TYPE_MAIL_JUNK_FILTER, 0, + G_IMPLEMENT_INTERFACE_DYNAMIC ( + CAMEL_TYPE_JUNK_FILTER, + e_spam_assassin_interface_init)) + +#ifdef G_OS_UNIX +static void +spam_assassin_cancelled_cb (GCancellable *cancellable, + GPid *pid) +{ + /* XXX On UNIX-like systems we can safely assume a GPid is the + * process ID and use it to terminate the process via signal. */ + kill (*pid, SIGTERM); +} +#endif + +static void +spam_assassin_exited_cb (GPid *pid, + gint status, + gpointer user_data) +{ + struct { + GMainLoop *loop; + gint exit_code; + } *source_data = user_data; + + if (WIFEXITED (status)) + source_data->exit_code = WEXITSTATUS (status); + else + source_data->exit_code = SPAM_ASSASSIN_EXIT_STATUS_ERROR; + + g_main_loop_quit (source_data->loop); +} + +static gint +spam_assassin_command_full (const gchar **argv, + CamelMimeMessage *message, + const gchar *input_data, + GByteArray *output_buffer, + GCancellable *cancellable, + GError **error) +{ + GMainContext *context; + GSpawnFlags flags; + GSource *source; + GPid child_pid; + gint standard_input; + gint standard_output; + gulong handler_id = 0; + gboolean success; + + struct { + GMainLoop *loop; + gint exit_code; + } source_data; + + flags = G_SPAWN_DO_NOT_REAP_CHILD; + if (output_buffer == NULL) + flags |= G_SPAWN_STDOUT_TO_DEV_NULL; + + /* Spawn SpamAssassin with an open stdin pipe. */ + success = g_spawn_async_with_pipes ( + NULL, + (gchar **) argv, + NULL, + flags, + NULL, NULL, + &child_pid, + &standard_input, + (output_buffer != NULL) ? &standard_output : NULL, + NULL, + error); + + if (!success) { + gchar *command_line; + + command_line = g_strjoinv (" ", (gchar **) argv); + g_prefix_error ( + error, _("Failed to spawn SpamAssassin (%s): "), + command_line); + g_free (command_line); + + return SPAM_ASSASSIN_EXIT_STATUS_ERROR; + } + + if (message != NULL) { + CamelStream *stream; + gssize bytes_written; + + /* Stream the CamelMimeMessage to SpamAssassin. */ + stream = camel_stream_fs_new_with_fd (standard_input); + bytes_written = camel_data_wrapper_write_to_stream_sync ( + CAMEL_DATA_WRAPPER (message), + stream, cancellable, error); + success = (bytes_written >= 0) && + (camel_stream_close (stream, cancellable, error) == 0); + g_object_unref (stream); + + if (!success) { + g_spawn_close_pid (child_pid); + g_prefix_error ( + error, _("Failed to stream mail " + "message content to SpamAssassin: ")); + return SPAM_ASSASSIN_EXIT_STATUS_ERROR; + } + + } else if (input_data != NULL) { + gssize bytes_written; + + /* Write raw data directly to SpamAssassin. */ + bytes_written = camel_write ( + standard_input, input_data, + strlen (input_data), cancellable, error); + success = (bytes_written >= 0); + + close (standard_input); + + if (!success) { + g_spawn_close_pid (child_pid); + g_prefix_error ( + error, _("Failed to write '%s' " + "to SpamAssassin: "), input_data); + return SPAM_ASSASSIN_EXIT_STATUS_ERROR; + } + } + + if (output_buffer != NULL) { + CamelStream *input_stream; + CamelStream *output_stream; + gssize bytes_written; + + input_stream = camel_stream_fs_new_with_fd (standard_output); + + output_stream = camel_stream_mem_new (); + camel_stream_mem_set_byte_array ( + CAMEL_STREAM_MEM (output_stream), output_buffer); + + bytes_written = camel_stream_write_to_stream ( + input_stream, output_stream, cancellable, error); + g_byte_array_append (output_buffer, (guint8 *) "", 1); + success = (bytes_written >= 0); + + g_object_unref (input_stream); + g_object_unref (output_stream); + + if (!success) { + g_spawn_close_pid (child_pid); + g_prefix_error ( + error, _("Failed to read " + "output from SpamAssassin: ")); + return SPAM_ASSASSIN_EXIT_STATUS_ERROR; + } + } + + /* Wait for the SpamAssassin process to terminate + * using GLib's main loop for better portability. */ + + context = g_main_context_new (); + + source = g_child_watch_source_new (child_pid); + g_source_set_callback ( + source, (GSourceFunc) + spam_assassin_exited_cb, + &source_data, NULL); + g_source_attach (source, context); + g_source_unref (source); + + source_data.loop = g_main_loop_new (context, TRUE); + source_data.exit_code = 0; + +#ifdef G_OS_UNIX + if (G_IS_CANCELLABLE (cancellable)) + handler_id = g_cancellable_connect ( + cancellable, + G_CALLBACK (spam_assassin_cancelled_cb), + &child_pid, (GDestroyNotify) NULL); +#endif + + g_main_loop_run (source_data.loop); + + if (handler_id > 0) + g_cancellable_disconnect (cancellable, handler_id); + + g_main_loop_unref (source_data.loop); + source_data.loop = NULL; + + g_main_context_unref (context); + + /* Clean up. */ + + g_spawn_close_pid (child_pid); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + source_data.exit_code = SPAM_ASSASSIN_EXIT_STATUS_ERROR; + + else if (source_data.exit_code == SPAM_ASSASSIN_EXIT_STATUS_ERROR) + g_set_error_literal ( + error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, + _("SpamAssassin either crashed or " + "failed to process a mail message")); + + return source_data.exit_code; +} + +static gint +spam_assassin_command (const gchar **argv, + CamelMimeMessage *message, + const gchar *input_data, + GCancellable *cancellable, + GError **error) +{ + return spam_assassin_command_full ( + argv, message, input_data, NULL, cancellable, error); +} + +static gboolean +spam_assassin_get_local_only (ESpamAssassin *extension) +{ + return extension->local_only; +} + +static void +spam_assassin_set_local_only (ESpamAssassin *extension, + gboolean local_only) +{ + extension->local_only = local_only; + + g_object_notify (G_OBJECT (extension), "local-only"); +} + +static const gchar * +spam_assassin_get_spamc_binary (ESpamAssassin *extension) +{ + return extension->spamc_binary; +} + +static void +spam_assassin_set_spamc_binary (ESpamAssassin *extension, + const gchar *spamc_binary) +{ + g_free (extension->spamc_binary); + extension->spamc_binary = g_strdup (spamc_binary); + + g_object_notify (G_OBJECT (extension), "spamc-binary"); +} + +static const gchar * +spam_assassin_get_spamd_binary (ESpamAssassin *extension) +{ + return extension->spamd_binary; +} + +static void +spam_assassin_set_spamd_binary (ESpamAssassin *extension, + const gchar *spamd_binary) +{ + g_free (extension->spamd_binary); + extension->spamd_binary = g_strdup (spamd_binary); + + g_object_notify (G_OBJECT (extension), "spamd-binary"); +} + +static const gchar * +spam_assassin_get_socket_path (ESpamAssassin *extension) +{ + return extension->socket_path; +} + +static void +spam_assassin_set_socket_path (ESpamAssassin *extension, + const gchar *socket_path) +{ + g_free (extension->socket_path); + extension->socket_path = g_strdup (socket_path); + + g_object_notify (G_OBJECT (extension), "socket-path"); +} + +static gboolean +spam_assassin_get_use_daemon (ESpamAssassin *extension) +{ + return extension->use_daemon; +} + +static void +spam_assassin_set_use_daemon (ESpamAssassin *extension, + gboolean use_daemon) +{ + extension->use_daemon = use_daemon; + + g_object_notify (G_OBJECT (extension), "use-daemon"); +} + +static gboolean +spam_assassin_get_version (ESpamAssassin *extension, + gint *spam_assassin_version, + GCancellable *cancellable, + GError **error) +{ + GByteArray *output_buffer; + gint exit_code; + guint ii; + + const gchar *argv[] = { + SA_LEARN_BINARY, + "--version", + NULL + }; + + if (extension->version_set) { + if (spam_assassin_version != NULL) + *spam_assassin_version = extension->version; + return TRUE; + } + + output_buffer = g_byte_array_new (); + + exit_code = spam_assassin_command_full ( + argv, NULL, NULL, output_buffer, cancellable, error); + + if (exit_code != 0) { + g_byte_array_free (output_buffer, TRUE); + return FALSE; + } + + for (ii = 0; ii < output_buffer->len; ii++) { + if (g_ascii_isdigit (output_buffer->data[ii])) { + guint8 ch = output_buffer->data[ii]; + extension->version = (ch - '0'); + extension->version_set = TRUE; + break; + } + } + + if (spam_assassin_version != NULL) + *spam_assassin_version = extension->version; + + g_byte_array_free (output_buffer, TRUE); + + return TRUE; +} + +static void +spam_assassin_test_spamd_allow_tell (ESpamAssassin *extension) +{ + gint exit_code; + GError *error = NULL; + + const gchar *argv[] = { + SPAMC_BINARY, + "--learntype=forget", + NULL + }; + + /* Check if spamd is running with --allow-tell. */ + + exit_code = spam_assassin_command (argv, NULL, "\n", NULL, &error); + extension->spamd_using_allow_tell = (exit_code == 0); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } +} + +static gboolean +spam_assassin_test_spamd_running (ESpamAssassin *extension, + gboolean system_spamd) +{ + const gchar *argv[5]; + gint exit_code; + gint ii = 0; + GError *error = NULL; + + g_mutex_lock (extension->socket_path_mutex); + + argv[ii++] = extension->spamc_binary; + argv[ii++] = "--no-safe-fallback"; + if (!system_spamd) { + argv[ii++] = "--socket"; + argv[ii++] = extension->socket_path; + } + argv[ii] = NULL; + + g_assert (ii < G_N_ELEMENTS (argv)); + + exit_code = spam_assassin_command ( + argv, NULL, "From test@127.0.0.1", NULL, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_mutex_unlock (extension->socket_path_mutex); + + return (exit_code == 0); +} + +static gboolean +spam_assassin_start_our_own_daemon (ESpamAssassin *extension) +{ + const gchar *argv[8]; + gchar *pid_file; + gchar *socket_path; + gboolean started = FALSE; + gint exit_code; + gint ii = 0; + GError *error = NULL; + + g_mutex_lock (extension->socket_path_mutex); + + pid_file = e_mktemp ("spamd-pid-file-XXXXXX"); + socket_path = e_mktemp ("spamd-socket-path-XXXXXX"); + + argv[ii++] = extension->spamd_binary; + argv[ii++] = "--socketpath"; + argv[ii++] = socket_path; + + if (spam_assassin_get_local_only (extension)) + argv[ii++] = "--local"; + + argv[ii++] = "--max-children=1"; + argv[ii++] = "--pidfile"; + argv[ii++] = pid_file; + argv[ii] = NULL; + + g_assert (ii < G_N_ELEMENTS (argv)); + + exit_code = spam_assassin_command (argv, NULL, NULL, NULL, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + goto exit; + } + + if (exit_code == 0) { + /* Wait for the socket path to appear. */ + for (ii = 0; ii < DAEMON_MAX_RETRIES; ii++) { + if (g_file_test (socket_path, G_FILE_TEST_EXISTS)) { + started = TRUE; + break; + } + g_usleep (DAEMON_RETRY_DELAY * G_USEC_PER_SEC); + } + } + + /* Set these directly to avoid emitting "notify" signals. */ + if (started) { + g_free (extension->pid_file); + extension->pid_file = pid_file; + pid_file = NULL; + + g_free (extension->socket_path); + extension->socket_path = socket_path; + socket_path = NULL; + } + +exit: + g_free (pid_file); + g_free (socket_path); + + g_mutex_unlock (extension->socket_path_mutex); + + return started; +} + +static void +spam_assassin_kill_our_own_daemon (ESpamAssassin *extension) +{ + gint pid; + gchar *contents = NULL; + GError *error = NULL; + + g_mutex_lock (extension->socket_path_mutex); + + g_free (extension->socket_path); + extension->socket_path = NULL; + + g_mutex_unlock (extension->socket_path_mutex); + + if (extension->pid_file == NULL) + return; + + g_file_get_contents (extension->pid_file, &contents, NULL, &error); + + if (error != NULL) { + g_warn_if_fail (contents == NULL); + g_warning ("%s", error->message); + g_error_free (error); + return; + } + + g_return_if_fail (contents != NULL); + + pid = atoi (contents); + g_free (contents); + + if (pid > 0 && kill (pid, SIGTERM) == 0) + waitpid (pid, NULL, 0); +} + +static void +spam_assassin_test_spamd (ESpamAssassin *extension) +{ + const gchar *spamd_binary; + gboolean try_system_spamd; + + /* XXX SpamAssassin could really benefit from a D-Bus interface + * these days. These tests are just needlessly painful for + * clients trying to talk to an already-running spamd. */ + + extension->use_spamc = FALSE; + spamd_binary = extension->spamd_binary; + try_system_spamd = (g_strcmp0 (spamd_binary, SPAMD_BINARY) == 0); + + if (extension->local_only && try_system_spamd) { + gint exit_code; + + /* Run a shell command to check for a running + * spamd process with a -L/--local option or a + * -p/--port option. */ + + const gchar *argv[] = { + "/bin/sh", + "-c", + "ps ax | grep -v grep | " + "grep -E 'spamd.*(\\-L|\\-\\-local)' | " + "grep -E -v '\\ \\-p\\ |\\ \\-\\-port\\ '", + NULL + }; + + exit_code = spam_assassin_command ( + argv, NULL, NULL, NULL, NULL); + try_system_spamd = (exit_code == 0); + } + + /* Try to use the system spamd first. */ + if (try_system_spamd) { + if (spam_assassin_test_spamd_running (extension, TRUE)) { + extension->use_spamc = TRUE; + extension->system_spamd_available = TRUE; + } + } + + /* If there's no system spamd running, try + * to use one with a user specified socket. */ + if (!extension->use_spamc && extension->socket_path != NULL) { + if (spam_assassin_test_spamd_running (extension, FALSE)) { + extension->use_spamc = TRUE; + extension->system_spamd_available = FALSE; + } + } + + /* Still unsuccessful? Try to start our own spamd. */ + if (!extension->use_spamc) { + extension->use_spamc = + spam_assassin_start_our_own_daemon (extension) && + spam_assassin_test_spamd_running (extension, FALSE); + } +} + +static void +spam_assassin_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_LOCAL_ONLY: + spam_assassin_set_local_only ( + E_SPAM_ASSASSIN (object), + g_value_get_boolean (value)); + return; + + case PROP_SPAMC_BINARY: + spam_assassin_set_spamc_binary ( + E_SPAM_ASSASSIN (object), + g_value_get_string (value)); + return; + + case PROP_SPAMD_BINARY: + spam_assassin_set_spamd_binary ( + E_SPAM_ASSASSIN (object), + g_value_get_string (value)); + return; + + case PROP_SOCKET_PATH: + spam_assassin_set_socket_path ( + E_SPAM_ASSASSIN (object), + g_value_get_string (value)); + return; + + case PROP_USE_DAEMON: + spam_assassin_set_use_daemon ( + E_SPAM_ASSASSIN (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +spam_assassin_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_LOCAL_ONLY: + g_value_set_boolean ( + value, spam_assassin_get_local_only ( + E_SPAM_ASSASSIN (object))); + return; + + case PROP_SPAMC_BINARY: + g_value_set_string ( + value, spam_assassin_get_spamc_binary ( + E_SPAM_ASSASSIN (object))); + return; + + case PROP_SPAMD_BINARY: + g_value_set_string ( + value, spam_assassin_get_spamd_binary ( + E_SPAM_ASSASSIN (object))); + return; + + case PROP_SOCKET_PATH: + g_value_set_string ( + value, spam_assassin_get_socket_path ( + E_SPAM_ASSASSIN (object))); + return; + + case PROP_USE_DAEMON: + g_value_set_boolean ( + value, spam_assassin_get_use_daemon ( + E_SPAM_ASSASSIN (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +spam_assassin_finalize (GObject *object) +{ + ESpamAssassin *extension = E_SPAM_ASSASSIN (object); + + /* If we started our own daemon, kill it. */ + spam_assassin_kill_our_own_daemon (extension); + + g_mutex_free (extension->socket_path_mutex); + + g_free (extension->pid_file); + g_free (extension->socket_path); + g_free (extension->spamc_binary); + g_free (extension->spamd_binary); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_spam_assassin_parent_class)->finalize (object); +} + +static gboolean +spam_assassin_available (EMailJunkFilter *junk_filter) +{ + ESpamAssassin *extension = E_SPAM_ASSASSIN (junk_filter); + gboolean available; + GError *error = NULL; + + available = spam_assassin_get_version (extension, NULL, NULL, &error); + + /* XXX These tests block like crazy so maybe this isn't the best + * place to be doing this, but the first available() call is + * done at startup before the UI is shown. So hopefully the + * delay will not be noticeable. */ + if (available && extension->use_daemon && !extension->spamd_tested) { + extension->spamd_tested = TRUE; + spam_assassin_test_spamd (extension); + spam_assassin_test_spamd_allow_tell (extension); + } + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + return available; +} + +static GtkWidget * +spam_assassin_new_config_widget (EMailJunkFilter *junk_filter) +{ + GtkWidget *box; + GtkWidget *widget; + GtkWidget *container; + gchar *markup; + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + + markup = g_markup_printf_escaped ( + "<b>%s</b>", _("SpamAssassin Options")); + widget = gtk_label_new (markup); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + g_free (markup); + + widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_check_button_new_with_mnemonic ( + _("I_nclude remote tests")); + gtk_widget_set_margin_left (widget, 12); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_object_bind_property ( + junk_filter, "local-only", + widget, "active", + G_BINDING_BIDIRECTIONAL | + G_BINDING_SYNC_CREATE | + G_BINDING_INVERT_BOOLEAN); + + markup = g_markup_printf_escaped ( + "<small>%s</small>", + _("This will make SpamAssassin more reliable, but slower.")); + widget = gtk_label_new (markup); + gtk_widget_set_margin_left (widget, 36); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + g_free (markup); + + return box; +} + +static gboolean +spam_assassin_classify (CamelJunkFilter *junk_filter, + CamelMimeMessage *message, + CamelJunkStatus *status, + GCancellable *cancellable, + GError **error) +{ + ESpamAssassin *extension = E_SPAM_ASSASSIN (junk_filter); + const gchar *argv[7]; + gboolean using_spamc; + gint exit_code; + gint ii = 0; + + g_mutex_lock (extension->socket_path_mutex); + + using_spamc = (extension->use_spamc && extension->use_daemon); + + if (using_spamc) { + argv[ii++] = extension->spamc_binary; + argv[ii++] = "--check"; + argv[ii++] = "--timeout=60"; + if (!extension->system_spamd_available) { + argv[ii++] = "--socket"; + argv[ii++] = extension->socket_path; + } + } else { + argv[ii++] = SPAMASSASSIN_BINARY; + argv[ii++] = "--exit-code"; + if (extension->local_only) + argv[ii++] = "--local"; + } + argv[ii] = NULL; + + g_assert (ii < G_N_ELEMENTS (argv)); + + exit_code = spam_assassin_command ( + argv, message, NULL, cancellable, error); + + /* For either program, exit code 0 means the message is ham. */ + if (exit_code == 0) + *status = CAMEL_JUNK_STATUS_MESSAGE_IS_NOT_JUNK; + + /* spamassassin(1) only specifies zero and non-zero exit codes. */ + else if (!using_spamc) + *status = CAMEL_JUNK_STATUS_MESSAGE_IS_JUNK; + + /* Whereas spamc(1) explicitly states exit code 1 means spam. */ + else if (exit_code == 1) + *status = CAMEL_JUNK_STATUS_MESSAGE_IS_JUNK; + + /* Consider any other spamc(1) exit code to be inconclusive + * since it most likely failed to process the message. */ + else + *status = CAMEL_JUNK_STATUS_INCONCLUSIVE; + + /* Check that the return value and GError agree. */ + if (exit_code != SPAM_ASSASSIN_EXIT_STATUS_ERROR) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + g_mutex_unlock (extension->socket_path_mutex); + + return (exit_code != SPAM_ASSASSIN_EXIT_STATUS_ERROR); +} + +static gboolean +spam_assassin_learn_junk (CamelJunkFilter *junk_filter, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error) +{ + ESpamAssassin *extension = E_SPAM_ASSASSIN (junk_filter); + const gchar *argv[5]; + gint exit_code; + gint ii = 0; + + if (extension->spamd_using_allow_tell) { + argv[ii++] = extension->spamc_binary; + argv[ii++] = "--learntype=spam"; + } else { + argv[ii++] = SA_LEARN_BINARY; + argv[ii++] = "--spam"; + if (extension->version >= 3) + argv[ii++] = "--no-sync"; + else + argv[ii++] = "--no-rebuild"; + if (extension->local_only) + argv[ii++] = "--local"; + } + argv[ii] = NULL; + + g_assert (ii < G_N_ELEMENTS (argv)); + + exit_code = spam_assassin_command ( + argv, message, NULL, cancellable, error); + + /* Check that the return value and GError agree. */ + if (exit_code == SPAM_ASSASSIN_EXIT_STATUS_SUCCESS) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + return (exit_code == SPAM_ASSASSIN_EXIT_STATUS_SUCCESS); +} + +static gboolean +spam_assassin_learn_not_junk (CamelJunkFilter *junk_filter, + CamelMimeMessage *message, + GCancellable *cancellable, + GError **error) +{ + ESpamAssassin *extension = E_SPAM_ASSASSIN (junk_filter); + const gchar *argv[5]; + gint exit_code; + gint ii = 0; + + if (extension->spamd_using_allow_tell) { + argv[ii++] = extension->spamc_binary; + argv[ii++] = "--learntype=ham"; + } else { + argv[ii++] = SA_LEARN_BINARY; + argv[ii++] = "--ham"; + if (extension->version >= 3) + argv[ii++] = "--no-sync"; + else + argv[ii++] = "--no-rebuild"; + if (extension->local_only) + argv[ii++] = "--local"; + } + argv[ii] = NULL; + + g_assert (ii < G_N_ELEMENTS (argv)); + + exit_code = spam_assassin_command ( + argv, message, NULL, cancellable, error); + + /* Check that the return value and GError agree. */ + if (exit_code == SPAM_ASSASSIN_EXIT_STATUS_SUCCESS) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + return (exit_code == SPAM_ASSASSIN_EXIT_STATUS_SUCCESS); +} + +static gboolean +spam_assassin_synchronize (CamelJunkFilter *junk_filter, + GCancellable *cancellable, + GError **error) +{ + ESpamAssassin *extension = E_SPAM_ASSASSIN (junk_filter); + const gchar *argv[4]; + gint exit_code; + gint ii = 0; + + /* If we're using a spamd that allows learning, + * there's no need to synchronize anything. */ + if (extension->spamd_using_allow_tell) + return TRUE; + + argv[ii++] = SA_LEARN_BINARY; + if (extension->version >= 3) + argv[ii++] = "--sync"; + else + argv[ii++] = "--rebuild"; + if (extension->local_only) + argv[ii++] = "--local"; + argv[ii] = NULL; + + g_assert (ii < G_N_ELEMENTS (argv)); + + exit_code = spam_assassin_command ( + argv, NULL, NULL, cancellable, error); + + /* Check that the return value and GError agree. */ + if (exit_code == SPAM_ASSASSIN_EXIT_STATUS_SUCCESS) + g_warn_if_fail (error == NULL || *error == NULL); + else + g_warn_if_fail (error == NULL || *error != NULL); + + return (exit_code == SPAM_ASSASSIN_EXIT_STATUS_SUCCESS); +} + +static void +e_spam_assassin_class_init (ESpamAssassinClass *class) +{ + GObjectClass *object_class; + EMailJunkFilterClass *junk_filter_class; + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = spam_assassin_set_property; + object_class->get_property = spam_assassin_get_property; + object_class->finalize = spam_assassin_finalize; + + junk_filter_class = E_MAIL_JUNK_FILTER_CLASS (class); + junk_filter_class->filter_name = "SpamAssassin"; + junk_filter_class->display_name = _("SpamAssassin"); + junk_filter_class->available = spam_assassin_available; + junk_filter_class->new_config_widget = spam_assassin_new_config_widget; + + /* XXX Argh, the boolean sense of the GConf key is inverted from + * that of the checkbox widget. The checkbox wording is more + * natural, but GConfBridge doesn't support transform functions + * so the property has to match the sense of the GConf key. */ + g_object_class_install_property ( + object_class, + PROP_LOCAL_ONLY, + g_param_spec_boolean ( + "local-only", + "Local Only", + "Do not use tests requiring DNS lookups", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_SPAMC_BINARY, + g_param_spec_string ( + "spamc-binary", + "spamc Binary", + "File path for the spamc binary", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_SPAMD_BINARY, + g_param_spec_string ( + "spamd-binary", + "spamd Binary", + "File path for the spamd binary", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_SOCKET_PATH, + g_param_spec_string ( + "socket-path", + "Socket Path", + "Socket path for a SpamAssassin daemon", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_USE_DAEMON, + g_param_spec_boolean ( + "use-daemon", + "Use Daemon", + "Whether to use a SpamAssassin daemon", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_spam_assassin_class_finalize (ESpamAssassinClass *class) +{ +} + +static void +e_spam_assassin_interface_init (CamelJunkFilterInterface *interface) +{ + interface->classify = spam_assassin_classify; + interface->learn_junk = spam_assassin_learn_junk; + interface->learn_not_junk = spam_assassin_learn_not_junk; + interface->synchronize = spam_assassin_synchronize; +} + +static void +e_spam_assassin_init (ESpamAssassin *extension) +{ + extension->socket_path_mutex = g_mutex_new (); + + /* XXX Once we move to GSettings these probably don't + * need to be properties anymore. GConfBridge is + * just easier to deal with than GConfClient. */ + + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/sa/local_only", + G_OBJECT (extension), "local-only"); + + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/sa/spamc_binary", + G_OBJECT (extension), "spamc-binary"); + + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/sa/spamd_binary", + G_OBJECT (extension), "spamd-binary"); + + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/sa/socket_path", + G_OBJECT (extension), "socket-path"); + + gconf_bridge_bind_property ( + gconf_bridge_get (), + "/apps/evolution/mail/junk/sa/use_daemon", + G_OBJECT (extension), "use-daemon"); + + if (extension->spamc_binary == NULL) + extension->spamc_binary = g_strdup (SPAMC_BINARY); + + if (extension->spamd_binary == NULL) + extension->spamd_binary = g_strdup (SPAMD_BINARY); +} + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_spam_assassin_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} diff --git a/modules/spamassassin/evolution-spamassassin.schemas.in b/modules/spamassassin/evolution-spamassassin.schemas.in new file mode 100644 index 0000000000..b344d1bffd --- /dev/null +++ b/modules/spamassassin/evolution-spamassassin.schemas.in @@ -0,0 +1,33 @@ +<gconfschemafile> + <schemalist> + + <schema> + <key>/schemas/apps/evolution/mail/junk/sa/local_only</key> + <applyto>/apps/evolution/mail/junk/sa/local_only</applyto> + <owner>evolution-spamassassin</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Use only local spam tests.</short> + <long> + Use only the local spam tests (no DNS). + </long> + </locale> + </schema> + + <schema> + <key>/schemas/apps/evolution/mail/junk/sa/use_daemon</key> + <applyto>/apps/evolution/mail/junk/sa/use_daemon</applyto> + <owner>evolution-spamassassin</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Use SpamAssassin daemon and client</short> + <long> + Use SpamAssassin daemon and client (spamc/spamd). + </long> + </locale> + </schema> + + </schemalist> +</gconfschemafile> diff --git a/plugins/bogo-junk-plugin/Makefile.am b/plugins/bogo-junk-plugin/Makefile.am deleted file mode 100644 index c4ee4a65ac..0000000000 --- a/plugins/bogo-junk-plugin/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-bogo-junk-plugin.eplug - -plugin_LTLIBRARIES = liborg-gnome-bogo-junk-plugin.la - -liborg_gnome_bogo_junk_plugin_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -DWELCOME_MESSAGE=\""$(privdatadir)/default/C/mail/local/Inbox"\" \ - $(GNOME_PLATFORM_CFLAGS) \ - $(EVOLUTION_MAIL_CFLAGS) - -liborg_gnome_bogo_junk_plugin_la_SOURCES = bf-junk-filter.c - -liborg_gnome_bogo_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_bogo_junk_plugin_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/shell/libeshell.la \ - $(EVOLUTION_MAIL_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -schemadir = $(GCONF_SCHEMA_FILE_DIR) -schema_in_files = bogo-junk-plugin.schemas.in -schema_DATA = $(schema_in_files:.schemas.in=.schemas) - -@INTLTOOL_SCHEMAS_RULE@ - -if GCONF_SCHEMAS_INSTALL - -if OS_WIN32 -install-data-local: - if test -z "$(DESTDIR)" ; then \ - for p in $(schema_DATA) ; do \ - (echo set GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE); \ - echo $(GCONFTOOL) --makefile-install-rule $$p) >_temp.bat; \ - cmd /c _temp.bat; \ - rm _temp.bat; \ - done \ - fi -else -install-data-local: - if test -z "$(DESTDIR)" ; then \ - for p in $(schema_DATA) ; do \ - GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) \ - $(GCONFTOOL) --makefile-install-rule $$p; \ - done \ - fi -endif - -endif - - -BUILT_SOURCES = $(plugin_DATA) $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -DISTCLEANFILES = $(schema_DATA) - -EXTRA_DIST = \ - org-gnome-bogo-junk-plugin.eplug.xml \ - $(schema_in_files) - - --include $(top_srcdir)/git.mk diff --git a/plugins/bogo-junk-plugin/README b/plugins/bogo-junk-plugin/README deleted file mode 100644 index a14bcf6dda..0000000000 --- a/plugins/bogo-junk-plugin/README +++ /dev/null @@ -1,35 +0,0 @@ -Bogofilter plugin for Evolution - -This plugin implements junk filtering for the Evolution mailer, -provided by the bogofilter utility. Bogofilter (http://www.bogofilter.org) -if a fast and nimble mail filter using a so-called Bayesian technique to -classify junk and non-junk email. - -CAVEATS: - -For Evolution versions before 2.5.2, the definition file for the stock -junk filter plugin, 'org-gnome-sa-junk-plugin.eplug', must be removed -from the plugin directory to avoid conflict with any alternate junk plugin. -Simply disabling the SA plugin in the configuration won't help. -This is due to a flaw in the loading code for this hook type -(see GNOME bug #313096). - -To be able to classify emails as spam, bogofilter needs to have some -messages in its ham (non-spam) wordlist. This presents something of a -chicken-and-egg problem for Evolution, because it can feed messages -to the junk filter for learning as non-junk only after these messages have been -classified as junk and moved into a junk folder (GNOME bug #322105). -Thus, if you haven't got a pre-existing bogofilter database, you may need -to feed it some messages known to be non-junk, using its -command line utility: - -bogofilter -n < saved-ham-message - -Alternatively, you may use Spam Trainer, which is a GUI tool that supports -drag-and-drop from Evolution: - -http://spamtrainer.sourceforge.net/ - -Set it up to use bogofilter commands for training: - Ham command: bogofilter -n < %f - Spam command: bogofilter -s < %f diff --git a/plugins/bogo-junk-plugin/bf-junk-filter.c b/plugins/bogo-junk-plugin/bf-junk-filter.c deleted file mode 100644 index 0d6726fd03..0000000000 --- a/plugins/bogo-junk-plugin/bf-junk-filter.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * 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/> - * - * - * Authors: - * Mikhail Zabaluev <mikhail.zabaluev@gmail.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright 2005 Mikhail Zabaluev <mikhail.zabaluev@gmail.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <signal.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -#define G_LOG_DOMAIN "bf-junk-filter" - -#ifndef G_OS_WIN32 -# include <sys/wait.h> -#else -# include <windows.h> -#endif - -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <e-util/e-plugin.h> -#include "mail/em-config.h" -#include <mail/em-junk.h> -#include <gconf/gconf-client.h> -#include "shell/e-shell.h" - -#ifndef BOGOFILTER_BINARY -#define BOGOFILTER_BINARY "/usr/bin/bogofilter" -#endif - -#define BOGOFILTER_ERROR 3 - -#define EM_JUNK_BF_GCONF_DIR "/apps/evolution/mail/junk/bogofilter" - -#define d(x) (camel_debug("junk")?(x):0) - -static gboolean is_installed = FALSE; - -static gchar em_junk_bf_binary[] = BOGOFILTER_BINARY; - -static const gchar em_junk_bf_gconf_dir[] = EM_JUNK_BF_GCONF_DIR; -GtkWidget * org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data); - -/* plugin fonction prototypes */ -gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target); -gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target); - -static gint -pipe_to_bogofilter (CamelMimeMessage *msg, - const gchar **argv, - GCancellable *cancellable, - GError **error); - -/* eplugin stuff */ -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -#define EM_JUNK_BF_GCONF_DIR_LENGTH (G_N_ELEMENTS (em_junk_bf_gconf_dir) - 1) - -static gboolean em_junk_bf_unicode = TRUE; - -static void -init_db (void) -{ - CamelStream *stream = camel_stream_fs_new_with_name (WELCOME_MESSAGE, O_RDONLY, 0, NULL); - CamelMimeParser *parser = camel_mime_parser_new (); - CamelMimeMessage *msg = camel_mime_message_new (); - const gchar *argv[] = { - em_junk_bf_binary, - "-n", - NULL, - NULL - }; - - camel_mime_parser_init_with_stream (parser, stream, NULL); - camel_mime_parser_scan_from (parser, FALSE); - g_object_unref (stream); - - camel_mime_part_construct_from_parser_sync ( - (CamelMimePart *) msg, parser, NULL, NULL); - g_object_unref (parser); - - d(fprintf (stderr, "Initing the bogofilter DB with Welcome message\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, NULL); - g_object_unref (msg); - -} - -static gint -pipe_to_bogofilter (CamelMimeMessage *msg, - const gchar **argv, - GCancellable *cancellable, - GError **error) -{ - GPid child_pid; - gint bf_in; - CamelStream *stream; - GError *err = NULL; - gint status; - gint waitres; - gint res; - static gboolean only_once = FALSE; - -retry: - if (camel_debug_start ("junk")) { - gint i; - - printf ("pipe_to_bogofilter "); - for (i = 0; argv[i]; i++) - printf ("%s ", argv[i]); - printf ("\n"); - camel_debug_end (); - } - - if (!g_spawn_async_with_pipes (NULL, - (gchar **) argv, - NULL, - G_SPAWN_DO_NOT_REAP_CHILD | - G_SPAWN_STDOUT_TO_DEV_NULL, - NULL, - NULL, - &child_pid, - &bf_in, - NULL, - NULL, - &err)) - { - g_warning ("error occurred while spawning %s: %s", argv[0], err->message); - - if (g_error_matches (err, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT)) { - if (is_installed) - g_set_error (error, EM_JUNK_ERROR, err->code, _("Bogofilter is not available. Please install it first.")); - is_installed = FALSE; - } else { - /* For Translators: The first %s stands for the executable full path with a file name, the second is the error message itself. */ - g_set_error (error, EM_JUNK_ERROR, err->code, _("Error occurred while spawning %s: %s."), argv[0], err->message); - } - - g_error_free (err); - - return BOGOFILTER_ERROR; - } - - stream = camel_stream_fs_new_with_fd (bf_in); - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL); - camel_stream_flush (stream, cancellable, NULL); - camel_stream_close (stream, cancellable, NULL); - g_object_unref (stream); - -#ifndef G_OS_WIN32 - waitres = waitpid (child_pid, &status, 0); - if (waitres < 0 && errno == EINTR) { - /* child process is hanging... */ - g_warning ("wait for bogofilter child process interrupted, terminating"); - kill (child_pid, SIGTERM); - sleep (1); - waitres = waitpid (child_pid, &status, WNOHANG); - if (waitres == 0) { - /* ...still hanging, set phasers to KILL */ - g_warning ("bogofilter child process does not respond, killing"); - kill (child_pid, SIGKILL); - sleep (1); - waitres = waitpid (child_pid, &status, WNOHANG); - g_set_error (error, EM_JUNK_ERROR, -2, _("Bogofilter child process does not respond, killing...")); - } else - g_set_error (error, EM_JUNK_ERROR, -3, _("Wait for Bogofilter child process interrupted, terminating...")); - } - - if (waitres >= 0 && WIFEXITED (status)) { - res = WEXITSTATUS (status); - } else { - res = BOGOFILTER_ERROR; - } -#else - WaitForSingleObject (child_pid, INFINITE); - GetExitCodeProcess (child_pid, &res); -#endif - - g_spawn_close_pid (child_pid); - - if (res < 0 || res > 2) { - if (!only_once) { - /* Create wordlist.db */ - only_once = TRUE; - init_db (); - - goto retry; - } - g_set_error (error, EM_JUNK_ERROR, res, _("Pipe to Bogofilter failed, error code: %d."), res); - - } - - return res; -} - -static void -em_junk_bf_setting_notify (GConfClient *gconf, - guint cnxn_id, - GConfEntry *entry, - void *data) -{ - const gchar *key; - GConfValue *value; - - value = gconf_entry_get_value (entry); - if (value == NULL) { - return; - } - - key = gconf_entry_get_key (entry); - g_return_if_fail (key != NULL); - - g_return_if_fail (!strncmp (key, em_junk_bf_gconf_dir, EM_JUNK_BF_GCONF_DIR_LENGTH)); - key += EM_JUNK_BF_GCONF_DIR_LENGTH; - - g_return_if_fail (*key == '/'); - ++key; - - if (strcmp (key, "unicode") == 0) { - em_junk_bf_unicode = gconf_value_get_bool (value); - } -} - -gboolean -em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - gint rv; - - const gchar *argv[] = { - em_junk_bf_binary, - NULL, - NULL - }; - - if (!is_installed) - return FALSE; - - d(fprintf (stderr, "em_junk_bf_check_junk\n")); - - if (em_junk_bf_unicode) { - argv[1] = "--unicode=yes"; - } - - rv = pipe_to_bogofilter (msg, argv, NULL, &target->error); - - d(fprintf (stderr, "em_junk_bf_check_junk rv = %d\n", rv)); - - return (rv == 0); -} - -void -em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - - const gchar *argv[] = { - em_junk_bf_binary, - "-s", - NULL, - NULL - }; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_bf_report_junk\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, &target->error); -} - -void -em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - - const gchar *argv[] = { - em_junk_bf_binary, - "-n", - NULL, - NULL - }; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_bf_report_non_junk\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, &target->error); -} - -void -em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target) -{ - if (!is_installed) - return; -} - -gpointer -em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target) -{ - gpointer res = g_file_test (em_junk_bf_binary, G_FILE_TEST_EXISTS) ? (gpointer) "1" : NULL; - - if (res != NULL) - is_installed = TRUE; - - return res; -} - -gint -e_plugin_lib_enable (EPlugin *ep, gint enable) -{ - static gboolean first = TRUE; - GConfClient *gconf; - - is_installed = enable != 0; - - if (!first) - return 0; - - first = FALSE; - gconf = gconf_client_get_default (); - - gconf_client_add_dir (gconf, - em_junk_bf_gconf_dir, - GCONF_CLIENT_PRELOAD_ONELEVEL, - NULL); - - gconf_client_notify_add (gconf, - em_junk_bf_gconf_dir, - em_junk_bf_setting_notify, - NULL, NULL, NULL); - - em_junk_bf_unicode = gconf_client_get_bool (gconf, - EM_JUNK_BF_GCONF_DIR "/unicode", NULL); - - g_object_unref (gconf); - - return 0; -} - -static void -convert_unicode_cb (GtkWidget *widget, gpointer data) -{ - - gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - GConfClient *gconf = gconf_client_get_default (); - - gconf_client_set_bool (gconf, data, active, NULL); - - g_object_unref (gconf); -} - -GtkWidget * -org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data) -{ - EShell *shell; - GtkWidget *check; - guint n_rows; - - g_object_get (data->parent, "n-rows", &n_rows, NULL); - - if (data->old) - return data->old; - - check = gtk_check_button_new_with_mnemonic (_("Convert message text to _Unicode")); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), em_junk_bf_unicode); - g_signal_connect (GTK_TOGGLE_BUTTON (check), "toggled", G_CALLBACK (convert_unicode_cb), (gpointer) "/apps/evolution/mail/junk/bogofilter/unicode"); - gtk_table_attach ( - GTK_TABLE (data->parent), check, - 0, 1, n_rows, n_rows+1, 0, 0, 0, 0); - - shell = e_shell_get_default (); - if (e_shell_get_express_mode (shell)) - gtk_widget_hide (check); - else - gtk_widget_show (check); - - return check; -} - diff --git a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml deleted file mode 100644 index 1317b988d9..0000000000 --- a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<e-plugin-list> - <e-plugin type="shlib" - location="@PLUGINDIR@/liborg-gnome-bogo-junk-plugin.so" - id="org.gnome.evolution.bogo.bf_junk_plugin" - _name="Bogofilter Junk Filter"> - <_description>Filter junk messages using Bogofilter.</_description> - <author name="Mikhail Zabaluev" email="mhz@altlinux.org"/> - <hook class="org.gnome.evolution.mail.junk:1.0"> - <interface name="Bogofilter" - report_non_junk="em_junk_bf_report_non_junk" - report_junk="em_junk_bf_report_junk" - check_junk="em_junk_bf_check_junk" - commit_reports="em_junk_bf_commit_reports" - validate_binary="em_junk_bf_validate_binary"/> - </hook> - <!-- hook into the 'mail properties' menu --> - <hook class="org.gnome.evolution.mail.config:1.0"> - <group target="prefs" id="org.gnome.evolution.mail.prefs"> - <item type="section_table" path="40.junk/30.options" _label="Bogofilter Options"/> - <item type="item_table" path="40.junk/40.options" factory="org_gnome_bogo_convert_unicode"/> - </group> - </hook> - - </e-plugin> -</e-plugin-list> diff --git a/plugins/sa-junk-plugin/Makefile.am b/plugins/sa-junk-plugin/Makefile.am deleted file mode 100644 index 0452fcd6ec..0000000000 --- a/plugins/sa-junk-plugin/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-sa-junk-plugin.eplug - -plugin_LTLIBRARIES = liborg-gnome-sa-junk-plugin.la - -liborg_gnome_sa_junk_plugin_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - $(GNOME_PLATFORM_CFLAGS) \ - $(EVOLUTION_MAIL_CFLAGS) - -liborg_gnome_sa_junk_plugin_la_SOURCES = em-junk-filter.c - -liborg_gnome_sa_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_sa_junk_plugin_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/shell/libeshell.la \ - $(EVOLUTION_MAIL_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -BUILT_SOURCES = $(plugin_DATA) $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = org-gnome-sa-junk-plugin.eplug.xml - --include $(top_srcdir)/git.mk diff --git a/plugins/sa-junk-plugin/em-junk-filter.c b/plugins/sa-junk-plugin/em-junk-filter.c deleted file mode 100644 index 635e1192c4..0000000000 --- a/plugins/sa-junk-plugin/em-junk-filter.c +++ /dev/null @@ -1,966 +0,0 @@ -/* - * 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/> - * - * - * Authors: - * Radek Doulik <rodo@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <signal.h> -#include <time.h> - -#include <mail/em-junk.h> -#include <mail/em-utils.h> -#include <e-util/e-mktemp.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include "mail/em-config.h" -#include "shell/e-shell.h" - -#include <gconf/gconf-client.h> - -#define d(x) (camel_debug("junk")?(x):0) - -G_LOCK_DEFINE_STATIC (init); -G_LOCK_DEFINE_STATIC (report); -G_LOCK_DEFINE_STATIC (socket_path); -G_LOCK_DEFINE_STATIC (spamd_restart); - -gint e_plugin_lib_enable (EPlugin *ep, gint enable); -gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_sa_commit_reports (EPlugin *ep); -gpointer em_junk_sa_validate_binary (EPlugin *ep); -GtkWidget *org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data); - -static void em_junk_sa_init (void); -static void em_junk_sa_finalize (void); -static void em_junk_sa_kill_spamd (void); - -static gboolean em_junk_sa_tested = FALSE; -static gboolean em_junk_sa_spamd_tested = FALSE; -static gboolean em_junk_sa_use_spamc = FALSE; -static gboolean em_junk_sa_available = FALSE; -static gboolean em_junk_sa_system_spamd_available = FALSE; -static gboolean em_junk_sa_new_daemon_started = FALSE; -static gboolean em_junk_sa_checked_spamassassin_version = FALSE; -static guint em_junk_sa_spamassassin_version = 0; -static gchar *em_junk_sa_socket_path = NULL; -static gchar *em_junk_sa_spamd_pidfile = NULL; -static const gchar *em_junk_sa_spamc_binary = NULL; -static GConfClient *em_junk_sa_gconf = NULL; - -/* volatile so not cached between threads */ -static volatile gboolean em_junk_sa_local_only; -static volatile gboolean em_junk_sa_use_daemon; -static gchar * em_junk_sa_preferred_socket_path; - -static const gchar *em_junk_sa_spamc_binaries [4] = {"spamc", "/usr/bin/spamc", "/usr/sbin/spamc", NULL}; -static const gchar *em_junk_sa_spamd_binaries [4] = {"spamd", "/usr/bin/spamd", "/usr/sbin/spamd", NULL}; - -#define SPAMD_RESTARTS_SIZE 8 -static time_t em_junk_sa_spamd_restarts[SPAMD_RESTARTS_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0}; -static gint em_junk_sa_spamd_restarts_count = 0; - -/* Variables to indicate whether spamd is running with --allow-tell */ -static gint no_allow_tell; -static gboolean em_junk_sa_allow_tell_tested = FALSE; -static gboolean is_installed = FALSE; - -gchar *em_junk_sa_spamc_gconf_binary = NULL; -gchar *em_junk_sa_spamd_gconf_binary = NULL; - -static gint -pipe_to_sa_full (CamelMimeMessage *msg, - const gchar *in, - const gchar **argv, - gint rv_err, - gint wait_for_termination, - GByteArray *output_buffer, - GCancellable *cancellable, - GError **error) -{ - gint result, status, errnosav, fds[2], out_fds[2]; - CamelStream *stream; - gchar *program; - pid_t pid; - - if (camel_debug_start ("junk")) { - gint i; - - printf ("pipe_to_sa "); - for (i = 0; argv[i]; i++) - printf ("%s ", argv[i]); - printf ("\n"); - camel_debug_end (); - } - - program = g_find_program_in_path (argv[0]); - if (program == NULL) { - d(printf ("program not found, returning %d\n", rv_err)); - g_set_error (error, EM_JUNK_ERROR, rv_err, _("SpamAssassin not found, code: %d"), rv_err); - return rv_err; - } - g_free (program); - - if (pipe (fds) == -1) { - errnosav = errno; - d(printf ("failed to create a pipe (for use with SpamAssassin: %s\n", g_strerror (errno))); - g_set_error (error, EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), g_strerror (errnosav)); - errno = errnosav; - return rv_err; - } - - if (output_buffer && pipe (out_fds) == -1) { - errnosav = errno; - d(printf ("failed to create a pipe (for use with SpamAssassin: %s\n", g_strerror (errno))); - g_set_error (error, EM_JUNK_ERROR, errnosav, _("Failed to create pipe: %s"), g_strerror (errnosav)); - close (fds[0]); - close (fds[1]); - errno = errnosav; - return rv_err; - } - - if (!(pid = fork ())) { - /* child process */ - gint maxfd, fd, nullfd; - - nullfd = open ("/dev/null", O_WRONLY); - - if (dup2 (fds[0], STDIN_FILENO) == -1 || - dup2 (nullfd, STDERR_FILENO) == -1 || - (output_buffer == NULL && dup2 (nullfd, STDOUT_FILENO) == -1) || - (output_buffer != NULL && dup2 (out_fds[1], STDOUT_FILENO) == -1)) - _exit (rv_err & 0377); - close (fds[0]); - if (output_buffer) - close (out_fds[1]); - - setsid (); - - maxfd = sysconf (_SC_OPEN_MAX); - for (fd = 3; fd < maxfd; fd++) - fcntl (fd, F_SETFD, FD_CLOEXEC); - - execvp (argv[0], (gchar * const *) argv); - _exit (rv_err & 0377); - } else if (pid < 0) { - errnosav = errno; - close (fds[0]); - close (fds[1]); - if (output_buffer) { - close (out_fds[0]); - close (out_fds[1]); - } - if (errnosav != 0 && errnosav != -1) - g_set_error (error, EM_JUNK_ERROR, errnosav, _("Error after fork: %s"), g_strerror (errnosav)); - errno = errnosav; - return rv_err; - } - - /* parent process */ - close (fds[0]); - if (output_buffer) - close (out_fds[1]); - - if (msg) { - stream = camel_stream_fs_new_with_fd (fds[1]); - - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL); - camel_stream_flush (stream, cancellable, NULL); - camel_stream_close (stream, cancellable, NULL); - g_object_unref (stream); - } else if (in) { - camel_write (fds[1], in, strlen (in), cancellable, NULL); - close (fds[1]); - } - - if (output_buffer) { - CamelStream *memstream; - - stream = camel_stream_fs_new_with_fd (out_fds[0]); - - memstream = camel_stream_mem_new (); - camel_stream_mem_set_byte_array ( - CAMEL_STREAM_MEM (memstream), output_buffer); - - camel_stream_write_to_stream ( - stream, memstream, cancellable, NULL); - g_object_unref (stream); - g_byte_array_append (output_buffer, (guchar *)"", 1); - - d(printf ("child process output: %s len: %d\n", output_buffer->data, output_buffer->len)); - } - - if (wait_for_termination) { - gint res; - - d(printf ("wait for child %d termination\n", pid)); - result = waitpid (pid, &status, 0); - - d(printf ("child %d terminated with result %d status %d exited %d exitstatus %d\n", pid, result, status, WIFEXITED (status), WEXITSTATUS (status))); - - if (result == -1 && errno == EINTR) { - /* child process is hanging... */ - kill (pid, SIGTERM); - sleep (1); - result = waitpid (pid, &status, WNOHANG); - if (result == 0) { - /* ...still hanging, set phasers to KILL */ - kill (pid, SIGKILL); - sleep (1); - result = waitpid (pid, &status, WNOHANG); - g_set_error (error, EM_JUNK_ERROR, -2, _("SpamAssassin child process does not respond, killing...")); - } else - g_set_error (error, EM_JUNK_ERROR, -3, _("Wait for SpamAssassin child process interrupted, terminating...")); - } - - if (result != -1 && WIFEXITED (status)) - res = WEXITSTATUS (status); - else - res = rv_err; - - if (res >= 64) - g_set_error (error, EM_JUNK_ERROR, res, _("Pipe to SpamAssassin failed, error code: %d"), res); - - return res; - } else - return 0; -} - -static gint -pipe_to_sa (CamelMimeMessage *msg, - const gchar *in, - const gchar **argv, - GCancellable *cancellable, - GError **error) -{ - return pipe_to_sa_full (msg, in, argv, -1, 1, NULL, cancellable, error); -} - -static gchar * -em_junk_sa_get_socket_path () -{ - if (em_junk_sa_preferred_socket_path) - return em_junk_sa_preferred_socket_path; - else - return em_junk_sa_socket_path; -} - -static gboolean -em_junk_sa_test_spamd_running (const gchar *binary, gboolean system) -{ - const gchar *argv[5]; - gint i = 0; - gboolean rv; - - G_LOCK (socket_path); - - d(fprintf (stderr, "test if spamd is running (system %d) or using socket path %s\n", system, em_junk_sa_get_socket_path ())); - - argv[i++] = binary; - argv[i++] = "-x"; - - if (!system) { - argv[i++] = "-U"; - argv[i++] = em_junk_sa_get_socket_path (); - } - - argv[i] = NULL; - - rv = pipe_to_sa (NULL, "From test@127.0.0.1", argv, NULL, NULL) == 0; - - d(fprintf (stderr, "result: %d (%s)\n", rv, rv ? "success" : "failed")); - - G_UNLOCK (socket_path); - - return rv; -} - -/* - One time test to see if spamd is running with --allow-tell. The call - to spamc should return 0 if it is. (Thanks to Karsten Bräckelmann - for the idea). -*/ -static void -em_junk_sa_test_allow_tell (void) -{ - const gchar *argv[4] = { - "spamc", - "-L", - "forget", - NULL - }; - - no_allow_tell = pipe_to_sa (NULL, "\n" , argv, NULL, NULL); - em_junk_sa_allow_tell_tested = TRUE; -} - -static void -em_junk_sa_test_spamassassin (void) -{ - const gchar *argv[3] = { - "spamassassin", - "--version", - NULL, - }; - - if (pipe_to_sa (NULL, NULL, argv, NULL, NULL) != 0) - em_junk_sa_available = FALSE; - else - em_junk_sa_available = TRUE; - - em_junk_sa_tested = TRUE; -} - -#define MAX_SPAMD_PORTS 1 - -static gboolean -em_junk_sa_run_spamd (const gchar *binary) -{ - const gchar *argv[8]; - gint i; - gboolean rv = FALSE; - - G_LOCK (socket_path); - - d(fprintf (stderr, "looks like spamd is not running\n")); - - i = 0; - argv[i++] = binary; - argv[i++] = "--socketpath"; - argv[i++] = em_junk_sa_get_socket_path (); - - if (em_junk_sa_local_only) - argv[i++] = "--local"; - - /* See bug #268852*/ - argv[i++] = "--max-children=1"; - /*argv[i++] = "--daemonize";*/ - argv[i++] = "--pidfile"; - argv[i++] = em_junk_sa_spamd_pidfile; - argv[i] = NULL; - - d(fprintf (stderr, "trying to run %s with socket path %s\n", binary, em_junk_sa_get_socket_path ())); - - if (!pipe_to_sa_full (NULL, NULL, argv, -1, 0, NULL, NULL, NULL)) { - struct timespec time_req; - struct stat stat_buf; - - d(fprintf (stderr, "success\n")); - d(fprintf (stderr, "waiting for spamd to come up\n")); - - time_req.tv_sec = 0; - time_req.tv_nsec = 50000000; - - for (i = 0; i < 100; i++) { - if (stat (em_junk_sa_get_socket_path (), &stat_buf) == 0) { - d(fprintf (stderr, "socket created\n")); - break; - } - nanosleep (&time_req, NULL); - } - d(fprintf (stderr, "waiting is over (after %dms)\n", 50*i)); - - rv = TRUE; - } - - G_UNLOCK (socket_path); - - return rv; -} - -static void -em_junk_sa_start_own_daemon () -{ - gint b; - - em_junk_sa_new_daemon_started = FALSE; - - em_junk_sa_socket_path = e_mktemp ("spamd-socket-path-XXXXXX"); - em_junk_sa_spamd_pidfile = e_mktemp ("spamd-pid-file-XXXXXX"); - - for (b = 0; em_junk_sa_spamd_binaries[b]; b++) { - em_junk_sa_use_spamc = em_junk_sa_run_spamd (em_junk_sa_spamd_binaries[b]); - if (em_junk_sa_use_spamc) { - em_junk_sa_new_daemon_started = TRUE; - break; - } - } -} - -static void -em_junk_sa_find_spamc () -{ - if (em_junk_sa_use_spamc && em_junk_sa_new_daemon_started) { - gint b; - - em_junk_sa_use_spamc = FALSE; - for (b = 0; em_junk_sa_spamc_binaries[b]; b++) { - em_junk_sa_spamc_binary = em_junk_sa_spamc_binaries[b]; - if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, FALSE)) { - em_junk_sa_use_spamc = TRUE; - break; - } - } - } -} - -static void -em_junk_sa_test_spamd (void) -{ - const gchar *argv[4]; - gint i, b; - gboolean try_system_spamd = TRUE; - - if (em_junk_sa_spamc_gconf_binary) { - em_junk_sa_spamc_binaries[0] = em_junk_sa_spamc_gconf_binary; - em_junk_sa_spamc_binaries[1] = NULL; - } - - if (em_junk_sa_spamd_gconf_binary) { - em_junk_sa_spamd_binaries[0] = em_junk_sa_spamd_gconf_binary; - em_junk_sa_spamd_binaries[1] = NULL; - try_system_spamd = FALSE; - } - - em_junk_sa_use_spamc = FALSE; - - if (em_junk_sa_local_only && try_system_spamd) { - i = 0; - argv [i++] = "/bin/sh"; - argv [i++] = "-c"; - argv [i++] = "ps ax|grep -v grep|grep -E 'spamd.*(\\-L|\\-\\-local)'|grep -E -v '\\ \\-p\\ |\\ \\-\\-port\\ '"; - argv[i] = NULL; - - if (pipe_to_sa (NULL, NULL, argv, NULL, NULL) != 0) { - try_system_spamd = FALSE; - d(fprintf (stderr, "there's no system spamd with -L/--local parameter running\n")); - } - } - - /* try to use sytem spamd first */ - if (try_system_spamd) { - for (b = 0; em_junk_sa_spamc_binaries[b]; b++) { - em_junk_sa_spamc_binary = em_junk_sa_spamc_binaries[b]; - if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, TRUE)) { - em_junk_sa_use_spamc = TRUE; - em_junk_sa_system_spamd_available = TRUE; - break; - } - } - } - - /* if there's no system spamd running, try to use user one with user specified socket */ - if (!em_junk_sa_use_spamc && em_junk_sa_preferred_socket_path) { - for (b = 0; em_junk_sa_spamc_binaries[b]; b++) { - em_junk_sa_spamc_binary = em_junk_sa_spamc_binaries[b]; - if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, FALSE)) { - em_junk_sa_use_spamc = TRUE; - em_junk_sa_system_spamd_available = FALSE; - break; - } - } - } - - /* unsuccessful? try to run one ourselfs */ - if (!em_junk_sa_use_spamc) - em_junk_sa_start_own_daemon (); - - /* new daemon started => let find spamc binary */ - em_junk_sa_find_spamc (); - - d(fprintf (stderr, "use spamd: %s\n", em_junk_sa_use_spamc ? "yes" : "no")); - - em_junk_sa_spamd_tested = TRUE; -} - -static gboolean -em_junk_sa_is_available (GError **error) -{ - G_LOCK (init); - - if (!em_junk_sa_tested) - em_junk_sa_test_spamassassin (); - - if (em_junk_sa_available && !em_junk_sa_spamd_tested && em_junk_sa_use_daemon) - em_junk_sa_test_spamd (); - - if (!em_junk_sa_available && error) { - if (is_installed) - g_set_error (error, EM_JUNK_ERROR, 1, _("SpamAssassin is not available. Please install it first.")); - - is_installed = FALSE; - } - - /* While we're at it, see if spamd is running with --allow-tell */ - if (!em_junk_sa_allow_tell_tested) - em_junk_sa_test_allow_tell (); - - G_UNLOCK (init); - - return em_junk_sa_available; -} - -static gboolean -em_junk_sa_check_respawn_too_fast () -{ - time_t time_now = time (NULL); - gboolean rv; - - G_LOCK (spamd_restart); - - if (em_junk_sa_spamd_restarts_count >= SPAMD_RESTARTS_SIZE) { - /* all restarts in last 5 minutes */ - rv = (time_now - em_junk_sa_spamd_restarts[em_junk_sa_spamd_restarts_count % SPAMD_RESTARTS_SIZE] < 5*60); - } else - rv = FALSE; - - em_junk_sa_spamd_restarts[em_junk_sa_spamd_restarts_count % SPAMD_RESTARTS_SIZE] = time_now; - em_junk_sa_spamd_restarts_count++; - - G_UNLOCK (spamd_restart); - - d(printf ("em_junk_sa_check_respawn_too_fast: %d\n", rv)); - - return rv; -} - -static gboolean -em_junk_sa_respawn_spamd () -{ - d(printf ("em_junk_sa_respawn_spamd\n")); - if (em_junk_sa_test_spamd_running (em_junk_sa_spamc_binary, em_junk_sa_system_spamd_available)) { - /* false alert */ - d(printf ("false alert, spamd still running\n")); - - return FALSE; - } - - d(printf ("going to kill old spamd and start new one\n")); - em_junk_sa_kill_spamd (); - - if (em_junk_sa_check_respawn_too_fast ()) { - g_warning ("respawning of spamd too fast => fallback to use SpamAssassin directly"); - - em_junk_sa_use_spamc = em_junk_sa_use_daemon = FALSE; - return FALSE; - } - - em_junk_sa_start_own_daemon (); - em_junk_sa_find_spamc (); - - d(printf ("%s\n", em_junk_sa_use_spamc ? "success" : "failed")); - - return em_junk_sa_use_spamc; -} - -gboolean -em_junk_sa_check_junk (EPlugin *ep, EMJunkTarget *target) -{ - GByteArray *out = NULL; - const gchar *argv[7]; - gchar *to_free = NULL; - gint i = 0, socket_i; - gboolean rv; - CamelMimeMessage *msg = target->m; - - if (!is_installed) - return FALSE; - - d(fprintf (stderr, "em_junk_sa_check_junk\n")); - - if (!em_junk_sa_is_available (&target->error)) { - return FALSE; - } - - if (em_junk_sa_use_spamc && em_junk_sa_use_daemon) { - out = g_byte_array_new (); - argv[i++] = em_junk_sa_spamc_binary; - argv[i++] = "-c"; - argv[i++] = "-t"; - argv[i++] = "60"; - if (!em_junk_sa_system_spamd_available) { - argv[i++] = "-U"; - - G_LOCK (socket_path); - socket_i = i; - argv[i++] = to_free = g_strdup (em_junk_sa_get_socket_path ()); - G_UNLOCK (socket_path); - } - } else { - argv [i++] = "spamassassin"; - argv [i++] = "--exit-code"; - if (em_junk_sa_local_only) - argv [i++] = "--local"; - } - - argv[i] = NULL; - - rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out, NULL, &target->error) != 0; - - if (!rv && out && out->data && !strcmp ((const gchar *)out->data, "0/0\n")) { - /* an error occurred */ - if (em_junk_sa_respawn_spamd ()) { - g_byte_array_set_size (out, 0); - - G_LOCK (socket_path); - g_free (to_free); - argv[socket_i] = to_free = g_strdup (em_junk_sa_get_socket_path ()); - G_UNLOCK (socket_path); - - rv = pipe_to_sa_full (msg, NULL, argv, 0, 1, out, NULL, &target->error) != 0; - } else if (!em_junk_sa_use_spamc) - /* in case respawning were too fast we fallback to spamassassin */ - rv = em_junk_sa_check_junk (ep, target); - } - - g_free (to_free); - - d(fprintf (stderr, "em_junk_sa_check_junk rv = %d\n", rv)); - - if (out) - g_byte_array_free (out, TRUE); - - return rv; -} - -static guint -get_spamassassin_version () -{ - GByteArray *out = NULL; - gint i; - - const gchar *argv[3] = { - "sa-learn", - "--version", - NULL - }; - - if (!em_junk_sa_checked_spamassassin_version) { - out = g_byte_array_new (); - - if (pipe_to_sa_full (NULL, NULL, argv, -1, 1, out, NULL, NULL) != 0) { - if (out) - g_byte_array_free (out, TRUE); - return em_junk_sa_spamassassin_version; - } - - if (out->len > 0) { - for (i = 0; i < out->len; i++) { - if (g_ascii_isdigit (out->data[i])) { - em_junk_sa_spamassassin_version = (out->data[i] - '0'); - em_junk_sa_checked_spamassassin_version = TRUE; - break; - } - } - } - - if (out) - g_byte_array_free (out, TRUE); - } - - return em_junk_sa_spamassassin_version; -} - -void -em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target) -{ - const gchar *sync_op = - (get_spamassassin_version () >= 3) - ? "--no-sync": "--no-rebuild"; - const gchar *argv[6] = { - "sa-learn", - sync_op, - "--spam", - "--single", - NULL, - NULL - }; - /* Call setup for spamc */ - const gchar *argv2[4] = { - "spamc", - "-L", - "spam", - NULL - }; - CamelMimeMessage *msg = target->m; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_sa_report_junk\n")); - if (em_junk_sa_is_available (&target->error)) { - if (no_allow_tell && em_junk_sa_local_only) - argv[4] = "--local"; - - G_LOCK (report); - pipe_to_sa (msg, NULL, - (no_allow_tell ? argv : argv2), - NULL, &target->error); - G_UNLOCK (report); - } -} - -void -em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target) -{ - const gchar *sync_op = - (get_spamassassin_version () >= 3) - ? "--no-sync": "--no-rebuild"; - const gchar *argv[6] = { - "sa-learn", - sync_op, - "--ham", - "--single", - NULL, - NULL - }; - /* Setup for spamc */ - const gchar *argv2[4] = { - "spamc", - "-L", - "ham", - NULL - }; - CamelMimeMessage *msg = target->m; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_sa_report_notjunk\n")); - - if (em_junk_sa_is_available (&target->error)) { - - if (no_allow_tell && em_junk_sa_local_only) - argv[4] = "--local"; - G_LOCK (report); - pipe_to_sa (msg, NULL, - (no_allow_tell ? argv : argv2), - NULL, &target->error); - G_UNLOCK (report); - } -} - -void -em_junk_sa_commit_reports (EPlugin *ep) -{ - const gchar *sync_op = - (get_spamassassin_version () >= 3) ? "--sync": "--rebuild"; - const gchar *argv[4] = { - "sa-learn", - sync_op, - NULL, - NULL - }; - - /* Only meaningful if we're using sa-learn */ - if (!no_allow_tell || !is_installed) - return; - - d(fprintf (stderr, "em_junk_sa_commit_reports\n")); - - if (em_junk_sa_is_available (NULL)) { - if (em_junk_sa_local_only) - argv[2] = "--local"; - - G_LOCK (report); - pipe_to_sa (NULL, NULL, argv, NULL, NULL); - G_UNLOCK (report); - } -} - -gpointer -em_junk_sa_validate_binary (EPlugin *ep) -{ - gpointer res = em_junk_sa_is_available (NULL) ? (gpointer) "1" : NULL; - - if (res != NULL) - is_installed = TRUE; - - return res; -} - -static void -em_junk_sa_setting_notify (GConfClient *gconf, guint cnxn_id, GConfEntry *entry, gpointer data) -{ - GConfValue *value; - gchar *tkey; - - g_return_if_fail (gconf_entry_get_key (entry) != NULL); - - if (!(value = gconf_entry_get_value (entry))) - return; - - tkey = strrchr (entry->key, '/'); - g_return_if_fail (tkey != NULL); - - if (!strcmp(tkey, "local_only")) - em_junk_sa_local_only = gconf_value_get_bool (value); - else if (!strcmp(tkey, "use_daemon")) - em_junk_sa_use_daemon = gconf_value_get_bool (value); - else if (!strcmp(tkey, "socket_path")) { - G_LOCK (socket_path); - g_free (em_junk_sa_preferred_socket_path); - em_junk_sa_preferred_socket_path = g_strdup (gconf_value_get_string (value)); - G_UNLOCK (socket_path); - } -} - -gint -e_plugin_lib_enable (EPlugin *ep, gint enable) -{ - is_installed = enable != 0; - - if (is_installed) - em_junk_sa_tested = FALSE; - - em_junk_sa_init (); - - return 0; -} - -static void -em_junk_sa_init (void) -{ - G_LOCK (init); - - if (!em_junk_sa_gconf) { - em_junk_sa_gconf = gconf_client_get_default (); - gconf_client_add_dir (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); - - em_junk_sa_local_only = gconf_client_get_bool (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/local_only", NULL); - em_junk_sa_use_daemon = gconf_client_get_bool (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/use_daemon", NULL); - - G_LOCK (socket_path); - g_free (em_junk_sa_preferred_socket_path); - em_junk_sa_preferred_socket_path = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/socket_path", NULL); - G_UNLOCK (socket_path); - - gconf_client_notify_add(em_junk_sa_gconf, "/apps/evolution/mail/junk/sa", - (GConfClientNotifyFunc) em_junk_sa_setting_notify, - NULL, NULL, NULL); - - em_junk_sa_spamc_gconf_binary = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/spamc_binary", NULL); - em_junk_sa_spamd_gconf_binary = gconf_client_get_string (em_junk_sa_gconf, "/apps/evolution/mail/junk/sa/spamd_binary", NULL); - - atexit (em_junk_sa_finalize); - } - - G_UNLOCK (init); -} - -static void -em_junk_sa_kill_spamd (void) -{ - G_LOCK (socket_path); - g_free (em_junk_sa_preferred_socket_path); - em_junk_sa_preferred_socket_path = NULL; - G_UNLOCK (socket_path); - - if (em_junk_sa_new_daemon_started) { - gint fd = open (em_junk_sa_spamd_pidfile, O_RDONLY); - - if (fd != -1) { - gchar pid_str[16]; - gint bytes; - - bytes = read (fd, pid_str, 15); - if (bytes > 0) { - gint pid; - - pid_str[bytes] = 0; - pid = atoi (pid_str); - - if (pid > 0) { - kill (pid, SIGTERM); - d(fprintf (stderr, "em_junk_sa_finalize send SIGTERM to daemon with pid %d\n", pid)); - waitpid (pid, NULL, 0); - } - } - - close (fd); - } - } -} - -static void -em_junk_sa_finalize (void) -{ - d(fprintf (stderr, "em_junk_sa_finalize\n")); - - g_object_unref (em_junk_sa_gconf); - em_junk_sa_kill_spamd (); -} - -static void -use_remote_tests_cb (GtkWidget *widget, gpointer data) -{ - gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - gconf_client_set_bool (em_junk_sa_gconf, data, !active, NULL); -} - -GtkWidget * -org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data) -{ - EShell *shell; - GtkWidget *check, *vbox, *label; - gchar *text = g_strdup_printf (" <small>%s</small>", _("This will make SpamAssassin more reliable, but slower")); - guint n_rows; - - g_object_get (data->parent, "n-rows", &n_rows, NULL); - - if (data->old) - return data->old; - - check = gtk_check_button_new_with_mnemonic (_("I_nclude remote tests")); - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), text); - g_free (text); - vbox = gtk_vbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (check), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), !em_junk_sa_local_only); - g_signal_connect (GTK_TOGGLE_BUTTON (check), "toggled", G_CALLBACK (use_remote_tests_cb), (gpointer) "/apps/evolution/mail/junk/sa/local_only"); - gtk_table_attach ( - GTK_TABLE (data->parent), vbox, - 0, 1, n_rows, n_rows+1, 0, 0, 0, 0); - - shell = e_shell_get_default (); - if (e_shell_get_express_mode (shell)) - gtk_widget_hide (vbox); - else - gtk_widget_show_all (vbox); - - return vbox; -} - diff --git a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml b/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml deleted file mode 100644 index 83ed170c74..0000000000 --- a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin id="org.gnome.evolution.sa_junk_plugin" - type="shlib" _name="SpamAssassin Junk Filter" - location="@PLUGINDIR@/liborg-gnome-sa-junk-plugin@SOEXT@"> - <_description>Filter junk messages using SpamAssassin.</_description> - <author name="Vivek Jain" email="jvivek@novell.com"/> - <hook class="org.gnome.evolution.mail.junk:1.0"> - <interface name="SpamAssassin" - check_junk="em_junk_sa_check_junk" - report_junk="em_junk_sa_report_junk" - report_non_junk="em_junk_sa_report_non_junk" - commit_reports="em_junk_sa_commit_reports" - validate_binary="em_junk_sa_validate_binary"/> - </hook> - <!-- hook into the 'mail properties' menu --> - <hook class="org.gnome.evolution.mail.config:1.0"> - <group target="prefs" id="org.gnome.evolution.mail.prefs"> - <item type="section_table" path="40.junk/10.options" _label="SpamAssassin Options"/> - <item type="item_table" path="40.junk/20.options" factory="org_gnome_sa_use_remote_tests"/> - </group> - </hook> - </e-plugin> -</e-plugin-list> |