]> www.fi.muni.cz Git - evince.git/commitdiff
Removed
authorCarlos Garcia Campos <carlosgc@gnome.org>
Wed, 27 Aug 2008 09:01:41 +0000 (09:01 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Wed, 27 Aug 2008 09:01:41 +0000 (09:01 +0000)
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.

svn path=/trunk/; revision=3123

17 files changed:
ChangeLog
backend/djvu/Makefile.am
backend/djvu/djvu-document-private.h
backend/djvu/djvu-document.c
backend/djvu/djvu-text-page.c
backend/djvu/djvu-text-page.h
backend/djvu/djvu-text.c [deleted file]
backend/djvu/djvu-text.h [deleted file]
backend/pdf/ev-poppler.cc
libdocument/ev-document-find.c
libdocument/ev-document-find.h
shell/ev-jobs.c
shell/ev-jobs.h
shell/ev-view-private.h
shell/ev-view.c
shell/ev-view.h
shell/ev-window.c

index 289bbea4a29bdf52441f9781d9dea77eeb908966..6eaf50738438bd4a10772a147d49206c2f319b9e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+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.
+       
 2008-08-25  Carlos Garcia Campos  <carlosgc@gnome.org>
 
        * backend/pdf/ev-poppler.cc:
index 956259b090333b0e1678cfc67f711b433020d8ba..4cd22f57f1e076100393321c84ffe89bc08b8d00 100644 (file)
@@ -18,8 +18,6 @@ libdjvudocument_la_SOURCES =  \
        djvu-document-private.h \
        djvu-links.c            \
        djvu-links.h            \
-       djvu-text.c             \
-       djvu-text.h             \
        djvu-text-page.c        \
        djvu-text-page.h
 
index 30810bbc43c70fc4a319b0a4e62c4cee8f4a1521..a110e15e00c8cbf2b036ae115ed8fa1f5ffd1fcb 100644 (file)
@@ -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 @@ struct _DjvuDocument {
 
        gchar            *uri;
 
-       DjvuText         *search;
-        
         /* PS exporter */
         gchar           *ps_filename;
         GString         *opts;
index 5f59a8ea3ab34c27baffcf97b1de158515235c79..40950c7829c8bf68fab7f56f5d994af717097cba 100644 (file)
@@ -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 @@ djvu_document_finalize (GObject *object)
 {
        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);
            
@@ -437,6 +434,30 @@ djvu_document_document_iface_init (EvDocumentIface *iface)
        iface->get_info = djvu_document_get_info;
 }
 
+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,
@@ -627,107 +648,62 @@ djvu_document_init (DjvuDocument *djvu_document)
        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;
 
-       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);
+       g_return_val_if_fail (text != NULL, NULL);
 
-        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;
+       while ((page_text = ddjvu_document_get_pagetext (djvu_document->d_document,
+                                                        page->index,
+                                                        "char")) == miniexp_dummy)
+               djvu_handle_events (djvu_document, TRUE, NULL);
 
-       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 *
index f0b2809448f7c68131d2759063c5e594690b18b5..696cec70ea3e4c4d88881bb81ef101d3691b5449 100644 (file)
@@ -371,7 +371,7 @@ djvu_text_page_append_text (DjvuTextPage *page,
  */
 void 
 djvu_text_page_search (DjvuTextPage *page, 
-                      char         *text)
+                      const char   *text)
 {
        char *haystack = page->text;
        int search_len;
index 61325af750c020c33dbb9536e7a5baccd8b709c3..5d2134cf47536bfb87d56099c09c881fe93732c7 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <string.h>
 #include <glib.h>
+#include <libdjvu/miniexp.h>
 
 
 typedef struct _DjvuTextPage DjvuTextPage;
@@ -50,8 +51,8 @@ char *                        djvu_text_page_copy             (DjvuTextPage *page,
 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__ */
diff --git a/backend/djvu/djvu-text.c b/backend/djvu/djvu-text.c
deleted file mode 100644 (file)
index e87dbb1..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Implements search and copy functionality for Djvu files.
- * Copyright (C) 2006 Michael Hofmann <mh21@piware.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <string.h>
-#include <glib.h>
-#include <libdjvu/miniexp.h>
-
-#include "djvu-document-private.h"
-#include "djvu-document.h"
-#include "djvu-text.h"
-#include "djvu-text-page.h"
-#include "ev-document-find.h"
-#include "ev-document.h"
-
-
-
-struct _DjvuText {
-       DjvuDocument *document;
-       gboolean case_sensitive;
-       char *text;
-       GList **pages;
-       guint idle;
-       int start_page;
-       int search_page;
-};
-
-/**
- * djvu_text_idle_callback:
- * @data: #DjvuText instance
- * 
- * Idle callback that processes one page at a time.
- * 
- * Returns: whether there are more pages to be processed
- */
-static gboolean 
-djvu_text_idle_callback (void *data)
-{
-       DjvuText *djvu_text = (DjvuText *) data;
-       DjvuDocument *djvu_document = djvu_text->document;
-       int n_pages;
-       miniexp_t page_text;
-
-       ev_document_doc_mutex_lock ();
-       while ((page_text =
-               ddjvu_document_get_pagetext (djvu_document->d_document,
-                                            djvu_text->search_page,
-                                            "char")) == miniexp_dummy)
-               djvu_handle_events (djvu_document, TRUE, NULL);
-
-       if (page_text != miniexp_nil) {
-               DjvuTextPage *page = djvu_text_page_new (page_text);
-               djvu_text_page_prepare_search (page, djvu_text->case_sensitive); 
-               if (page->links->len > 0) {
-                       djvu_text_page_search (page, djvu_text->text);
-                       djvu_text->pages[djvu_text->search_page] = page->results;
-                       ev_document_find_changed (EV_DOCUMENT_FIND
-                                                 (djvu_document),
-                                                 djvu_text->search_page);
-               }
-               djvu_text_page_free (page);
-               ddjvu_miniexp_release (djvu_document->d_document,
-                                      page_text);
-       }
-       ev_document_doc_mutex_unlock ();
-
-       n_pages =
-           djvu_document_get_n_pages (EV_DOCUMENT (djvu_text->document));
-       djvu_text->search_page += 1;
-       if (djvu_text->search_page == n_pages) {
-               /* wrap around */
-               djvu_text->search_page = 0;
-       }
-
-       if (djvu_text->search_page != djvu_text->start_page)
-               return TRUE;
-
-       /* We're done. */
-       djvu_text->idle = 0;
-       /* will return FALSE to remove */
-       return FALSE;
-}
-
-/**
- * djvu_text_new:
- * @djvu_document: document to search
- * @start_page: first page to search
- * @case_sensitive: uses g_utf8_case_fold() to enable case-insensitive 
- *     searching
- * @text: text to search
- * 
- * Creates a new #DjvuText instance to enable searching. An idle call
- * is used to process all pages starting from @start_page.
- * 
- * Returns: newly created instance
- */
-DjvuText *
-djvu_text_new (DjvuDocument *djvu_document,
-              int           start_page,
-              gboolean      case_sensitive, 
-              const char   *text)
-{
-       DjvuText *djvu_text;
-       int n_pages;
-       int i;
-
-       n_pages = djvu_document_get_n_pages (EV_DOCUMENT (djvu_document));
-
-       djvu_text = g_new0 (DjvuText, 1);
-
-       if (case_sensitive)
-               djvu_text->text = g_strdup (text);
-       else
-               djvu_text->text = g_utf8_casefold (text, -1);
-       djvu_text->pages = g_new0 (GList *, n_pages);
-       for (i = 0; i < n_pages; i++) {
-               djvu_text->pages[i] = NULL;
-       }
-
-       djvu_text->document = djvu_document;
-
-       /* We add at low priority so the progress bar repaints */
-       djvu_text->idle = g_idle_add_full (G_PRIORITY_LOW,
-                                       djvu_text_idle_callback,
-                                       djvu_text, NULL);
-
-       djvu_text->case_sensitive = case_sensitive;
-       djvu_text->start_page = start_page;
-       djvu_text->search_page = start_page;
-
-       return djvu_text;
-}
-
-/**
- * djvu_text_copy:
- * @djvu_document: document to search
- * @page: page to search
- * @rectangle: rectangle to copy
- * 
- * Copies and returns the text in the given rectangle.
- * 
- * Returns: newly allocated text or NULL of none is available
- */
-char *
-djvu_text_copy (DjvuDocument *djvu_document,
-                       int           page,
-               EvRectangle  *rectangle)
-{
-       miniexp_t page_text;
-       char* 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;
-}
-
-/**
- * djvu_text_free:
- * @djvu_text: instance to free
- * 
- * Frees the given #DjvuText instance.
- */
-void djvu_text_free (DjvuText * djvu_text)
-{
-       DjvuDocument *djvu_document = djvu_text->document;
-       int n_pages;
-       int i;
-
-       if (djvu_text->idle != 0)
-               g_source_remove (djvu_text->idle);
-
-       n_pages = djvu_document_get_n_pages (EV_DOCUMENT (djvu_document));
-       for (i = 0; i < n_pages; i++) {
-               g_list_foreach (djvu_text->pages[i], (GFunc) g_free, NULL);
-               g_list_free (djvu_text->pages[i]);
-       }
-
-       g_free (djvu_text->text);
-}
-
-/**
- * djvu_text_get_text:
- * @djvu_text: #DjvuText instance
- * 
- * Returns the search text. This is mainly to be able to avoid reinstantiation 
- * for the same search text.
- * 
- * Returns: the text this instance of #DjvuText is looking for
- */
-const char *
-djvu_text_get_text (DjvuText *djvu_text)
-{
-       return djvu_text->text;
-}
-
-/**
- * djvu_text_n_results:
- * @djvu_text: #DjvuText instance
- * @page: page number
- * 
- * Returns the number of search results available for the given page.
- * 
- * Returns: number of search results
- */
-int 
-djvu_text_n_results (DjvuText *djvu_text, 
-                    int       page)
-{
-       return g_list_length (djvu_text->pages[page]);
-}
-
-/**
- * djvu_text_has_results:
- * @djvu_text: #DjvuText instance
- * @page: page number
- * 
- * Returns whether there are search results available for the given page.
- * This method executes faster than djvu_text_n_results().
- * 
- * Returns: whether there are search results
- */
-int 
-djvu_text_has_results (DjvuText *djvu_text, 
-                       int       page)
-{
-       return djvu_text->pages[page] != NULL;
-}
-
-/**
- * djvu_text_get_result:
- * @djvu_text: #DjvuText instance
- * @page: page number
- * @n_result: result number
- * 
- * Returns the n-th search result of a given page. The coordinates are 
- * Djvu-specific and need to be processed to be compatible with the Evince
- * coordinate system. The result may span several lines!
- * 
- * Returns: the rectangle for the search result
- */
-EvRectangle *
-djvu_text_get_result (DjvuText *djvu_text, 
-                      int       page,
-                     int       n_result)
-{
-       return (EvRectangle *) g_list_nth_data (djvu_text->pages[page],
-                                               n_result);
-}
-
-/**
- * djvu_text_get_progress:
- * @djvu_text: #DjvuText instance
- * 
- * Returns the percentage of pages done searching.
- * 
- * Returns: the progress as value between 0 and 1
- */
-double
-djvu_text_get_progress (DjvuText *djvu_text)
-{
-       int pages_done;
-       int n_pages;
-
-       n_pages =
-           djvu_document_get_n_pages (EV_DOCUMENT (djvu_text->document));
-       if (djvu_text->search_page > djvu_text->start_page) {
-               pages_done = djvu_text->search_page - djvu_text->start_page + 1;
-       } else if (djvu_text->search_page == djvu_text->start_page) {
-               pages_done = n_pages;
-       } else {
-               pages_done =
-                   n_pages - djvu_text->start_page + djvu_text->search_page;
-       }
-       return pages_done / (double) n_pages;
-}
-
diff --git a/backend/djvu/djvu-text.h b/backend/djvu/djvu-text.h
deleted file mode 100644 (file)
index b7371df..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 
- * Copyright (C) 2006 Michael Hofmann <mh21@piware.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __DJVU_TEXT_H__
-#define __DJVU_TEXT_H__
-
-#include "ev-document.h"
-
-#include <glib.h>
-
-typedef struct _DjvuText DjvuText;
-
-DjvuText    *djvu_text_new          (DjvuDocument *djvu_document,
-                                    int           start_page,
-                                    gboolean      case_sensitive, 
-                                    const char   *text);
-void         djvu_text_free         (DjvuText     *djvu_text);
-const char  *djvu_text_get_text     (DjvuText     *djvu_text);
-int          djvu_text_n_results    (DjvuText     *djvu_text, 
-                                    int           page);
-EvRectangle *djvu_text_get_result   (DjvuText     *djvu_text, 
-                                    int           page,
-                                    int           n_result);
-int          djvu_text_has_results  (DjvuText     *djvu_text, 
-                                     int           page);
-double       djvu_text_get_progress (DjvuText     *djvu_text);
-char       *djvu_text_copy         (DjvuDocument *djvu_document,
-                                            int           page,
-                                    EvRectangle  *rectangle);
-
-#endif /* __DJVU_TEXT_H__ */
index 4687ac21fd6b040d51002e6d767d990134e4d78a..983298e254780098d27e1520d5f4cac07005add7 100644 (file)
@@ -1364,195 +1364,42 @@ pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
 }
 
 
-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;
+       for (l = matches; l && l->data; l = g_list_next (l)) {
+               PopplerRectangle *rect = (PopplerRectangle *)l->data;
+               gdouble           tmp;
 
-       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;
-
-       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
index 02fbae2e122ff3b3eae4a85a2a6fe219374c29c4..59b8755a700959812e2bfa4b543eab741fe41d5e 100644 (file)
@@ -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 @@ ev_document_find_get_type (void)
                const GTypeInfo our_info =
                {
                        sizeof (EvDocumentFindIface),
-                       ev_document_find_base_init,
+                       NULL,
                        NULL,
                };
 
@@ -47,80 +44,14 @@ ev_document_find_get_type (void)
        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);
-}
index f365df13479b8a21723583b03dea0dde99048372..40db0174c8390999561b9a4becdd931235382dfa 100644 (file)
@@ -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 @@ G_BEGIN_DECLS
 #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 */
index fb967cc8e3d8dd001518665b722777bfb1478df0..6e1e3f19c445c80a96cb8ddfcb89888152fe8671 100644 (file)
@@ -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_init              (EvJobSave             *job);
 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 {
 };
 
 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 (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
 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 @@ ev_job_fonts_run (EvJob *job)
 #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 @@ ev_job_fonts_class_init (EvJobFontsClass *class)
        
        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 @@ ev_job_print_new (EvDocument    *document,
        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;
+}
+
index e89f64649ff2072dc49380573720a6c3adbbe344..188759e928972098d833f49fc4150b4861557ecf 100644 (file)
@@ -57,6 +57,9 @@ typedef struct _EvJobSaveClass EvJobSaveClass;
 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 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
 #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 @@ struct _EvJobFontsClass
         EvJobClass parent_class;
 
        /* Signals */
-       void (* updated)  (EvJobFonts *job);
+       void (* updated)  (EvJobFonts *job,
+                          gdouble     progress);
 };
 
 struct _EvJobLoad
@@ -289,6 +298,28 @@ struct _EvJobPrintClass
        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 @@ EvJob          *ev_job_print_new          (EvDocument      *document,
                                           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
 
index 1618417d084f16c9837eee7e0c6dcf41367ab430..547d1654111af32554edb2bffaa7e8c09067da77 100644 (file)
@@ -97,8 +97,9 @@ struct _EvView {
 
        EvDocument *document;
 
-       char *find_status;
-       int find_result;
+       /* Find */
+       GList **find_pages;
+       gint find_result;
        gboolean jump_to_find_result;
        gboolean highlight_find_results;
        
index 2524d11cb095d9bea4ce64d8f73cd683c5d539cc..d00f98c5a7e177331f3b1e13b7b8a4d37995a69b 100644 (file)
@@ -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 @@ static void   draw_loading_text                          (EvView             *view,
                                                              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 @@ static void       ev_view_handle_cursor_over_xy              (EvView *view,
                                                              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 @@ ev_view_expose_event (GtkWidget      *widget,
 
                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 @@ draw_rubberband (GtkWidget *widget, GdkWindow *window,
 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 @@ highlight_find_results (EvView *view, int page)
                        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 @@ ev_view_finalize (GObject *object)
 {
        EvView *view = EV_VIEW (object);
 
-       g_free (view->find_status);
-
        clear_selection (view);
        clear_link_selected (view);
 
@@ -3973,9 +3964,6 @@ ev_view_get_property (GObject *object,
        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;
@@ -4091,14 +4079,6 @@ ev_view_class_init (EvViewClass *class)
                         G_TYPE_OBJECT);
 
 
-       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",
@@ -4223,25 +4203,6 @@ ev_view_init (EvView *view)
 
 /*** 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 @@ page_changed_cb (EvPageCache *page_cache,
                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 @@ ev_view_set_document (EvView     *view,
                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 @@ ev_view_set_document (EvView     *view,
 
                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 @@ ev_view_set_zoom_for_size (EvView *view,
 }
 
 /*** Find ***/
-static void
-update_find_status_message (EvView *view, gboolean this_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);
-}
-
-const char *
-ev_view_get_find_status (EvView *view)
+static gint
+ev_view_find_get_n_results (EvView *view, gint page)
 {
-       g_return_val_if_fail (EV_IS_VIEW (view), NULL);
-
-       return view->find_status;
+       return view->find_pages ? g_list_length (view->find_pages[page]) : 0;
 }
 
-static void
-ev_view_set_find_status (EvView *view, const char *message)
+static EvRectangle *
+ev_view_find_get_result (EvView *view, gint page, gint result)
 {
-       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 @@ jump_to_find_page (EvView *view, EvViewFindDirection direction, gint shift)
        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 @@ jump_to_find_page (EvView *view, EvViewFindDirection direction, gint shift)
                
                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 @@ ev_view_find_next (EvView *view)
        }
 }
 
-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 @@ ev_view_find_previous (EvView *view)
 }
 
 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 @@ ev_view_set_highlight_search (EvView *view, gboolean value)
 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 ***/
index cbcf7682a3bc0827ba9a36a2cff92f20d2c4dc05..b6e5e8201d8fe762bbcf884199ea26febddc7877 100644 (file)
@@ -117,18 +117,15 @@ void            ev_view_set_rotation      (EvView         *view,
 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);
index 7b5a7705990256abd88841cc3ffed7da3e139e54..65f5d468893a7f082a447ca9ddb3f32c09bf0990 100644 (file)
@@ -179,6 +179,7 @@ struct _EvWindowPrivate {
        EvJob            *thumbnail_job;
        EvJob            *save_job;
        EvJob            *print_job;
+       EvJob            *find_job;
 
        /* Printing */
        gboolean          print_preview;
@@ -275,6 +276,7 @@ static void ev_window_cmd_view_page_width           (GtkAction        *action,
 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 @@ ev_window_update_actions (EvWindow *ev_window)
        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 @@ ev_window_update_actions (EvWindow *ev_window)
                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);
        
@@ -687,19 +693,15 @@ ev_window_warning_message (GtkWindow *window, const gchar *msg)
        ev_window_set_message_area (EV_WINDOW (window), area);
 }
 
-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_setup_document (EvWindow *ev_window)
 
        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 @@ attachment_bar_menu_popup_cb (EvSidebarAttachments *attachbar,
 }
 
 static void
-view_find_status_changed_cb (EvView     *view,
-                            GParamSpec *pspec,
-                            EvWindow   *ev_window)
+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)
 {
-       const char *text;
+       ev_window_update_find_status_message (ev_window);
+}
 
-       text = ev_view_get_find_status (view);
-       egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
-                                     text);
+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 @@ find_bar_close_cb (EggFindBar *find_bar,
                   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 @@ find_bar_search_changed_cb (EggFindBar *find_bar,
        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 @@ find_bar_visibility_changed_cb (EggFindBar *find_bar,
 
        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 @@ find_bar_visibility_changed_cb (EggFindBar *find_bar,
 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 @@ ev_window_dispose (GObject *object)
        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);
@@ -5489,10 +5550,6 @@ ev_window_init (EvWindow *ev_window)
        gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window),
                           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),