+ ev_job_succeeded (job);
+
+ return FALSE;
+}
+
+static void
+ev_job_print_class_init (EvJobPrintClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ oclass->dispose = ev_job_print_dispose;
+ job_class->run = ev_job_print_run;
+}
+
+EvJob *
+ev_job_print_new (EvDocument *document,
+ const gchar *format,
+ gdouble width,
+ gdouble height,
+ EvPrintRange *ranges,
+ gint n_ranges,
+ EvPrintPageSet page_set,
+ gint pages_per_sheet,
+ gint copies,
+ gdouble collate,
+ gdouble reverse)
+{
+ EvJobPrint *job;
+
+ ev_debug_message (DEBUG_JOBS, "format: %s, width: %f, height:%f,"
+ "n_ranges: %d, pages_per_sheet: %d, copies: %d,"
+ "collate: %s, reverse: %s",
+ format, width, height, n_ranges, pages_per_sheet, copies,
+ collate ? "True" : "False", reverse ? "True" : "False");
+
+ job = g_object_new (EV_TYPE_JOB_PRINT, NULL);
+
+ EV_JOB (job)->document = g_object_ref (document);
+
+ job->format = format;
+
+ job->temp_file = NULL;
+
+ job->width = width;
+ job->height = height;
+
+ job->ranges = ranges;
+ job->n_ranges = n_ranges;
+
+ job->page_set = page_set;
+
+ job->pages_per_sheet = CLAMP (pages_per_sheet, 1, 16);
+
+ job->copies = copies;
+ job->collate = collate;
+ job->reverse = reverse;
+
+ 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;