Commit 166b8d4a authored by Milan Crha's avatar Milan Crha

I#344 - Make 'next unread mail' shortcut jump to next folder

Closes #344
parent 01f29ba9
......@@ -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
......
......@@ -3219,7 +3219,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)
{
......@@ -3227,12 +3227,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)) {
......@@ -3240,6 +3242,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;
......@@ -3277,26 +3284,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
......@@ -3339,7 +3353,7 @@ folder_tree_descend (GtkTreeModel *model,
return TRUE;
}
void
gboolean
em_folder_tree_select_prev_path (EMFolderTree *folder_tree,
gboolean skip_read_folders)
{
......@@ -3350,16 +3364,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. */
......@@ -3396,21 +3413,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
......
......@@ -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,
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment