diff options
Diffstat (limited to 'mail/e-mail-junk-options.c')
-rw-r--r-- | mail/e-mail-junk-options.c | 372 |
1 files changed, 372 insertions, 0 deletions
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); +} |