[evince] Keep track of the current search result page instead of using the current page



commit 8d3ac1d8de83f3c6d9c51e9ad2c56e000d4bb4e7
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Sun Oct 27 16:38:27 2013 +0100

    Keep track of the current search result page instead of using the current page
    
    In continous mode the page of the current search result might not the
    the current page. Also make sure that when the search is restarted (the
    find bar is closed and opened with the same search string) both the view
    and the sidebar highlight the first match found from the current page.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=710778

 help/reference/libview/libevview-sections.txt |    1 +
 libview/ev-view-private.h                     |    1 +
 libview/ev-view.c                             |   84 +++++++++++++++++--------
 libview/ev-view.h                             |    2 +
 shell/ev-find-sidebar.c                       |   63 +++++++++++++++----
 shell/ev-find-sidebar.h                       |    2 +
 shell/ev-window.c                             |   33 +++++++---
 7 files changed, 139 insertions(+), 47 deletions(-)
---
diff --git a/help/reference/libview/libevview-sections.txt b/help/reference/libview/libevview-sections.txt
index 3e2fb91..f20a0e0 100644
--- a/help/reference/libview/libevview-sections.txt
+++ b/help/reference/libview/libevview-sections.txt
@@ -42,6 +42,7 @@ ev_view_find_previous
 ev_view_find_search_changed
 ev_view_find_set_highlight_search
 ev_view_find_started
+ev_view_find_restart
 ev_view_find_cancel
 ev_view_find_set_result
 ev_view_highlight_forward_search
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 3bb289b..7633c3a 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -118,6 +118,7 @@ struct _EvView {
        /* Find */
        EvJobFind *find_job;
        GList **find_pages; /* Backwards compatibility */
+       gint find_page;
        gint find_result;
        gboolean jump_to_find_result;
        gboolean highlight_find_results;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 4e22dc4..da69022 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -5866,7 +5866,8 @@ highlight_find_results (EvView *view,
                         cairo_t *cr,
                         int page)
 {
-       gint       i, n_results = 0;
+       gint i, n_results = 0;
+
        n_results = ev_view_find_get_n_results (view, page);
 
        for (i = 0; i < n_results; i++) {
@@ -5874,7 +5875,7 @@ highlight_find_results (EvView *view,
                GdkRectangle view_rectangle;
                gdouble      alpha;
 
-               if (i == view->find_result && page == view->current_page) {
+               if (i == view->find_result && page == view->find_page) {
                        alpha = 0.6;
                } else {
                        alpha = 0.3;
@@ -6669,6 +6670,7 @@ ev_view_init (EvView *view)
        view->sizing_mode = EV_SIZING_FIT_WIDTH;
        view->page_layout = EV_PAGE_LAYOUT_SINGLE;
        view->pending_scroll = SCROLL_TO_KEEP_POSITION;
+       view->find_page = -1;
        view->jump_to_find_result = TRUE;
        view->highlight_find_results = FALSE;
        view->pixbuf_cache_size = DEFAULT_PIXBUF_CACHE_SIZE;
@@ -6721,8 +6723,6 @@ ev_view_page_changed_cb (EvDocumentModel *model,
        } else {
                gtk_widget_queue_draw (GTK_WIDGET (view));
        }
-
-       view->find_result = 0;
 }
 
 static void
@@ -6981,6 +6981,7 @@ ev_view_document_changed_cb (EvDocumentModel *model,
                 }
 
                view->document = document ? g_object_ref (document) : NULL;
+               view->find_page = -1;
                view->find_result = 0;
 
                if (view->document) {
@@ -7570,7 +7571,7 @@ static void
 jump_to_find_result (EvView *view)
 {
        gint n_results;
-       gint page = view->current_page;
+       gint page = view->find_page;
 
        n_results = ev_view_find_get_n_results (view, page);
 
@@ -7604,20 +7605,20 @@ jump_to_find_page (EvView *view, EvViewFindDirection direction, gint shift)
 
        for (i = 0; i < n_pages; i++) {
                int page;
-               
+
                if (direction == EV_VIEW_FIND_NEXT)
-                       page = view->current_page + i;
+                       page = view->find_page + i;
                else
-                       page = view->current_page - i;          
+                       page = view->find_page - i;
                page += shift;
-               
-               if (page >= n_pages) {
+
+               if (page >= n_pages)
                        page = page - n_pages;
-               } else if (page < 0) 
+               else if (page < 0)
                        page = page + n_pages;
 
-               if (ev_view_find_get_n_results (view, page) > 0) {
-                       ev_document_model_set_page (view->model, page);
+               if (view->find_pages && view->find_pages[page]) {
+                       view->find_page = page;
                        break;
                }
        }
@@ -7644,6 +7645,8 @@ ev_view_find_started (EvView *view, EvJobFind *job)
 
        ev_view_find_cancel (view);
        view->find_job = g_object_ref (job);
+       view->find_page = view->current_page;
+       view->find_result = 0;
 
        g_signal_connect (job, "updated", G_CALLBACK (find_job_updated_cb), view);
 }
@@ -7662,32 +7665,56 @@ ev_view_find_changed (EvView *view, GList **results, gint page)
        g_return_if_fail (view->current_page >= 0);
 
        view->find_pages = results;
-       
+       if (view->find_page == -1)
+               view->find_page = view->current_page;
+
        if (view->jump_to_find_result == TRUE) {
                jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
                jump_to_find_result (view);
        }
 
-       if (view->current_page == page)
+       if (view->find_page == page)
                gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
+/**
+ * ev_view_find_restart:
+ * @view: an #EvView
+ * @page: a page index
+ *
+ * Restart the current search operation from the given @page.
+ *
+ * Since: 3.12
+ */
+void
+ev_view_find_restart (EvView *view,
+                     gint    page)
+{
+       if (!view->find_job)
+               return;
+
+       view->find_page = page;
+       view->find_result = 0;
+       jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
+       jump_to_find_result (view);
+       gtk_widget_queue_draw (GTK_WIDGET (view));
+}
+
 void
 ev_view_find_next (EvView *view)
 {
        gint n_results;
 
-       n_results = ev_view_find_get_n_results (view, view->current_page);
+       n_results = ev_view_find_get_n_results (view, view->find_page);
        view->find_result++;
 
        if (view->find_result >= n_results) {
                view->find_result = 0;
                jump_to_find_page (view, EV_VIEW_FIND_NEXT, 1);
-               jump_to_find_result (view);
-       } else {
-               jump_to_find_result (view);
-               gtk_widget_queue_draw (GTK_WIDGET (view));
        }
+
+       jump_to_find_result (view);
+       gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
 void
@@ -7697,12 +7724,11 @@ ev_view_find_previous (EvView *view)
 
        if (view->find_result < 0) {
                jump_to_find_page (view, EV_VIEW_FIND_PREV, -1);
-               view->find_result = MAX (0, ev_view_find_get_n_results (view, view->current_page) - 1);
-               jump_to_find_result (view);
-       } else {
-               jump_to_find_result (view);
-               gtk_widget_queue_draw (GTK_WIDGET (view));
+               view->find_result = MAX (0, ev_view_find_get_n_results (view, view->find_page) - 1);
        }
+
+       jump_to_find_result (view);
+       gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
 /**
@@ -7718,9 +7744,13 @@ ev_view_find_previous (EvView *view)
 void
 ev_view_find_set_result (EvView *view, gint page, gint result)
 {
-       ev_document_model_set_page (view->model, page);
+       if (view->find_page == page && view->find_result == result)
+               return;
+
+       view->find_page = page;
        view->find_result = result;
        jump_to_find_result (view);
+       gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
 void
@@ -7742,6 +7772,8 @@ void
 ev_view_find_cancel (EvView *view)
 {
        view->find_pages = NULL;
+       view->find_page = -1;
+       view->find_result = 0;
 
        if (!view->find_job)
                return;
diff --git a/libview/ev-view.h b/libview/ev-view.h
index e7a8523..193bcce 100644
--- a/libview/ev-view.h
+++ b/libview/ev-view.h
@@ -72,6 +72,8 @@ void          ev_view_zoom_out          (EvView         *view);
 /* Find */
 void            ev_view_find_started              (EvView         *view,
                                                   EvJobFind      *job);
+void            ev_view_find_restart              (EvView         *view,
+                                                   gint            page);
 void            ev_view_find_next                 (EvView         *view);
 void            ev_view_find_previous             (EvView         *view);
 void            ev_view_find_set_result           (EvView         *view,
diff --git a/shell/ev-find-sidebar.c b/shell/ev-find-sidebar.c
index b6fe0f8..7025d78 100644
--- a/shell/ev-find-sidebar.c
+++ b/shell/ev-find-sidebar.c
@@ -205,6 +205,26 @@ ev_find_sidebar_select_highlighted_result (EvFindSidebar *sidebar)
         g_signal_handler_unblock (selection, priv->selection_id);
 }
 
+static void
+ev_find_sidebar_highlight_first_match_of_page (EvFindSidebar *sidebar,
+                                               gint           page)
+{
+        EvFindSidebarPrivate *priv = sidebar->priv;
+        gint                  index = 0;
+        gint                  i;
+
+        if (!priv->job)
+                return;
+
+        for (i = 0; i < page; i++)
+                index += ev_job_find_get_n_results (priv->job, i);
+
+        if (priv->highlighted_result)
+                gtk_tree_path_free (priv->highlighted_result);
+        priv->highlighted_result = gtk_tree_path_new_from_indices (index, -1);
+        ev_find_sidebar_select_highlighted_result (sidebar);
+}
+
 static gchar *
 sanitized_substring (const gchar  *text,
                      gint          start,
@@ -453,18 +473,8 @@ process_matches_idle (EvFindSidebar *sidebar)
                 g_free (areas);
         } while (current_page != priv->job_current_page);
 
-        if (ev_job_is_finished (EV_JOB (priv->job)) && priv->current_page == priv->job->start_page) {
-                gint index = 0;
-                gint i;
-
-                for (i = 0; i < priv->first_match_page; i++)
-                        index += ev_job_find_get_n_results (priv->job, i);
-
-                priv->highlighted_result = gtk_tree_path_new_from_indices (index, -1);
-                ev_find_sidebar_select_highlighted_result (sidebar);
-
-                g_clear_object (&priv->job);
-        }
+        if (ev_job_is_finished (EV_JOB (priv->job)) && priv->current_page == priv->job->start_page)
+                ev_find_sidebar_highlight_first_match_of_page (sidebar, priv->first_match_page);
 
         return FALSE;
 }
@@ -514,6 +524,35 @@ ev_find_sidebar_start (EvFindSidebar *sidebar,
 }
 
 void
+ev_find_sidebar_restart (EvFindSidebar *sidebar,
+                         gint           page)
+{
+        EvFindSidebarPrivate *priv = sidebar->priv;
+        gint                  first_match_page = -1;
+        gint                  i;
+
+        if (!priv->job)
+                return;
+
+        for (i = 0; i < priv->job->n_pages; i++) {
+                int index;
+
+                index = page + i;
+
+                if (index >= priv->job->n_pages)
+                        index -= priv->job->n_pages;
+
+                if (priv->job->pages[index]) {
+                        first_match_page = index;
+                        break;
+                }
+        }
+
+        if (first_match_page != -1)
+                ev_find_sidebar_highlight_first_match_of_page (sidebar, first_match_page);
+}
+
+void
 ev_find_sidebar_update (EvFindSidebar *sidebar)
 {
         EvFindSidebarPrivate *priv = sidebar->priv;
diff --git a/shell/ev-find-sidebar.h b/shell/ev-find-sidebar.h
index bee721e..8cf6ed0 100644
--- a/shell/ev-find-sidebar.h
+++ b/shell/ev-find-sidebar.h
@@ -54,6 +54,8 @@ GtkWidget *ev_find_sidebar_new      (void);
 
 void       ev_find_sidebar_start    (EvFindSidebar *find_sidebar,
                                      EvJobFind     *job);
+void       ev_find_sidebar_restart  (EvFindSidebar *find_sidebar,
+                                     gint           page);
 void       ev_find_sidebar_update   (EvFindSidebar *find_sidebar);
 void       ev_find_sidebar_clear    (EvFindSidebar *find_sidebar);
 void       ev_find_sidebar_previous (EvFindSidebar *find_sidebar);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index a11fe50..3291949 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -376,7 +376,8 @@ static void         ev_window_emit_doc_loaded               (EvWindow         *window);
 #endif
 static void     ev_window_setup_bookmarks               (EvWindow         *window);
 
-static void     ev_window_show_find_bar                 (EvWindow         *ev_window);
+static void     ev_window_show_find_bar                 (EvWindow         *ev_window,
+                                                        gboolean          restart);
 static void     ev_window_close_find_bar                (EvWindow         *ev_window);
 
 static gchar *nautilus_sendto = NULL;
@@ -1501,7 +1502,7 @@ ev_window_setup_document (EvWindow *ev_window)
 
                if (ev_window->priv->search_string &&
                    !EV_WINDOW_IS_PRESENTATION (ev_window)) {
-                       ev_window_show_find_bar (ev_window);
+                       ev_window_show_find_bar (ev_window, FALSE);
                        egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar), 
ev_window->priv->search_string);
                }
 
@@ -2225,7 +2226,7 @@ ev_window_open_document (EvWindow       *ev_window,
 
        if (search_string && EV_IS_DOCUMENT_FIND (document) &&
            mode != EV_WINDOW_MODE_PRESENTATION) {
-               ev_window_show_find_bar (ev_window);
+               ev_window_show_find_bar (ev_window, FALSE);
                egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
                                                search_string);
        }
@@ -3967,7 +3968,7 @@ ev_window_cmd_toggle_find (GtkAction *action, EvWindow *ev_window)
 
        show_find_bar = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        if (show_find_bar)
-               ev_window_show_find_bar (ev_window);
+               ev_window_show_find_bar (ev_window, TRUE);
        else
                ev_window_close_find_bar (ev_window);
 }
@@ -3975,7 +3976,17 @@ ev_window_cmd_toggle_find (GtkAction *action, EvWindow *ev_window)
 static void
 ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window)
 {
-       ev_window_show_find_bar (ev_window);
+       ev_window_show_find_bar (ev_window, TRUE);
+}
+
+static void
+ev_window_find_restart (EvWindow *ev_window)
+{
+       gint page;
+
+       page = ev_document_model_get_page (ev_window->priv->model);
+       ev_view_find_restart (EV_VIEW (ev_window->priv->view), page);
+       ev_find_sidebar_restart (EV_FIND_SIDEBAR (ev_window->priv->find_sidebar), page);
 }
 
 static void
@@ -4008,7 +4019,7 @@ ev_window_cmd_edit_find_next (GtkAction *action, EvWindow *ev_window)
                return;
 
        find_bar_hidden = !gtk_widget_get_visible (ev_window->priv->find_bar);
-       ev_window_show_find_bar (ev_window);
+       ev_window_show_find_bar (ev_window, FALSE);
 
        /* Use idle to make sure view allocation happens before find */
        if (find_bar_hidden)
@@ -4033,7 +4044,7 @@ ev_window_cmd_edit_find_previous (GtkAction *action, EvWindow *ev_window)
                return;
 
        find_bar_hidden = !gtk_widget_get_visible (ev_window->priv->find_bar);
-       ev_window_show_find_bar (ev_window);
+       ev_window_show_find_bar (ev_window, FALSE);
 
        /* Use idle to make sure view allocation happens before find */
        if (find_bar_hidden)
@@ -5553,7 +5564,8 @@ update_toggle_find_action (EvWindow *ev_window,
 }
 
 static void
-ev_window_show_find_bar (EvWindow *ev_window)
+ev_window_show_find_bar (EvWindow *ev_window,
+                        gboolean  restart)
 {
        if (gtk_widget_get_visible (ev_window->priv->find_bar)) {
                gtk_widget_grab_focus (ev_window->priv->find_bar);
@@ -5580,6 +5592,9 @@ ev_window_show_find_bar (EvWindow *ev_window)
        update_chrome_visibility (ev_window);
        gtk_widget_grab_focus (ev_window->priv->find_bar);
        update_toggle_find_action (ev_window, TRUE);
+
+       if (restart && ev_window->priv->find_job)
+               ev_window_find_restart (ev_window);
 }
 
 static void
@@ -6653,7 +6668,7 @@ do_action_named (EvWindow *window, EvLinkAction *action)
        } else if (g_ascii_strcasecmp (name, "GoToPage") == 0) {
                ev_window_cmd_focus_page_selector (NULL, window);
        } else if (g_ascii_strcasecmp (name, "Find") == 0) {
-               ev_window_show_find_bar (window);
+               ev_window_show_find_bar (window, TRUE);
        } else if (g_ascii_strcasecmp (name, "Close") == 0) {
                ev_window_cmd_file_close_window (NULL, window);
        } else if (g_ascii_strcasecmp (name, "Print") == 0) {


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