[evolution] I#113 - Make 'Mark messages as read' a folder/account option



commit 7d138f7fd225d22b8d7c4982ac2868ad9b1441cc
Author: Milan Crha <mcrha redhat com>
Date:   Wed Nov 7 21:56:12 2018 +0100

    I#113 - Make 'Mark messages as read' a folder/account option
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/113

 src/e-util/e-dialog-widgets.c          | 225 +++++++++++++++++++++++++++++++++
 src/e-util/e-dialog-widgets.h          |   2 +
 src/mail/e-mail-browser.c              |   6 +-
 src/mail/e-mail-config-defaults-page.c |  14 ++
 src/mail/e-mail-reader-utils.c         |  69 ++++++++++
 src/mail/e-mail-reader-utils.h         |   3 +
 src/mail/e-mail-reader.c               |  11 +-
 src/mail/em-folder-properties.c        |  21 +++
 8 files changed, 338 insertions(+), 13 deletions(-)
---
diff --git a/src/e-util/e-dialog-widgets.c b/src/e-util/e-dialog-widgets.c
index fd23d8d847..2f7b58b9e5 100644
--- a/src/e-util/e-dialog-widgets.c
+++ b/src/e-util/e-dialog-widgets.c
@@ -289,3 +289,228 @@ e_dialog_offline_settings_new_limit_box (CamelOfflineSettings *offline_settings)
 
        return hbox;
 }
+
+static CamelThreeState
+edw_three_state_source_to_camel (EThreeState value)
+{
+       switch (value) {
+       case E_THREE_STATE_OFF:
+               return CAMEL_THREE_STATE_OFF;
+       case E_THREE_STATE_ON:
+               return CAMEL_THREE_STATE_ON;
+       case E_THREE_STATE_INCONSISTENT:
+               return CAMEL_THREE_STATE_INCONSISTENT;
+       }
+
+       return CAMEL_THREE_STATE_INCONSISTENT;
+}
+
+static EThreeState
+edw_three_state_camel_to_source (CamelThreeState value)
+{
+       switch (value) {
+       case CAMEL_THREE_STATE_OFF:
+               return E_THREE_STATE_OFF;
+       case CAMEL_THREE_STATE_ON:
+               return E_THREE_STATE_ON;
+       case CAMEL_THREE_STATE_INCONSISTENT:
+               return E_THREE_STATE_INCONSISTENT;
+       }
+
+       return E_THREE_STATE_INCONSISTENT;
+}
+
+static gboolean
+edw_three_state_to_sensitive_cb (GBinding *binding,
+                                const GValue *from_value,
+                                GValue *to_value,
+                                gpointer user_data)
+{
+       CamelThreeState value;
+
+       if (CAMEL_IS_FOLDER (g_binding_get_source (binding))) {
+               value = g_value_get_enum (from_value);
+       } else {
+               value = edw_three_state_source_to_camel (g_value_get_enum (from_value));
+       }
+
+       g_value_set_boolean (to_value, value == CAMEL_THREE_STATE_ON);
+
+       return TRUE;
+}
+
+static gboolean
+edw_mark_seen_timeout_to_double_cb (GBinding *binding,
+                                   const GValue *from_value,
+                                   GValue *to_value,
+                                   gpointer user_data)
+{
+       gint value;
+
+       value = g_value_get_int (from_value);
+       g_value_set_double (to_value, ((gdouble) value) / 1000.0);
+
+       return TRUE;
+}
+
+static gboolean
+edw_double_to_mark_seen_timeout_cb (GBinding *binding,
+                                   const GValue *from_value,
+                                   GValue *to_value,
+                                   gpointer user_data)
+{
+       gdouble value;
+
+       value = g_value_get_double (from_value);
+       g_value_set_int (to_value, value * 1000);
+
+       return TRUE;
+}
+
+typedef struct _ThreeStateData {
+       GObject *object;
+       gulong handler_id;
+} ThreeStateData;
+
+static void
+three_state_data_free (gpointer data,
+                      GClosure *closure)
+{
+       ThreeStateData *tsd = data;
+
+       if (tsd) {
+               g_clear_object (&tsd->object);
+               g_free (tsd);
+       }
+}
+
+static void
+edw_three_state_toggled_cb (GtkToggleButton *widget,
+                           gpointer user_data)
+{
+       ThreeStateData *tsd = user_data;
+       CamelThreeState set_to;
+
+       g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
+       g_return_if_fail (tsd != NULL);
+
+       g_signal_handler_block (widget, tsd->handler_id);
+
+       if (gtk_toggle_button_get_inconsistent (widget) &&
+           gtk_toggle_button_get_active (widget)) {
+               gtk_toggle_button_set_active (widget, FALSE);
+               gtk_toggle_button_set_inconsistent (widget, FALSE);
+               set_to = CAMEL_THREE_STATE_OFF;
+       } else if (!gtk_toggle_button_get_active (widget)) {
+               gtk_toggle_button_set_inconsistent (widget, TRUE);
+               gtk_toggle_button_set_active (widget, FALSE);
+               set_to = CAMEL_THREE_STATE_INCONSISTENT;
+       } else {
+               set_to = CAMEL_THREE_STATE_ON;
+       }
+
+       if (CAMEL_IS_FOLDER (tsd->object)) {
+               g_object_set (G_OBJECT (tsd->object), "mark-seen", set_to, NULL);
+       } else {
+               g_object_set (G_OBJECT (tsd->object),
+                       "mark-seen", edw_three_state_camel_to_source (set_to),
+                       NULL);
+       }
+
+       g_signal_handler_unblock (widget, tsd->handler_id);
+}
+
+/**
+ * e_dialog_new_mark_seen_box:
+ * @object: either #CamelFolder or #ESourceMailAccount
+ *
+ * Returns: (transfer full): a new #GtkBox containing widgets to
+ *   setup "[x] Mark messages as read after [spin button] seconds"
+ *   option using @object properties "mark-seen" and "mark-seen-timeout".
+ *
+ * Since: 3.32
+ **/
+GtkWidget *
+e_dialog_new_mark_seen_box (gpointer object)
+{
+       /* Translators: The %s is replaced with a spin button; always keep it in the string at the right 
position */
+       const gchar *blurb = _("Mark messages as read after %s seconds");
+       GtkWidget *hbox, *widget;
+       CamelThreeState three_state = CAMEL_THREE_STATE_INCONSISTENT;
+       ThreeStateData *tsd;
+       gboolean set_inconsistent = FALSE, set_active = FALSE;
+       gchar **strv;
+
+       g_return_val_if_fail (CAMEL_IS_FOLDER (object) || E_IS_SOURCE_MAIL_ACCOUNT (object), NULL);
+
+       if (CAMEL_IS_FOLDER (object)) {
+               three_state = camel_folder_get_mark_seen (object);
+       } else {
+               three_state = edw_three_state_source_to_camel (e_source_mail_account_get_mark_seen (object));
+       }
+
+       switch (three_state) {
+               case CAMEL_THREE_STATE_ON:
+                       set_inconsistent = FALSE;
+                       set_active = TRUE;
+                       break;
+               case CAMEL_THREE_STATE_OFF:
+                       set_inconsistent = FALSE;
+                       set_active = FALSE;
+                       break;
+               case CAMEL_THREE_STATE_INCONSISTENT:
+                       set_inconsistent = TRUE;
+                       set_active = FALSE;
+                       break;
+       }
+
+       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
+       gtk_widget_show (hbox);
+
+       strv = g_strsplit (blurb, "%s", -1);
+       g_warn_if_fail (strv && strv[0] && strv[1] && !strv[2]);
+
+       widget = gtk_check_button_new_with_mnemonic (strv && strv[0] ? strv[0] : "Mark messages as read after 
");
+
+       g_object_set (G_OBJECT (widget),
+               "inconsistent", set_inconsistent,
+               "active", set_active,
+               NULL);
+
+       tsd = g_new0 (ThreeStateData, 1);
+       tsd->object = g_object_ref (object);
+       tsd->handler_id = g_signal_connect_data (widget, "toggled",
+               G_CALLBACK (edw_three_state_toggled_cb),
+               tsd, three_state_data_free, 0);
+
+       gtk_widget_show (widget);
+
+       gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+       widget = gtk_spin_button_new_with_range (0.0, 10.0, 1.0);
+       gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), TRUE);
+       gtk_spin_button_set_digits (GTK_SPIN_BUTTON (widget), 1);
+       e_binding_bind_property_full (object, "mark-seen",
+               widget, "sensitive",
+               G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE,
+               edw_three_state_to_sensitive_cb,
+               NULL, NULL, NULL);
+       e_binding_bind_property_full (object, "mark-seen-timeout",
+               widget, "value",
+               G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
+               edw_mark_seen_timeout_to_double_cb,
+               edw_double_to_mark_seen_timeout_cb,
+               NULL, NULL);
+       gtk_widget_show (widget);
+
+       gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+       widget = gtk_label_new (strv && strv[0] && strv[1] ? strv[1] : " seconds");
+       gtk_widget_show (widget);
+
+       gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+       g_strfreev (strv);
+
+       return hbox;
+}
diff --git a/src/e-util/e-dialog-widgets.h b/src/e-util/e-dialog-widgets.h
index 8e0323b24f..414622a680 100644
--- a/src/e-util/e-dialog-widgets.h
+++ b/src/e-util/e-dialog-widgets.h
@@ -40,4 +40,6 @@ GtkWidget *   e_dialog_button_new_with_icon   (const gchar *icon_name,
 GtkWidget *    e_dialog_offline_settings_new_limit_box
                                                (CamelOfflineSettings *offline_settings);
 
+GtkWidget *    e_dialog_new_mark_seen_box      (gpointer object);
+
 #endif
diff --git a/src/mail/e-mail-browser.c b/src/mail/e-mail-browser.c
index b8dc5cc8ef..a054990c0d 100644
--- a/src/mail/e-mail-browser.c
+++ b/src/mail/e-mail-browser.c
@@ -280,7 +280,6 @@ mail_browser_message_selected_cb (EMailBrowser *browser,
        info = camel_folder_get_message_info (folder, uid);
 
        if (info != NULL) {
-               GSettings *settings;
                EMailDisplay *display;
                const gchar *title;
 
@@ -293,10 +292,9 @@ mail_browser_message_selected_cb (EMailBrowser *browser,
                gtk_window_set_title (GTK_WINDOW (browser), title);
                gtk_widget_grab_focus (GTK_WIDGET (display));
 
-               settings = e_util_ref_settings ("org.gnome.evolution.mail");
-               if (g_settings_get_boolean (settings, "mark-seen"))
+               if (e_mail_reader_utils_get_mark_seen_setting (reader, NULL))
                        camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
-               g_clear_object (&settings);
+
                g_clear_object (&info);
        }
 
diff --git a/src/mail/e-mail-config-defaults-page.c b/src/mail/e-mail-config-defaults-page.c
index c091150101..24d361c004 100644
--- a/src/mail/e-mail-config-defaults-page.c
+++ b/src/mail/e-mail-config-defaults-page.c
@@ -883,6 +883,20 @@ mail_config_defaults_page_constructed (GObject *object)
 
        g_object_unref (size_group);
 
+       /* Other options */
+       markup = g_markup_printf_escaped ("<b>%s</b>", _("Miscellaneous"));
+       widget = gtk_label_new (markup);
+       gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+       gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+       gtk_grid_attach (GTK_GRID (container), widget, 0, 9, 2, 1);
+       gtk_widget_show (widget);
+       g_free (markup);
+
+       widget = e_dialog_new_mark_seen_box (account_ext);
+       gtk_widget_set_margin_start (widget, 12);
+       gtk_grid_attach (GTK_GRID (container), widget, 0, 10, 2, 1);
+       gtk_widget_show (widget);
+
        e_mail_config_page_set_content (E_MAIL_CONFIG_PAGE (page), main_box);
 
        e_extensible_load_extensions (E_EXTENSIBLE (page));
diff --git a/src/mail/e-mail-reader-utils.c b/src/mail/e-mail-reader-utils.c
index 1b3f9e1ba4..22e7cefa97 100644
--- a/src/mail/e-mail-reader-utils.c
+++ b/src/mail/e-mail-reader-utils.c
@@ -3406,3 +3406,72 @@ e_mail_reader_parse_message_finish (EMailReader *reader,
 
        return async_context->part_list;
 }
+
+gboolean
+e_mail_reader_utils_get_mark_seen_setting (EMailReader *reader,
+                                          gint *out_timeout_interval)
+{
+       CamelFolder *folder;
+       GSettings *settings;
+       gboolean mark_seen = FALSE;
+
+       g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
+
+       folder = e_mail_reader_ref_folder (reader);
+
+       if (folder) {
+               CamelStore *store;
+               CamelThreeState cts_value;
+
+               cts_value = camel_folder_get_mark_seen (folder);
+               if (cts_value == CAMEL_THREE_STATE_OFF || cts_value == CAMEL_THREE_STATE_ON) {
+                       if (out_timeout_interval)
+                               *out_timeout_interval = camel_folder_get_mark_seen_timeout (folder);
+
+                       g_clear_object (&folder);
+
+                       return cts_value == CAMEL_THREE_STATE_ON;
+               }
+
+               store = camel_folder_get_parent_store (folder);
+               if (store) {
+                       ESourceRegistry *registry;
+                       ESource *source;
+                       EThreeState ets_value = E_THREE_STATE_INCONSISTENT;
+
+                       registry = e_mail_session_get_registry (e_mail_backend_get_session 
(e_mail_reader_get_backend (reader)));
+                       source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE 
(store)));
+
+                       if (source && e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT)) {
+                               ESourceMailAccount *account_ext;
+
+                               account_ext = e_source_get_extension (source, 
E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+                               ets_value = e_source_mail_account_get_mark_seen (account_ext);
+
+                               if (out_timeout_interval && ets_value != E_THREE_STATE_INCONSISTENT)
+                                       *out_timeout_interval = e_source_mail_account_get_mark_seen_timeout 
(account_ext);
+                       }
+
+                       g_clear_object (&source);
+
+                       if (ets_value == E_THREE_STATE_OFF || ets_value == E_THREE_STATE_ON) {
+                               g_clear_object (&folder);
+
+                               return ets_value == E_THREE_STATE_ON;
+                       }
+               }
+
+               g_clear_object (&folder);
+       }
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+
+       mark_seen = g_settings_get_boolean (settings, "mark-seen");
+
+       if (out_timeout_interval)
+               *out_timeout_interval = g_settings_get_int (settings, "mark-seen-timeout");
+
+       g_object_unref (settings);
+
+       return mark_seen;
+}
diff --git a/src/mail/e-mail-reader-utils.h b/src/mail/e-mail-reader-utils.h
index 115079f455..829195fd47 100644
--- a/src/mail/e-mail-reader-utils.h
+++ b/src/mail/e-mail-reader-utils.h
@@ -112,6 +112,9 @@ EMailPartList *     e_mail_reader_parse_message_finish
                                                (EMailReader *reader,
                                                 GAsyncResult *result,
                                                 GError **error);
+gboolean       e_mail_reader_utils_get_mark_seen_setting
+                                               (EMailReader *reader,
+                                                gint *out_timeout_interval);
 
 G_END_DECLS
 
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index bb8a22f4e4..363090127c 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -3292,9 +3292,8 @@ maybe_schedule_timeout_mark_seen (EMailReader *reader)
 {
        EMailReaderPrivate *priv;
        MessageList *message_list;
-       GSettings *settings;
        gboolean schedule_timeout;
-       gint timeout_interval;
+       gint timeout_interval = -1;
        const gchar *message_uid;
 
        message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
@@ -3304,15 +3303,9 @@ maybe_schedule_timeout_mark_seen (EMailReader *reader)
            e_tree_is_dragging (E_TREE (message_list)))
                return;
 
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-
-       /* FIXME These should be EMailReader properties. */
        schedule_timeout =
                (message_uid != NULL) &&
-               g_settings_get_boolean (settings, "mark-seen");
-       timeout_interval = g_settings_get_int (settings, "mark-seen-timeout");
-
-       g_object_unref (settings);
+               e_mail_reader_utils_get_mark_seen_setting (reader, &timeout_interval);
 
        if (message_list->seen_id > 0) {
                g_source_remove (message_list->seen_id);
diff --git a/src/mail/em-folder-properties.c b/src/mail/em-folder-properties.c
index 6af1add6ab..1be107ba46 100644
--- a/src/mail/em-folder-properties.c
+++ b/src/mail/em-folder-properties.c
@@ -222,6 +222,7 @@ emfp_get_folder_item (EConfig *ec,
        EMailSendAccountOverride *account_override;
        gchar *folder_uri, *account_uid, *alias_name = NULL, *alias_address = NULL;
        GtkWidget *label;
+       gboolean has_mark_seen = FALSE, has_mark_seen_timeout = FALSE;
 
        if (old)
                return old;
@@ -315,6 +316,16 @@ emfp_get_folder_item (EConfig *ec,
                    g_strcmp0 (properties[ii]->name, "apply-filters") == 0)
                        continue;
 
+               if (!has_mark_seen && g_strcmp0 (properties[ii]->name, "mark-seen") == 0) {
+                       has_mark_seen = TRUE;
+                       continue;
+               }
+
+               if (!has_mark_seen_timeout && g_strcmp0 (properties[ii]->name, "mark-seen-timeout") == 0) {
+                       has_mark_seen_timeout = TRUE;
+                       continue;
+               }
+
                blurb = g_param_spec_get_blurb (properties[ii]);
 
                switch (properties[ii]->value_type) {
@@ -388,6 +399,16 @@ emfp_get_folder_item (EConfig *ec,
                }
        }
 
+       if (has_mark_seen && has_mark_seen_timeout) {
+               widget = e_dialog_new_mark_seen_box (context->folder);
+
+               gtk_table_attach (
+                       GTK_TABLE (table), widget,
+                       0, 2, row, row + 1,
+                       GTK_FILL | GTK_EXPAND, 0, 0, 0);
+               row++;
+       }
+
        g_free (properties);
 
        /* add send-account-override setting widgets */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]