From ae6a79781ff5126c19c84570277376f43158ec86 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sat, 29 Jan 2005 17:50:09 +0000 Subject: [PATCH] Enanche the find interface to be really able to do multi page find. 2005-01-29 Marco Pesenti Gritti * backend/ev-backend-marshalers.list: * backend/ev-document-find.c: (ev_document_find_base_init), (ev_document_find_cancel), (ev_document_find_page_has_results), (ev_document_find_get_n_results), (ev_document_find_get_result), (ev_document_find_get_progress), (ev_document_find_changed): * backend/ev-document-find.h: Enanche the find interface to be really able to do multi page find. * pdf/xpdf/pdf-document.cc: Implement * shell/ev-view.c: (ev_view_finalize), (highlight_find_results), (expose_bin_window), (ev_view_init), (ev_view_get_find_status_message), (find_changed_cb), (ev_view_set_document), (set_document_page): Adapt to the new interface. A few things are regressed sorry, I will finish it soon. --- ChangeLog | 24 +++++ backend/ev-backend-marshalers.list | 1 - backend/ev-document-find.c | 52 ++++++--- backend/ev-document-find.h | 59 +++++------ pdf/xpdf/pdf-document.cc | 123 +++++++++------------ shell/ev-view.c | 165 +++++------------------------ 6 files changed, 165 insertions(+), 259 deletions(-) diff --git a/ChangeLog b/ChangeLog index edd9cad7..aa880fb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2005-01-29 Marco Pesenti Gritti + + * backend/ev-backend-marshalers.list: + * backend/ev-document-find.c: (ev_document_find_base_init), + (ev_document_find_cancel), (ev_document_find_page_has_results), + (ev_document_find_get_n_results), (ev_document_find_get_result), + (ev_document_find_get_progress), (ev_document_find_changed): + * backend/ev-document-find.h: + + Enanche the find interface to be really able to do + multi page find. + + * pdf/xpdf/pdf-document.cc: + + Implement + + * shell/ev-view.c: (ev_view_finalize), (highlight_find_results), + (expose_bin_window), (ev_view_init), + (ev_view_get_find_status_message), (find_changed_cb), + (ev_view_set_document), (set_document_page): + + Adapt to the new interface. A few things are regressed sorry, + I will finish it soon. + 2005-01-28 Martin Kretzschmar * shell/ev-sidebar-thumbnails.c (ev_sidebar_thumbnails_destroy) diff --git a/backend/ev-backend-marshalers.list b/backend/ev-backend-marshalers.list index ad912f9a..e69de29b 100644 --- a/backend/ev-backend-marshalers.list +++ b/backend/ev-backend-marshalers.list @@ -1 +0,0 @@ -VOID:POINTER,INT,DOUBLE diff --git a/backend/ev-document-find.c b/backend/ev-document-find.c index 78c07c90..9dc05c48 100644 --- a/backend/ev-document-find.c +++ b/backend/ev-document-find.c @@ -53,16 +53,13 @@ ev_document_find_base_init (gpointer g_class) static gboolean initialized = FALSE; if (!initialized) { - g_signal_new ("found", + g_signal_new ("find_changed", EV_TYPE_DOCUMENT_FIND, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EvDocumentFindIface, found), + G_STRUCT_OFFSET (EvDocumentFindIface, find_changed), NULL, NULL, - _ev_backend_marshal_VOID__POINTER_INT_DOUBLE, - G_TYPE_NONE, 3, - G_TYPE_POINTER, - G_TYPE_INT, - G_TYPE_DOUBLE); + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); initialized = TRUE; } @@ -85,18 +82,43 @@ ev_document_find_cancel (EvDocumentFind *document_find) { EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find); iface->cancel (document_find); +} + +int +ev_document_find_page_has_results (EvDocumentFind *document_find, + int page) +{ + EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find); + return iface->page_has_results (document_find, page); +} + +int +ev_document_find_get_n_results (EvDocumentFind *document_find) +{ + EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find); + return iface->get_n_results (document_find); +} + +gboolean +ev_document_find_get_result (EvDocumentFind *document_find, + int n_result, + GdkRectangle *rectangle) +{ + EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find); + return iface->get_result (document_find, n_result, rectangle); +} - ev_document_find_found (document_find, NULL, 0, 1.0); +void +ev_document_find_get_progress (EvDocumentFind *document_find, + double percent_complete) +{ + EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find); + iface->get_progress (document_find, percent_complete); } void -ev_document_find_found (EvDocumentFind *document_find, - const EvFindResult *results, - int n_results, - double percent_complete) +ev_document_find_changed (EvDocumentFind *document_find) { - g_signal_emit_by_name (document_find, - "found", - results, n_results, percent_complete); + g_signal_emit_by_name (document_find, "find_changed"); } diff --git a/backend/ev-document-find.h b/backend/ev-document-find.h index 112faf2d..d17b9de4 100644 --- a/backend/ev-document-find.h +++ b/backend/ev-document-find.h @@ -28,12 +28,6 @@ G_BEGIN_DECLS -typedef struct -{ - int page_num; - GdkRectangle highlight_area; -} EvFindResult; - #define EV_TYPE_DOCUMENT_FIND (ev_document_find_get_type ()) #define EV_DOCUMENT_FIND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_FIND, EvDocumentFind)) #define EV_DOCUMENT_FIND_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_FIND, EvDocumentFindIface)) @@ -50,29 +44,38 @@ struct _EvDocumentFindIface /* Methods */ - void (* begin) (EvDocumentFind *document_find, - const char *search_string, - gboolean case_sensitive); - void (* cancel) (EvDocumentFind *document_find); + void (* begin) (EvDocumentFind *document_find, + const char *search_string, + gboolean case_sensitive); + void (* cancel) (EvDocumentFind *document_find); + int (* page_has_results) (EvDocumentFind *document_find, + int page); + int (* get_n_results) (EvDocumentFind *document_find); + gboolean (* get_result) (EvDocumentFind *document_find, + int n_result, + GdkRectangle *rectangle); + void (* get_progress) (EvDocumentFind *document_find, + double percent_complete); /* Signals */ - void (* found) (EvDocumentFind *document_find, - const EvFindResult *results, - int n_results, - double percent_complete); + void (* find_changed) (EvDocumentFind *document_find); }; -GType ev_document_find_get_type (void); - -void ev_document_find_begin (EvDocumentFind *document_find, - const char *search_string, - gboolean case_sensitive); -void ev_document_find_cancel (EvDocumentFind *document_find); -void ev_document_find_found (EvDocumentFind *document_find, - const EvFindResult *results, - int n_results, - double percent_complete); +GType ev_document_find_get_type (void); +void ev_document_find_begin (EvDocumentFind *document_find, + const char *search_string, + gboolean case_sensitive); +void ev_document_find_cancel (EvDocumentFind *document_find); +int ev_document_find_page_has_results (EvDocumentFind *document_find, + int page); +int ev_document_find_get_n_results (EvDocumentFind *document_find); +gboolean ev_document_find_get_result (EvDocumentFind *document_find, + int n_result, + GdkRectangle *rectangle); +void ev_document_find_get_progress (EvDocumentFind *document_find, + double percent_complete); +void ev_document_find_changed (EvDocumentFind *document_find); /* How this interface works: @@ -81,14 +84,6 @@ void ev_document_find_found (EvDocumentFind *document_find, * * cancel() cancels a search if any, otherwise does nothing. * - * If begin() has been called and cancel() has not, then the - * "found" signal can be emitted at any time. - * The results given in the "found" signal are always all-inclusive, - * that is, the array will contain all results found so far. - * There are no guarantees about the ordering of the array, - * or consistency of ordering between "found" signal emissions. - * - * When cancel() is called, "found" will always be emitted with NULL,0 */ G_END_DECLS diff --git a/pdf/xpdf/pdf-document.cc b/pdf/xpdf/pdf-document.cc index 06c82cc9..df380ad3 100644 --- a/pdf/xpdf/pdf-document.cc +++ b/pdf/xpdf/pdf-document.cc @@ -399,61 +399,50 @@ pdf_document_render (EvDocument *document, draw.width, draw.height); } -static void -pdf_document_search_emit_found (PdfDocumentSearch *search) +int +pdf_document_find_page_has_results (EvDocumentFind *document_find, + int page) { - PdfDocument *pdf_document = search->document; - int n_pages; - int pages_done; - GArray *tmp_results; - int i; + PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search; - n_pages = ev_document_get_n_pages (EV_DOCUMENT (search->document)); - if (search->search_page > search->start_page) { - pages_done = search->search_page - search->start_page; - } else if (search->search_page == search->start_page) { - pages_done = n_pages; - } else { - pages_done = n_pages - search->start_page + search->search_page; - } + g_return_val_if_fail (search != NULL, FALSE); - tmp_results = g_array_new (FALSE, FALSE, sizeof (EvFindResult)); - g_array_append_vals (tmp_results, - search->current_page_results->data, - search->current_page_results->len); + return search->other_page_flags[page]; +} - /* Now append a bogus element for each page that has a result in it, - * that is not the current page - */ - i = 1; - while (i <= n_pages) { - if (i != pdf_document->page && - search->other_page_flags[i]) { - EvFindResult result; - - result.page_num = i; - - /* Use bogus coordinates, again we can't get coordinates - * until this is the current page because TextOutputDev - * isn't good enough - */ - result.highlight_area.x = -1; - result.highlight_area.y = -1; - result.highlight_area.width = 1; - result.highlight_area.height = 1; - - g_array_append_val (tmp_results, result); - } +int +pdf_document_find_get_n_results (EvDocumentFind *document_find) +{ + PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search; - ++i; - } + if (search) { + return search->current_page_results->len; + } else { + return 0; + } +} - ev_document_find_found (EV_DOCUMENT_FIND (pdf_document), - (EvFindResult*) tmp_results->data, - tmp_results->len, - pages_done / (double) n_pages); +gboolean +pdf_document_find_get_result (EvDocumentFind *document_find, + int n_result, + GdkRectangle *rectangle) +{ + PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search; + GdkRectangle r; + + if (search != NULL) { + r = g_array_index (search->current_page_results, + GdkRectangle, n_result); - g_array_free (tmp_results, TRUE); + rectangle->x = r.x; + rectangle->y = r.y; + rectangle->width = r.width; + rectangle->height = r.height; + + return TRUE; + } else { + return FALSE; + } } static void @@ -461,7 +450,7 @@ pdf_document_search_page_changed (PdfDocumentSearch *search) { PdfDocument *pdf_document = search->document; int current_page; - EvFindResult result; + GdkRectangle result; int xMin, yMin, xMax, yMax; current_page = pdf_document->page; @@ -482,12 +471,10 @@ pdf_document_search_page_changed (PdfDocumentSearch *search) gTrue, gTrue, // startAtTop, stopAtBottom gFalse, gFalse, // startAtLast, stopAtLast &xMin, &yMin, &xMax, &yMax)) { - result.page_num = pdf_document->page; - - result.highlight_area.x = xMin; - result.highlight_area.y = yMin; - result.highlight_area.width = xMax - xMin; - result.highlight_area.height = yMax - yMin; + result.x = xMin; + result.y = yMin; + result.width = xMax - xMin; + result.height = yMax - yMin; g_array_append_val (search->current_page_results, result); /* Now find further results */ @@ -496,25 +483,14 @@ pdf_document_search_page_changed (PdfDocumentSearch *search) gFalse, gTrue, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax)) { - - result.page_num = pdf_document->page; - - result.highlight_area.x = xMin; - result.highlight_area.y = yMin; - result.highlight_area.width = xMax - xMin; - result.highlight_area.height = yMax - yMin; + result.x = xMin; + result.y = yMin; + result.width = xMax - xMin; + result.height = yMax - yMin; g_array_append_val (search->current_page_results, result); } } - - /* needed for the initial current page since we don't search - * it in the idle - */ - search->other_page_flags[current_page] = - search->current_page_results->len > 0; - - pdf_document_search_emit_found (search); } static gboolean @@ -566,7 +542,7 @@ pdf_document_search_idle_callback (void *data) } /* We do this even if nothing was found, to update the percent complete */ - pdf_document_search_emit_found (search); + ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document)); return TRUE; @@ -618,7 +594,7 @@ pdf_document_find_begin (EvDocumentFind *document, search->current_page_results = g_array_new (FALSE, FALSE, - sizeof (EvFindResult)); + sizeof (GdkRectangle)); n_pages = ev_document_get_n_pages (EV_DOCUMENT (document)); /* This is an array of bool; with the first value ignored @@ -1128,6 +1104,9 @@ static void pdf_document_find_iface_init (EvDocumentFindIface *iface) { iface->begin = pdf_document_find_begin; + iface->get_n_results = pdf_document_find_get_n_results; + iface->get_result = pdf_document_find_get_result; + iface->page_has_results = pdf_document_find_page_has_results; iface->cancel = pdf_document_find_cancel; } diff --git a/shell/ev-view.c b/shell/ev-view.c index 5de9c20c..79bb2dde 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -83,7 +83,6 @@ struct _EvView { GtkAdjustment *hadjustment; GtkAdjustment *vadjustment; - GArray *find_results; int results_on_this_page; int next_page_with_result; double find_percent_complete; @@ -189,9 +188,6 @@ ev_view_finalize (GObject *object) ev_view_set_scroll_adjustments (view, NULL, NULL); - g_array_free (view->find_results, TRUE); - view->find_results = NULL; - G_OBJECT_CLASS (ev_view_parent_class)->finalize (object); } @@ -366,14 +362,29 @@ draw_rubberband (GtkWidget *widget, GdkWindow *window, const GdkRectangle *rect) gdk_color_free (fill_color_gdk); } +static void +highlight_find_results (EvView *view) +{ + EvDocumentFind *find = EV_DOCUMENT_FIND (view->document); + int i, results; + + results = ev_document_find_get_n_results (find); + + for (i = 0; i < results; i++) { + GdkRectangle rectangle; + + ev_document_find_get_result (find, i, &rectangle); + draw_rubberband (GTK_WIDGET (view), + view->bin_window, &rectangle); + } +} + static void expose_bin_window (GtkWidget *widget, GdkEventExpose *event) { EvView *view = EV_VIEW (widget); - int i, current_page; int x_offset, y_offset; - const EvFindResult *results; if (view->document == NULL) return; @@ -398,30 +409,7 @@ expose_bin_window (GtkWidget *widget, event->area.x, event->area.y, event->area.width, event->area.height); - results = (EvFindResult*) view->find_results->data; - current_page = ev_document_get_page (view->document); - i = 0; - while (i < view->find_results->len) { -#if 0 - g_printerr ("highlighting result %d page %d at %d,%d %dx%d\n", - i, results[i].page_num, - results[i].highlight_area.x, - results[i].highlight_area.y, - results[i].highlight_area.width, - results[i].highlight_area.height); -#endif - if (results[i].page_num == current_page) { - GdkRectangle highlight_area_fixed; - highlight_area_fixed.x = results[i].highlight_area.x + x_offset + 1; - highlight_area_fixed.y = results[i].highlight_area.y + y_offset + 1; - highlight_area_fixed.width = results[i].highlight_area.width; - highlight_area_fixed.height = results[i].highlight_area.height; - - draw_rubberband (widget, view->bin_window, - &highlight_area_fixed); - } - ++i; - } + highlight_find_results (view); if (view->has_selection) { draw_rubberband (widget, view->bin_window, &view->selection); @@ -590,6 +578,7 @@ ev_view_set_find_status (EvView *view, const char *message) g_object_notify (G_OBJECT (view), "find-status"); } + static void ev_view_set_cursor (EvView *view, EvViewCursor new_cursor) { @@ -914,10 +903,6 @@ ev_view_init (EvView *view) view->scale = 1.0; view->pressed_button = -1; view->cursor = EV_VIEW_CURSOR_NORMAL; - - view->find_results = g_array_new (FALSE, - FALSE, - sizeof (EvFindResult)); view->results_on_this_page = 0; view->next_page_with_result = 0; } @@ -925,6 +910,7 @@ ev_view_init (EvView *view) static char * ev_view_get_find_status_message (EvView *view) { +/* if (view->find_results->len == 0) { if (view->find_percent_complete >= (1.0 - 1e-10)) { return g_strdup (_("Not found")); @@ -940,105 +926,13 @@ ev_view_get_find_status_message (EvView *view) return g_strdup_printf (_("%d found on this page"), view->results_on_this_page); } +*/ } static void -update_find_results (EvView *view) -{ - const EvFindResult *results; - int i; - int on_this_page; - int next_page_with_result; - int earliest_page_with_result; - int current_page; - gboolean counts_changed; - - results = (EvFindResult*) view->find_results->data; - current_page = ev_document_get_page (view->document); - next_page_with_result = 0; - on_this_page = 0; - earliest_page_with_result = 0; - - i = 0; - while (i < view->find_results->len) { - if (results[i].page_num == current_page) { - ++on_this_page; - } else { - int delta = results[i].page_num - current_page; - - if (delta > 0 && /* result on later page */ - (next_page_with_result == 0 || - results[i].page_num < next_page_with_result)) - next_page_with_result = results[i].page_num; - - if (delta < 0 && /* result on a previous page */ - (earliest_page_with_result == 0 || - results[i].page_num < earliest_page_with_result)) - earliest_page_with_result = results[i].page_num; - } - ++i; - } - - /* If earliest page is just the current page, there is no earliest page */ - if (earliest_page_with_result == current_page) - earliest_page_with_result = 0; - - /* If no next page, then wrap and the wrapped page is the next page */ - if (next_page_with_result == 0) - next_page_with_result = earliest_page_with_result; - - counts_changed = FALSE; - if (on_this_page != view->results_on_this_page || - next_page_with_result != view->next_page_with_result) { - view->results_on_this_page = on_this_page; - view->next_page_with_result = next_page_with_result; - counts_changed = TRUE; - } - - if (counts_changed || - view->find_results->len == 0) { - char *message; - - message = ev_view_get_find_status_message (view); - ev_view_set_find_status (view, message); - g_free (message); - } -} - -static void -found_results_callback (EvDocument *document, - const EvFindResult *results, - int n_results, - double percent_complete, - void *data) +find_changed_cb (EvDocument *document, EvView *view) { - EvView *view = EV_VIEW (data); - - g_array_set_size (view->find_results, 0); - - if (n_results > 0) - g_array_append_vals (view->find_results, - results, n_results); - -#if 0 - { - int i; - - g_printerr ("%d results %d%%: ", n_results, - (int) (percent_complete * 100)); - i = 0; - while (i < n_results) { - g_printerr ("%d ", results[i].page_num); - ++i; - } - g_printerr ("\n"); - } -#endif - - view->find_percent_complete = percent_complete; - update_find_results (view); - - gtk_widget_queue_draw (GTK_WIDGET (view)); + gtk_widget_queue_draw (GTK_WIDGET (view)); } static void @@ -1066,12 +960,8 @@ ev_view_set_document (EvView *view, if (document != view->document) { if (view->document) { g_signal_handlers_disconnect_by_func (view->document, - found_results_callback, + find_changed_cb, view); - g_array_set_size (view->find_results, 0); - view->results_on_this_page = 0; - view->next_page_with_result = 0; - g_object_unref (view->document); } @@ -1081,8 +971,8 @@ ev_view_set_document (EvView *view, g_object_ref (view->document); if (EV_IS_DOCUMENT_FIND (view->document)) g_signal_connect (view->document, - "found", - G_CALLBACK (found_results_callback), + "find_changed", + G_CALLBACK (find_changed_cb), view); g_signal_connect (view->document, "changed", @@ -1124,9 +1014,6 @@ set_document_page (EvView *view, int page) &width, &height); if (width != old_width || height != old_height) gtk_widget_queue_resize (GTK_WIDGET (view)); - - view->find_percent_complete = 0.0; - update_find_results (view); } } } -- 2.43.5