From a521d16eb7f59cbda6881b66e0e7a00125377cd8 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sun, 30 Jan 2005 12:28:10 +0000 Subject: More work on find implementation, mostly there now 2005-01-30 Marco Pesenti Gritti * 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 --- diff --git a/ChangeLog b/ChangeLog index aa880fb..673d9e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-01-30 Marco Pesenti Gritti + + * 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 * backend/ev-backend-marshalers.list: diff --git a/backend/ev-document-find.c b/backend/ev-document-find.c index 9dc05c4..01ae739 100644 --- a/backend/ev-document-find.c +++ b/backend/ev-document-find.c @@ -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); } diff --git a/backend/ev-document-find.h b/backend/ev-document-find.h index d17b9de..ebce196 100644 --- a/backend/ev-document-find.h +++ b/backend/ev-document-find.h @@ -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: diff --git a/pdf/xpdf/pdf-document.cc b/pdf/xpdf/pdf-document.cc index df380ad..5a7304c 100644 --- a/pdf/xpdf/pdf-document.cc +++ b/pdf/xpdf/pdf-document.cc @@ -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; diff --git a/shell/ev-view.c b/shell/ev-view.c index 79bb2dd..4e5db8b 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -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 (>K_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); @@ -990,35 +1106,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) { EvLinkType type; @@ -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)); + } +} diff --git a/shell/ev-view.h b/shell/ev-view.h index 2849918..a72ed6b 100644 --- a/shell/ev-view.h +++ b/shell/ev-view.h @@ -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); diff --git a/shell/ev-window.c b/shell/ev-window.c index 5187d51..9364c99 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -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 -- cgit v0.9.1