evince r3123 - in trunk: . backend/djvu backend/pdf libdocument shell



Author: carlosgc
Date: Wed Aug 27 09:01:41 2008
New Revision: 3123
URL: http://svn.gnome.org/viewvc/evince?rev=3123&view=rev

Log:
2008-08-27  Carlos Garcia Campos  <carlosgc gnome org>

	* backend/djvu/Makefile.am:
	* backend/djvu/djvu-document-private.h:
	* backend/djvu/djvu-document.c: (djvu_document_find_find_text),
	(djvu_document_find_iface_init):
	* backend/djvu/djvu-text-page.[ch]:
	* backend/djvu/djvu-text.[ch]: Removed
	* backend/pdf/ev-poppler.cc: (pdf_document_find_find_text),
	(pdf_document_find_iface_init):
	* libdocument/ev-document-find.[ch]: (ev_document_find_find_text):
	* shell/ev-jobs.[ch]: (ev_job_find_init), (ev_job_find_dispose),
	(ev_job_find_run), (ev_job_find_class_init), (ev_job_find_new),
	(ev_job_find_get_n_results), (ev_job_find_get_progress),
	(ev_job_find_has_results), (ev_job_find_get_results):
	* shell/ev-view-private.h:
	* shell/ev-view.[ch]: (ev_view_expose_event),
	(highlight_find_results), (ev_view_finalize),
	(ev_view_get_property), (ev_view_class_init), (page_changed_cb),
	(ev_view_set_document), (ev_view_find_get_n_results),
	(ev_view_find_get_result), (jump_to_find_result),
	(jump_to_find_page), (ev_view_find_changed), (ev_view_find_next),
	(ev_view_find_previous), (ev_view_find_search_changed),
	(ev_view_find_set_highlight_search), (ev_view_find_cancel):
	* shell/ev-window.c: (ev_window_update_actions),
	(page_changed_cb), (ev_window_setup_document),
	(ev_window_update_find_status_message),
	(ev_window_find_job_finished_cb), (ev_window_find_job_updated_cb),
	(ev_window_clear_find_job), (find_bar_close_cb),
	(find_bar_search_changed_cb), (find_bar_visibility_changed_cb),
	(ev_window_dispose), (ev_window_init):

	Rework find interface. The find logic has been moved from backends
	to the shell avoiding a lot of duplicated code in the backends and
	making easier to implement the find interface in the backends.


Removed:
   trunk/backend/djvu/djvu-text.c
   trunk/backend/djvu/djvu-text.h
Modified:
   trunk/ChangeLog
   trunk/backend/djvu/Makefile.am
   trunk/backend/djvu/djvu-document-private.h
   trunk/backend/djvu/djvu-document.c
   trunk/backend/djvu/djvu-text-page.c
   trunk/backend/djvu/djvu-text-page.h
   trunk/backend/pdf/ev-poppler.cc
   trunk/libdocument/ev-document-find.c
   trunk/libdocument/ev-document-find.h
   trunk/shell/ev-jobs.c
   trunk/shell/ev-jobs.h
   trunk/shell/ev-view-private.h
   trunk/shell/ev-view.c
   trunk/shell/ev-view.h
   trunk/shell/ev-window.c

Modified: trunk/backend/djvu/Makefile.am
==============================================================================
--- trunk/backend/djvu/Makefile.am	(original)
+++ trunk/backend/djvu/Makefile.am	Wed Aug 27 09:01:41 2008
@@ -18,8 +18,6 @@
 	djvu-document-private.h \
 	djvu-links.c		\
 	djvu-links.h		\
-	djvu-text.c		\
-	djvu-text.h		\
 	djvu-text-page.c 	\
 	djvu-text-page.h
 

Modified: trunk/backend/djvu/djvu-document-private.h
==============================================================================
--- trunk/backend/djvu/djvu-document-private.h	(original)
+++ trunk/backend/djvu/djvu-document-private.h	Wed Aug 27 09:01:41 2008
@@ -22,7 +22,6 @@
 #define __DJVU_DOCUMENT_INTERNAL_H__
 
 #include "djvu-document.h"
-#include "djvu-text.h"
 
 #include <libdjvu/ddjvuapi.h>
 
@@ -36,8 +35,6 @@
 
 	gchar            *uri;
 
-	DjvuText         *search;
-        
         /* PS exporter */
         gchar		 *ps_filename;
         GString 	 *opts;

Modified: trunk/backend/djvu/djvu-document.c
==============================================================================
--- trunk/backend/djvu/djvu-document.c	(original)
+++ trunk/backend/djvu/djvu-document.c	Wed Aug 27 09:01:41 2008
@@ -21,7 +21,7 @@
 
 #include <config.h>
 #include "djvu-document.h"
-#include "djvu-text.h"
+#include "djvu-text-page.h"
 #include "djvu-links.h"
 #include "djvu-document-private.h"
 #include "ev-document-thumbnails.h"
@@ -388,9 +388,6 @@
 {
 	DjvuDocument *djvu_document = DJVU_DOCUMENT (object);
 
-	if (djvu_document->search)
-	    djvu_text_free (djvu_document->search);
-
 	if (djvu_document->d_document)
 	    ddjvu_document_release (djvu_document->d_document);
 	    
@@ -438,6 +435,30 @@
 }
 
 static gchar *
+djvu_text_copy (DjvuDocument *djvu_document,
+		gint           page,
+		EvRectangle  *rectangle)
+{
+	miniexp_t page_text;
+	gchar    *text = NULL;
+
+	while ((page_text =
+		ddjvu_document_get_pagetext (djvu_document->d_document,
+					     page, "char")) == miniexp_dummy)
+		djvu_handle_events (djvu_document, TRUE, NULL);
+
+	if (page_text != miniexp_nil) {
+		DjvuTextPage *page = djvu_text_page_new (page_text);
+		
+		text = djvu_text_page_copy (page, rectangle);
+		djvu_text_page_free (page);
+		ddjvu_miniexp_release (djvu_document->d_document, page_text);
+	}
+
+	return text;
+}
+
+static gchar *
 djvu_selection_get_selected_text (EvSelection     *selection,
 				  EvRenderContext *rc,
 				  EvSelectionStyle style,
@@ -627,107 +648,62 @@
 	djvu_document->d_document = NULL;
 }
 
-static void
-djvu_document_find_begin (EvDocumentFind   *document,
-			  int               page,
-                          const char       *search_string,
-                          gboolean          case_sensitive)
+static GList *
+djvu_document_find_find_text (EvDocumentFind   *document,
+			      EvPage           *page,
+			      const char       *text,
+			      gboolean          case_sensitive)
 {
         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
+	miniexp_t page_text;
+	gdouble width, height;
+	GList *matches = NULL, *l;
+
+	g_return_val_if_fail (text != NULL, NULL);
+
+	while ((page_text = ddjvu_document_get_pagetext (djvu_document->d_document,
+							 page->index,
+							 "char")) == miniexp_dummy)
+		djvu_handle_events (djvu_document, TRUE, NULL);
 
-	if (djvu_document->search && 
-	    strcmp (search_string, djvu_text_get_text (djvu_document->search)) == 0)
-                return;
-
-        if (djvu_document->search)
-                djvu_text_free (djvu_document->search);
-
-        djvu_document->search = djvu_text_new (djvu_document,
-							  page,
-							  case_sensitive,
-							  search_string);
-}
-
-static int
-djvu_document_find_get_n_results (EvDocumentFind *document_find, int page)
-{
-	DjvuText *search = DJVU_DOCUMENT (document_find)->search;
-
-	if (search) {
-		return djvu_text_n_results (search, page);
-	} else {
-		return 0;
+	if (page_text != miniexp_nil) {
+		DjvuTextPage *tpage = djvu_text_page_new (page_text);
+		
+		djvu_text_page_prepare_search (tpage, case_sensitive);
+		if (tpage->links->len > 0) {
+			djvu_text_page_search (tpage, text);
+			matches = tpage->results;
+		}
+		djvu_text_page_free (tpage);
+		ddjvu_miniexp_release (djvu_document->d_document, page_text);
 	}
-}
-
-static gboolean
-djvu_document_find_get_result (EvDocumentFind *document_find,
-			       int             page,
-			       int             n_result,
-			       EvRectangle    *rectangle)
-{
-	DjvuDocument *djvu_document = DJVU_DOCUMENT (document_find);
-	DjvuText *search = djvu_document->search;
-	EvRectangle *r;
-	double width, height;
 
-	if (search == NULL)
-		return FALSE;
+	if (!matches)
+		return NULL;
 
-	r = djvu_text_get_result (search, page, n_result);
-	if (r == NULL)
-		return FALSE;
+	document_get_page_size (djvu_document, page->index, &width, &height);
+	for (l = matches; l && l->data; l = g_list_next (l)) {
+		EvRectangle *r = (EvRectangle *)l->data;
+		gdouble      tmp;
 
-	document_get_page_size (djvu_document, page, &width, &height);
-	rectangle->x1 = r->x1 * SCALE_FACTOR;
-	rectangle->y1 = height - r->y2 * SCALE_FACTOR;
-	rectangle->x2 = r->x2 * SCALE_FACTOR;
-	rectangle->y2 = height - r->y1 * SCALE_FACTOR;
+		tmp = r->y1;
 		
-	return TRUE;
-}
-
-static int
-djvu_document_find_page_has_results (EvDocumentFind *document_find,
-				    int             page)
-{
-	DjvuText *search = DJVU_DOCUMENT (document_find)->search;
-
-	return search && djvu_text_has_results (search, page);
-}
+		r->x1 *= SCALE_FACTOR;
+		r->x2 *= SCALE_FACTOR;
 
-static double
-djvu_document_find_get_progress (EvDocumentFind *document_find)
-{
-	DjvuText *search = DJVU_DOCUMENT (document_find)->search;
-	
-	if (search == NULL) {
-		return 0;
+		tmp = r->y1;
+		r->y1 = height - r->y2 * SCALE_FACTOR;
+		r->y2 = height - tmp * SCALE_FACTOR;
 	}
+	
 
-	return djvu_text_get_progress (search);
-}
-
-static void
-djvu_document_find_cancel (EvDocumentFind *document)
-{
-        DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
-
-	if (djvu_document->search) {
-		djvu_text_free (djvu_document->search);
-		djvu_document->search = NULL;
-	}
+	return matches;
 }
 
 static void
 djvu_document_find_iface_init (EvDocumentFindIface *iface)
 {
-        iface->begin = djvu_document_find_begin;
-	iface->get_n_results = djvu_document_find_get_n_results;
-	iface->get_result = djvu_document_find_get_result;
-	iface->page_has_results = djvu_document_find_page_has_results;
-	iface->get_progress = djvu_document_find_get_progress;
-        iface->cancel = djvu_document_find_cancel;
+        iface->find_text = djvu_document_find_find_text;
 }
 
 static GList *

Modified: trunk/backend/djvu/djvu-text-page.c
==============================================================================
--- trunk/backend/djvu/djvu-text-page.c	(original)
+++ trunk/backend/djvu/djvu-text-page.c	Wed Aug 27 09:01:41 2008
@@ -371,7 +371,7 @@
  */
 void 
 djvu_text_page_search (DjvuTextPage *page, 
-		       char         *text)
+		       const char   *text)
 {
 	char *haystack = page->text;
 	int search_len;

Modified: trunk/backend/djvu/djvu-text-page.h
==============================================================================
--- trunk/backend/djvu/djvu-text-page.h	(original)
+++ trunk/backend/djvu/djvu-text-page.h	Wed Aug 27 09:01:41 2008
@@ -23,6 +23,7 @@
 
 #include <string.h>
 #include <glib.h>
+#include <libdjvu/miniexp.h>
 
 
 typedef struct _DjvuTextPage DjvuTextPage;
@@ -50,8 +51,8 @@
 void			djvu_text_page_prepare_search	(DjvuTextPage *page,
 	       		    				 gboolean      case_sensitive);
 void 			djvu_text_page_search 		(DjvuTextPage *page, 
-		    					char         *text);
-DjvuTextPage*		djvu_text_page_new 		(miniexp_t text);
+		    					const char    *text);
+DjvuTextPage*		djvu_text_page_new 		(miniexp_t     text);
 void 			djvu_text_page_free 		(DjvuTextPage *page);
 
 #endif /* __DJVU_TEXT_PAGE_H__ */

Modified: trunk/backend/pdf/ev-poppler.cc
==============================================================================
--- trunk/backend/pdf/ev-poppler.cc	(original)
+++ trunk/backend/pdf/ev-poppler.cc	Wed Aug 27 09:01:41 2008
@@ -1364,195 +1364,42 @@
 }
 
 
-static gboolean
-pdf_document_search_idle_callback (void *data)
-{
-        PdfDocumentSearch *search = (PdfDocumentSearch*) data;
-        PdfDocument *pdf_document = search->document;
-        int n_pages;
-	GList *matches;
-	PopplerPage *page;
-
-	page = poppler_document_get_page (search->document->document,
-					  search->search_page);
-
-	ev_document_doc_mutex_lock ();
-	matches = poppler_page_find_text (page, search->text);
-	ev_document_doc_mutex_unlock ();
-
-	g_object_unref (page);
-
-	search->pages[search->search_page] = matches;
-	ev_document_find_changed (EV_DOCUMENT_FIND (pdf_document),
-				  search->search_page);
-
-        n_pages = pdf_document_get_n_pages (EV_DOCUMENT (search->document));
-        search->search_page += 1;
-        if (search->search_page == n_pages) {
-                /* wrap around */
-                search->search_page = 0;
-        }
-
-        if (search->search_page != search->start_page) {
-	        return TRUE;
-	}
-
-        /* We're done. */
-        search->idle = 0; /* will return FALSE to remove */
-        return FALSE;
-}
-
-
-static PdfDocumentSearch *
-pdf_document_search_new (PdfDocument *pdf_document,
-			 int          start_page,
-			 const char  *text)
-{
-	PdfDocumentSearch *search;
-	int n_pages;
-	int i;
-
-	n_pages = pdf_document_get_n_pages (EV_DOCUMENT (pdf_document));
-
-        search = g_new0 (PdfDocumentSearch, 1);
-
-	search->text = g_strdup (text);
-        search->pages = g_new0 (GList *, n_pages);
-        search->document = pdf_document;
-
-        /* We add at low priority so the progress bar repaints */
-        search->idle = g_idle_add_full (G_PRIORITY_LOW,
-                                        pdf_document_search_idle_callback,
-                                        search,
-                                        NULL);
-
-        search->start_page = start_page;
-        search->search_page = start_page;
-
-	return search;
-}
-
-static void
-pdf_document_find_begin (EvDocumentFind   *document,
-			 int               page,
-                         const char       *search_string,
-                         gboolean          case_sensitive)
-{
-        PdfDocument *pdf_document = PDF_DOCUMENT (document);
-
-        /* FIXME handle case_sensitive (right now XPDF
-         * code is always case insensitive for ASCII
-         * and case sensitive for all other languaages)
-         */
-
-	if (pdf_document->search &&
-	    strcmp (search_string, pdf_document->search->text) == 0)
-                return;
-
-        if (pdf_document->search)
-                pdf_document_search_free (pdf_document->search);
-
-        pdf_document->search = pdf_document_search_new (pdf_document,
-							page,
-							search_string);
-}
-
-static int
-pdf_document_find_get_n_results (EvDocumentFind *document_find, int page)
-{
-	PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search;
-
-	if (search) {
-		return g_list_length (search->pages[page]);
-	} else {
-		return 0;
-	}
-}
-
-static gboolean
-pdf_document_find_get_result (EvDocumentFind *document_find,
-			      int             page,
-			      int             n_result,
-			      EvRectangle    *rectangle)
+static GList *
+pdf_document_find_find_text (EvDocumentFind *document_find,
+			     EvPage         *page,
+			     const gchar    *text,
+			     gboolean        case_sensitive)
 {
-	PdfDocument *pdf_document = PDF_DOCUMENT (document_find);
-	PdfDocumentSearch *search = pdf_document->search;
+	GList *matches, *l;
 	PopplerPage *poppler_page;
-	PopplerRectangle *r;
-	double height;
-
-	if (search == NULL)
-		return FALSE;
+	gdouble height;
+	
+	g_return_val_if_fail (POPPLER_IS_PAGE (page->backend_page), NULL);
+	g_return_val_if_fail (text != NULL, NULL);
 
-	r = (PopplerRectangle *) g_list_nth_data (search->pages[page],
-						  n_result);
-	if (r == NULL)
-		return FALSE;
+	poppler_page = POPPLER_PAGE (page->backend_page);
+	
+	matches = poppler_page_find_text (poppler_page, text);
+	if (!matches)
+		return NULL;
 
-	poppler_page = poppler_document_get_page (pdf_document->document, page);
 	poppler_page_get_size (poppler_page, NULL, &height);
-	rectangle->x1 = r->x1;
-	rectangle->y1 = height - r->y2;
-	rectangle->x2 = r->x2;
-	rectangle->y2 = height - r->y1;
-	g_object_unref (poppler_page);
-		
-	return TRUE;
-}
-
-static int
-pdf_document_find_page_has_results (EvDocumentFind *document_find,
-				    int             page)
-{
-	PdfDocumentSearch *search = PDF_DOCUMENT (document_find)->search;
-
-	return search && search->pages[page] != NULL;
-}
-
-static double
-pdf_document_find_get_progress (EvDocumentFind *document_find)
-{
-	PdfDocumentSearch *search;
-	int n_pages, pages_done;
-
-	search = PDF_DOCUMENT (document_find)->search;
+	for (l = matches; l && l->data; l = g_list_next (l)) {
+		PopplerRectangle *rect = (PopplerRectangle *)l->data;
+		gdouble           tmp;
 
-	if (search == NULL) {
-		return 0;
-	}
-
-	n_pages = pdf_document_get_n_pages (EV_DOCUMENT (document_find));
-	if (search->search_page > search->start_page) {
-		pages_done = search->search_page - search->start_page + 1;
-	} else if (search->search_page == search->start_page) {
-		pages_done = n_pages;
-	} else {
-		pages_done = n_pages - search->start_page + search->search_page;
-	}
-
-	return pages_done / (double) n_pages;
-}
-
-static void
-pdf_document_find_cancel (EvDocumentFind *document)
-{
-        PdfDocument *pdf_document = PDF_DOCUMENT (document);
-
-	if (pdf_document->search) {
-		pdf_document_search_free (pdf_document->search);
-		pdf_document->search = NULL;
+		tmp = rect->y1;
+		rect->y1 = height - rect->y2;
+		rect->y2 = height - tmp;
 	}
+	
+	return matches;
 }
 
 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->get_progress = pdf_document_find_get_progress;
-        iface->cancel = pdf_document_find_cancel;
+        iface->find_text = pdf_document_find_find_text;
 }
 
 static void

Modified: trunk/libdocument/ev-document-find.c
==============================================================================
--- trunk/libdocument/ev-document-find.c	(original)
+++ trunk/libdocument/ev-document-find.c	Wed Aug 27 09:01:41 2008
@@ -21,9 +21,6 @@
 #include "config.h"
 
 #include "ev-document-find.h"
-#include "ev-backend-marshalers.h"
-
-static void ev_document_find_base_init (gpointer g_class);
 
 GType
 ev_document_find_get_type (void)
@@ -35,7 +32,7 @@
 		const GTypeInfo our_info =
 		{
 			sizeof (EvDocumentFindIface),
-			ev_document_find_base_init,
+			NULL,
 			NULL,
 		};
 
@@ -47,80 +44,14 @@
 	return type;
 }
 
-static void
-ev_document_find_base_init (gpointer g_class)
-{
-	static gboolean initialized = FALSE;
-
-	if (!initialized) {
-		g_signal_new ("find_changed",
-			      EV_TYPE_DOCUMENT_FIND,
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (EvDocumentFindIface, find_changed),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__INT,
-			      G_TYPE_NONE, 1,
-			      G_TYPE_INT);
-
-		initialized = TRUE;
-	}
-}
-
-void
-ev_document_find_begin (EvDocumentFind   *document_find,
-			int               page,
-                        const char       *search_string,
-                        gboolean          case_sensitive)
+GList *
+ev_document_find_find_text (EvDocumentFind *document_find,
+			    EvPage         *page,
+			    const gchar    *text,
+			    gboolean        case_sensitive)
 {
 	EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find);
-
-        g_return_if_fail (search_string != NULL);
-        
-	iface->begin (document_find, page, search_string, case_sensitive);
-}
-
-void
-ev_document_find_cancel (EvDocumentFind   *document_find)
-{
-	EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find);
-	iface->cancel (document_find);
+	
+	return iface->find_text (document_find, page, text, case_sensitive);
 }
 
-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,
-				int             page)
-{
-	EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find);
-	return iface->get_n_results (document_find, page);
-}
-
-gboolean
-ev_document_find_get_result (EvDocumentFind *document_find,
-			     int             page,
-			     int             n_result,
-			     EvRectangle    *rectangle)
-{
-	EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find);
-	return iface->get_result (document_find, page, n_result, rectangle);
-}
-
-double
-ev_document_find_get_progress (EvDocumentFind *document_find)
-{
-	EvDocumentFindIface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find);
-	return iface->get_progress (document_find);
-}
-
-void
-ev_document_find_changed (EvDocumentFind  *document_find, int page)
-{
-	g_signal_emit_by_name (document_find, "find_changed", page);
-}

Modified: trunk/libdocument/ev-document-find.h
==============================================================================
--- trunk/libdocument/ev-document-find.h	(original)
+++ trunk/libdocument/ev-document-find.h	Wed Aug 27 09:01:41 2008
@@ -24,9 +24,8 @@
 
 #include <glib-object.h>
 #include <glib.h>
-#include <gdk/gdk.h>
 
-#include "ev-document.h"	/* For EvRectangle */
+#include "ev-document.h"
 
 G_BEGIN_DECLS
 
@@ -37,62 +36,26 @@
 #define EV_IS_DOCUMENT_FIND_IFACE(k)	    (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_FIND))
 #define EV_DOCUMENT_FIND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_FIND, EvDocumentFindIface))
 
-typedef struct _EvDocumentFind	EvDocumentFind;
-typedef struct _EvDocumentFindIface	EvDocumentFindIface;
+typedef struct _EvDocumentFind	    EvDocumentFind;
+typedef struct _EvDocumentFindIface EvDocumentFindIface;
 
 struct _EvDocumentFindIface
 {
 	GTypeInterface base_iface;
 
         /* Methods */
-        
-        void     (* begin)	      (EvDocumentFind *document_find,
-				       int             page,
-                                       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,
-				       int             page);
-	gboolean (* get_result)	      (EvDocumentFind *document_find,
-				       int             page,
-				       int             n_result,
-				       EvRectangle    *rectangle); 
-	double	 (* get_progress)     (EvDocumentFind *document_find);
-
-        /* Signals */
-
-        void     (* find_changed)     (EvDocumentFind *document_find,
-				       int             page);
+	GList 	*(* find_text)     (EvDocumentFind *document_find,
+				    EvPage         *page,
+				    const gchar    *text,
+				    gboolean        case_sensitive);
 };
 
-GType     ev_document_find_get_type         (void);
-void      ev_document_find_begin	    (EvDocumentFind *document_find,
-					     int             page,
-					     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,
-					     int             page);
-gboolean  ev_document_find_get_result	    (EvDocumentFind *document_find,
-					     int             page,
-					     int             n_result,
-					     EvRectangle    *rectangle); 
-double	  ev_document_find_get_progress     (EvDocumentFind *document_find);
-void      ev_document_find_changed          (EvDocumentFind *document_find,
-					     int             page);
-
-/* How this interface works:
- *
- * begin() begins a new search, canceling any previous search.
- * 
- * cancel() cancels a search if any, otherwise does nothing.
- * 
- */
+GType  ev_document_find_get_type  (void) G_GNUC_CONST;
+GList *ev_document_find_find_text (EvDocumentFind *document_find,
+				   EvPage         *page,
+				   const gchar    *text,
+				   gboolean        case_sensitive);
 
 G_END_DECLS
 
-#endif
+#endif /* EV_DOCUMENT_FIND_H */

Modified: trunk/shell/ev-jobs.c
==============================================================================
--- trunk/shell/ev-jobs.c	(original)
+++ trunk/shell/ev-jobs.c	Wed Aug 27 09:01:41 2008
@@ -31,6 +31,7 @@
 #include "ev-file-helpers.h"
 #include "ev-document-fonts.h"
 #include "ev-document-security.h"
+#include "ev-document-find.h"
 #include "ev-debug.h"
 
 #include <errno.h>
@@ -54,6 +55,8 @@
 static void ev_job_save_class_init        (EvJobSaveClass        *class);
 static void ev_job_print_init             (EvJobPrint            *job);
 static void ev_job_print_class_init       (EvJobPrintClass       *class);
+static void ev_job_find_init              (EvJobFind             *job);
+static void ev_job_find_class_init        (EvJobFindClass        *class);
 
 enum {
 	CANCELLED,
@@ -67,13 +70,19 @@
 };
 
 enum {
-	UPDATED,
+	FONTS_UPDATED,
 	FONTS_LAST_SIGNAL
 };
 
+enum {
+	FIND_UPDATED,
+	FIND_LAST_SIGNAL
+};
+
 static guint job_signals[LAST_SIGNAL] = { 0 };
 static guint job_render_signals[RENDER_LAST_SIGNAL] = { 0 };
 static guint job_fonts_signals[FONTS_LAST_SIGNAL] = { 0 };
+static guint job_find_signals[FIND_LAST_SIGNAL] = { 0 };
 
 G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
 G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
@@ -84,6 +93,7 @@
 G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobPrint, ev_job_print, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobFind, ev_job_find, EV_TYPE_JOB)
 
 /* EvJob */
 static void
@@ -721,7 +731,7 @@
 #endif
 
 	job_fonts->scan_completed = !ev_document_fonts_scan (fonts, 20);
-	g_signal_emit (job_fonts, job_fonts_signals[UPDATED], 0,
+	g_signal_emit (job_fonts, job_fonts_signals[FONTS_UPDATED], 0,
 		       ev_document_fonts_get_progress (fonts));
 
 	ev_document_fc_mutex_unlock ();
@@ -740,7 +750,7 @@
 	
 	job_class->run = ev_job_fonts_run;
 	
-	job_fonts_signals[UPDATED] =
+	job_fonts_signals[FONTS_UPDATED] =
 		g_signal_new ("updated",
 			      EV_TYPE_JOB_FONTS,
 			      G_SIGNAL_RUN_LAST,
@@ -1366,3 +1376,163 @@
 	return EV_JOB (job);
 }
 
+/* EvJobFind */
+static void
+ev_job_find_init (EvJobFind *job)
+{
+	EV_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
+}
+
+static void
+ev_job_find_dispose (GObject *object)
+{
+	EvJobFind *job = EV_JOB_FIND (object);
+
+	ev_debug_message (DEBUG_JOBS, NULL);
+
+	if (job->text) {
+		g_free (job->text);
+		job->text = NULL;
+	}
+
+	if (job->pages) {
+		gint i;
+
+		for (i = 0; i < job->n_pages; i++) {
+			g_list_foreach (job->pages[i], (GFunc)g_free, NULL);
+			g_list_free (job->pages[i]);
+		}
+
+		g_free (job->pages);
+		job->pages = NULL;
+	}
+	
+	(* G_OBJECT_CLASS (ev_job_find_parent_class)->dispose) (object);
+}
+
+static gboolean
+ev_job_find_run (EvJob *job)
+{
+	EvJobFind      *job_find = EV_JOB_FIND (job);
+	EvDocumentFind *find = EV_DOCUMENT_FIND (job->document);
+	EvPage         *ev_page;
+	GList          *matches;
+
+	ev_debug_message (DEBUG_JOBS, NULL);
+	
+	/* Do not block the main loop */
+	if (!ev_document_doc_mutex_trylock ())
+		return TRUE;
+	
+#ifdef EV_ENABLE_DEBUG
+	/* We use the #ifdef in this case because of the if */
+	if (job_find->current_page == job_find->start_page)
+		ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+#endif
+
+	ev_page = ev_document_get_page (job->document, job_find->current_page);
+	matches = ev_document_find_find_text (find, ev_page, job_find->text,
+					      job_find->case_sensitive);
+	g_object_unref (ev_page);
+	
+	ev_document_doc_mutex_unlock ();
+
+	if (!job_find->has_results)
+		job_find->has_results = (matches != NULL);
+
+	job_find->pages[job_find->current_page] = matches;
+	g_signal_emit (job_find, job_find_signals[FIND_UPDATED], 0, job_find->current_page);
+		       
+	job_find->current_page = (job_find->current_page + 1) % job_find->n_pages;
+	if (job_find->current_page == job_find->start_page) {
+		ev_job_succeeded (job);
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+ev_job_find_class_init (EvJobFindClass *class)
+{
+	EvJobClass   *job_class = EV_JOB_CLASS (class);
+	GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+	
+	job_class->run = ev_job_find_run;
+	gobject_class->dispose = ev_job_find_dispose;
+	
+	job_find_signals[FIND_UPDATED] =
+		g_signal_new ("updated",
+			      EV_TYPE_JOB_FIND,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EvJobFindClass, updated),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__INT,
+			      G_TYPE_NONE,
+			      1, G_TYPE_INT);
+}
+
+EvJob *
+ev_job_find_new (EvDocument  *document,
+		 gint         start_page,
+		 gint         n_pages,
+		 const gchar *text,
+		 gboolean     case_sensitive)
+{
+	EvJobFind *job;
+	
+	ev_debug_message (DEBUG_JOBS, NULL);
+	
+	job = g_object_new (EV_TYPE_JOB_FIND, NULL);
+
+	EV_JOB (job)->document = g_object_ref (document);
+	job->start_page = start_page;
+	job->current_page = start_page;
+	job->n_pages = n_pages;
+	job->pages = g_new0 (GList *, n_pages);
+	job->text = g_strdup (text);
+	job->case_sensitive = case_sensitive;
+	job->has_results = FALSE;
+
+	return EV_JOB (job);
+}
+
+gint
+ev_job_find_get_n_results (EvJobFind *job,
+			   gint       page)
+{
+	return g_list_length (job->pages[page]);
+}
+
+gdouble
+ev_job_find_get_progress (EvJobFind *job)
+{
+	gint pages_done;
+
+	if (ev_job_is_finished (EV_JOB (job)))
+		return 1.0;
+	
+	if (job->current_page > job->start_page) {
+		pages_done = job->current_page - job->start_page + 1;
+	} else if (job->current_page == job->start_page) {
+		pages_done = job->n_pages;
+	} else {
+		pages_done = job->n_pages - job->start_page + job->current_page;
+	}
+
+	return pages_done / (gdouble) job->n_pages;
+}
+
+gboolean
+ev_job_find_has_results (EvJobFind *job)
+{
+	return job->has_results;
+}
+
+GList **
+ev_job_find_get_results (EvJobFind *job)
+{
+	return job->pages;
+}
+

Modified: trunk/shell/ev-jobs.h
==============================================================================
--- trunk/shell/ev-jobs.h	(original)
+++ trunk/shell/ev-jobs.h	Wed Aug 27 09:01:41 2008
@@ -57,6 +57,9 @@
 typedef struct _EvJobPrint EvJobPrint;
 typedef struct _EvJobPrintClass EvJobPrintClass;
 
+typedef struct _EvJobFind EvJobFind;
+typedef struct _EvJobFindClass EvJobFindClass;
+
 #define EV_TYPE_JOB		     	     (ev_job_get_type())
 #define EV_JOB(object)		             (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB, EvJob))
 #define EV_JOB_CLASS(klass)	             (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB, EvJobClass))
@@ -103,6 +106,11 @@
 #define EV_JOB_PRINT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_PRINT, EvJobPrintClass))
 #define EV_IS_JOB_PRINT(object)              (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_PRINT))
 
+#define EV_TYPE_JOB_FIND                    (ev_job_find_get_type())
+#define EV_JOB_FIND(object)                 (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_FIND, EvJobFind))
+#define EV_JOB_FIND_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_FIND, EvJobFindClass))
+#define EV_IS_JOB_FIND(object)              (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_FIND))
+
 typedef enum {
 	EV_JOB_RUN_THREAD,
 	EV_JOB_RUN_MAIN_LOOP
@@ -235,7 +243,8 @@
         EvJobClass parent_class;
 
 	/* Signals */
-	void (* updated)  (EvJobFonts *job);
+	void (* updated)  (EvJobFonts *job,
+			   gdouble     progress);
 };
 
 struct _EvJobLoad
@@ -289,6 +298,28 @@
 	EvJobClass parent_class;
 };
 
+struct _EvJobFind
+{
+	EvJob parent;
+
+	gint start_page;
+	gint current_page;
+	gint n_pages;
+	GList **pages;
+	gchar *text;
+	gboolean case_sensitive;
+	gboolean has_results;
+};
+
+struct _EvJobFindClass
+{
+	EvJobClass parent_class;
+
+	/* Signals */
+	void (* updated)  (EvJobFind *job,
+			   gint       page);
+};
+
 /* Base job class */
 GType           ev_job_get_type           (void) G_GNUC_CONST;
 gboolean        ev_job_run                (EvJob          *job);
@@ -370,6 +401,18 @@
 					   gint             copies,
 					   gdouble          collate,
 					   gdouble          reverse);
+/* EvJobFind */
+GType           ev_job_find_get_type      (void) G_GNUC_CONST;
+EvJob          *ev_job_find_new           (EvDocument      *document,
+					   gint             start_page,
+					   gint             n_pages,
+					   const gchar     *text,
+					   gboolean         case_sensitive);
+gint            ev_job_find_get_n_results (EvJobFind       *job,
+					   gint             pages);
+gdouble         ev_job_find_get_progress  (EvJobFind       *job);
+gboolean        ev_job_find_has_results   (EvJobFind       *job);
+GList         **ev_job_find_get_results   (EvJobFind       *job);
 
 G_END_DECLS
 

Modified: trunk/shell/ev-view-private.h
==============================================================================
--- trunk/shell/ev-view-private.h	(original)
+++ trunk/shell/ev-view-private.h	Wed Aug 27 09:01:41 2008
@@ -97,8 +97,9 @@
 
 	EvDocument *document;
 
-	char *find_status;
-	int find_result;
+	/* Find */
+	GList **find_pages;
+	gint find_result;
 	gboolean jump_to_find_result;
 	gboolean highlight_find_results;
 	

Modified: trunk/shell/ev-view.c
==============================================================================
--- trunk/shell/ev-view.c	(original)
+++ trunk/shell/ev-view.c	Wed Aug 27 09:01:41 2008
@@ -29,7 +29,6 @@
 #include <gdk/gdkkeysyms.h>
 
 #include "ev-application.h"
-#include "ev-document-find.h"
 #include "ev-document-forms.h"
 #include "ev-document-images.h"
 #include "ev-document-links.h"
@@ -53,7 +52,6 @@
 
 enum {
 	PROP_0,
-	PROP_FIND_STATUS,
 	PROP_CONTINUOUS,
 	PROP_DUAL_PAGE,
 	PROP_FULLSCREEN,
@@ -228,9 +226,6 @@
 							      GdkRectangle       *expose_area);
 
 /*** Callbacks ***/
-static void       find_changed_cb                            (EvDocument         *document,
-							      int                 page,
-							      EvView             *view);
 static void       job_finished_cb                            (EvPixbufCache      *pixbuf_cache,
 							      GdkRegion          *region,
 							      EvView             *view);
@@ -303,10 +298,11 @@
 							      gint y);
 
 /*** Find ***/
-static void       update_find_status_message                 (EvView             *view,
-							      gboolean            this_page);
-static void       ev_view_set_find_status                    (EvView             *view,
-							      const char         *message);
+static gint         ev_view_find_get_n_results               (EvView             *view,
+							      gint                page);
+static EvRectangle *ev_view_find_get_result                  (EvView             *view,
+							      gint                page,
+							      gint                result);
 static void       jump_to_find_result                        (EvView             *view);
 static void       jump_to_find_page                          (EvView             *view, 
 							      EvViewFindDirection direction,
@@ -2547,7 +2543,7 @@
 
 		draw_one_page (view, i, cr, &page_area, &border, &(event->area), &page_ready);
 
-		if (page_ready && EV_IS_DOCUMENT_FIND (view->document) && view->highlight_find_results)
+		if (page_ready && view->find_pages && view->highlight_find_results)
 			highlight_find_results (view, i);
 	}
 
@@ -3608,15 +3604,12 @@
 static void
 highlight_find_results (EvView *view, int page)
 {
-	EvDocumentFind *find;
-	int i, results = 0;
+	gint i, n_results = 0;
 
-	find = EV_DOCUMENT_FIND (view->document);
+	n_results = ev_view_find_get_n_results (view, page);
 
-	results = ev_document_find_get_n_results (find, page);
-
-	for (i = 0; i < results; i++) {
-		EvRectangle rectangle;
+	for (i = 0; i < n_results; i++) {
+		EvRectangle *rectangle;
 		GdkRectangle view_rectangle;
 		guchar alpha;
 
@@ -3626,8 +3619,8 @@
 			alpha = 0x20;
 		}
 
-		ev_document_find_get_result (find, page, i, &rectangle);
-		doc_rect_to_view_rect (view, page, &rectangle, &view_rectangle);
+		rectangle = ev_view_find_get_result (view, page, i);
+		doc_rect_to_view_rect (view, page, rectangle, &view_rectangle);
 		draw_rubberband (GTK_WIDGET (view), view->layout.bin_window,
 				 &view_rectangle, alpha);
         }
@@ -3822,8 +3815,6 @@
 {
 	EvView *view = EV_VIEW (object);
 
-	g_free (view->find_status);
-
 	clear_selection (view);
 	clear_link_selected (view);
 
@@ -3973,9 +3964,6 @@
 	EvView *view = EV_VIEW (object);
 
 	switch (prop_id) {
-	        case PROP_FIND_STATUS:
-			g_value_set_string (value, view->find_status);
-			break;
 	        case PROP_CONTINUOUS:
 			g_value_set_boolean (value, view->continuous);
 			break;
@@ -4092,14 +4080,6 @@
 
 
 	g_object_class_install_property (object_class,
-					 PROP_FIND_STATUS,
-					 g_param_spec_string ("find-status",
-							      "Find Status Message",
-							      "The find status message",
-							      NULL,
-							      G_PARAM_READABLE));
-
-	g_object_class_install_property (object_class,
 					 PROP_CONTINUOUS,
 					 g_param_spec_boolean ("continuous",
 							       "Continuous",
@@ -4224,25 +4204,6 @@
 /*** Callbacks ***/
 
 static void
-find_changed_cb (EvDocument *document, int page, EvView *view)
-{
-	double percent;
-	int n_pages;
-
-	percent = ev_document_find_get_progress
-		        (EV_DOCUMENT_FIND (view->document)); 
-	n_pages = ev_page_cache_get_n_pages (view->page_cache);
-	
-	if (view->jump_to_find_result == TRUE) {
-		jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
-		jump_to_find_result (view);
-	}
-	update_find_status_message (view, percent * n_pages >= n_pages - 1 );
-	if (view->current_page == page)
-		gtk_widget_queue_draw (GTK_WIDGET (view));
-}
-
-static void
 ev_view_change_page (EvView *view,
 		     gint    new_page)
 {
@@ -4334,10 +4295,7 @@
 		gtk_widget_queue_draw (GTK_WIDGET (view));
 	}
 
-	if (EV_IS_DOCUMENT_FIND (view->document)) {
-		view->find_result = 0;
-		update_find_status_message (view, TRUE);
-	}
+	view->find_result = 0;
 }
 
 static void
@@ -4519,12 +4477,8 @@
 		clear_caches (view);
 
 		if (view->document) {
-                        g_signal_handlers_disconnect_by_func (view->document,
-                                                              find_changed_cb,
-                                                              view);
 			g_object_unref (view->document);
 			view->page_cache = NULL;
-
                 }
 
 		view->document = document;
@@ -4532,13 +4486,6 @@
 
 		if (view->document) {
 			g_object_ref (view->document);
-			if (EV_IS_DOCUMENT_FIND (view->document)) {
-				g_signal_connect (view->document,
-						  "find_changed",
-						  G_CALLBACK (find_changed_cb),
-						  view);
-			}
-
 			setup_caches (view);
                 }
 
@@ -5139,71 +5086,32 @@
 }
 
 /*** Find ***/
-static void
-update_find_status_message (EvView *view, gboolean this_page)
+static gint
+ev_view_find_get_n_results (EvView *view, gint page)
 {
-	char *message;
-
-	if (this_page) {
-		int results;
-
-		results = ev_document_find_get_n_results
-				(EV_DOCUMENT_FIND (view->document),
-				 view->current_page);
-		/* TRANS: Sometimes this could be better translated as
-		   "%d hit(s) on this page".  Therefore this string
-		   contains plural cases. */
-		message = g_strdup_printf (ngettext ("%d found on this page",
-						     "%d found on this page",
-						     results),
-					   results);
-	} else {
-		double percent;
-
-		percent = ev_document_find_get_progress
-				(EV_DOCUMENT_FIND (view->document));
-		message = g_strdup_printf (_("%3d%% remaining to search"),
-					   (int) ((1.0 - percent) * 100));
-		
-	}
-	ev_view_set_find_status (view, message);
-	g_free (message);
+	return view->find_pages ? g_list_length (view->find_pages[page]) : 0;
 }
 
-const char *
-ev_view_get_find_status (EvView *view)
+static EvRectangle *
+ev_view_find_get_result (EvView *view, gint page, gint result)
 {
-	g_return_val_if_fail (EV_IS_VIEW (view), NULL);
-
-	return view->find_status;
-}
-
-static void
-ev_view_set_find_status (EvView *view, const char *message)
-{
-	g_return_if_fail (EV_IS_VIEW (view));
-
-	g_free (view->find_status);
-	view->find_status = g_strdup (message);
-	g_object_notify (G_OBJECT (view), "find-status");
+	return view->find_pages ? (EvRectangle *) g_list_nth_data (view->find_pages[page], result) : NULL;
 }
 
 static void
 jump_to_find_result (EvView *view)
 {
-	EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
-	EvRectangle rect;
-	GdkRectangle view_rect;
-	int n_results;
-	int page = view->current_page;
+	gint n_results;
+	gint page = view->current_page;
 
-	n_results = ev_document_find_get_n_results (find, page);
+	n_results = ev_view_find_get_n_results (view, page);
 
-	if (n_results > 0  && view->find_result < n_results) {
-		ev_document_find_get_result
-			(find, page, view->find_result, &rect);
+	if (n_results > 0 && view->find_result < n_results) {
+		EvRectangle *rect;
+		GdkRectangle view_rect;
 
-		doc_rect_to_view_rect (view, page, &rect, &view_rect);
+		rect = ev_view_find_get_result (view, page, view->find_result);
+		doc_rect_to_view_rect (view, page, rect, &view_rect);
 		ensure_rectangle_is_visible (view, &view_rect);
 	}
 }
@@ -5226,7 +5134,6 @@
 	n_pages = ev_page_cache_get_n_pages (view->page_cache);
 
 	for (i = 0; i < n_pages; i++) {
-		int has_results;
 		int page;
 		
 		if (direction == EV_VIEW_FIND_NEXT)
@@ -5237,53 +5144,39 @@
 		
 		if (page >= n_pages) {
 			page = page - n_pages;
-		}
-		if (page < 0) 
+		} else if (page < 0) 
 			page = page + n_pages;
-		
-		has_results = ev_document_find_page_has_results
-				(EV_DOCUMENT_FIND (view->document), page);
-		if (has_results == -1) {
-			break;
-		} else if (has_results == 1) {
+
+		if (ev_view_find_get_n_results (view, page) > 0) {
 			ev_page_cache_set_current_page (view->page_cache, page);
 			break;
 		}
 	}
 }
 
-gboolean
-ev_view_can_find_next (EvView *view)
+void
+ev_view_find_changed (EvView *view, GList **results, gint page)
 {
-	if (EV_IS_DOCUMENT_FIND (view->document)) {
-		EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
-		int i, n_pages;
-
-		n_pages = ev_page_cache_get_n_pages (view->page_cache);
-		for (i = 0; i < n_pages; i++) {
-			if (ev_document_find_get_n_results (find, i) > 0) {
-				return TRUE;
-			}
-		}
+	view->find_pages = results;
+	
+	if (view->jump_to_find_result == TRUE) {
+		jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
+		jump_to_find_result (view);
 	}
 
-	return FALSE;
+	if (view->current_page == page)
+		gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
 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, view->current_page);
-
-	n_pages = ev_page_cache_get_n_pages (view->page_cache);
+	gint n_results;
 
+	n_results = ev_view_find_get_n_results (view, view->current_page);
 	view->find_result++;
 
 	if (view->find_result >= n_results) {
-
 		view->find_result = 0;
 		jump_to_find_page (view, EV_VIEW_FIND_NEXT, 1);
 		jump_to_find_result (view);
@@ -5293,42 +5186,14 @@
 	}
 }
 
-gboolean
-ev_view_can_find_previous (EvView *view)
-{
-	if (EV_IS_DOCUMENT_FIND (view->document)) {
-		EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
-		int i, n_pages;
-
-		n_pages = ev_page_cache_get_n_pages (view->page_cache);
-		for (i = n_pages - 1; i >= 0; i--) {
-			if (ev_document_find_get_n_results (find, i) > 0) {
-				return TRUE;
-			}
-		}
-	}
-
-	return FALSE;
-}
 void
 ev_view_find_previous (EvView *view)
 {
-	int n_results, n_pages;
-	EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
-	EvPageCache *page_cache;
-
-	page_cache = ev_page_cache_get (view->document);
-
-	n_results = ev_document_find_get_n_results (find, view->current_page);
-
-	n_pages = ev_page_cache_get_n_pages (page_cache);
-
 	view->find_result--;
 
 	if (view->find_result < 0) {
-
 		jump_to_find_page (view, EV_VIEW_FIND_PREV, -1);
-		view->find_result = ev_document_find_get_n_results (find, view->current_page) - 1;
+		view->find_result = ev_view_find_get_n_results (view, view->current_page) - 1;
 		jump_to_find_result (view);
 	} else {
 		jump_to_find_result (view);
@@ -5337,14 +5202,15 @@
 }
 
 void
-ev_view_search_changed (EvView *view)
+ev_view_find_search_changed (EvView *view)
 {
 	/* search string has changed, focus on new search result */
 	view->jump_to_find_result = TRUE;
+	view->find_pages = NULL;
 }
 
 void
-ev_view_set_highlight_search (EvView *view, gboolean value)
+ev_view_find_set_highlight_search (EvView *view, gboolean value)
 {
 	view->highlight_find_results = value;
 	gtk_widget_queue_draw (GTK_WIDGET (view));
@@ -5353,11 +5219,7 @@
 void
 ev_view_find_cancel (EvView *view)
 {
-	if (EV_IS_DOCUMENT_FIND (view->document)) {
-		EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
-
-		ev_document_find_cancel (find);
-	}
+	view->find_pages = NULL;
 }
 
 /*** Selections ***/

Modified: trunk/shell/ev-view.h
==============================================================================
--- trunk/shell/ev-view.h	(original)
+++ trunk/shell/ev-view.h	Wed Aug 27 09:01:41 2008
@@ -117,18 +117,15 @@
 int             ev_view_get_rotation      (EvView         *view);
 
 /* Find */
-gboolean        ev_view_can_find_next        (EvView         *view);
-void            ev_view_find_next            (EvView         *view);
-gboolean        ev_view_can_find_previous    (EvView         *view);
-void            ev_view_find_previous        (EvView         *view);
-void            ev_view_search_changed       (EvView         *view);
-void     	ev_view_set_highlight_search (EvView         *view,
-					      gboolean        value);
-void            ev_view_find_cancel          (EvView         *view);
-
-/* Status */
-const char     *ev_view_get_status        (EvView         *view);
-const char     *ev_view_get_find_status   (EvView         *view);
+void            ev_view_find_next                 (EvView         *view);
+void            ev_view_find_previous             (EvView         *view);
+void            ev_view_find_search_changed       (EvView         *view);
+void     	ev_view_find_set_highlight_search (EvView         *view,
+						   gboolean        value);
+void            ev_view_find_changed              (EvView         *view,
+						   GList         **results,
+						   gint            page);
+void            ev_view_find_cancel               (EvView         *view);
 
 /* Cursor */
 void           ev_view_hide_cursor        (EvView         *view);

Modified: trunk/shell/ev-window.c
==============================================================================
--- trunk/shell/ev-window.c	(original)
+++ trunk/shell/ev-window.c	Wed Aug 27 09:01:41 2008
@@ -179,6 +179,7 @@
 	EvJob            *thumbnail_job;
 	EvJob            *save_job;
 	EvJob            *print_job;
+	EvJob            *find_job;
 
 	/* Printing */
 	gboolean          print_preview;
@@ -275,6 +276,7 @@
 static void	view_handle_link_cb 			(EvView           *view, 
 							 EvLink           *link, 
 							 EvWindow         *window);
+static void     ev_window_update_find_status_message    (EvWindow         *ev_window);
 static void     ev_window_cmd_edit_find                 (GtkAction        *action,
 							 EvWindow         *ev_window);
 static void     find_bar_search_changed_cb              (EggFindBar       *find_bar,
@@ -396,6 +398,7 @@
 	int n_pages = 0, page = -1;
 	gboolean has_pages = FALSE;
 	gboolean presentation_mode;
+	gboolean can_find_in_page = FALSE;
 
 	if (ev_window->priv->document && ev_window->priv->page_cache) {
 		page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
@@ -403,13 +406,16 @@
 		has_pages = n_pages > 0;
 	}
 
+	can_find_in_page = (ev_window->priv->find_job &&
+			    ev_job_find_has_results (EV_JOB_FIND (ev_window->priv->find_job)));
+
 	ev_window_set_action_sensitive (ev_window, "EditCopy",
 					has_pages &&
 					ev_view_get_has_selection (view));
 	ev_window_set_action_sensitive (ev_window, "EditFindNext",
-					ev_view_can_find_next (view));
+					has_pages && can_find_in_page);
 	ev_window_set_action_sensitive (ev_window, "EditFindPrevious",
-					ev_view_can_find_previous (view));
+					has_pages && can_find_in_page);
 
 	presentation_mode = ev_view_get_presentation (view);
 	
@@ -688,18 +694,14 @@
 }
 
 static void
-find_changed_cb (EvDocument *document, int page, EvWindow *ev_window)
-{
-	ev_window_update_actions (ev_window);
-}
-
-static void
 page_changed_cb (EvPageCache *page_cache,
 		 gint         page,
 		 EvWindow    *ev_window)
 {
 	ev_window_update_actions (ev_window);
-	
+
+	ev_window_update_find_status_message (ev_window);
+
 	if (!ev_window_is_empty (ev_window))
 		ev_metadata_manager_set_int (ev_window->priv->uri, "page", page);
 }
@@ -1142,13 +1144,6 @@
 
 	ev_window->priv->setup_document_idle = 0;
 	
-	if (EV_IS_DOCUMENT_FIND (document)) {
-		g_signal_connect_object (G_OBJECT (document),
-				         "find_changed",
-				         G_CALLBACK (find_changed_cb),	
-				         ev_window, 0);
-	}
-	
 	ev_window_refresh_window_thumbnail (ev_window, 0);
 
 	ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT);
@@ -4019,15 +4014,73 @@
 }
 
 static void
-view_find_status_changed_cb (EvView     *view,
-			     GParamSpec *pspec,
-			     EvWindow   *ev_window)
-{
-	const char *text;
-
-	text = ev_view_get_find_status (view);
-	egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
-				      text);
+ev_window_update_find_status_message (EvWindow *ev_window)
+{
+	gchar *message;
+
+	if (!ev_window->priv->find_job)
+		return;
+	
+	if (ev_job_is_finished (ev_window->priv->find_job)) {
+		gint n_results;
+
+		n_results = ev_job_find_get_n_results (EV_JOB_FIND (ev_window->priv->find_job),
+						       ev_page_cache_get_current_page (ev_window->priv->page_cache));
+		/* TRANS: Sometimes this could be better translated as
+		                      "%d hit(s) on this page".  Therefore this string
+				      contains plural cases. */
+		message = g_strdup_printf (ngettext ("%d found on this page",
+						     "%d found on this page",
+						     n_results),
+					   n_results);
+	} else {
+		gdouble percent;
+
+		percent = ev_job_find_get_progress (EV_JOB_FIND (ev_window->priv->find_job));
+		message = g_strdup_printf (_("%3d%% remaining to search"),
+					   (gint) ((1.0 - percent) * 100));
+	}
+	
+	egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), message);
+	g_free (message);
+}
+
+static void
+ev_window_find_job_finished_cb (EvJobFind *job,
+				EvWindow  *ev_window)
+{
+	ev_window_update_find_status_message (ev_window);
+}
+
+static void
+ev_window_find_job_updated_cb (EvJobFind *job,
+			       gint       page,
+			       EvWindow  *ev_window)
+{
+	ev_window_update_actions (ev_window);
+	
+	ev_view_find_changed (EV_VIEW (ev_window->priv->view),
+			      ev_job_find_get_results (job),
+			      page);
+	ev_window_update_find_status_message (ev_window);
+}
+
+static void
+ev_window_clear_find_job (EvWindow *ev_window)
+{
+	if (ev_window->priv->find_job != NULL) {
+		if (!ev_job_is_finished (ev_window->priv->find_job))
+			ev_job_cancel (ev_window->priv->find_job);
+
+		g_signal_handlers_disconnect_by_func (ev_window->priv->find_job,
+						      ev_window_find_job_finished_cb,
+						      ev_window);
+		g_signal_handlers_disconnect_by_func (ev_window->priv->find_job,
+						      ev_window_find_job_updated_cb,
+						      ev_window);
+		g_object_unref (ev_window->priv->find_job);
+		ev_window->priv->find_job = NULL;
+	}
 }
 
 static void
@@ -4049,6 +4102,7 @@
 		   EvWindow   *ev_window)
 {
 	ev_view_find_cancel (EV_VIEW (ev_window->priv->view));
+	ev_window_clear_find_job (ev_window);
 	update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE);
 	update_chrome_visibility (ev_window);
 }
@@ -4061,39 +4115,42 @@
 	gboolean case_sensitive;
 	const char *search_string;
 
+	if (!ev_window->priv->document || !EV_IS_DOCUMENT_FIND (ev_window->priv->document))
+		return;
+	
 	/* Either the string or case sensitivity could have changed. */
-
 	case_sensitive = egg_find_bar_get_case_sensitive (find_bar);
 	search_string = egg_find_bar_get_search_string (find_bar);
 
-	ev_view_search_changed (EV_VIEW(ev_window->priv->view));
+	ev_view_find_search_changed (EV_VIEW (ev_window->priv->view));
 
-	if (ev_window->priv->document &&
-	    EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
-		if (search_string && search_string[0]) {
-			ev_document_doc_mutex_lock ();
-			ev_document_find_begin (EV_DOCUMENT_FIND (ev_window->priv->document), 
-						ev_page_cache_get_current_page (ev_window->priv->page_cache),
-						search_string,
-						case_sensitive);
-			ev_document_doc_mutex_unlock ();
-		} else {
-			ev_document_doc_mutex_lock ();
-			ev_document_find_cancel (EV_DOCUMENT_FIND (ev_window->priv->document));
-			ev_document_doc_mutex_unlock ();
-
-		        ev_window_update_actions (ev_window);
-			egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
-						      NULL);
-			gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view));
-		}
+	ev_window_clear_find_job (ev_window);
+
+	if (search_string && search_string[0]) {
+		ev_window->priv->find_job = ev_job_find_new (ev_window->priv->document,
+							     ev_page_cache_get_current_page (ev_window->priv->page_cache),
+							     ev_page_cache_get_n_pages (ev_window->priv->page_cache),
+							     search_string,
+							     case_sensitive);
+		g_signal_connect (ev_window->priv->find_job, "finished",
+				  G_CALLBACK (ev_window_find_job_finished_cb),
+				  ev_window);
+		g_signal_connect (ev_window->priv->find_job, "updated",
+				  G_CALLBACK (ev_window_find_job_updated_cb),
+				  ev_window);
+		ev_job_scheduler_push_job (ev_window->priv->find_job, EV_JOB_PRIORITY_NONE);
+	} else {
+		ev_window_update_actions (ev_window);
+		egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
+					      NULL);
+		gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view));
 	}
 }
 
 static void
 find_bar_visibility_changed_cb (EggFindBar *find_bar,
-			    GParamSpec *param,
-			    EvWindow   *ev_window)
+				GParamSpec *param,
+				EvWindow   *ev_window)
 {
 	gboolean visible;
 
@@ -4101,8 +4158,8 @@
 
 	if (ev_window->priv->document &&
 	    EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
-		ev_view_set_highlight_search (EV_VIEW (ev_window->priv->view), visible);
-		ev_view_search_changed (EV_VIEW (ev_window->priv->view));
+		ev_view_find_set_highlight_search (EV_VIEW (ev_window->priv->view), visible);
+		ev_view_find_search_changed (EV_VIEW (ev_window->priv->view));
 		ev_window_update_actions (ev_window);
 
 		if (visible)
@@ -4115,7 +4172,7 @@
 static void
 find_bar_scroll(EggFindBar *find_bar, GtkScrollType scroll, EvWindow* ev_window)
 {
-	ev_view_scroll(EV_VIEW(ev_window->priv->view), scroll, FALSE);
+	ev_view_scroll (EV_VIEW (ev_window->priv->view), scroll, FALSE);
 }
 
 static void
@@ -4257,6 +4314,10 @@
 	if (priv->thumbnail_job) {
 		ev_window_clear_thumbnail_job (window);
 	}
+
+	if (priv->find_job) {
+		ev_window_clear_find_job (window);
+	}
 	
 	if (priv->local_uri) {
 		ev_window_clear_local_uri (window);
@@ -5490,10 +5551,6 @@
 			   ev_window->priv->view);
 
 	g_signal_connect (ev_window->priv->view,
-			  "notify::find-status",
-			  G_CALLBACK (view_find_status_changed_cb),
-			  ev_window);
-	g_signal_connect (ev_window->priv->view,
 			  "notify::sizing-mode",
 			  G_CALLBACK (ev_window_sizing_mode_changed_cb),
 			  ev_window);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]