]> www.fi.muni.cz Git - evince.git/commitdiff
More work on find implementation, mostly there now
authorMarco Pesenti Gritti <marco@gnome.org>
Sun, 30 Jan 2005 12:28:10 +0000 (12:28 +0000)
committerMarco Pesenti Gritti <marco@src.gnome.org>
Sun, 30 Jan 2005 12:28:10 +0000 (12:28 +0000)
2005-01-30  Marco Pesenti Gritti  <marco@gnome.org>

        * backend/ev-document-find.c: (ev_document_find_base_init),
        (ev_document_find_changed):
        * backend/ev-document-find.h:
        * pdf/xpdf/pdf-document.cc:
        * shell/ev-view.c: (draw_rubberband), (highlight_find_results),
        (expose_bin_window), (ev_view_init), (set_document_page),
        (ensure_rectangle_is_visible), (jump_to_find_result),
        (jump_to_find_page), (find_changed_cb), (ev_view_set_document),
        (ev_view_find_next), (ev_view_find_previous):
        * shell/ev-view.h:
        * shell/ev-window.c: (find_bar_previous_cb), (find_bar_next_cb):

        More work on find implementation, mostly there now

ChangeLog
backend/ev-document-find.c
backend/ev-document-find.h
pdf/xpdf/pdf-document.cc
shell/ev-view.c
shell/ev-view.h
shell/ev-window.c

index aa880fb093b149f40a5a78c2a996a99017fabf11..673d9e1f33735a08a0d8c2ff13fb81a1999df372 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-01-30  Marco Pesenti Gritti  <marco@gnome.org>
+
+       * backend/ev-document-find.c: (ev_document_find_base_init),
+       (ev_document_find_changed):
+       * backend/ev-document-find.h:
+       * pdf/xpdf/pdf-document.cc:
+       * shell/ev-view.c: (draw_rubberband), (highlight_find_results),
+       (expose_bin_window), (ev_view_init), (set_document_page),
+       (ensure_rectangle_is_visible), (jump_to_find_result),
+       (jump_to_find_page), (find_changed_cb), (ev_view_set_document),
+       (ev_view_find_next), (ev_view_find_previous):
+       * shell/ev-view.h:
+       * shell/ev-window.c: (find_bar_previous_cb), (find_bar_next_cb):
+
+       More work on find implementation, mostly there now
+
 2005-01-29  Marco Pesenti Gritti  <marco@gnome.org>
 
        * backend/ev-backend-marshalers.list:
index 9dc05c48c96422392da548fb1dd131af59e051ba..01ae7398bb5e7e972ebcafee36f3321f115c35d3 100644 (file)
@@ -58,8 +58,9 @@ ev_document_find_base_init (gpointer g_class)
                              G_SIGNAL_RUN_LAST,
                              G_STRUCT_OFFSET (EvDocumentFindIface, find_changed),
                              NULL, NULL,
-                             g_cclosure_marshal_VOID__VOID,
-                             G_TYPE_NONE, 0);
+                             g_cclosure_marshal_VOID__INT,
+                             G_TYPE_NONE, 1,
+                             G_TYPE_INT);
 
                initialized = TRUE;
        }
@@ -117,8 +118,8 @@ ev_document_find_get_progress (EvDocumentFind *document_find,
 }
 
 void
-ev_document_find_changed (EvDocumentFind  *document_find)
+ev_document_find_changed (EvDocumentFind  *document_find, int page)
 {
-       g_signal_emit_by_name (document_find, "find_changed");
+       g_signal_emit_by_name (document_find, "find_changed", page);
 }
                                    
index d17b9de42ce1d62f0e711f22d91260f1a0b7c0be..ebce196bfd936f01aeb931963ca353d0af1f66c3 100644 (file)
@@ -59,7 +59,8 @@ struct _EvDocumentFindIface
 
         /* Signals */
 
-        void (* find_changed) (EvDocumentFind *document_find);
+        void     (* find_changed)     (EvDocumentFind *document_find,
+                                      int             page);
 };
 
 GType     ev_document_find_get_type         (void);
@@ -75,7 +76,8 @@ gboolean  ev_document_find_get_result     (EvDocumentFind *document_find,
                                             GdkRectangle   *rectangle); 
 void     ev_document_find_get_progress     (EvDocumentFind *document_find,
                                             double          percent_complete);
-void      ev_document_find_changed          (EvDocumentFind *document_find);
+void      ev_document_find_changed          (EvDocumentFind *document_find,
+                                            int             page);
 
 
 /* How this interface works:
index df380ad37e79b8d84c393026fe8c830529721c4f..5a7304c6162afe6d5b73fea8b138a40cb822dcc7 100644 (file)
@@ -56,7 +56,7 @@ typedef struct
         /* full results are only possible for the rendered current page */
         int current_page;
         GArray *current_page_results;
-        guchar *other_page_flags; /* length n_pages + 1, first element ignored */
+        int *other_page_flags; /* length n_pages + 1, first element ignored */
         int start_page;   /* skip this one as we iterate, since we did it first */
         int search_page;  /* the page we're searching now */
         TextOutputDev *output_dev;
@@ -510,10 +510,6 @@ pdf_document_search_idle_callback (void *data)
          */
         n_pages = ev_document_get_n_pages (EV_DOCUMENT (search->document));
 
-        if (search->search_page == search->start_page) {
-                goto end_search;
-        }
-
         if (search->output_dev == 0) {
                 /* First time through here... */
                 search->output_dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
@@ -532,8 +528,16 @@ pdf_document_search_idle_callback (void *data)
                                           gFalse, gFalse, // startAtLast, stopAtLast
                                           &xMin, &yMin, &xMax, &yMax)) {
                 /* This page has results */
-                search->other_page_flags[search->search_page] = TRUE;
-        }
+                search->other_page_flags[search->search_page] = 1;
+        } else {
+               search->other_page_flags[search->search_page] = 0;
+       }
+
+        if (search->search_page != search->start_page) {
+               ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document),
+                                         search->search_page);
+               return TRUE;
+       }
 
         search->search_page += 1;
         if (search->search_page > n_pages) {
@@ -541,12 +545,7 @@ pdf_document_search_idle_callback (void *data)
                 search->search_page = 1;
         }
 
-        /* We do this even if nothing was found, to update the percent complete */
-        ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document));
-
-        return TRUE;
-
- end_search:
+end_search:
         /* We're done. */
         search->idle = 0; /* will return FALSE to remove */
         return FALSE;
@@ -559,7 +558,7 @@ pdf_document_find_begin (EvDocumentFind   *document,
 {
         PdfDocument *pdf_document = PDF_DOCUMENT (document);
         PdfDocumentSearch *search;
-        int n_pages;
+        int n_pages, i;
         gunichar *ucs4;
         glong ucs4_len;
 
@@ -597,10 +596,10 @@ pdf_document_find_begin (EvDocumentFind   *document,
                                                     sizeof (GdkRectangle));
         n_pages = ev_document_get_n_pages (EV_DOCUMENT (document));
 
-        /* This is an array of bool; with the first value ignored
-         * so we can index by the based-at-1 page numbers
-         */
-        search->other_page_flags = g_new0 (guchar, n_pages + 1);
+        search->other_page_flags = g_new0 (int, n_pages + 1);
+       for (i = 0; i <= n_pages; i++) {
+               search->other_page_flags[i] = -1;
+       }
 
         search->document = pdf_document;
 
@@ -613,9 +612,7 @@ pdf_document_find_begin (EvDocumentFind   *document,
         search->output_dev = 0;
 
         search->start_page = pdf_document->page;
-        search->search_page = search->start_page + 1;
-        if (search->search_page > n_pages)
-                search->search_page = 1;
+        search->search_page = search->start_page;
 
         search->current_page = -1;
 
index 79bb2dde0a2bca35f9a1d1a537322121c5db1075..4e5db8b18b11ec5b4808e8c581c7abafb503fa1c 100644 (file)
@@ -83,9 +83,8 @@ struct _EvView {
        GtkAdjustment *hadjustment;
        GtkAdjustment *vadjustment;
 
-       int results_on_this_page;
-       int next_page_with_result;
-       double find_percent_complete;
+       int find_page;
+       int find_result;
 
        double scale;
 };
@@ -328,7 +327,8 @@ ev_gdk_color_to_rgb (const GdkColor *color)
 }
 
 static void
-draw_rubberband (GtkWidget *widget, GdkWindow *window, const GdkRectangle *rect)
+draw_rubberband (GtkWidget *widget, GdkWindow *window,
+                const GdkRectangle *rect, gboolean dark)
 {
        GdkGC *gc;
        GdkPixbuf *pixbuf;
@@ -336,7 +336,8 @@ draw_rubberband (GtkWidget *widget, GdkWindow *window, const GdkRectangle *rect)
        guint fill_color;
 
        fill_color_gdk = gdk_color_copy (&GTK_WIDGET (widget)->style->base[GTK_STATE_SELECTED]);
-       fill_color = ev_gdk_color_to_rgb (fill_color_gdk) << 8 | 0x40;
+       fill_color = ev_gdk_color_to_rgb (fill_color_gdk) << 8 |
+                    (dark ? 0x90 : 0x40);
 
        pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
                                 rect->width, rect->height);
@@ -372,10 +373,12 @@ highlight_find_results (EvView *view)
 
        for (i = 0; i < results; i++) {
                GdkRectangle rectangle;
+               gboolean current;
 
+               current = (i == view->find_result);
                ev_document_find_get_result (find, i, &rectangle);
-               draw_rubberband (GTK_WIDGET (view),
-                                view->bin_window, &rectangle);
+               draw_rubberband (GTK_WIDGET (view), view->bin_window,
+                                &rectangle, current);
         }
 }
 
@@ -412,7 +415,8 @@ expose_bin_window (GtkWidget      *widget,
        highlight_find_results (view);
 
        if (view->has_selection) {
-               draw_rubberband (widget, view->bin_window, &view->selection);
+               draw_rubberband (widget, view->bin_window,
+                                &view->selection, FALSE);
        }
 }
 
@@ -903,8 +907,6 @@ ev_view_init (EvView *view)
        view->scale = 1.0;
        view->pressed_button = -1;
        view->cursor = EV_VIEW_CURSOR_NORMAL;
-       view->results_on_this_page = 0;
-       view->next_page_with_result = 0;
 }
 
 static char *
@@ -930,9 +932,121 @@ ev_view_get_find_status_message (EvView *view)
 }
 
 static void
-find_changed_cb (EvDocument *document, EvView *view)
+set_document_page (EvView *view, int page)
 {
-       gtk_widget_queue_draw (GTK_WIDGET (view));
+       if (view->document) {
+               int old_page = ev_document_get_page (view->document);
+               int old_width, old_height;
+
+               ev_document_get_page_size (view->document,
+                                          &old_width, &old_height);
+
+               if (old_page != page) {
+                       ev_view_set_cursor (view, EV_VIEW_CURSOR_WAIT);
+                       ev_document_set_page (view->document, page);
+               }
+
+               if (old_page != ev_document_get_page (view->document)) {
+                       int width, height;
+                       
+                       g_signal_emit (view, page_changed_signal, 0);
+
+                       view->has_selection = FALSE;
+                       ev_document_get_page_size (view->document,
+                                                  &width, &height);
+                       if (width != old_width || height != old_height)
+                               gtk_widget_queue_resize (GTK_WIDGET (view));
+               }
+
+               view->find_page = page;
+               view->find_result = 0;
+       }
+}
+
+#define MARGIN 5
+
+static void
+ensure_rectangle_is_visible (EvView *view, GdkRectangle *rect)
+{
+       GtkWidget *widget = GTK_WIDGET (view);
+       GtkAdjustment *adjustment;
+       int value;
+
+       adjustment = view->vadjustment;
+
+       if (rect->y < adjustment->value) {
+               value = MAX (adjustment->lower, rect->y - MARGIN);
+               gtk_adjustment_set_value (view->vadjustment, value);
+       } else if (rect->y + rect->height >
+                  adjustment->value + widget->allocation.height) {
+               value = MIN (adjustment->upper, rect->y + rect->height -
+                            widget->allocation.height + MARGIN);
+               gtk_adjustment_set_value (view->vadjustment, value);
+       }
+
+       adjustment = view->hadjustment;
+
+       if (rect->x < adjustment->value) {
+               value = MAX (adjustment->lower, rect->x - MARGIN);
+               gtk_adjustment_set_value (view->hadjustment, value);
+       } else if (rect->x + rect->height >
+                  adjustment->value + widget->allocation.width) {
+               value = MIN (adjustment->upper, rect->x + rect->width -
+                            widget->allocation.width + MARGIN);
+               gtk_adjustment_set_value (view->hadjustment, value);
+       }
+}
+
+static void
+jump_to_find_result (EvView *view)
+{
+       GdkRectangle rect;
+
+       ev_document_find_get_result (EV_DOCUMENT_FIND (view->document),
+                                    view->find_result, &rect);
+       ensure_rectangle_is_visible (view, &rect);
+}
+
+static void
+jump_to_find_page (EvView *view)
+{
+       int n_pages, i;
+
+       n_pages = ev_document_get_n_pages (view->document);
+
+       for (i = 0; i <= n_pages; i++) {
+               int has_results;
+               int page;
+
+               page = i + view->find_page;
+               if (page > n_pages) {
+                       page = page - n_pages;
+               }
+
+               has_results = ev_document_find_page_has_results
+                               (EV_DOCUMENT_FIND (view->document), page);
+               if (has_results == -1) {
+                       view->find_page = page;
+                       break;
+               } else if (has_results == 1) {
+                       set_document_page (view, page);
+                       jump_to_find_result (view);
+                       break;
+               }
+       }
+}
+
+static void
+find_changed_cb (EvDocument *document, int page, EvView *view)
+{
+       jump_to_find_page (view);
+       jump_to_find_result (view);
+
+       g_print ("Update for page %d\n", page);
+
+       if (ev_document_get_page (document) == page) {
+               gtk_widget_queue_draw (GTK_WIDGET (view));
+       }
 }
 
 static void
@@ -966,6 +1080,8 @@ ev_view_set_document (EvView     *view,
                 }
 
                view->document = document;
+               view->find_page = 1;
+               view->find_result = 0;
 
                if (view->document) {
                        g_object_ref (view->document);
@@ -989,35 +1105,6 @@ ev_view_set_document (EvView     *view,
        }
 }
 
-static void
-set_document_page (EvView *view, int page)
-{
-       if (view->document) {
-               int old_page = ev_document_get_page (view->document);
-               int old_width, old_height;
-
-               ev_document_get_page_size (view->document,
-                                          &old_width, &old_height);
-
-               if (old_page != page) {
-                       ev_view_set_cursor (view, EV_VIEW_CURSOR_WAIT);
-                       ev_document_set_page (view->document, page);
-               }
-
-               if (old_page != ev_document_get_page (view->document)) {
-                       int width, height;
-                       
-                       g_signal_emit (view, page_changed_signal, 0);
-
-                       view->has_selection = FALSE;
-                       ev_document_get_page_size (view->document,
-                                                  &width, &height);
-                       if (width != old_width || height != old_height)
-                               gtk_widget_queue_resize (GTK_WIDGET (view));
-               }
-       }
-}
-
 static void
 go_to_link (EvView *view, EvLink *link)
 {
@@ -1162,4 +1249,54 @@ ev_view_get_find_status (EvView *view)
        return view->find_status;
 }
 
+void
+ev_view_find_next (EvView *view)
+{
+       int n_results, n_pages;
+       EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
 
+       n_results = ev_document_find_get_n_results (find);
+       n_pages = ev_document_get_n_pages (view->document);
+
+       view->find_result++;
+
+       if (view->find_result >= n_results) {
+               view->find_result = 0;
+               view->find_page++;
+
+               if (view->find_page > n_pages) {
+                       view->find_page = 1;
+               }
+
+               jump_to_find_page (view);
+       } else {
+               jump_to_find_result (view);
+               gtk_widget_queue_draw (GTK_WIDGET (view));
+       }
+}
+
+void
+ev_view_find_previous (EvView *view)
+{
+       int n_results, n_pages;
+       EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
+
+       n_results = ev_document_find_get_n_results (find);
+       n_pages = ev_document_get_n_pages (view->document);
+
+       view->find_result--;
+
+       if (view->find_result < 0) {
+               view->find_result = 0;
+               view->find_page--;
+
+               if (view->find_page < 1) {
+                       view->find_page = n_pages;
+               }
+
+               jump_to_find_page (view);
+       } else {
+               jump_to_find_result (view);
+               gtk_widget_queue_draw (GTK_WIDGET (view));
+       }
+}
index 284991862ae436db43bae3259fe03d894d698ed1..a72ed6b48f25d0b64b687010ababf1baf505efb7 100644 (file)
@@ -61,6 +61,10 @@ void         ev_view_normal_size     (EvView     *view);
 void           ev_view_best_fit        (EvView     *view);
 void           ev_view_fit_width       (EvView     *view);
 
+/* Find */
+void            ev_view_find_next       (EvView     *view);
+void            ev_view_find_previous   (EvView     *view);
+
 /* Status */
 const char     *ev_view_get_status      (EvView     *view);
 const char     *ev_view_get_find_status (EvView     *view);
index 5187d51adf8c448c0006806a9496facdf63e56ec..9364c99abc353d4cf8ad0ce466d3854cb8fc457c 100644 (file)
@@ -1291,17 +1291,14 @@ static void
 find_bar_previous_cb (EggFindBar *find_bar,
                      EvWindow   *ev_window)
 {
-       /* FIXME - highlight previous result */
-       g_printerr ("Find Previous\n");
-
+       ev_view_find_previous (EV_VIEW (ev_window->priv->view));
 }
 
 static void
 find_bar_next_cb (EggFindBar *find_bar,
                  EvWindow   *ev_window)
 {
-       /* FIXME - highlight next result */
-       g_printerr ("Find Next\n");
+       ev_view_find_next (EV_VIEW (ev_window->priv->view));
 }
 
 static void