[evolution/gnome-3-32] I#344 - Make 'next unread mail' shortcut jump to next folder



commit 5b02fc352197107085f3ebedca98f9e54abe6ab0
Author: Milan Crha <mcrha redhat com>
Date:   Mon Mar 11 18:20:26 2019 +0100

    I#344 - Make 'next unread mail' shortcut jump to next folder
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/344

 src/mail/e-mail-reader.c                     | 67 +++++++++++++++++------
 src/mail/em-folder-tree.c                    | 80 ++++++++++++++++++----------
 src/mail/em-folder-tree.h                    |  4 +-
 src/mail/message-list.c                      | 48 +++++++++++++++++
 src/mail/message-list.h                      |  5 ++
 src/modules/mail/e-mail-shell-view-actions.c |  9 +++-
 6 files changed, 164 insertions(+), 49 deletions(-)
---
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index c59cdab3e1..11a7dd607b 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -1332,21 +1332,65 @@ action_mail_next_thread_cb (GtkAction *action,
 }
 
 static void
-action_mail_next_unread_cb (GtkAction *action,
-                            EMailReader *reader)
+mail_reader_select_unread (EMailReader *reader,
+                          gboolean move_forward)
 {
        GtkWidget *message_list;
        MessageListSelectDirection direction;
        guint32 flags, mask;
 
-       direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+
+       direction = (move_forward ? MESSAGE_LIST_SELECT_NEXT : MESSAGE_LIST_SELECT_PREVIOUS) |
+                   MESSAGE_LIST_SELECT_WRAP | MESSAGE_LIST_SELECT_INCLUDE_COLLAPSED;
        flags = 0;
        mask = CAMEL_MESSAGE_SEEN;
 
        message_list = e_mail_reader_get_message_list (reader);
 
-       message_list_select (
-               MESSAGE_LIST (message_list), direction, flags, mask);
+       if (!message_list_select (MESSAGE_LIST (message_list), direction, flags, mask)) {
+               GtkWindow *window;
+
+               window = e_mail_reader_get_window (reader);
+               if (E_IS_SHELL_WINDOW (window)) {
+                       EShellWindow *shell_window;
+                       EMFolderTree *folder_tree = NULL;
+                       const gchar *active_view;
+
+                       shell_window = E_SHELL_WINDOW (window);
+                       active_view = e_shell_window_get_active_view (shell_window);
+
+                       if (g_strcmp0 (active_view, "mail") == 0) {
+                               EShellView *shell_view;
+                               EShellSidebar *shell_sidebar;
+
+                               shell_view = e_shell_window_get_shell_view (shell_window, "mail");
+                               shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+                               g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+
+                               if (folder_tree) {
+                                       gboolean selected;
+
+                                       if (move_forward)
+                                               selected = em_folder_tree_select_next_path (folder_tree, 
TRUE);
+                                       else
+                                               selected = em_folder_tree_select_prev_path (folder_tree, 
TRUE);
+
+                                       if (selected)
+                                               message_list_set_regen_selects_unread (MESSAGE_LIST 
(message_list), TRUE);
+                               }
+
+                               g_clear_object (&folder_tree);
+                       }
+               }
+       }
+}
+
+static void
+action_mail_next_unread_cb (GtkAction *action,
+                            EMailReader *reader)
+{
+       mail_reader_select_unread (reader, TRUE);
 }
 
 static void
@@ -1400,18 +1444,7 @@ static void
 action_mail_previous_unread_cb (GtkAction *action,
                                 EMailReader *reader)
 {
-       GtkWidget *message_list;
-       MessageListSelectDirection direction;
-       guint32 flags, mask;
-
-       direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
-       flags = 0;
-       mask = CAMEL_MESSAGE_SEEN;
-
-       message_list = e_mail_reader_get_message_list (reader);
-
-       message_list_select (
-               MESSAGE_LIST (message_list), direction, flags, mask);
+       mail_reader_select_unread (reader, FALSE);
 }
 
 static void
diff --git a/src/mail/em-folder-tree.c b/src/mail/em-folder-tree.c
index 3a9dd2eacf..bfdddc74e7 100644
--- a/src/mail/em-folder-tree.c
+++ b/src/mail/em-folder-tree.c
@@ -3212,7 +3212,7 @@ em_folder_tree_set_selected (EMFolderTree *folder_tree,
        g_list_free (l);
 }
 
-void
+gboolean
 em_folder_tree_select_next_path (EMFolderTree *folder_tree,
                                  gboolean skip_read_folders)
 {
@@ -3220,12 +3220,14 @@ em_folder_tree_select_next_path (EMFolderTree *folder_tree,
        GtkTreeSelection *selection;
        GtkTreeModel *model;
        GtkTreeIter iter, parent, child;
-       GtkTreePath *current_path, *path = NULL;
+       GtkTreePath *current_path = NULL, *path = NULL;
+       gboolean changed = FALSE;
        guint unread = 0;
-       EMFolderTreePrivate *priv = folder_tree->priv;
+       EMFolderTreePrivate *priv;
 
-       g_return_if_fail (EM_IS_FOLDER_TREE (folder_tree));
+       g_return_val_if_fail (EM_IS_FOLDER_TREE (folder_tree), FALSE);
 
+       priv = folder_tree->priv;
        tree_view = GTK_TREE_VIEW (folder_tree);
        selection = gtk_tree_view_get_selection (tree_view);
        if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
@@ -3233,6 +3235,11 @@ em_folder_tree_select_next_path (EMFolderTree *folder_tree,
                current_path = gtk_tree_model_get_path (model, &iter);
 
                do {
+                       if (path) {
+                               gtk_tree_path_free (path);
+                               path = NULL;
+                       }
+
                        if (gtk_tree_model_iter_has_child (model, &iter)) {
                                if (!gtk_tree_model_iter_children (model, &child, &iter))
                                        break;
@@ -3270,26 +3277,33 @@ em_folder_tree_select_next_path (EMFolderTree *folder_tree,
                /* TODO : Flags here for better options */
                } while (skip_read_folders && unread <=0 &&
                        gtk_tree_path_compare (current_path, path));
-
-               gtk_tree_path_free (current_path);
        }
 
-       if (path) {
-               if (!gtk_tree_view_row_expanded (tree_view, path))
-                       gtk_tree_view_expand_to_path (tree_view, path);
+       if (current_path && path) {
+               if (gtk_tree_path_compare (current_path, path) != 0) {
+                       if (!gtk_tree_view_row_expanded (tree_view, path))
+                               gtk_tree_view_expand_to_path (tree_view, path);
 
-               gtk_tree_selection_select_path (selection, path);
+                       gtk_tree_selection_select_path (selection, path);
 
-               if (!priv->cursor_set) {
-                       gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
-                       priv->cursor_set = TRUE;
+                       if (!priv->cursor_set) {
+                               gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+                               priv->cursor_set = TRUE;
+                       }
+
+                       gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
+
+                       changed = TRUE;
                }
-               gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
+       }
 
+       if (path)
                gtk_tree_path_free (path);
-       }
 
-       return;
+       if (current_path)
+               gtk_tree_path_free (current_path);
+
+       return changed;
 }
 
 static gboolean
@@ -3332,7 +3346,7 @@ folder_tree_descend (GtkTreeModel *model,
        return TRUE;
 }
 
-void
+gboolean
 em_folder_tree_select_prev_path (EMFolderTree *folder_tree,
                                  gboolean skip_read_folders)
 {
@@ -3343,16 +3357,19 @@ em_folder_tree_select_prev_path (EMFolderTree *folder_tree,
        GtkTreePath *sentinel;
        GtkTreeIter iter;
        guint unread = 0;
-       EMFolderTreePrivate *priv = folder_tree->priv;
+       gboolean changed = FALSE;
+       EMFolderTreePrivate *priv;
 
-       g_return_if_fail (EM_IS_FOLDER_TREE (folder_tree));
+       g_return_val_if_fail (EM_IS_FOLDER_TREE (folder_tree), FALSE);
+
+       priv = folder_tree->priv;
 
        tree_view = GTK_TREE_VIEW (folder_tree);
        selection = gtk_tree_view_get_selection (tree_view);
 
        /* Nothing selected means nothing to do. */
        if (!gtk_tree_selection_get_selected (selection, &model, &iter))
-               return;
+               return FALSE;
 
        /* This prevents us from looping over the model indefinitely,
         * looking for unread messages when there are none. */
@@ -3389,21 +3406,26 @@ em_folder_tree_select_prev_path (EMFolderTree *folder_tree,
        } while (skip_read_folders && unread <= 0 &&
                gtk_tree_path_compare (path, sentinel) != 0);
 
-       if (!gtk_tree_view_row_expanded (tree_view, path))
-               gtk_tree_view_expand_to_path (tree_view, path);
+       if (gtk_tree_path_compare (path, sentinel) != 0) {
+               if (!gtk_tree_view_row_expanded (tree_view, path))
+                       gtk_tree_view_expand_to_path (tree_view, path);
 
-       gtk_tree_selection_select_path (selection, path);
+               gtk_tree_selection_select_path (selection, path);
 
-       if (!priv->cursor_set) {
-               gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
-               priv->cursor_set = TRUE;
-       }
+               if (!priv->cursor_set) {
+                       gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+                       priv->cursor_set = TRUE;
+               }
+
+               gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
 
-       gtk_tree_view_scroll_to_cell (
-               tree_view, path, NULL, TRUE, 0.5f, 0.0f);
+               changed = TRUE;
+       }
 
        gtk_tree_path_free (sentinel);
        gtk_tree_path_free (path);
+
+       return changed;
 }
 
 void
diff --git a/src/mail/em-folder-tree.h b/src/mail/em-folder-tree.h
index 98fcf56081..b7ffe9e720 100644
--- a/src/mail/em-folder-tree.h
+++ b/src/mail/em-folder-tree.h
@@ -116,9 +116,9 @@ GList *             em_folder_tree_get_selected_paths
 void           em_folder_tree_set_selected     (EMFolderTree *folder_tree,
                                                 const gchar *uri,
                                                 gboolean expand_only);
-void           em_folder_tree_select_next_path (EMFolderTree *folder_tree,
+gboolean       em_folder_tree_select_next_path (EMFolderTree *folder_tree,
                                                 gboolean skip_read_folders);
-void           em_folder_tree_select_prev_path (EMFolderTree *folder_tree,
+gboolean       em_folder_tree_select_prev_path (EMFolderTree *folder_tree,
                                                 gboolean skip_read_folders);
 void           em_folder_tree_edit_selected    (EMFolderTree *folder_tree);
 gboolean       em_folder_tree_get_selected     (EMFolderTree *folder_tree,
diff --git a/src/mail/message-list.c b/src/mail/message-list.c
index 19baff901b..b0583fdccb 100644
--- a/src/mail/message-list.c
+++ b/src/mail/message-list.c
@@ -108,6 +108,7 @@ struct _MessageListPrivate {
        gboolean thread_subject;
        gboolean any_row_changed; /* save state before regen list when this is set to true */
        gboolean show_subject_above_sender;
+       gboolean regen_selects_unread;
 
        GtkTargetList *copy_target_list;
        GtkTargetList *paste_target_list;
@@ -152,6 +153,7 @@ struct _RegenData {
 
        gboolean group_by_threads;
        gboolean thread_subject;
+       gboolean select_unread;
 
        CamelFolderThread *thread_tree;
 
@@ -5404,6 +5406,26 @@ message_list_set_thread_subject (MessageList *message_list,
        g_object_notify (G_OBJECT (message_list), "thread-subject");
 }
 
+gboolean
+message_list_get_regen_selects_unread (MessageList *message_list)
+{
+       g_return_val_if_fail (IS_MESSAGE_LIST (message_list), FALSE);
+
+       return message_list->priv->regen_selects_unread;
+}
+
+void
+message_list_set_regen_selects_unread (MessageList *message_list,
+                                      gboolean regen_selects_unread)
+{
+       g_return_if_fail (IS_MESSAGE_LIST (message_list));
+
+       if ((regen_selects_unread ? 1 : 0) == (message_list->priv->regen_selects_unread ? 1 : 0))
+               return;
+
+       message_list->priv->regen_selects_unread = regen_selects_unread;
+}
+
 static gboolean
 on_cursor_activated_idle (gpointer data)
 {
@@ -6649,6 +6671,27 @@ message_list_regen_done_cb (GObject *source_object,
 
        message_list->priv->any_row_changed = FALSE;
        message_list->just_set_folder = FALSE;
+
+       if (!regen_data->select_all && regen_data->select_unread) {
+               ETreePath cursor_path;
+               gboolean call_select = TRUE;
+
+               cursor_path = e_tree_get_cursor (E_TREE (message_list));
+
+               if (cursor_path) {
+                       CamelMessageInfo *info;
+
+                       info = get_message_info (message_list, cursor_path);
+                       if (info && !(camel_message_info_get_flags (info) & CAMEL_MESSAGE_SEEN))
+                               call_select = FALSE;
+               }
+
+               if (call_select) {
+                       message_list_select (MESSAGE_LIST (message_list), MESSAGE_LIST_SELECT_NEXT |
+                               MESSAGE_LIST_SELECT_WRAP | MESSAGE_LIST_SELECT_INCLUDE_COLLAPSED,
+                               0, CAMEL_MESSAGE_SEEN);
+               }
+       }
 }
 
 static gboolean
@@ -6676,6 +6719,11 @@ message_list_regen_idle_cb (gpointer user_data)
                message_list_get_group_by_threads (message_list);
        regen_data->thread_subject =
                message_list_get_thread_subject (message_list);
+       regen_data->select_unread =
+               message_list_get_regen_selects_unread (message_list);
+
+       if (regen_data->select_unread)
+               message_list_set_regen_selects_unread (message_list, FALSE);
 
        searching = message_list_is_searching (message_list);
 
diff --git a/src/mail/message-list.h b/src/mail/message-list.h
index 82781c3a6c..3888e2803f 100644
--- a/src/mail/message-list.h
+++ b/src/mail/message-list.h
@@ -190,6 +190,11 @@ void               message_list_set_thread_latest  (MessageList *message_list,
 gboolean       message_list_get_thread_subject (MessageList *message_list);
 void           message_list_set_thread_subject (MessageList *message_list,
                                                 gboolean thread_subject);
+gboolean       message_list_get_regen_selects_unread
+                                               (MessageList *message_list);
+void           message_list_set_regen_selects_unread
+                                               (MessageList *message_list,
+                                                gboolean regen_selects_unread);
 void           message_list_freeze             (MessageList *message_list);
 void           message_list_thaw               (MessageList *message_list);
 GPtrArray *    message_list_get_selected       (MessageList *message_list);
diff --git a/src/modules/mail/e-mail-shell-view-actions.c b/src/modules/mail/e-mail-shell-view-actions.c
index 56872be27d..1a6ab78f80 100644
--- a/src/modules/mail/e-mail-shell-view-actions.c
+++ b/src/modules/mail/e-mail-shell-view-actions.c
@@ -1347,6 +1347,7 @@ mail_shell_view_magic_spacebar (EMailShellView *mail_shell_view,
 
        if (!e_mail_display_process_magic_spacebar (display, move_forward)) {
                guint32 direction = move_forward ? MESSAGE_LIST_SELECT_NEXT : MESSAGE_LIST_SELECT_PREVIOUS;
+               gboolean selected;
 
                if (!magic_spacebar)
                        return;
@@ -1357,7 +1358,13 @@ mail_shell_view_magic_spacebar (EMailShellView *mail_shell_view,
                    0, CAMEL_MESSAGE_SEEN))
                        return;
 
-               em_folder_tree_select_next_path (folder_tree, TRUE);
+               if (move_forward)
+                       selected = em_folder_tree_select_next_path (folder_tree, TRUE);
+               else
+                       selected = em_folder_tree_select_prev_path (folder_tree, TRUE);
+
+               if (selected)
+                       message_list_set_regen_selects_unread (MESSAGE_LIST (message_list), TRUE);
 
                gtk_widget_grab_focus (message_list);
        }


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