]> www.fi.muni.cz Git - evince.git/commitdiff
Implements another history variant
authorNickolay V. Shmyrev <nshmyrev@yandex.ru>
Sun, 28 Jan 2007 20:43:21 +0000 (20:43 +0000)
committerNickolay V. Shmyrev <nshmyrev@src.gnome.org>
Sun, 28 Jan 2007 20:43:21 +0000 (20:43 +0000)
2007-01-28  Nickolay V. Shmyrev  <nshmyrev@yandex.ru>

* NOTES:
* backend/djvu/djvu-links.c: (djvu_links_get_links_model):
* backend/pdf/ev-poppler.cc:
* libdocument/ev-document-links.h:
* libdocument/ev-link.c: (ev_link_get_page):
* libdocument/ev-link.h:
* shell/ev-history.c: (ev_history_init), (ev_history_class_init),
(ev_history_add_link):
* shell/ev-history.h:
* shell/ev-navigation-action.c: (activate_menu_item_cb),
(new_history_menu_item), (build_menu):
* shell/ev-page-cache.c: (ev_page_cache_set_current_page_history):
* shell/ev-sidebar-links.c: (create_loading_model),
(print_section_cb), (ev_sidebar_links_construct),
(fill_page_labels), (update_page_callback_foreach),
(update_page_callback), (job_finished_callback):
* shell/ev-view.c: (ev_view_handle_link):
* shell/ev-window.c: (ev_window_find_chapter),
(ev_window_add_history), (view_handle_link_cb),
(history_changed_cb):

Implements another history variant

svn path=/trunk/; revision=2264

14 files changed:
ChangeLog
NOTES
backend/djvu/djvu-links.c
backend/pdf/ev-poppler.cc
libdocument/ev-document-links.h
libdocument/ev-link.c
libdocument/ev-link.h
shell/ev-history.c
shell/ev-history.h
shell/ev-navigation-action.c
shell/ev-page-cache.c
shell/ev-sidebar-links.c
shell/ev-view.c
shell/ev-window.c

index 9c4d6b473f4bfdc90bdc601099bdd3fcd01ac096..bca1bacec538c2248dc0cee6a9f2c414147c0f93 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2007-01-28  Nickolay V. Shmyrev  <nshmyrev@yandex.ru>
+
+       * NOTES:
+       * backend/djvu/djvu-links.c: (djvu_links_get_links_model):
+       * backend/pdf/ev-poppler.cc:
+       * libdocument/ev-document-links.h:
+       * libdocument/ev-link.c: (ev_link_get_page):
+       * libdocument/ev-link.h:
+       * shell/ev-history.c: (ev_history_init), (ev_history_class_init),
+       (ev_history_add_link):
+       * shell/ev-history.h:
+       * shell/ev-navigation-action.c: (activate_menu_item_cb),
+       (new_history_menu_item), (build_menu):
+       * shell/ev-page-cache.c: (ev_page_cache_set_current_page_history):
+       * shell/ev-sidebar-links.c: (create_loading_model),
+       (print_section_cb), (ev_sidebar_links_construct),
+       (fill_page_labels), (update_page_callback_foreach),
+       (update_page_callback), (job_finished_callback):
+       * shell/ev-view.c: (ev_view_handle_link):
+       * shell/ev-window.c: (ev_window_find_chapter),
+       (ev_window_add_history), (view_handle_link_cb),
+       (history_changed_cb):
+       
+       Implements another history variant
+
 2007-01-28  Carlos Garcia Campos  <carlosgc@gnome.org>
 
        * shell/ev-window.c: (view_external_link_cb):
diff --git a/NOTES b/NOTES
index fadc30fbbc0d87e0cd11f6d6ee3607d96d7f9fe3..3c7db7a61bc203fbff5476e13ce422b8b121806f 100644 (file)
--- a/NOTES
+++ b/NOTES
@@ -52,3 +52,26 @@ THOUGHTS ON SELECTION:
 
  * click-drag, dbl click, triple click, shift-click, search, shift-cursor move
 
+
+THOUGHTS ON HISTORY:
+====================
+
+ * We need single history button, back/forward will complicate things.
+ * When we jump on dest link we should add current page and link to the history.
+ * When we jump on external link we should just add external link.
+ * It's enough to have 7 entries in history, too many entries complicates things.
+ * We should avoid duplicate entries in history. If we'll activate entry
+   that already exists (have the same title) we can just move it to the top.
+   
+
index 38fad0d198943de0fce5d5528831dd8fdf36077c..1fc394ada488f6927f04f803aab3e47a6d68853d 100644 (file)
@@ -383,7 +383,8 @@ djvu_links_get_links_model (EvDocumentLinks *document_links)
                model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
                                                             G_TYPE_STRING,
                                                             G_TYPE_OBJECT,
-                                                            G_TYPE_BOOLEAN);
+                                                            G_TYPE_BOOLEAN,
+                                                            G_TYPE_STRING);
                build_tree (djvu_document, model, NULL, outline);
 
                ddjvu_miniexp_release (djvu_document->d_document, outline);
index 2068998ecded64b76070ec760f8db0379cbd074b..5c7f495d3301f17e8fcdeb9296d588e99562fb06 100644 (file)
@@ -1052,7 +1052,8 @@ pdf_document_links_get_links_model (EvDocumentLinks *document_links)
                model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
                                                             G_TYPE_STRING,
                                                             G_TYPE_OBJECT,
-                                                            G_TYPE_BOOLEAN);
+                                                            G_TYPE_BOOLEAN,
+                                                            G_TYPE_STRING);
                build_tree (pdf_document, model, NULL, iter);
                poppler_index_iter_free (iter);
        }
index 8e8f20a7dca9ca6ce5424143643362cb69d7e0fa..a9208f48d6cb458c9ecff878218724341fc9cea7 100644 (file)
@@ -48,6 +48,7 @@ enum {
        EV_DOCUMENT_LINKS_COLUMN_MARKUP,
        EV_DOCUMENT_LINKS_COLUMN_LINK,
        EV_DOCUMENT_LINKS_COLUMN_EXPAND,
+       EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL,
        EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS
 };
 
index 8561914b69935e5af88933eb31368f11c130ecb7..17e44213951323282b2f483d957113d92297eb8e 100644 (file)
@@ -224,3 +224,23 @@ ev_link_mapping_find (GList   *link_mapping,
        return link;
 }
 
+gint
+ev_link_get_page (EvLink *link)
+{
+       EvLinkAction *action;
+       EvLinkDest *dest;
+
+       action = ev_link_get_action (link);
+       if (!action)
+               return -1;
+
+       if (ev_link_action_get_action_type (action) !=
+           EV_LINK_ACTION_TYPE_GOTO_DEST)
+               return -1;
+
+       dest = ev_link_action_get_dest (action);
+       if (dest)
+               return ev_link_dest_get_page (dest);
+               
+       return -1;
+}
index b7304debfe1e9d8435f8dab7fb6fcf905ab3d5cb..9bd7f6e0af18e6d170ce23302f84214777be06ba 100644 (file)
@@ -43,6 +43,7 @@ EvLink             *ev_link_new        (const gchar  *title,
 
 const gchar  *ev_link_get_title  (EvLink       *self);
 EvLinkAction *ev_link_get_action (EvLink       *self);
+gint         ev_link_get_page   (EvLink *link);
 
 /* Link Mapping stuff */
 typedef struct _EvLinkMapping    EvLinkMapping;
index 87a506f33b0c05bf36d67d62dc027594e8f5cb01..c06fa25fa8349b94c44dfcb52a82e49f2d481959 100644 (file)
 #include "config.h"
 
 #include <glib/gi18n.h>
+#include <string.h>
 
 #include "ev-history.h"
 
 struct _EvHistoryPrivate
 {
        GList *links;
-       int current_index;
-};
-
-enum {
-       PROP_0,
-       PROP_INDEX
 };
 
 static void ev_history_init       (EvHistory *history);
@@ -47,7 +42,6 @@ ev_history_init (EvHistory *history)
        history->priv = EV_HISTORY_GET_PRIVATE (history);
 
        history->priv->links = NULL;
-       history->priv->current_index = -1;
 }
 
 static void
@@ -67,103 +61,43 @@ ev_history_finalize (GObject *object)
        G_OBJECT_CLASS (ev_history_parent_class)->finalize (object);
 }
 
-static void
-ev_history_get_property (GObject *object, guint prop_id, GValue *value,
-                        GParamSpec *param_spec)
-{
-       EvHistory *self;
-
-       self = EV_HISTORY (object);
-
-       switch (prop_id) {
-       case PROP_INDEX:
-               g_value_set_int (value, self->priv->current_index);
-               break;
-       default:
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
-                                                  prop_id,
-                                                  param_spec);
-               break;
-       }
-}
-
-static void
-ev_history_set_property (GObject *object, guint prop_id, const GValue *value,
-                        GParamSpec *param_spec)
-{
-       EvHistory *self;
-       
-       self = EV_HISTORY (object);
-       
-       switch (prop_id) {
-       case PROP_INDEX:
-               ev_history_set_current_index (self, g_value_get_int (value));
-               break;
-       default:
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
-                                                  prop_id,
-                                                  param_spec);
-               break;
-       }
-}
-
 static void
 ev_history_class_init (EvHistoryClass *class)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (class);
 
        object_class->finalize = ev_history_finalize;
-       object_class->set_property = ev_history_set_property;
-       object_class->get_property = ev_history_get_property;
-
-       g_object_class_install_property (object_class,
-                                        PROP_INDEX,
-                                        g_param_spec_int ("index",
-                                                          "Current Index",
-                                                          "The current index",
-                                                           -1,
-                                                           G_MAXINT,
-                                                           0,
-                                                           G_PARAM_READWRITE));
 
        g_type_class_add_private (object_class, sizeof (EvHistoryPrivate));
 }
 
+#define HISTORY_LENGTH   7
+
 void
 ev_history_add_link (EvHistory *history, EvLink *link)
 {
-       int length;
+       GList *l;
 
        g_return_if_fail (EV_IS_HISTORY (history));
        g_return_if_fail (EV_IS_LINK (link));
 
+       for (l = history->priv->links; l; l = l->next) {
+               if (!strcmp (ev_link_get_title (EV_LINK (l->data)), ev_link_get_title (link))) {
+                       g_object_unref (G_OBJECT (l->data));
+                       history->priv->links = g_list_delete_link (history->priv->links, l);
+                       break;
+               }
+       }
 
        g_object_ref (link);
        history->priv->links = g_list_append (history->priv->links,
                                              link);
-
-       length = g_list_length (history->priv->links);
-       history->priv->current_index = length - 1;
-}
-
-void
-ev_history_add_page (EvHistory *history, int page, const gchar *label)
-{
-       EvLink *link;
-       EvLinkDest *dest;
-       EvLinkAction *action;
-       gchar *title;
-
-       g_return_if_fail (EV_IS_HISTORY (history));
-       
-       title = g_strdup_printf (_("Page: %s"), label);
-
-       dest = ev_link_dest_new_page (page);
-       action = ev_link_action_new_dest (dest);
-       link = ev_link_new (title, action);
-       g_free (title);
-
-       ev_history_add_link (history, link);
+                                             
+       if (g_list_length (history->priv->links) > HISTORY_LENGTH) {
+               g_object_unref (G_OBJECT (history->priv->links->data));
+               history->priv->links = g_list_delete_link (history->priv->links, 
+                                                          history->priv->links);
+       }
 }
 
 EvLink *
@@ -186,26 +120,9 @@ ev_history_get_n_links (EvHistory *history)
        return g_list_length (history->priv->links);
 }
 
-int
-ev_history_get_current_index (EvHistory *history)
-{
-       g_return_val_if_fail (EV_IS_HISTORY (history), -1);
-
-       return history->priv->current_index;
-}
-
-void
-ev_history_set_current_index (EvHistory *history, int index)
-{
-       g_return_if_fail (EV_IS_HISTORY (history));
-
-       history->priv->current_index = index;
-
-       g_object_notify (G_OBJECT (history), "index");
-}
-
 EvHistory *
 ev_history_new (void)
 {
        return EV_HISTORY (g_object_new (EV_TYPE_HISTORY, NULL));
 }
+
index 4f1ec1aa3c4a591f2443f43b5273061b162ff5f9..2d27bda615c6b341be6cdd7a97bb21335c44c6db 100644 (file)
@@ -54,15 +54,9 @@ GType                ev_history_get_type             (void);
 EvHistory      *ev_history_new                 (void);
 void           ev_history_add_link             (EvHistory  *history,
                                                 EvLink     *linkk);
-void           ev_history_add_page             (EvHistory  *history,
-                                                int         page,
-                                                const gchar *label);
 EvLink        *ev_history_get_link_nth         (EvHistory  *history,
                                                 int         index);
 int            ev_history_get_n_links          (EvHistory  *history);
-int            ev_history_get_current_index    (EvHistory  *history);
-void           ev_history_set_current_index    (EvHistory  *history,
-                                                int         index);
 
 G_END_DECLS
 
index 88fe67b6de01bbadca11021d4876aa0568fa9fe5..c87940a64236a5477bf8c35c5fd7d37d4b581a26 100644 (file)
@@ -72,7 +72,6 @@ activate_menu_item_cb (GtkWidget *widget, EvNavigationAction *action)
        g_return_if_fail (EV_IS_HISTORY (action->priv->history));
 
        index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "index"));
-       ev_history_set_current_index (action->priv->history, index);
        
        if (action->priv->history) {
                EvLink *link;
@@ -94,6 +93,7 @@ new_history_menu_item (EvNavigationAction *action,
 
        title = ev_link_get_title (link);
        item = gtk_image_menu_item_new_with_label (title);
+       gtk_label_set_use_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), TRUE);
        g_object_set_data (G_OBJECT (item), "index",
                           GINT_TO_POINTER (index));
 
@@ -139,8 +139,8 @@ build_menu (EvNavigationAction *action)
                return GTK_WIDGET (menu);
        }
 
-       start = MAX (ev_history_get_current_index (action->priv->history) - 5, 0);
-       end = MIN (ev_history_get_n_links (history), start + 7);
+       start = 0;
+       end = ev_history_get_n_links (history);
 
        for (i = start; i < end; i++) {
                link = ev_history_get_link_nth (history, i);
index 7ea0c0f9d04d7020d80b18075d95d0008b90428b..070df9d767a0972ca8d9fc3fcef8d8cf443186c1 100644 (file)
@@ -341,8 +341,8 @@ ev_page_cache_set_current_page_history (EvPageCache *page_cache,
                                        int          page)
 {
        if (abs (page - page_cache->current_page) > 1)
-               g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page_cache->current_page);
-               
+               g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page);
+       
        ev_page_cache_set_current_page (page_cache, page);
 }
 
index 1205b4e2ecc700c8b1129dbbbeea3adf9b15e734..8017f7c605b071aae21054bdf59c7d5bf2d5c240 100644 (file)
@@ -59,11 +59,6 @@ enum {
        N_SIGNALS
 };
 
-static void links_page_num_func                                (GtkTreeViewColumn *tree_column,
-                                                        GtkCellRenderer   *cell,
-                                                        GtkTreeModel      *tree_model,
-                                                        GtkTreeIter       *iter,
-                                                        EvSidebarLinks    *sidebar_links);
 static void update_page_callback                       (EvPageCache       *page_cache,
                                                         gint               current_page,
                                                         EvSidebarLinks    *sidebar_links);
@@ -264,7 +259,8 @@ create_loading_model (void)
        retval = (GtkTreeModel *)gtk_list_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
                                                     G_TYPE_STRING,
                                                     G_TYPE_OBJECT,
-                                                    G_TYPE_BOOLEAN);
+                                                    G_TYPE_BOOLEAN,
+                                                    G_TYPE_STRING);
 
        gtk_list_store_append (GTK_LIST_STORE (retval), &iter);
        markup = g_strdup_printf ("<span size=\"larger\" style=\"italic\">%s</span>", _("Loading..."));
@@ -278,27 +274,6 @@ create_loading_model (void)
        return retval;
 }
 
-static gint
-get_page_from_link (EvLink *link)
-{
-       EvLinkAction *action;
-       EvLinkDest *dest;
-
-       action = ev_link_get_action (link);
-       if (!action)
-               return -1;
-
-       if (ev_link_action_get_action_type (action) !=
-           EV_LINK_ACTION_TYPE_GOTO_DEST)
-               return -1;
-
-       dest = ev_link_action_get_dest (action);
-       if (dest)
-               return ev_link_dest_get_page (dest);
-               
-       return -1;
-}
-
 static void
 print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
 {
@@ -321,7 +296,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
                if (!link)
                        return;
 
-               first_page = get_page_from_link (link);
+               first_page = ev_link_get_page (link);
                if (first_page == -1) {
                        g_object_unref (link);
                        return;
@@ -336,7 +311,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
                                            -1);
 
                        if (link) {
-                               last_page = get_page_from_link (link);
+                               last_page = ev_link_get_page (link);
                                g_object_unref (link);
                        }
                } else {
@@ -461,9 +436,9 @@ ev_sidebar_links_construct (EvSidebarLinks *ev_sidebar_links)
        
        renderer = gtk_cell_renderer_text_new ();
        gtk_tree_view_column_pack_end (GTK_TREE_VIEW_COLUMN (column), renderer, FALSE);
-       gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column), renderer,
-                                                (GtkTreeCellDataFunc) links_page_num_func,
-                                                ev_sidebar_links, NULL);
+       gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer,
+                                            "markup", EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL,
+                                            NULL);
 
        g_signal_connect (GTK_TREE_VIEW (priv->tree_view),
                          "button_press_event",
@@ -483,51 +458,43 @@ ev_sidebar_links_init (EvSidebarLinks *ev_sidebar_links)
        ev_sidebar_links_construct (ev_sidebar_links);
 }
 
-static void
-links_page_num_func (GtkTreeViewColumn *tree_column,
-                    GtkCellRenderer   *cell,
-                    GtkTreeModel      *tree_model,
-                    GtkTreeIter       *iter,
-                    EvSidebarLinks    *sidebar_links)
+static gboolean
+fill_page_labels (GtkTreeModel *tree_model,
+                  GtkTreePath *path,
+                  GtkTreeIter *iter,
+                 EvSidebarLinks    *sidebar_links)
 {
        EvLink *link;
        gint page;
+       gchar *page_label;
+       gchar *page_string;
+
 
        gtk_tree_model_get (tree_model, iter,
                            EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
                            -1);
 
-       if (!link) {
-               g_object_set (cell,
-                             "visible", FALSE,
-                             NULL);
-               return;
-       }
-
-       page = get_page_from_link (link);
+       if (!link)
+               return FALSE;
 
-       if (page >= 0) {
-               gchar *page_label;
-               gchar *page_string;
+       page = ev_link_get_page (link);
 
-               page_label = ev_page_cache_get_page_label (sidebar_links->priv->page_cache,
-                                                          page);
-               page_string = g_markup_printf_escaped ("<i>%s</i>", page_label);
-
-               g_object_set (cell,
-                             "markup", page_string,
-                             "visible", TRUE,
-                             NULL);
+       if (page < 0) 
+               return FALSE;
+       
+       page_label = ev_page_cache_get_page_label (sidebar_links->priv->page_cache,
+                                                  page);
+       page_string = g_markup_printf_escaped ("<i>%s</i>", page_label);
+               
+       gtk_tree_store_set (GTK_TREE_STORE (tree_model), iter,
+                           EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, page_string, 
+                             -1);
 
-               g_free (page_label);
-               g_free (page_string);
-       } else {
-               g_object_set (cell,
-                             "visible", FALSE,
-                             NULL);
-       }
+       g_free (page_label);
+       g_free (page_string);
 
        g_object_unref (link);
+       return FALSE;
 }
 
 /* Public Functions */
@@ -559,7 +526,7 @@ update_page_callback_foreach (GtkTreeModel *model,
                int current_page;
                int dest_page;
 
-               dest_page = get_page_from_link (link);
+               dest_page = ev_link_get_page (link);
                g_object_unref (link);
                
                current_page = ev_page_cache_get_current_page (sidebar_links->priv->page_cache);
@@ -601,7 +568,7 @@ update_page_callback (EvPageCache    *page_cache,
                if (link) {
                        gint dest_page;
 
-                       dest_page = get_page_from_link (link);
+                       dest_page = ev_link_get_page (link);
                        g_object_unref (link);
                        
                        if (dest_page == current_page)
@@ -673,6 +640,8 @@ job_finished_callback (EvJobLinks     *job,
        
        priv->model = job->model;
        g_object_notify (G_OBJECT (sidebar_links), "model");
+       
+       gtk_tree_model_foreach (priv->model, (GtkTreeModelForeachFunc)fill_page_labels, sidebar_links);
 
        gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), job->model);
        
index b722785ea4027d370a599169b21ec4e0ebe1f3d8..a01a217125be401546f875f7ed0e96ef06f241ab 100644 (file)
@@ -1348,7 +1348,6 @@ ev_view_handle_link (EvView *view, EvLink *link)
        if (!action)
                return;
 
-       g_signal_emit (view, signals[SIGNAL_HANDLE_LINK], 0, link);
        
        type = ev_link_action_get_action_type (action);
 
@@ -1356,6 +1355,8 @@ ev_view_handle_link (EvView *view, EvLink *link)
                case EV_LINK_ACTION_TYPE_GOTO_DEST: {
                        EvLinkDest *dest;
                        
+                       g_signal_emit (view, signals[SIGNAL_HANDLE_LINK], 0, link);
+               
                        dest = ev_link_action_get_dest (action);
                        ev_view_goto_dest (view, dest);
                }
index 8e414a57e46a77bf77f3427a34e485da1e4fadfd..1680b4218932747079d2823b1d6e41a98ef3dfc1 100644 (file)
@@ -643,13 +643,112 @@ page_changed_cb (EvPageCache *page_cache,
        if (!ev_window_is_empty (ev_window))
                ev_metadata_manager_set_int (ev_window->priv->uri, "page", page);
 }
+
+typedef struct _FindTask {
+    gchar *page_label;
+    gchar *chapter;
+} FindTask;
+
+static gboolean
+ev_window_find_chapter (GtkTreeModel *tree_model,
+                       GtkTreePath  *path,
+                       GtkTreeIter  *iter,
+                       gpointer      data)
+{
+    FindTask *task = (FindTask *)data;
+    gchar *page_string;
+    
+    gtk_tree_model_get (tree_model, iter,
+                       EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, &page_string, 
+                       -1);
+                       
+    if (!page_string)
+           return FALSE;
+           
+    if (!strncmp (page_string + strlen ("<i>"), task->page_label, strlen (task->page_label))) {
+           gtk_tree_model_get (tree_model, iter,
+                               EV_DOCUMENT_LINKS_COLUMN_MARKUP, &task->chapter, 
+                               -1);
+           g_free (page_string);
+           return TRUE;
+    }
+    
+    g_free (page_string);
+    return FALSE;
+}
+
+static void
+ev_window_add_history (EvWindow *window, gint page, EvLink *link)
+{
+       gchar *page_label;
+       gchar *link_title;
+       FindTask find_task;
+
+       EvLink *real_link;
+       EvLinkAction *action;
+       EvLinkDest *dest;
+       
+       if (link) {
+               action = g_object_ref (ev_link_get_action (link));
+               dest = ev_link_action_get_dest (action);
+               page = ev_link_dest_get_page (dest);
+       } else {
+               dest = ev_link_dest_new_page (page);
+               action = ev_link_action_new_dest (dest);
+       }
+
+       if (page < 0)
+               return;
+       
+       page_label = ev_page_cache_get_page_label (window->priv->page_cache, page);
+       
+       find_task.page_label = page_label;
+       find_task.chapter = NULL;
+       
+       if (EV_IS_DOCUMENT_LINKS (window->priv->document)) {
+               GtkTreeModel *model;
+       
+               g_object_get (G_OBJECT (window->priv->sidebar_links), "model", &model, NULL);
+               
+               gtk_tree_model_foreach (model,
+                                       ev_window_find_chapter,
+                                       &find_task);
+       
+               g_object_unref (model);
+       }
+
+       if (find_task.chapter)
+               link_title = g_strdup_printf (_("Page %s - %s"), page_label, find_task.chapter);
+       else
+               link_title = g_strdup_printf (_("Page %s"), page_label);
+       
+       real_link = ev_link_new (link_title, action);
+       
+       ev_history_add_link (window->priv->history, real_link);
+       
+       g_free (link_title);
+       g_object_unref (real_link);
+}
+
+static void
+view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window)
+{
+       int current_page = ev_page_cache_get_current_page (window->priv->page_cache);
+       
+       ev_window_add_history (window, 0, link);
+       ev_window_add_history (window, current_page, NULL);
+}
+
 static void
 history_changed_cb (EvPageCache *page_cache,
                    gint         page,
-                   EvWindow    *ev_window)
+                   EvWindow    *window)
 {
-       ev_history_add_page (ev_window->priv->history, page, 
-                            ev_page_cache_get_page_label (ev_window->priv->page_cache, page));
+       int current_page = ev_page_cache_get_current_page (window->priv->page_cache);
+
+       ev_window_add_history (window, page, NULL);
+       ev_window_add_history (window, current_page, NULL);
+
        return;
 }
 
@@ -4045,11 +4144,7 @@ static void
 navigation_action_activate_link_cb (EvNavigationAction *action, EvLink *link, EvWindow *window)
 {
        
-       g_signal_handlers_block_by_func
-               (window->priv->view, G_CALLBACK (view_handle_link_cb), window);
        ev_view_handle_link (EV_VIEW (window->priv->view), link);
-       g_signal_handlers_unblock_by_func
-               (window->priv->view, G_CALLBACK (view_handle_link_cb), window);
        gtk_widget_grab_focus (window->priv->view);
 }
 
@@ -4337,15 +4432,6 @@ do_action_named (EvWindow *window, EvLinkAction *action)
        }
 }
 
-static void
-view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window)
-{
-       int current_page = ev_page_cache_get_current_page (window->priv->page_cache);
-       ev_history_add_page (window->priv->history, 
-                            current_page,
-                            ev_page_cache_get_page_label (window->priv->page_cache, current_page));
-}
-
 static void
 view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window)
 {