From c86fea736694b17beb9fb621fceac7e2970afe08 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Wed, 27 Aug 2008 09:01:41 +0000 Subject: Removed 2008-08-27 Carlos Garcia Campos * 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 --- (limited to 'shell') diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index fb967cc..6e1e3f1 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -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 @@ -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; +} + diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index e89f646..188759e 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -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 diff --git a/shell/ev-view-private.h b/shell/ev-view-private.h index 1618417..547d165 100644 --- a/shell/ev-view-private.h +++ b/shell/ev-view-private.h @@ -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; diff --git a/shell/ev-view.c b/shell/ev-view.c index 2524d11..d00f98c 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -29,7 +29,6 @@ #include #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; @@ -4092,14 +4080,6 @@ ev_view_class_init (EvViewClass *class) 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 @@ 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 ***/ diff --git a/shell/ev-view.h b/shell/ev-view.h index cbcf768..b6e5e82 100644 --- a/shell/ev-view.h +++ b/shell/ev-view.h @@ -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); diff --git a/shell/ev-window.c b/shell/ev-window.c index 7b5a770..65f5d46 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -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); @@ -688,18 +694,14 @@ ev_window_warning_message (GtkWindow *window, const gchar *msg) } 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); @@ -5490,10 +5551,6 @@ ev_window_init (EvWindow *ev_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), ev_window); -- cgit v0.9.1