+2005-01-29 Marco Pesenti Gritti <marco@gnome.org>
+
+ * 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 <martink@gnome.org>
* shell/ev-sidebar-thumbnails.c (ev_sidebar_thumbnails_destroy)
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;
}
{
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");
}
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))
/* 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:
*
* 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
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
{
PdfDocument *pdf_document = search->document;
int current_page;
- EvFindResult result;
+ GdkRectangle result;
int xMin, yMin, xMax, yMax;
current_page = pdf_document->page;
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 */
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
}
/* 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;
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
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;
}
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
- GArray *find_results;
int results_on_this_page;
int next_page_with_result;
double find_percent_complete;
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);
}
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;
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);
g_object_notify (G_OBJECT (view), "find-status");
}
+
static void
ev_view_set_cursor (EvView *view, EvViewCursor new_cursor)
{
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;
}
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"));
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
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);
}
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",
&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);
}
}
}