Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--backend/ev-document-find.c9
-rw-r--r--backend/ev-document-find.h6
-rw-r--r--pdf/xpdf/pdf-document.cc39
-rw-r--r--shell/ev-view.c219
-rw-r--r--shell/ev-view.h4
-rw-r--r--shell/ev-window.c7
7 files changed, 227 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index aa880fb..673d9e1 100644
--- 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:
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 (&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);
@@ -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