2012-02-05 [colin] 3.8.0cvs26
authorColin Leroy <colin@colino.net>
Sun, 5 Feb 2012 20:00:36 +0000 (20:00 +0000)
committerColin Leroy <colin@colino.net>
Sun, 5 Feb 2012 20:00:36 +0000 (20:00 +0000)
* src/main.c
* src/mainwindow.c
* src/messageview.c
* src/messageview.h
* src/prefs_common.c
* src/prefs_common.h
* src/procmsg.c
* src/procmsg.h
* src/summaryview.c
* src/summaryview.h
Add an history to navigate in mails

13 files changed:
ChangeLog
PATCHSETS
configure.ac
src/main.c
src/mainwindow.c
src/messageview.c
src/messageview.h
src/prefs_common.c
src/prefs_common.h
src/procmsg.c
src/procmsg.h
src/summaryview.c
src/summaryview.h

index 8aba6bd..484503e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2012-02-05 [colin]     3.8.0cvs26
+
+       * src/main.c
+       * src/mainwindow.c
+       * src/messageview.c
+       * src/messageview.h
+       * src/prefs_common.c
+       * src/prefs_common.h
+       * src/procmsg.c
+       * src/procmsg.h
+       * src/summaryview.c
+       * src/summaryview.h
+               Add an history to navigate in mails
+
 2012-02-05 [colin]     3.8.0cvs25
 
        * src/procmime.c
index c9fbecf..64850f7 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.207.2.226 -r 1.207.2.227 src/folderview.c;  ) > 3.8.0cvs23.patchset
 ( cvs diff -u -r 1.1.4.29 -r 1.1.4.30 src/gtk/progressdialog.c;  ) > 3.8.0cvs24.patchset
 ( cvs diff -u -r 1.49.2.140 -r 1.49.2.141 src/procmime.c;  ) > 3.8.0cvs25.patchset
+( cvs diff -u -r 1.115.2.246 -r 1.115.2.247 src/main.c;  cvs diff -u -r 1.274.2.342 -r 1.274.2.343 src/mainwindow.c;  cvs diff -u -r 1.94.2.226 -r 1.94.2.227 src/messageview.c;  cvs diff -u -r 1.19.2.27 -r 1.19.2.28 src/messageview.h;  cvs diff -u -r 1.204.2.207 -r 1.204.2.208 src/prefs_common.c;  cvs diff -u -r 1.103.2.136 -r 1.103.2.137 src/prefs_common.h;  cvs diff -u -r 1.150.2.121 -r 1.150.2.122 src/procmsg.c;  cvs diff -u -r 1.60.2.58 -r 1.60.2.59 src/procmsg.h;  cvs diff -u -r 1.395.2.443 -r 1.395.2.444 src/summaryview.c;  cvs diff -u -r 1.68.2.58 -r 1.68.2.59 src/summaryview.h;  ) > 3.8.0cvs26.patchset
index d127d2b..039440f 100644 (file)
@@ -12,7 +12,7 @@ MINOR_VERSION=8
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=25
+EXTRA_VERSION=26
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 60a5c85..7f06011 100644 (file)
@@ -2554,7 +2554,7 @@ static void lock_socket_input_cb(gpointer data,
                if (folder_name)
                        folderItem = folder_find_item_from_identifier(folder_name);
                if (folder_name && folderItem == NULL) {
-                       debug_print("Unknow folder item : '%s', searching folder\n",folder_name);
+                       debug_print("Unknown folder item : '%s', searching folder\n",folder_name);
                        Folder* folder = folder_find_from_path(folder_name);
                        if (folder != NULL)
                                folderItem = FOLDER_ITEM(folder->node->data);
index 0d16119..922da32 100644 (file)
@@ -306,7 +306,9 @@ static void prev_labeled_cb  (GtkAction     *action,
                                  gpointer       data);
 static void next_labeled_cb     (GtkAction     *action,
                                  gpointer       data);
-static void last_read_cb        (GtkAction     *action,
+static void prev_history_cb     (GtkAction     *action,
+                                 gpointer       data);
+static void next_history_cb     (GtkAction     *action,
                                  gpointer       data);
 static void parent_cb           (GtkAction     *action,
                                  gpointer       data);
@@ -557,7 +559,9 @@ static GtkActionEntry mainwin_entries[] =
        {"View/Goto/PrevLabeled",               NULL, N_("Previous _labeled message"), NULL, NULL, G_CALLBACK(prev_labeled_cb) },
        {"View/Goto/NextLabeled",               NULL, N_("Next la_beled message"), NULL, NULL, G_CALLBACK(next_labeled_cb) },
        /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
-       {"View/Goto/LastRead",                  NULL, N_("Last read message"), NULL, NULL, G_CALLBACK(last_read_cb) },
+       {"View/Goto/PrevHistory",               NULL, N_("Previous opened message"), "<alt>Left", NULL, G_CALLBACK(prev_history_cb) },
+       {"View/Goto/NextHistory",               NULL, N_("Next opened message"), "<alt>Right", NULL, G_CALLBACK(next_history_cb) },
+       /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/ParentMessage",             NULL, N_("Parent message"), "<control>Up", NULL, G_CALLBACK(parent_cb) },
        /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/NextUnreadFolder",          NULL, N_("Next unread _folder"), "<shift>G", NULL, G_CALLBACK(goto_unread_folder_cb) },
@@ -1020,7 +1024,6 @@ static void mainwindow_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
        for (; sel != NULL; sel = sel->next) {
                MsgInfo *msginfo;
                GSList *tags = NULL;
-               gint id;
                GtkCheckMenuItem *item;
                msginfo = (MsgInfo *)sel->data;
                sel_len++;
@@ -1031,7 +1034,6 @@ static void mainwindow_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
 
                        for (; tags; tags = tags->next) {
                                gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, tags->data));
-                               id = GPOINTER_TO_INT(tags->data);
                                item = g_hash_table_lookup(menu_table, GINT_TO_POINTER(tags->data));
                                if (item && !gtk_check_menu_item_get_active(item)) {
                                        gtk_check_menu_item_set_active
@@ -1742,9 +1744,11 @@ MainWindow *main_window_create()
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "PrevLabeled", "View/Goto/PrevLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "NextLabeled", "View/Goto/NextLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "Separator5", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
-       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "LastRead", "View/Goto/LastRead", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "PrevHistory", "View/Goto/PrevHistory", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "NextHistory", "View/Goto/NextHistory", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "Separator6", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "Separator7", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "NextUnreadFolder", "View/Goto/NextUnreadFolder", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "OtherFolder", "View/Goto/OtherFolder", GTK_UI_MANAGER_MENUITEM)
         MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "Scroll", "View/Scroll", GTK_UI_MANAGER_MENU)
@@ -3236,7 +3240,6 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                {"Menu/View/Goto/PrevMarked" , M_MSG_EXIST},
                {"Menu/View/Goto/PrevLabeled", M_MSG_EXIST},
                {"Menu/View/Goto/NextLabeled", M_MSG_EXIST},
-               {"Menu/View/Goto/LastRead"   , M_SINGLE_TARGET_EXIST},
                {"Menu/View/Goto/ParentMessage"      , M_SINGLE_TARGET_EXIST},
                {"Menu/View/OpenNewWindow"        , M_SINGLE_TARGET_EXIST},
                {"Menu/View/MessageSource"            , M_SINGLE_TARGET_EXIST},
@@ -3400,7 +3403,12 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadThreads", FALSE);
        if (mainwin->summaryview->folder_item && mainwin->summaryview->folder_item->hide_read_threads)
                cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadMessages", FALSE);
-               
+
+       cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/Goto/PrevHistory",
+               messageview_nav_has_prev(mainwin->messageview));
+       cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/Goto/NextHistory",
+               messageview_nav_has_next(mainwin->messageview));
+
        main_window_menu_callback_unblock(mainwin);
 }
 
@@ -3896,7 +3904,7 @@ void main_window_destroy_all(void)
 {
        while (mainwin_list != NULL) {
                MainWindow *mainwin = (MainWindow*)mainwin_list->data;
-               
+
                /* free toolbar stuff */
                toolbar_clear_list(TOOLBAR_MAIN);
                TOOLBAR_DESTROY_ACTIONS(mainwin->toolbar->action_list);
@@ -4818,10 +4826,33 @@ static void next_labeled_cb(GtkAction *action, gpointer data)
        summary_select_next_labeled(mainwin->summaryview);
 }
 
-static void last_read_cb(GtkAction *action, gpointer data)
+static void prev_history_cb(GtkAction *action, gpointer data)
 {
        MainWindow *mainwin = (MainWindow *)data;
-       summary_select_last_read(mainwin->summaryview);
+       MsgInfo *info = messageview_nav_get_prev(mainwin->messageview);
+       if (info) {
+               if (info->folder != mainwin->summaryview->folder_item)
+                       folderview_select(mainwin->folderview, info->folder);
+               summary_display_by_msgnum(mainwin->summaryview, info->msgnum);
+               summary_display_msg_selected(mainwin->summaryview, FALSE);
+               procmsg_msginfo_free(info);
+               main_window_set_menu_sensitive(mainwindow_get_mainwindow());
+               toolbar_main_set_sensitive(mainwindow_get_mainwindow());
+       }
+}
+
+static void next_history_cb(GtkAction *action, gpointer data)
+{
+       MainWindow *mainwin = (MainWindow *)data;
+       MsgInfo *info = messageview_nav_get_next(mainwin->messageview);
+       if (info) {
+               if (info->folder != mainwin->summaryview->folder_item)
+                       folderview_select(mainwin->folderview, info->folder);
+               summary_display_by_msgnum(mainwin->summaryview, info->msgnum);
+               procmsg_msginfo_free(info);
+               main_window_set_menu_sensitive(mainwindow_get_mainwindow());
+               toolbar_main_set_sensitive(mainwindow_get_mainwindow());
+       }
 }
 
 static void parent_cb(GtkAction *action, gpointer data)
index e080501..97bc7e4 100644 (file)
@@ -126,7 +126,9 @@ static void prev_labeled_cb         (GtkAction      *action,
                                         gpointer        data);
 static void next_labeled_cb            (GtkAction      *action,
                                         gpointer        data);
-static void last_read_cb               (GtkAction      *action,
+static void prev_history_cb            (GtkAction      *action,
+                                        gpointer        data);
+static void next_history_cb            (GtkAction      *action,
                                         gpointer        data);
 static void parent_cb                  (GtkAction      *action,
                                         gpointer        data);
@@ -227,8 +229,10 @@ static GtkActionEntry msgview_entries[] =
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/PrevLabeled",       NULL, N_("Previous _labeled message"), NULL, NULL, G_CALLBACK(prev_labeled_cb) },
        {"View/Goto/NextLabeled",       NULL, N_("Next la_beled message"), NULL, NULL, G_CALLBACK(next_labeled_cb) },
+       /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
+       {"View/Goto/PrevHistory",       NULL, N_("Previous opened message"), "<alt>Left", NULL, G_CALLBACK(prev_history_cb) },
+       {"View/Goto/NextHistory",       NULL, N_("Next opened message"), "<alt>Right", NULL, G_CALLBACK(next_history_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
-       {"View/Goto/LastRead",          NULL, N_("Last read message"), NULL, NULL, G_CALLBACK(last_read_cb) },
        {"View/Goto/ParentMessage",     NULL, N_("Parent message"), "<control>Up", NULL, G_CALLBACK(parent_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/NextUnreadFolder",  NULL, N_("Next unread _folder"), "<shift>G", NULL, G_CALLBACK(goto_unread_folder_cb) },
@@ -495,9 +499,11 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevLabeled", "View/Goto/PrevLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextLabeled", "View/Goto/NextLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator5", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "LastRead", "View/Goto/LastRead", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevHistory", "View/Goto/PrevHistory", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextHistory", "View/Goto/NextHistory", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator6", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator7", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextUnreadFolder", "View/Goto/NextUnreadFolder", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "OtherFolder", "View/Goto/OtherFolder", GTK_UI_MANAGER_MENUITEM)
 
@@ -1133,6 +1139,118 @@ static MimeInfo *find_broken_part(MimeInfo *rootinfo)
        return brokeninfo;
 }
 
+static void messageview_register_nav(MessageView *messageview)
+{
+       gchar *id;
+       gint pos = -1;
+       GList *existing;
+
+       cm_return_if_fail(messageview);
+       cm_return_if_fail(messageview->msginfo);
+
+       id = procmsg_msginfo_get_identifier(messageview->msginfo);
+       existing = g_list_find_custom(messageview->trail, id, (GCompareFunc)g_strcmp0);
+
+       if (existing != NULL)
+               pos = g_list_position(messageview->trail, existing);
+       else
+               pos = -1;
+
+       if (pos != -1) {
+               messageview->trail_pos = pos;
+               g_free(id);
+       } else {
+               /* Cut the end of the list */
+               GList *end = g_list_nth(messageview->trail, messageview->trail_pos + 1);
+               if (end) {
+                       if (end->prev) {
+                               end->prev->next = NULL;
+                               end->prev = NULL;
+                               list_free_strings(end);
+                               g_list_free(end);
+                       } else {
+                               list_free_strings(messageview->trail);
+                               g_list_free(messageview->trail);
+                               messageview->trail = NULL;
+                       }
+               }
+               messageview->trail = g_list_append(messageview->trail, id);
+               messageview->trail_pos = g_list_length(messageview->trail) - 1;
+               
+               /* Cut the beginning if needed */
+               while (messageview->trail_pos > prefs_common.nav_history_length) {
+                       g_free(messageview->trail->data);
+                       messageview->trail = g_list_delete_link(messageview->trail,
+                                               messageview->trail);
+                       messageview->trail_pos--;
+               }
+       }
+       messageview_set_menu_sensitive(messageview);
+}
+
+gboolean messageview_nav_has_prev(MessageView *messageview) {
+       return messageview->trail != NULL &&  messageview->trail_pos > 0;
+}
+
+gboolean messageview_nav_has_next(MessageView *messageview) {
+       if (!messageview->trail)
+               return FALSE;
+       
+       return sc_g_list_bigger(messageview->trail, messageview->trail_pos + 1);
+}
+
+MsgInfo *messageview_nav_get_prev(MessageView *messageview) {
+       GList *item;
+       MsgInfo *info;
+
+       cm_return_val_if_fail(messageview, NULL);
+       cm_return_val_if_fail(messageview->trail, NULL);
+
+       do {
+               if (!messageview_nav_has_prev(messageview))
+                       return NULL;
+
+               item = g_list_nth(messageview->trail, messageview->trail_pos - 1);
+               cm_return_val_if_fail(item != NULL, NULL);
+
+               info = procmsg_get_msginfo_from_identifier((const gchar *)item->data);
+               if (info != NULL)
+                       break;
+
+               g_free(item->data);
+               messageview->trail = g_list_delete_link(messageview->trail, item);
+               if (messageview->trail_pos > 0)
+                       messageview->trail_pos--;
+       } while (info == NULL);
+
+       return info;
+}
+
+MsgInfo *messageview_nav_get_next(MessageView *messageview) {
+       GList *item;
+       MsgInfo *info;
+
+       cm_return_val_if_fail(messageview, NULL);
+       cm_return_val_if_fail(messageview->trail, NULL);
+
+       do {
+               if (!messageview_nav_has_next(messageview))
+                       return NULL;
+
+               item = g_list_nth(messageview->trail, messageview->trail_pos + 1);
+               cm_return_val_if_fail(item != NULL, NULL);
+
+               info = procmsg_get_msginfo_from_identifier((const gchar *)item->data);
+               if (info != NULL)
+                       break;
+
+               g_free(item->data);
+               messageview->trail = g_list_delete_link(messageview->trail, item);
+       } while (info == NULL);
+       
+       return info;
+}
+
 gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                      gboolean all_headers)
 {
@@ -1244,6 +1362,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
        }
        headerview_show(messageview->headerview, messageview->msginfo);
 
+       messageview_register_nav(messageview);
        messageview_set_position(messageview, 0);
 
 #ifdef MAEMO
@@ -1489,7 +1608,9 @@ void messageview_destroy(MessageView *messageview)
                toolbar_destroy(messageview->toolbar);
                g_free(messageview->toolbar);
        }
-       
+
+       list_free_strings(messageview->trail);
+       g_list_free(messageview->trail);
        msgview_list = g_list_remove(msgview_list, messageview); 
 
        if (messageview->window)
@@ -2369,28 +2490,39 @@ static void next_labeled_cb(GtkAction *action, gpointer data)
        }
 }
 
-static void last_read_cb(GtkAction *action, gpointer data)
+static void prev_history_cb(GtkAction *action, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
-       messageview->updating = TRUE;
-       summary_select_last_read(messageview->mainwin->summaryview);
-       messageview->updating = FALSE;
-
-       if (messageview->deferred_destroy) {
-               debug_print("messageview got away!\n");
-               messageview_destroy(messageview);
-               return;
+       MsgInfo *info = messageview_nav_get_prev(messageview);
+       if (info) {
+               messageview->updating = TRUE;
+               messageview_show(messageview, info, 
+                                        messageview->all_headers);
+               messageview->updating = FALSE;
+               procmsg_msginfo_free(info);
+               if (messageview->deferred_destroy) {
+                       debug_print("messageview got away!\n");
+                       messageview_destroy(messageview);
+                       return;
+               }
        }
-       if (messageview->mainwin->summaryview->selected) {
-#ifndef GENERIC_UMPC
-               MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
-                      
-               if (msginfo)
-                       messageview_show(messageview, msginfo, 
+}
+
+static void next_history_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+       MsgInfo *info = messageview_nav_get_next(messageview);
+       if (info) {
+               messageview->updating = TRUE;
+               messageview_show(messageview, info, 
                                         messageview->all_headers);
-#endif
-       } else {
-               gtk_widget_destroy(messageview->window);
+               messageview->updating = FALSE;
+               procmsg_msginfo_free(info);
+               if (messageview->deferred_destroy) {
+                       debug_print("messageview got away!\n");
+                       messageview_destroy(messageview);
+                       return;
+               }
        }
 }
 
@@ -2792,6 +2924,8 @@ void messageview_set_menu_sensitive(MessageView *messageview)
        cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/CollapseAll", (prefs_common.hide_quotes == 1));
        cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse2", (prefs_common.hide_quotes == 2));
        cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse3", (prefs_common.hide_quotes == 3));
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/View/Goto/PrevHistory", messageview_nav_has_prev(messageview));
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/View/Goto/NextHistory", messageview_nav_has_next(messageview));
 }
 
 void messageview_learn (MessageView *msgview, gboolean is_spam)
index 2152fc4..d4ae59a 100644 (file)
@@ -82,6 +82,8 @@ struct _MessageView
        gboolean show_full_text;
        gboolean partial_display_shown;
        GtkUIManager *ui_manager;
+       GList *trail;
+       gint trail_pos;
 };
 
 MessageView *messageview_create                        (MainWindow     *mainwin);
@@ -128,4 +130,9 @@ void messageview_list_urls                  (MessageView    *msgview);
 void messageview_show_partial_display          (MessageView    *msgview, 
                                                 MsgInfo        *msginfo,
                                                 size_t          length);
+gboolean messageview_nav_has_prev(MessageView *messageview);
+gboolean messageview_nav_has_next(MessageView *messageview);
+MsgInfo *messageview_nav_get_prev(MessageView *messageview);
+MsgInfo *messageview_nav_get_next(MessageView *messageview);
+
 #endif /* __MESSAGEVIEW_H__ */
index 25e11b2..e2ca215 100644 (file)
@@ -1165,6 +1165,9 @@ static PrefParam param[] = {
        {"flush_metadata", "TRUE", &prefs_common.flush_metadata, P_BOOL,
         NULL, NULL, NULL},
 
+       {"nav_history_length", "50", &prefs_common.nav_history_length, P_INT,
+        NULL, NULL, NULL},
+
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
index 03761b5..fb6600b 100644 (file)
@@ -519,6 +519,7 @@ struct _PrefsCommon
        gboolean inherit_folder_props;
        gboolean flush_metadata;
 
+       gint nav_history_length;
 };
 
 extern PrefsCommon prefs_common;
index dab25a9..e567237 100644 (file)
@@ -756,6 +756,52 @@ static PrefsAccount *procmsg_get_account_from_file(const gchar *file)
        return mailac;
 }
 
+gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo)
+{
+       gchar *folder_id;
+       const gchar *msgid;
+       gchar *id;
+
+       cm_return_val_if_fail(msginfo != NULL, NULL);
+       folder_id = folder_item_get_identifier(msginfo->folder);
+       msgid = msginfo->msgid;
+
+       id = g_strconcat(folder_id, G_DIR_SEPARATOR_S, msgid, NULL);
+
+       g_free(folder_id);
+
+       return id;
+}
+
+MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id)
+{
+       gchar *folder_id = g_strdup(id);
+       gchar *separator = strrchr(folder_id, G_DIR_SEPARATOR);
+       const gchar *msgid;
+       FolderItem *item;
+       MsgInfo *msginfo;
+
+       if (separator == NULL) {
+               g_free(folder_id);
+               return NULL;
+       }
+
+       *separator = '\0';
+       msgid = separator + 1;
+
+       item = folder_find_item_from_identifier(folder_id);
+
+       if (item == NULL) {
+               g_free(folder_id);
+               return NULL;
+       }
+
+       msginfo = folder_item_get_msginfo_by_msgid(item, msgid);
+       g_free(folder_id);
+
+       return msginfo;
+}
+
 static GSList *procmsg_list_sort_by_account(FolderItem *queue, GSList *list)
 {
        GSList *result = NULL;
index 859d1c5..db488ff 100644 (file)
@@ -401,4 +401,6 @@ gchar *procmsg_msginfo_get_tags_str(MsgInfo *msginfo);
 void procmsg_msginfo_update_tags(MsgInfo *msginfo, gboolean set, gint id);
 void procmsg_msginfo_clear_tags(MsgInfo *msginfo);
 void procmsg_msginfo_commit_tags(GSList *msglist);
+MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id);
+gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo);
 #endif /* __PROCMSG_H__ */
index 6134f58..16c53eb 100644 (file)
@@ -1134,7 +1134,6 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        if (!summaryview->mainwin)
                return FALSE;
        START_TIMING("");
-       summaryview->last_displayed = NULL;
        summary_switch_from_to(summaryview, item);
 
        inc_lock();
@@ -1383,7 +1382,6 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
        if (is_refresh) {
                if (!quicksearch_is_in_typing(summaryview->quicksearch)) {
-                       summaryview->last_displayed = summaryview->displayed;
                        summaryview->displayed =
                                summary_find_msg_by_msgnum(summaryview,
                                                           displayed_msgnum);
@@ -2044,12 +2042,6 @@ void summary_select_next_labeled(SummaryView *summaryview)
                summary_select_node(summaryview, node, TRUE, FALSE);
 }
 
-void summary_select_last_read(SummaryView *summaryview)
-{
-       if (summaryview->last_displayed)
-               summary_select_node(summaryview, summaryview->last_displayed, TRUE, FALSE);
-}
-
 void summary_select_parent(SummaryView *summaryview)
 {
        GtkCMCTreeNode *node = NULL;
@@ -2068,6 +2060,14 @@ void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum)
        summary_select_node(summaryview, node, FALSE, TRUE);
 }
 
+void summary_display_by_msgnum(SummaryView *summaryview, guint msgnum)
+{
+       GtkCMCTreeNode *node;
+
+       node = summary_find_msg_by_msgnum(summaryview, msgnum);
+       summary_select_node(summaryview, node, TRUE, FALSE);
+}
+
 void summary_select_by_msg_list(SummaryView    *summaryview, GSList *msginfos)
 {
        GtkCMCTree *ctree;
@@ -3502,7 +3502,6 @@ static void summary_display_msg_full(SummaryView *summaryview,
                        else
                                gtkut_window_popup(summaryview->ext_messageview->window);
                        msgview = summaryview->ext_messageview;
-                       summaryview->last_displayed = summaryview->displayed;
                        summaryview->displayed = row;
                        val = messageview_show(msgview, msginfo, all_headers);
                        if (mimeview_tree_is_empty(msgview->mimeview))
@@ -3511,7 +3510,6 @@ static void summary_display_msg_full(SummaryView *summaryview,
                                GTK_CMCLIST(summaryview->ctree)->focus_row);
                } else {
                        msgview = summaryview->messageview;
-                       summaryview->last_displayed = summaryview->displayed;
                        summaryview->displayed = row;
                        if (!messageview_is_visible(msgview) &&
                            gtk_window_is_active(GTK_WINDOW(summaryview->mainwin->window))) {
@@ -6518,7 +6516,6 @@ void summary_set_column_order(SummaryView *summaryview)
 
        summaryview->selected = summary_find_msg_by_msgnum(summaryview, selected_msgnum);
        summaryview->displayed = summary_find_msg_by_msgnum(summaryview, displayed_msgnum);
-       summaryview->last_displayed = summaryview->displayed;
        if (!summaryview->displayed)
                messageview_clear(summaryview->messageview);
        else
index ceabaaf..6db31e4 100644 (file)
@@ -115,7 +115,6 @@ struct _SummaryView
 
        GtkCMCTreeNode *selected;
        GtkCMCTreeNode *displayed;
-       GtkCMCTreeNode *last_displayed;
 
        gboolean display_msg;
 
@@ -204,10 +203,11 @@ void summary_select_prev_marked     (SummaryView          *summaryview);
 void summary_select_next_marked          (SummaryView          *summaryview);
 void summary_select_prev_labeled  (SummaryView         *summaryview);
 void summary_select_next_labeled  (SummaryView         *summaryview);
-void summary_select_last_read     (SummaryView         *summaryview);
 void summary_select_parent        (SummaryView         *summaryview);
 void summary_select_by_msgnum    (SummaryView          *summaryview,
                                   guint                 msgnum);
+void summary_display_by_msgnum   (SummaryView          *summaryview,
+                                  guint                 msgnum);
 void summary_select_by_msg_list   (SummaryView         *summaryview, GSList *msginfos);
 guint summary_get_current_msgnum  (SummaryView         *summaryview);
 void summary_select_node         (SummaryView          *summaryview,