evince r3092 - in trunk: . libdocument shell



Author: carlosgc
Date: Sun Aug  3 11:01:28 2008
New Revision: 3092
URL: http://svn.gnome.org/viewvc/evince?rev=3092&view=rev

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

	* libdocument/ev-document.[ch]: (ev_document_doc_mutex_trylock),
	(ev_document_fc_mutex_trylock):
	* shell/Makefile.am:
	* shell/ev-job-queue.[ch]:
	* shell/ev-job-scheduler.[ch]:
	* shell/ev-jobs.[ch]: (ev_job_init), (ev_job_dispose),
	(ev_job_class_init), (emit_finished), (ev_job_emit_finished),
	(ev_job_run), (ev_job_cancel), (ev_job_failed),
	(ev_job_failed_from_error), (ev_job_succeeded),
	(ev_job_is_finished), (ev_job_is_failed), (ev_job_get_run_mode),
	(ev_job_set_run_mode), (ev_job_links_init), (ev_job_links_run),
	(ev_job_links_class_init), (ev_job_render_init),
	(notify_page_ready), (ev_job_render_page_ready),
	(ev_job_render_run), (ev_job_render_class_init),
	(ev_job_thumbnail_init), (ev_job_thumbnail_run),
	(ev_job_thumbnail_class_init), (ev_job_fonts_init),
	(ev_job_fonts_run), (ev_job_fonts_class_init), (ev_job_load_init),
	(ev_job_load_run), (ev_job_load_class_init), (ev_job_save_init),
	(ev_job_save_dispose), (ev_job_save_run),
	(ev_job_save_class_init), (ev_job_print_init),
	(ev_job_print_dispose), (ev_job_print_run),
	(ev_job_print_class_init):
	* shell/ev-page-cache.c:
	* shell/ev-pixbuf-cache.[ch]: (dispose_cache_job_info),
	(check_job_size_and_unref), (move_one_job),
	(copy_job_to_job_info), (add_job),
	(ev_pixbuf_cache_add_jobs_if_needed):
	* shell/ev-properties-fonts.c: (ev_properties_fonts_dispose),
	(job_fonts_finished_cb), (job_fonts_updated_cb),
	(ev_properties_fonts_set_document):
	* shell/ev-sidebar-links.c: (ev_sidebar_links_dispose),
	(ev_sidebar_links_set_document):
	* shell/ev-sidebar-thumbnails.c: (clear_range), (add_range),
	(ev_sidebar_thumbnails_set_document),
	(ev_sidebar_thumbnails_clear_job):
	* shell/ev-view-private.h:
	* shell/ev-view.c:
	* shell/ev-window.c: (ev_window_clear_thumbnail_job),
	(ev_window_refresh_window_thumbnail), (password_dialog_response),
	(ev_window_clear_load_job), (ev_window_clear_reload_job),
	(ev_window_load_job_cb), (ev_window_reload_job_cb),
	(window_open_file_copy_ready_cb), (ev_window_open_uri),
	(ev_window_reload_document), (ev_window_clear_save_job),
	(ev_window_save_job_cb), (file_save_dialog_response_cb),
	(ev_window_clear_print_job), (ev_window_print_job_cb),
	(ev_window_print_dialog_response_cb):
	* shell/main.c: (main):

	Rework the jobs system in order to make it simpler and more
	extensible. It allows to run jobs in the main loop instead of
	using a thread when it's appropriate like the fonts job. Now it's
	also possible to cancel jobs that are currently running.


Added:
   trunk/shell/ev-job-scheduler.c
   trunk/shell/ev-job-scheduler.h
      - copied, changed from r3091, /trunk/shell/ev-job-queue.h
Removed:
   trunk/shell/ev-job-queue.c
   trunk/shell/ev-job-queue.h
Modified:
   trunk/ChangeLog
   trunk/libdocument/ev-document.c
   trunk/libdocument/ev-document.h
   trunk/shell/Makefile.am
   trunk/shell/ev-jobs.c
   trunk/shell/ev-jobs.h
   trunk/shell/ev-page-cache.c
   trunk/shell/ev-pixbuf-cache.c
   trunk/shell/ev-pixbuf-cache.h
   trunk/shell/ev-properties-fonts.c
   trunk/shell/ev-sidebar-links.c
   trunk/shell/ev-sidebar-thumbnails.c
   trunk/shell/ev-view-private.h
   trunk/shell/ev-view.c
   trunk/shell/ev-window.c
   trunk/shell/main.c

Modified: trunk/libdocument/ev-document.c
==============================================================================
--- trunk/libdocument/ev-document.c	(original)
+++ trunk/libdocument/ev-document.c	Sun Aug  3 11:01:28 2008
@@ -89,6 +89,12 @@
 	g_mutex_unlock (ev_document_get_doc_mutex ());
 }
 
+gboolean
+ev_document_doc_mutex_trylock (void)
+{
+	return g_mutex_trylock (ev_document_get_doc_mutex ());
+}
+
 GMutex *
 ev_document_get_fc_mutex (void)
 {
@@ -111,6 +117,12 @@
 }
 
 gboolean
+ev_document_fc_mutex_trylock (void)
+{
+	return g_mutex_trylock (ev_document_get_fc_mutex ());
+}
+
+gboolean
 ev_document_load (EvDocument  *document,
 		  const char  *uri,
 		  GError     **error)

Modified: trunk/libdocument/ev-document.h
==============================================================================
--- trunk/libdocument/ev-document.h	(original)
+++ trunk/libdocument/ev-document.h	Sun Aug  3 11:01:28 2008
@@ -101,11 +101,13 @@
 GMutex          *ev_document_get_doc_mutex    (void);
 void             ev_document_doc_mutex_lock   (void);
 void             ev_document_doc_mutex_unlock (void);
+gboolean         ev_document_doc_mutex_trylock(void);
 
 /* FontConfig mutex */
 GMutex          *ev_document_get_fc_mutex     (void);
 void             ev_document_fc_mutex_lock    (void);
 void             ev_document_fc_mutex_unlock  (void);
+gboolean         ev_document_fc_mutex_trylock (void);
 
 EvDocumentInfo  *ev_document_get_info         (EvDocument      *document);
 gboolean         ev_document_load             (EvDocument      *document,

Modified: trunk/shell/Makefile.am
==============================================================================
--- trunk/shell/Makefile.am	(original)
+++ trunk/shell/Makefile.am	Sun Aug  3 11:01:28 2008
@@ -28,8 +28,8 @@
 	eggfindbar.h			\
 	ev-application.c		\
 	ev-application.h		\
-	ev-job-queue.h			\
-	ev-job-queue.c			\
+	ev-job-scheduler.h		\
+	ev-job-scheduler.c		\
 	ev-jobs.h			\
 	ev-jobs.c			\
 	ev-file-monitor.h		\

Added: trunk/shell/ev-job-scheduler.c
==============================================================================
--- (empty file)
+++ trunk/shell/ev-job-scheduler.c	Sun Aug  3 11:01:28 2008
@@ -0,0 +1,305 @@
+/* ev-job-scheduler.c
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * Evince 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 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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 "ev-debug.h"
+#include "ev-job-scheduler.h"
+
+typedef struct _EvSchedulerJob {
+	EvJob         *job;
+	EvJobPriority  priority;
+	GSList        *job_link;
+} EvSchedulerJob;
+
+G_LOCK_DEFINE_STATIC(job_list);
+static GSList *job_list = NULL;
+
+static gpointer ev_job_thread_proxy               (gpointer        data);
+static void     ev_scheduler_thread_job_cancelled (EvSchedulerJob *job,
+						   GCancellable   *cancellable);
+
+/* EvJobQueue */
+static GQueue queue_urgent = G_QUEUE_INIT;
+static GQueue queue_high = G_QUEUE_INIT;
+static GQueue queue_low = G_QUEUE_INIT;
+static GQueue queue_none = G_QUEUE_INIT;
+
+static GCond *job_queue_cond = NULL;
+static GMutex *job_queue_mutex = NULL;
+static GQueue *job_queue[EV_JOB_N_PRIORITIES] = {
+	&queue_urgent,
+	&queue_high,
+	&queue_low,
+	&queue_none
+};
+
+static void
+ev_job_queue_push (EvSchedulerJob *job,
+		   EvJobPriority   priority)
+{
+	ev_debug_message (DEBUG_JOBS, "%s priority %d", EV_GET_TYPE_NAME (job->job), priority);
+	
+	g_mutex_lock (job_queue_mutex);
+
+	g_queue_push_tail (job_queue[priority], job);
+	g_cond_broadcast (job_queue_cond);
+	
+	g_mutex_unlock (job_queue_mutex);
+}
+
+static EvSchedulerJob *
+ev_job_queue_get_next_unlocked (void)
+{
+	gint i;
+	EvSchedulerJob *job = NULL;
+	
+	for (i = EV_JOB_PRIORITY_URGENT; i < EV_JOB_N_PRIORITIES; i++) {
+		job = (EvSchedulerJob *) g_queue_pop_head (job_queue[i]);
+		if (job)
+			break;
+	}
+
+	ev_debug_message (DEBUG_JOBS, "%s", job ? EV_GET_TYPE_NAME (job->job) : "No jobs in queue");
+
+	return job;
+}
+
+static gpointer
+ev_job_scheduler_init (gpointer data)
+{
+	job_queue_cond = g_cond_new ();
+	job_queue_mutex = g_mutex_new ();
+	g_thread_create (ev_job_thread_proxy, NULL, FALSE, NULL);
+	
+	return NULL;
+}
+
+static void
+ev_scheduler_job_list_add (EvSchedulerJob *job)
+{
+	ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+	
+	G_LOCK (job_list);
+
+	job_list = g_slist_prepend (job_list, job);
+	job->job_link = job_list;
+	
+	G_UNLOCK (job_list);
+}
+
+static void
+ev_scheduler_job_list_remove (EvSchedulerJob *job)
+{
+	ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+	
+	G_LOCK (job_list);
+
+	job_list = g_slist_delete_link (job_list, job->job_link);
+	
+	G_UNLOCK (job_list);
+}
+
+static void
+ev_scheduler_job_free (EvSchedulerJob *job)
+{
+	if (!job)
+		return;
+
+	g_object_unref (job->job);
+	g_free (job);
+}
+
+static void
+ev_scheduler_job_destroy (EvSchedulerJob *job)
+{
+	ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+
+	if (job->job->run_mode == EV_JOB_RUN_MAIN_LOOP) {
+		g_signal_handlers_disconnect_by_func (job->job, 
+						      G_CALLBACK (ev_scheduler_job_destroy),
+						      job);
+	} else {
+		g_signal_handlers_disconnect_by_func (job->job->cancellable,
+						      G_CALLBACK (ev_scheduler_thread_job_cancelled),
+						      job);
+	}
+	
+	ev_scheduler_job_list_remove (job);
+	ev_scheduler_job_free (job);
+}
+
+static void
+ev_scheduler_thread_job_cancelled (EvSchedulerJob *job,
+				   GCancellable   *cancellable)
+{
+	GList   *list;
+	
+	ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+
+	g_mutex_lock (job_queue_mutex);
+
+	/* If the job is not still running,
+	 * remove it from the job queue and job list.
+	 * If the job is currently running, it will be
+	 * destroyed as soon as it finishes. 
+	 */
+	list = g_queue_find (job_queue[job->priority], job);
+	if (list) {
+		g_queue_delete_link (job_queue[job->priority], list);
+		g_mutex_unlock (job_queue_mutex);
+		ev_scheduler_job_destroy (job);
+	} else {
+		g_mutex_unlock (job_queue_mutex);
+	}
+}
+
+static void
+ev_job_thread (EvJob *job)
+{
+	gboolean result;
+
+	ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job));
+
+	do {
+		if (g_cancellable_is_cancelled (job->cancellable))
+			result = FALSE;
+		else
+			result = ev_job_run (job);
+	} while (result);
+}
+
+static gboolean
+ev_job_idle (EvJob *job)
+{
+	ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job));
+
+	if (g_cancellable_is_cancelled (job->cancellable))
+		return FALSE;
+
+	return ev_job_run (job);
+}
+
+static gpointer
+ev_job_thread_proxy (gpointer data)
+{
+	while (TRUE) {
+		EvSchedulerJob *job;
+
+		g_mutex_lock (job_queue_mutex);
+		job = ev_job_queue_get_next_unlocked ();
+		if (!job) {
+			g_cond_wait (job_queue_cond, job_queue_mutex);
+			g_mutex_unlock (job_queue_mutex);
+			continue;
+		}
+		g_mutex_unlock (job_queue_mutex);
+		
+		ev_job_thread (job->job);
+		ev_scheduler_job_destroy (job);
+	}
+
+	return NULL;
+}
+
+void
+ev_job_scheduler_push_job (EvJob         *job,
+			   EvJobPriority  priority)
+{
+	static GOnce once_init = G_ONCE_INIT;
+	EvSchedulerJob *s_job;
+
+	g_once (&once_init, ev_job_scheduler_init, NULL);
+
+	ev_debug_message (DEBUG_JOBS, "%s pirority %d", EV_GET_TYPE_NAME (job), priority);
+
+	s_job = g_new0 (EvSchedulerJob, 1);
+	s_job->job = g_object_ref (job);
+	s_job->priority = priority;
+
+	ev_scheduler_job_list_add (s_job);
+	
+	switch (ev_job_get_run_mode (job)) {
+	case EV_JOB_RUN_THREAD:
+		g_signal_connect_swapped (job->cancellable, "cancelled",
+					  G_CALLBACK (ev_scheduler_thread_job_cancelled),
+					  s_job);
+		ev_job_queue_push (s_job, priority);
+		break;
+	case EV_JOB_RUN_MAIN_LOOP:
+		g_signal_connect_swapped (job, "finished",
+					  G_CALLBACK (ev_scheduler_job_destroy),
+					  s_job);
+		g_signal_connect_swapped (job, "cancelled",
+					  G_CALLBACK (ev_scheduler_job_destroy),
+					  s_job);
+		g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+				 (GSourceFunc)ev_job_idle,
+				 g_object_ref (job),
+				 (GDestroyNotify)g_object_unref);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+}
+
+void
+ev_job_scheduler_update_job (EvJob         *job,
+			     EvJobPriority  priority)
+{
+	GSList         *l;
+	EvSchedulerJob *s_job = NULL;
+	gboolean        need_resort = FALSE;
+
+	/* Main loop jobs are scheduled inmediately */
+	if (ev_job_get_run_mode (job) == EV_JOB_RUN_MAIN_LOOP)
+		return;
+
+	ev_debug_message (DEBUG_JOBS, "%s pirority %d", EV_GET_TYPE_NAME (job), priority);
+	
+	G_LOCK (job_list);
+
+	for (l = job_list; l; l = l->next) {
+		s_job = (EvSchedulerJob *)l->data;
+
+		if (s_job->job == job) {
+			need_resort = (s_job->priority != priority);
+			break;
+		}
+	}
+	
+	G_UNLOCK (job_list);
+
+	if (need_resort) {
+		GList *list;
+	
+		g_mutex_lock (job_queue_mutex);
+		
+		list = g_queue_find (job_queue[s_job->priority], s_job);
+		if (list) {
+			ev_debug_message (DEBUG_JOBS, "Moving job %s from pirority %d to %d",
+					  EV_GET_TYPE_NAME (job), s_job->priority, priority);
+			g_queue_delete_link (job_queue[s_job->priority], list);
+			g_queue_push_tail (job_queue[priority], s_job);
+			g_cond_broadcast (job_queue_cond);
+		}
+		
+		g_mutex_unlock (job_queue_mutex);
+	}
+}
+

Copied: trunk/shell/ev-job-scheduler.h (from r3091, /trunk/shell/ev-job-queue.h)
==============================================================================
--- /trunk/shell/ev-job-queue.h	(original)
+++ trunk/shell/ev-job-scheduler.h	Sun Aug  3 11:01:28 2008
@@ -1,6 +1,7 @@
-/* this file is part of evince, a gnome document viewer
+/* ev-job-scheduler.h
+ *  this file is part of evince, a gnome document viewer
  *
- *  Copyright (C) 2005 Red Hat, Inc
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
  *
  * Evince is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -17,23 +18,27 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef __EV_JOB_QUEUE_H__
-#define __EV_JOB_QUEUE_H__
+#ifndef EV_JOB_SCHEDULER_H
+#define EV_JOB_SCHEDULER_H
 
-#include <gtk/gtk.h>
+#include <glib.h>
 #include "ev-jobs.h"
 
 G_BEGIN_DECLS
 
-
-void     ev_job_queue_init       (void);
-
-void     ev_job_queue_add_job    (EvJob         *job,
-				  EvJobPriority  priority);
-gboolean ev_job_queue_update_job (EvJob         *job,
-				  EvJobPriority  new_priority);
-gboolean ev_job_queue_remove_job (EvJob         *job);
+typedef enum {
+	EV_JOB_PRIORITY_URGENT, /* Rendering current page range */
+	EV_JOB_PRIORITY_HIGH,   /* Rendering current thumbnail range */
+	EV_JOB_PRIORITY_LOW,    /* Rendering pages not in current range */
+	EV_JOB_PRIORITY_NONE,   /* Any other job: load, save, print, ... */
+	EV_JOB_N_PRIORITIES
+} EvJobPriority;
+
+void ev_job_scheduler_push_job   (EvJob        *job,
+				  EvJobPriority priority);
+void ev_job_scheduler_update_job (EvJob        *job,
+				  EvJobPriority priority);
 
 G_END_DECLS
 
-#endif /* __EV_JOB_QUEUE_H__ */
+#endif /* EV_JOB_SCHEDULER_H */

Modified: trunk/shell/ev-jobs.c
==============================================================================
--- trunk/shell/ev-jobs.c	(original)
+++ trunk/shell/ev-jobs.c	Sun Aug  3 11:01:28 2008
@@ -1,6 +1,26 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ *  Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *  Copyright (C) 2005 Red Hat, Inc
+ *
+ * Evince 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 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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 "ev-jobs.h"
-#include "ev-job-queue.h"
 #include "ev-document-thumbnails.h"
 #include "ev-document-links.h"
 #include "ev-document-images.h"
@@ -34,6 +54,7 @@
 static void ev_job_print_class_init     (EvJobPrintClass     *class);
 
 enum {
+	CANCELLED,
 	FINISHED,
 	LAST_SIGNAL
 };
@@ -43,10 +64,16 @@
 	RENDER_LAST_SIGNAL
 };
 
+enum {
+	UPDATED,
+	FONTS_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 };
 
-G_DEFINE_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
 G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
@@ -55,7 +82,12 @@
 G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobPrint, ev_job_print, EV_TYPE_JOB)
 
-static void ev_job_init (EvJob *job) { /* Do Nothing */ }
+/* EvJob */
+static void
+ev_job_init (EvJob *job)
+{
+	job->cancellable = g_cancellable_new ();
+}
 
 static void
 ev_job_dispose (GObject *object)
@@ -69,6 +101,16 @@
 		job->document = NULL;
 	}
 
+	if (job->cancellable) {
+		g_object_unref (job->cancellable);
+		job->cancellable = NULL;
+	}
+
+	if (job->error) {
+		g_error_free (job->error);
+		job->error = NULL;
+	}
+
 	(* G_OBJECT_CLASS (ev_job_parent_class)->dispose) (object);
 }
 
@@ -81,18 +123,173 @@
 
 	oclass->dispose = ev_job_dispose;
 
+	job_signals[CANCELLED] =
+		g_signal_new ("cancelled",
+			      EV_TYPE_JOB,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EvJobClass, cancelled),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
 	job_signals [FINISHED] =
 		g_signal_new ("finished",
 			      EV_TYPE_JOB,
-			      G_SIGNAL_RUN_LAST,
+			      G_SIGNAL_RUN_FIRST,
 			      G_STRUCT_OFFSET (EvJobClass, finished),
 			      NULL, NULL,
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
 }
 
+static gboolean
+emit_finished (EvJob *job)
+{
+	ev_debug_message (DEBUG_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
 
-static void ev_job_links_init (EvJobLinks *job) { /* Do Nothing */ }
+	job->idle_finished_id = 0;
+	
+	if (job->cancelled) {
+		ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit finished", EV_GET_TYPE_NAME (job), job);
+	} else {
+		ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+		g_signal_emit (job, job_signals[FINISHED], 0);
+	}
+	
+	return FALSE;
+}
+
+static void
+ev_job_emit_finished (EvJob *job)
+{
+	ev_debug_message (DEBUG_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+	if (g_cancellable_is_cancelled (job->cancellable)) {
+		ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, returning", EV_GET_TYPE_NAME (job), job);
+		return;
+	}
+	
+	job->finished = TRUE;
+	
+	if (job->run_mode == EV_JOB_RUN_THREAD) {
+		job->idle_finished_id =
+			g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+					 (GSourceFunc)emit_finished,
+					 g_object_ref (job),
+					 (GDestroyNotify)g_object_unref);
+	} else {
+		ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+		g_signal_emit (job, job_signals[FINISHED], 0);
+	}
+}
+
+gboolean
+ev_job_run (EvJob *job)
+{
+	EvJobClass *class = EV_JOB_GET_CLASS (job);
+	
+	return class->run (job);
+}
+
+void
+ev_job_cancel (EvJob *job)
+{
+	if (job->cancelled || (job->finished && job->idle_finished_id == 0))
+		return;
+
+	ev_debug_message (DEBUG_JOBS, "job %s (%p) cancelled", EV_GET_TYPE_NAME (job), job);
+	ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+	
+	/* This should never be called from a thread */
+	job->cancelled = TRUE;
+	g_cancellable_cancel (job->cancellable);
+	g_signal_emit (job, job_signals[CANCELLED], 0);
+}
+
+void
+ev_job_failed (EvJob       *job,
+	       GQuark       domain,
+	       gint         code,
+	       const gchar *format,
+	       ...)
+{
+	va_list args;
+	gchar  *message;
+	
+	if (job->failed || job->finished)
+		return;
+
+	ev_debug_message (DEBUG_JOBS, "job %s (%p) failed", EV_GET_TYPE_NAME (job), job);
+	
+	job->failed = TRUE;
+	
+	va_start (args, format);
+	message = g_strdup_vprintf (format, args);
+	va_end (args);
+	
+	job->error = g_error_new (domain, code, message);
+	g_free (message);
+	
+	ev_job_emit_finished (job);                                                                                                               
+}
+
+void
+ev_job_failed_from_error (EvJob  *job,
+			  GError *error)
+{
+	if (job->failed || job->finished)
+		return;
+	
+	ev_debug_message (DEBUG_JOBS, "job %s (%p) failed", EV_GET_TYPE_NAME (job), job);
+
+	job->failed = TRUE;
+	job->error = g_error_copy (error);
+
+	ev_job_emit_finished (job);
+}
+
+void
+ev_job_succeeded (EvJob *job)
+{
+	if (job->finished)
+		return;
+
+	ev_debug_message (DEBUG_JOBS, "job %s (%p) succeeded", EV_GET_TYPE_NAME (job), job);
+	
+	job->failed = FALSE;
+	ev_job_emit_finished (job);
+}
+
+gboolean
+ev_job_is_finished (EvJob *job)
+{
+	return job->finished;
+}
+
+gboolean
+ev_job_is_failed (EvJob *job)
+{
+	return job->failed;
+}
+
+EvJobRunMode
+ev_job_get_run_mode (EvJob *job)
+{
+	return job->run_mode;
+}
+
+void
+ev_job_set_run_mode (EvJob       *job,
+		     EvJobRunMode run_mode)
+{
+	job->run_mode = run_mode;
+}
+
+/* EvJobLinks */
+static void
+ev_job_links_init (EvJobLinks *job)
+{
+	EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
 
 static void
 ev_job_links_dispose (GObject *object)
@@ -111,18 +308,52 @@
 	(* G_OBJECT_CLASS (ev_job_links_parent_class)->dispose) (object);
 }
 
+static gboolean
+ev_job_links_run (EvJob *job)
+{
+	EvJobLinks *job_links = EV_JOB_LINKS (job);
+
+	ev_debug_message (DEBUG_JOBS, NULL);
+	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+	
+	ev_document_doc_mutex_lock ();
+	job_links->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (job->document));
+	ev_document_doc_mutex_unlock ();
+	
+	ev_job_succeeded (job);
+	
+	return FALSE;
+}
+
 static void
 ev_job_links_class_init (EvJobLinksClass *class)
 {
-	GObjectClass *oclass;
-
-	oclass = G_OBJECT_CLASS (class);
+	GObjectClass *oclass = G_OBJECT_CLASS (class);
+	EvJobClass   *job_class = EV_JOB_CLASS (class);
 
 	oclass->dispose = ev_job_links_dispose;
+	job_class->run = ev_job_links_run;
 }
 
+EvJob *
+ev_job_links_new (EvDocument *document)
+{
+	EvJob *job;
 
-static void ev_job_render_init (EvJobRender *job) { /* Do Nothing */ }
+	ev_debug_message (DEBUG_JOBS, NULL);
+
+	job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
+	job->document = g_object_ref (document);
+	
+	return job;
+}
+
+/* EvJobRender */
+static void
+ev_job_render_init (EvJobRender *job)
+{
+	EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
 
 static void
 ev_job_render_dispose (GObject *object)
@@ -132,7 +363,7 @@
 	job = EV_JOB_RENDER (object);
 
 	if (job->ev_page) {
-		ev_debug_message (DEBUG_JOBS, "page: %d", job->ev_page->index);
+		ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job->ev_page->index, job);
 		g_object_unref (job->ev_page);
 		job->ev_page = NULL;
 	}
@@ -155,132 +386,121 @@
 	(* G_OBJECT_CLASS (ev_job_render_parent_class)->dispose) (object);
 }
 
-static void
-ev_job_render_class_init (EvJobRenderClass *class)
+static gboolean
+notify_page_ready (EvJobRender *job)
 {
-	GObjectClass *oclass;
-
-	oclass = G_OBJECT_CLASS (class);
+	ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job);
+	ev_profiler_stop (EV_PROFILE_JOBS, "Rendering page %d", job->ev_page->index);
 
-	job_render_signals [PAGE_READY] =
-		g_signal_new ("page-ready",
-			      EV_TYPE_JOB_RENDER,
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (EvJobRenderClass, page_ready),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
+	if (EV_JOB (job)->cancelled) {
+		ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit page_ready", EV_GET_TYPE_NAME (job), job);
+	} else {
+		g_signal_emit (job, job_render_signals[PAGE_READY], 0);
+	}
 
-	oclass->dispose = ev_job_render_dispose;
+	return FALSE;
 }
 
-static void ev_job_thumbnail_init (EvJobThumbnail *job) { /* Do Nothing */ }
-
 static void
-ev_job_thumbnail_dispose (GObject *object)
+ev_job_render_page_ready (EvJobRender *job)
 {
-	EvJobThumbnail *job;
-
-	job = EV_JOB_THUMBNAIL (object);
-
-	ev_debug_message (DEBUG_JOBS, "%d", job->page);
+	ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job);
 	
-	if (job->thumbnail) {
-		g_object_unref (job->thumbnail);
-		job->thumbnail = NULL;
-	}
-
-	(* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
+	job->page_ready = TRUE;
+	g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+			 (GSourceFunc)notify_page_ready,
+			 g_object_ref (job),
+			 (GDestroyNotify)g_object_unref);
 }
 
-static void
-ev_job_thumbnail_class_init (EvJobThumbnailClass *class)
+static gboolean
+ev_job_render_run (EvJob *job)
 {
-	GObjectClass *oclass;
-
-	oclass = G_OBJECT_CLASS (class);
-
-	oclass->dispose = ev_job_thumbnail_dispose;
-}
-
-static void ev_job_print_init (EvJobPrint *job) { /* Do Nothing */ }
+	EvJobRender     *job_render = EV_JOB_RENDER (job);
+	EvRenderContext *rc;
 
-static void
-ev_job_print_dispose (GObject *object)
-{
-	EvJobPrint *job;
+	ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job_render->page, job);
+	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+	
+	ev_document_doc_mutex_lock ();
 
-	job = EV_JOB_PRINT (object);
+	ev_profiler_start (EV_PROFILE_JOBS, "Rendering page %d", job_render->page);
+		
+	ev_document_fc_mutex_lock ();
 
-	ev_debug_message (DEBUG_JOBS, NULL);
-	
-	if (job->temp_file) {
-		g_unlink (job->temp_file);
-		g_free (job->temp_file);
-		job->temp_file = NULL;
-	}
+	job_render->ev_page = ev_document_get_page (job->document, job_render->page);
+	rc = ev_render_context_new (job_render->ev_page, job_render->rotation, job_render->scale);
+		
+	job_render->surface = ev_document_render (job->document, rc);
+	/* If job was cancelled during the page rendering,
+	 * we return now, so that the thread is finished ASAP
+	 */
+	if (g_cancellable_is_cancelled (job->cancellable)) {
+		ev_document_fc_mutex_unlock ();
+		ev_document_doc_mutex_unlock ();
+		g_object_unref (rc);
 
-	if (job->error) {
-		g_error_free (job->error);
-		job->error = NULL;
+		return FALSE;
 	}
-
-	if (job->ranges) {
-		g_free (job->ranges);
-		job->ranges = NULL;
-		job->n_ranges = 0;
+	
+	if ((job_render->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (job->document)) {
+		ev_selection_render_selection (EV_SELECTION (job->document),
+					       rc,
+					       &(job_render->selection),
+					       &(job_render->selection_points),
+					       NULL,
+					       job_render->selection_style,
+					       &(job_render->text), &(job_render->base));
+		job_render->selection_region =
+			ev_selection_get_selection_region (EV_SELECTION (job->document),
+							   rc,
+							   job_render->selection_style,
+							   &(job_render->selection_points));
 	}
 
-	(* G_OBJECT_CLASS (ev_job_print_parent_class)->dispose) (object);
-}
-
-static void
-ev_job_print_class_init (EvJobPrintClass *class)
-{
-	GObjectClass *oclass;
-
-	oclass = G_OBJECT_CLASS (class);
-
-	oclass->dispose = ev_job_print_dispose;
-}
-
-/* Public functions */
-void
-ev_job_finished (EvJob *job)
-{
-	ev_debug_message (DEBUG_JOBS, EV_GET_TYPE_NAME (job));
-	ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+	ev_job_render_page_ready (job_render);
+		
+	ev_document_fc_mutex_unlock ();
+		
+	if ((job_render->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (job->document))
+		job_render->text_mapping =
+			ev_selection_get_selection_map (EV_SELECTION (job->document), rc);
+	if ((job_render->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (job->document))
+		job_render->link_mapping =
+			ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), job_render->page);
+	if ((job_render->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (job->document))
+		job_render->form_field_mapping =
+			ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (job->document),
+							   job_render->ev_page);
+	if ((job_render->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (job->document))
+		job_render->image_mapping =
+			ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (job->document),
+							      job_render->page);
+	g_object_unref (rc);
+	ev_document_doc_mutex_unlock ();
 	
-	g_return_if_fail (EV_IS_JOB (job));
+	ev_job_succeeded (job);
 	
-	g_signal_emit (job, job_signals[FINISHED], 0);
+	return FALSE;
 }
 
-EvJob *
-ev_job_links_new (EvDocument *document)
+static void
+ev_job_render_class_init (EvJobRenderClass *class)
 {
-	EvJob *job;
+	GObjectClass *oclass = G_OBJECT_CLASS (class);
+	EvJobClass   *job_class = EV_JOB_CLASS (class);
 
-	ev_debug_message (DEBUG_JOBS, NULL);
-	
-	job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
-	job->document = g_object_ref (document);
-
-	return job;
-}
-
-void
-ev_job_links_run (EvJobLinks *job)
-{
-	ev_debug_message (DEBUG_JOBS, NULL);
-	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-	
-	g_return_if_fail (EV_IS_JOB_LINKS (job));
+	job_render_signals [PAGE_READY] =
+		g_signal_new ("page-ready",
+			      EV_TYPE_JOB_RENDER,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EvJobRenderClass, page_ready),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
 
-	ev_document_doc_mutex_lock ();
-	job->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (EV_JOB (job)->document));
-	EV_JOB (job)->finished = TRUE;
-	ev_document_doc_mutex_unlock ();
+	oclass->dispose = ev_job_render_dispose;
+	job_class->run = ev_job_render_run;
 }
 
 EvJob *
@@ -306,10 +526,6 @@
 	job->target_height = height;
 	job->flags = flags;
 
-	if (EV_IS_ASYNC_RENDERER (document)) {	
-		EV_JOB (job)->async = TRUE;
-	}
-
 	return EV_JOB (job);
 }
 
@@ -328,111 +544,64 @@
 	job->base = *base;
 }
 
+/* EvJobThumbnail */
 static void
-render_finished_cb (EvDocument      *document,
-		    GdkPixbuf       *pixbuf,
-		    EvJobRender     *job)
+ev_job_thumbnail_init (EvJobThumbnail *job)
 {
-	g_signal_handlers_disconnect_by_func (EV_JOB (job)->document,
-					      render_finished_cb, job);
-
-	job->surface = ev_document_misc_surface_from_pixbuf (pixbuf);
-	job->page_ready = TRUE;
-	g_signal_emit (job, job_render_signals[PAGE_READY], 0);
-	EV_JOB (job)->finished = TRUE;
-	ev_job_finished (EV_JOB (job));
+	EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
 }
 
-static gboolean
-notify_page_ready (EvJobRender *job)
+static void
+ev_job_thumbnail_dispose (GObject *object)
 {
-	ev_debug_message (DEBUG_JOBS, "%d", job->ev_page->index);
-	ev_profiler_stop (EV_PROFILE_JOBS, "Rendering page %d", job->ev_page->index);
-	
-	g_signal_emit (job, job_render_signals[PAGE_READY], 0);
+	EvJobThumbnail *job;
 
-	return FALSE;
-}
+	job = EV_JOB_THUMBNAIL (object);
 
-static void
-ev_job_render_page_ready (EvJobRender *job)
-{
-	ev_debug_message (DEBUG_JOBS, "%d", job->ev_page->index);
+	ev_debug_message (DEBUG_JOBS, "%d (%p)", job->page, job);
 	
-	job->page_ready = TRUE;
-	g_idle_add_full (G_PRIORITY_HIGH_IDLE,
-			 (GSourceFunc)notify_page_ready,
-			 g_object_ref (job),
-			 (GDestroyNotify)g_object_unref);
+	if (job->thumbnail) {
+		g_object_unref (job->thumbnail);
+		job->thumbnail = NULL;
+	}
+
+	(* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
 }
 
-void
-ev_job_render_run (EvJobRender *job)
+static gboolean
+ev_job_thumbnail_run (EvJob *job)
 {
-	g_return_if_fail (EV_IS_JOB_RENDER (job));
+	EvJobThumbnail  *job_thumb = EV_JOB_THUMBNAIL (job);
+	EvRenderContext *rc;
+	EvPage          *page;
 
-	ev_debug_message (DEBUG_JOBS, "page: %d", job->page);
+	ev_debug_message (DEBUG_JOBS, "%d (%p)", job_thumb->page, job);
 	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
 	
 	ev_document_doc_mutex_lock ();
 
-	if (EV_JOB (job)->async) {
-		EvAsyncRenderer *renderer = EV_ASYNC_RENDERER (EV_JOB (job)->document);
-		ev_async_renderer_render_pixbuf (renderer, job->page, job->scale,
-						 job->rotation);
-		g_signal_connect (EV_JOB (job)->document, "render_finished",
-				  G_CALLBACK (render_finished_cb), job);
-	} else {
-		EvRenderContext *rc;
-
-		ev_profiler_start (EV_PROFILE_JOBS, "Rendering page %d", job->page);
-		
-		ev_document_fc_mutex_lock ();
+	page = ev_document_get_page (job->document, job_thumb->page);
+	rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale);
+	g_object_unref (page);
 
-		job->ev_page = ev_document_get_page (EV_JOB (job)->document, job->page);
+	job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document),
+								     rc, TRUE);
+	g_object_unref (rc);
+	ev_document_doc_mutex_unlock ();
 
-		rc = ev_render_context_new (job->ev_page, job->rotation, job->scale);
-		
-		job->surface = ev_document_render (EV_JOB (job)->document, rc);
-		if ((job->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (EV_JOB (job)->document)) {
-			ev_selection_render_selection (EV_SELECTION (EV_JOB (job)->document),
-						       rc,
-						       &(job->selection),
-						       &(job->selection_points),
-						       NULL,
-						       job->selection_style,
-						       &(job->text), &(job->base));
-			job->selection_region =
-				ev_selection_get_selection_region (EV_SELECTION (EV_JOB (job)->document),
-								   rc,
-								   job->selection_style,
-								   &(job->selection_points));
-		}
+	ev_job_succeeded (job);
+	
+	return FALSE;
+}
 
-		ev_job_render_page_ready (job);
-		
-		ev_document_fc_mutex_unlock ();
-		
-		if ((job->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (EV_JOB (job)->document))
-			job->text_mapping =
-				ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document), rc);
-		if ((job->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (EV_JOB (job)->document))
-			job->link_mapping =
-				ev_document_links_get_links (EV_DOCUMENT_LINKS (EV_JOB (job)->document), job->page);
-		if ((job->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (EV_JOB (job)->document))
-			job->form_field_mapping =
-				ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (EV_JOB (job)->document),
-								   job->ev_page);
-		if ((job->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (EV_JOB (job)->document))
-			job->image_mapping =
-				ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (EV_JOB (job)->document),
-								      job->page);
-		g_object_unref (rc);
-		
-		EV_JOB (job)->finished = TRUE;
-	}
+static void
+ev_job_thumbnail_class_init (EvJobThumbnailClass *class)
+{
+	GObjectClass *oclass = G_OBJECT_CLASS (class);
+	EvJobClass   *job_class = EV_JOB_CLASS (class);
 
-	ev_document_doc_mutex_unlock ();
+	oclass->dispose = ev_job_thumbnail_dispose;
+	job_class->run = ev_job_thumbnail_run;
 }
 
 EvJob *
@@ -455,35 +624,64 @@
 	return EV_JOB (job);
 }
 
-void
-ev_job_thumbnail_run (EvJobThumbnail *job)
+/* EvJobFonts */
+static void
+ev_job_fonts_init (EvJobFonts *job)
 {
-	EvRenderContext *rc;
-	EvPage          *page;
-
-	ev_debug_message (DEBUG_JOBS, "%d", job->page);
-	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-	
-	g_return_if_fail (EV_IS_JOB_THUMBNAIL (job));
+	EV_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
+}
 
-	ev_document_doc_mutex_lock ();
+static gboolean
+ev_job_fonts_run (EvJob *job)
+{
+	EvJobFonts      *job_fonts = EV_JOB_FONTS (job);
+	EvDocumentFonts *fonts = EV_DOCUMENT_FONTS (job->document);
 
-	page = ev_document_get_page (EV_JOB (job)->document, job->page);
-	rc = ev_render_context_new (page, job->rotation, job->scale);
-	g_object_unref (page);
+	ev_debug_message (DEBUG_JOBS, NULL);
+	
+	/* Do not block the main loop */
+	if (!ev_document_doc_mutex_trylock ())
+		return TRUE;
+	
+	if (!ev_document_fc_mutex_trylock ())
+		return TRUE;
+
+#ifdef EV_ENABLE_DEBUG
+	/* We use the #ifdef in this case because of the if */
+	if (ev_document_fonts_get_progress (fonts) == 0)
+		ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+#endif
+
+	job_fonts->scan_completed = !ev_document_fonts_scan (fonts, 20);
+	g_signal_emit (job_fonts, job_fonts_signals[UPDATED], 0,
+		       ev_document_fonts_get_progress (fonts));
 
-	job->thumbnail =
-		ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (EV_JOB (job)->document),
-						      rc, TRUE);
-	g_object_unref (rc);
+	ev_document_fc_mutex_unlock ();
 	ev_document_doc_mutex_unlock ();
+
+	if (job_fonts->scan_completed)
+		ev_job_succeeded (job);
 	
-	EV_JOB (job)->finished = TRUE;
+	return !job_fonts->scan_completed;
 }
 
-static void ev_job_fonts_init (EvJobFonts *job) { /* Do Nothing */ }
-
-static void ev_job_fonts_class_init (EvJobFontsClass *class) { /* Do Nothing */ }
+static void
+ev_job_fonts_class_init (EvJobFontsClass *class)
+{
+	EvJobClass *job_class = EV_JOB_CLASS (class);
+	
+	job_class->run = ev_job_fonts_run;
+	
+	job_fonts_signals[UPDATED] =
+		g_signal_new ("updated",
+			      EV_TYPE_JOB_FONTS,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EvJobFontsClass, updated),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__DOUBLE,
+			      G_TYPE_NONE,
+			      1, G_TYPE_DOUBLE);
+}
 
 EvJob *
 ev_job_fonts_new (EvDocument *document)
@@ -499,30 +697,13 @@
 	return EV_JOB (job);
 }
 
-void
-ev_job_fonts_run (EvJobFonts *job)
+/* EvJobLoad */
+static void
+ev_job_load_init (EvJobLoad *job)
 {
-	EvDocumentFonts *fonts;
-
-	ev_debug_message (DEBUG_JOBS, NULL);
-	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-	
-	g_return_if_fail (EV_IS_JOB_FONTS (job));
-
-	ev_document_doc_mutex_lock ();
-	
-	fonts = EV_DOCUMENT_FONTS (EV_JOB (job)->document);
-	ev_document_fc_mutex_lock ();
-	job->scan_completed = !ev_document_fonts_scan (fonts, 20);
-	ev_document_fc_mutex_unlock ();
-	
-	EV_JOB (job)->finished = TRUE;
-
-	ev_document_doc_mutex_unlock ();
+	EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
 }
 
-static void ev_job_load_init (EvJobLoad *job) { /* Do Nothing */ }
-
 static void
 ev_job_load_dispose (GObject *object)
 {
@@ -535,11 +716,6 @@
 		job->uri = NULL;
 	}
 
-	if (job->error) {
-		g_error_free (job->error);
-		job->error = NULL;
-	}
-
 	if (job->dest) {
 		g_object_unref (job->dest);
 		job->dest = NULL;
@@ -553,17 +729,52 @@
 	(* G_OBJECT_CLASS (ev_job_load_parent_class)->dispose) (object);
 }
 
+static gboolean
+ev_job_load_run (EvJob *job)
+{
+	EvJobLoad *job_load = EV_JOB_LOAD (job);
+	GError    *error = NULL;
+	
+	ev_debug_message (DEBUG_JOBS, "%s", job_load->uri);
+	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+	
+	ev_document_fc_mutex_lock ();
+
+	/* TODO: reuse the job!!! */
+	/* This job may already have a document even if the job didn't complete
+	   because, e.g., a password is required - if so, just reload rather than
+	   creating a new instance */
+	if (job->document) {
+		ev_document_load (job->document,
+				  job_load->uri,
+				  &error);
+	} else {
+		job->document = ev_document_factory_get_document (job_load->uri,
+								  &error);
+	}
+
+	ev_document_fc_mutex_unlock ();
+
+	if (error) {
+		ev_job_failed_from_error (job, error);
+		g_error_free (error);
+	} else {
+		ev_job_succeeded (job);
+	}
+
+	return FALSE;
+}
+
 static void
 ev_job_load_class_init (EvJobLoadClass *class)
 {
-	GObjectClass *oclass;
-
-	oclass = G_OBJECT_CLASS (class);
+	GObjectClass *oclass = G_OBJECT_CLASS (class);
+	EvJobClass   *job_class = EV_JOB_CLASS (class);
 
 	oclass->dispose = ev_job_load_dispose;
+	job_class->run = ev_job_load_run;
 }
 
-
 EvJob *
 ev_job_load_new (const gchar    *uri,
 		 EvLinkDest     *dest,
@@ -577,12 +788,9 @@
 	job = g_object_new (EV_TYPE_JOB_LOAD, NULL);
 
 	job->uri = g_strdup (uri);
-	if (dest)
-		job->dest = g_object_ref (dest);
-
+	job->dest = dest ? g_object_ref (dest) : NULL;
 	job->mode = mode;
-	if (search_string)
-		job->search_string = g_strdup (search_string);
+	job->search_string = search_string ? g_strdup (search_string) : NULL;
 
 	return EV_JOB (job);
 }
@@ -597,40 +805,13 @@
 	job->uri = g_strdup (uri);
 }
 
-void
-ev_job_load_run (EvJobLoad *job)
+/* EvJobSave */
+static void
+ev_job_save_init (EvJobSave *job)
 {
-	g_return_if_fail (EV_IS_JOB_LOAD (job));
-
-	ev_debug_message (DEBUG_JOBS, "%s", job->uri);
-	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-	
-	if (job->error) {
-	        g_error_free (job->error);
-		job->error = NULL;
-	}
-
-	ev_document_fc_mutex_lock ();
-	
-	/* This job may already have a document even if the job didn't complete
-	   because, e.g., a password is required - if so, just reload rather than
-	   creating a new instance */
-	if (EV_JOB (job)->document) {
-		ev_document_load (EV_JOB (job)->document,
-				  job->uri,
-				  &job->error);
-	} else {
-		EV_JOB(job)->document =
-			ev_document_factory_get_document (job->uri,
-							  &job->error);
-	}
-
-	ev_document_fc_mutex_unlock ();
-	EV_JOB (job)->finished = TRUE;
+	EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
 }
 
-static void ev_job_save_init (EvJobSave *job) { /* Do Nothing */ }
-
 static void
 ev_job_save_dispose (GObject *object)
 {
@@ -648,52 +829,20 @@
 		job->document_uri = NULL;
 	}
 
-	if (job->error) {
-		g_error_free (job->error);
-		job->error = NULL;
-	}
-
 	(* G_OBJECT_CLASS (ev_job_save_parent_class)->dispose) (object);
 }
 
-static void
-ev_job_save_class_init (EvJobSaveClass *class)
-{
-	GObjectClass *oclass;
-
-	oclass = G_OBJECT_CLASS (class);
-
-	oclass->dispose = ev_job_save_dispose;
-}
-
-EvJob *
-ev_job_save_new (EvDocument  *document,
-		 const gchar *uri,
-		 const gchar *document_uri)
-{
-	EvJobSave *job;
-
-	ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", uri, document_uri);
-
-	job = g_object_new (EV_TYPE_JOB_SAVE, NULL);
-
-	EV_JOB (job)->document = g_object_ref (document);
-	job->uri = g_strdup (uri);
-	job->document_uri = g_strdup (document_uri);
-	job->error = NULL;
-
-	return EV_JOB (job);
-}
-
-void
-ev_job_save_run (EvJobSave *job)
+static gboolean
+ev_job_save_run (EvJob *job)
 {
-	gint   fd;
-	gchar *filename;
-	gchar *tmp_filename;
-	gchar *local_uri;
-
-	ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job->uri, job->document_uri);
+	EvJobSave *job_save = EV_JOB_SAVE (job);
+	gint       fd;
+	gchar     *filename;
+	gchar     *tmp_filename;
+	gchar     *local_uri;
+	GError    *error = NULL;
+	
+	ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job_save->uri, job_save->document_uri);
 	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
 	
 	filename = ev_tmp_filename ("saveacopy");
@@ -706,53 +855,55 @@
 		gint   save_errno = errno;
 
 		display_name = g_filename_display_name (tmp_filename);
-		g_set_error (&(job->error),
-			     G_FILE_ERROR,
-			     g_file_error_from_errno (save_errno),
-			     _("Failed to create file â%sâ: %s"),
-			     display_name, g_strerror (save_errno));
+		ev_job_failed (job,
+			       G_FILE_ERROR,
+			       g_file_error_from_errno (save_errno),
+			       _("Failed to create file â%sâ: %s"),
+			       display_name, g_strerror (save_errno));
 		g_free (display_name);
 		g_free (tmp_filename);
 
-		return;
+		return FALSE;
 	}
 
 	ev_document_doc_mutex_lock ();
 
 	/* Save document to temp filename */
 	local_uri = g_filename_to_uri (tmp_filename, NULL, NULL);
-	ev_document_save (EV_JOB (job)->document, local_uri, &(job->error));
+	ev_document_save (job->document, local_uri, &error);
 	close (fd);
 
 	ev_document_doc_mutex_unlock ();
 
-	if (job->error) {
+	if (error) {
 		g_free (local_uri);
-		return;
+		ev_job_failed_from_error (job, error);
+		g_error_free (error);
+		
+		return FALSE;
 	}
 
 	/* If original document was compressed,
 	 * compress it again before saving
 	 */
-	if (g_object_get_data (G_OBJECT (EV_JOB (job)->document),
-			       "uri-uncompressed")) {
+	if (g_object_get_data (G_OBJECT (job->document), "uri-uncompressed")) {
 		EvCompressionType ctype = EV_COMPRESSION_NONE;
 		const gchar      *ext;
 		gchar            *uri_comp;
 		
-		ext = g_strrstr (job->document_uri, ".gz");
+		ext = g_strrstr (job_save->document_uri, ".gz");
 		if (ext && g_ascii_strcasecmp (ext, ".gz") == 0)
 			ctype = EV_COMPRESSION_GZIP;
 		
-		ext = g_strrstr (job->document_uri, ".bz2");
+		ext = g_strrstr (job_save->document_uri, ".bz2");
 		if (ext && g_ascii_strcasecmp (ext, ".bz2") == 0)
 			ctype = EV_COMPRESSION_BZIP2;
 
-		uri_comp = ev_file_compress (local_uri, ctype, &(job->error));
+		uri_comp = ev_file_compress (local_uri, ctype, &error);
 		g_free (local_uri);
 		ev_tmp_filename_unlink (tmp_filename);
 
-		if (!uri_comp || job->error) {
+		if (!uri_comp || error) {
 			local_uri = NULL;
 		} else {
 			local_uri = uri_comp;
@@ -761,63 +912,87 @@
 
 	g_free (tmp_filename);
 	
-	if (job->error) {
+	if (error) {
 		g_free (local_uri);
-		return;
+		ev_job_failed_from_error (job, error);
+		g_error_free (error);
+		
+		return FALSE;
 	}
 
 	if (!local_uri)
-		return;
+		return FALSE;
 
-	ev_xfer_uri_simple (local_uri, job->uri, &(job->error));
+	ev_xfer_uri_simple (local_uri, job_save->uri, &error);
 	ev_tmp_uri_unlink (local_uri);
+
+	if (error) {
+		ev_job_failed_from_error (job, error);
+		g_error_free (error);
+	} else {
+		ev_job_succeeded (job);
+	}
+	
+	return FALSE;
+}
+
+static void
+ev_job_save_class_init (EvJobSaveClass *class)
+{
+	GObjectClass *oclass = G_OBJECT_CLASS (class);
+	EvJobClass   *job_class = EV_JOB_CLASS (class);
+
+	oclass->dispose = ev_job_save_dispose;
+	job_class->run = ev_job_save_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)
+ev_job_save_new (EvDocument  *document,
+		 const gchar *uri,
+		 const gchar *document_uri)
 {
-	EvJobPrint *job;
+	EvJobSave *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");
+	ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", uri, document_uri);
 
-	job = g_object_new (EV_TYPE_JOB_PRINT, NULL);
+	job = g_object_new (EV_TYPE_JOB_SAVE, NULL);
 
 	EV_JOB (job)->document = g_object_ref (document);
+	job->uri = g_strdup (uri);
+	job->document_uri = g_strdup (document_uri);
 
-	job->format = format;
-	
-	job->temp_file = NULL;
-	job->error = NULL;
+	return EV_JOB (job);
+}
 
-	job->width = width;
-	job->height = height;
+/* EvJobPrint */
+static void
+ev_job_print_init (EvJobPrint *job)
+{
+	EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
 
-	job->ranges = ranges;
-	job->n_ranges = n_ranges;
+static void
+ev_job_print_dispose (GObject *object)
+{
+	EvJobPrint *job;
 
-	job->page_set = page_set;
+	job = EV_JOB_PRINT (object);
 
-	job->pages_per_sheet = CLAMP (pages_per_sheet, 1, 16);
-	
-	job->copies = copies;
-	job->collate = collate;
-	job->reverse = reverse;
+	ev_debug_message (DEBUG_JOBS, NULL);
 	
-	return EV_JOB (job);
+	if (job->temp_file) {
+		g_unlink (job->temp_file);
+		g_free (job->temp_file);
+		job->temp_file = NULL;
+	}
+
+	if (job->ranges) {
+		g_free (job->ranges);
+		job->ranges = NULL;
+		job->n_ranges = 0;
+	}
+
+	(* G_OBJECT_CLASS (ev_job_print_parent_class)->dispose) (object);
 }
 
 static gint
@@ -933,10 +1108,11 @@
 	return page_list;
 }
 
-void
-ev_job_print_run (EvJobPrint *job)
+static gboolean
+ev_job_print_run (EvJob *job)
 {
 	EvDocument            *document = EV_JOB (job)->document;
+	EvJobPrint            *job_print = EV_JOB_PRINT (job);
 	EvFileExporterContext  fc;
 	EvRenderContext       *rc;
 	gint                   fd;
@@ -946,68 +1122,67 @@
 	gint                   first_page;
 	gint                   i, j;
 	gchar                 *filename;
+	GError                *error = NULL;
 	
-	g_return_if_fail (EV_IS_JOB_PRINT (job));
-
 	ev_debug_message (DEBUG_JOBS, NULL);
 	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
 	
-	if (job->temp_file)
-		g_free (job->temp_file);
-	job->temp_file = NULL;
+	if (job_print->temp_file)
+		g_free (job_print->temp_file);
+	job_print->temp_file = NULL;
 	
-	if (job->error)
-		g_error_free (job->error);
-	job->error = NULL;
-
-	filename = g_strdup_printf ("evince_print.%s.XXXXXX", job->format);
-	fd = g_file_open_tmp (filename, &job->temp_file, &job->error);
+	filename = g_strdup_printf ("evince_print.%s.XXXXXX", job_print->format);
+	fd = g_file_open_tmp (filename, &job_print->temp_file, &error);
 	g_free (filename);
 	if (fd <= -1) {
-		EV_JOB (job)->finished = TRUE;
-		return;
+		ev_job_failed_from_error (job, error);
+		g_error_free (error);
+		
+		return FALSE;
 	}
 
-	page_list = ev_job_print_get_page_list (job, &n_pages);
+	page_list = ev_job_print_get_page_list (job_print, &n_pages);
 	if (n_pages == 0) {
 		close (fd);
-		EV_JOB (job)->finished = TRUE;
-		return;
+		/* TODO: error */
+		ev_job_succeeded (job);
+		
+		return FALSE;
 	}
 
-	first_page = ev_print_job_get_first_page (job);
-	last_page = ev_print_job_get_last_page (job);
+	first_page = ev_print_job_get_first_page (job_print);
+	last_page = ev_print_job_get_last_page (job_print);
 
-	fc.format = g_ascii_strcasecmp (job->format, "pdf") == 0 ?
+	fc.format = g_ascii_strcasecmp (job_print->format, "pdf") == 0 ?
 		EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
-	fc.filename = job->temp_file;
+	fc.filename = job_print->temp_file;
 	fc.first_page = MIN (first_page, last_page);
 	fc.last_page = MAX (first_page, last_page);
-	fc.paper_width = job->width;
-	fc.paper_height = job->height;
+	fc.paper_width = job_print->width;
+	fc.paper_height = job_print->height;
 	fc.duplex = FALSE;
-	fc.pages_per_sheet = MAX (1, job->pages_per_sheet);
+	fc.pages_per_sheet = MAX (1, job_print->pages_per_sheet);
 
 	rc = ev_render_context_new (NULL, 0, 1.0);
 
 	ev_document_doc_mutex_lock ();
 	ev_file_exporter_begin (EV_FILE_EXPORTER (document), &fc);
 
-	for (i = 0; i < job->copies; i++) {
+	for (i = 0; i < job_print->copies; i++) {
 		gint page, step;
 		gint n_copies;
 		
-		step = job->reverse ? -1 * job->pages_per_sheet : job->pages_per_sheet;
-		page = job->reverse ? ((n_pages - 1) / job->pages_per_sheet) * job->pages_per_sheet : 0;
-		n_copies = job->collate ? 1 : job->copies;
+		step = job_print->reverse ? -1 * job_print->pages_per_sheet : job_print->pages_per_sheet;
+		page = job_print->reverse ? ((n_pages - 1) / job_print->pages_per_sheet) * job_print->pages_per_sheet : 0;
+		n_copies = job_print->collate ? 1 : job_print->copies;
 
-		while ((job->reverse && (page >= 0)) || (!job->reverse && (page < n_pages))) {
+		while ((job_print->reverse && (page >= 0)) || (!job_print->reverse && (page < n_pages))) {
 			gint k;
 
 			for (k = 0; k < n_copies; k++) {
 				ev_file_exporter_begin_page (EV_FILE_EXPORTER (document));
 				
-				for (j = 0; j < job->pages_per_sheet; j++) {
+				for (j = 0; j < job_print->pages_per_sheet; j++) {
 					EvPage *ev_page;
 					
 					gint p = page + j;
@@ -1028,7 +1203,7 @@
 			page += step;
 		}
 
-		if (!job->collate)
+		if (!job_print->collate)
 			break;
 	}
 
@@ -1039,5 +1214,64 @@
 	close (fd);
 	g_object_unref (rc);
 	
-	EV_JOB (job)->finished = TRUE;
+	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);
 }
+

Modified: trunk/shell/ev-jobs.h
==============================================================================
--- trunk/shell/ev-jobs.h	(original)
+++ trunk/shell/ev-jobs.h	Sun Aug  3 11:01:28 2008
@@ -1,5 +1,6 @@
 /* this file is part of evince, a gnome document viewer
  *
+ *  Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
  *  Copyright (C) 2005 Red Hat, Inc
  *
  * Evince is free software; you can redistribute it and/or modify it
@@ -55,6 +56,7 @@
 #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))
 #define EV_IS_JOB(object)		     (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB))
+#define EV_JOB_GET_CLASS(object)             (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_JOB, EvJobClass))
 
 #define EV_TYPE_JOB_LINKS		     (ev_job_links_get_type())
 #define EV_JOB_LINKS(object)		     (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_LINKS, EvJobLinks))
@@ -92,23 +94,38 @@
 #define EV_IS_JOB_PRINT(object)              (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_PRINT))
 
 typedef enum {
-	EV_JOB_PRIORITY_LOW,
-	EV_JOB_PRIORITY_HIGH,
-} EvJobPriority;
+	EV_JOB_RUN_THREAD,
+	EV_JOB_RUN_MAIN_LOOP
+} EvJobRunMode;
 
 struct _EvJob
 {
 	GObject parent;
+	
 	EvDocument *document;
-	gboolean finished;
-	gboolean async;
+
+	EvJobRunMode run_mode;
+
+	guint cancelled : 1;
+	guint finished : 1;
+	guint failed : 1;
+	
+	GError *error;
+	GCancellable *cancellable;
+
+	guint idle_finished_id;
+	guint idle_cancelled_id;
 };
 
 struct _EvJobClass
 {
 	GObjectClass parent_class;
 
-	void    (* finished) (EvJob *job);
+	gboolean (*run)         (EvJob *job);
+	
+	/* Signals */
+	void     (* cancelled)  (EvJob *job);
+	void     (* finished)   (EvJob *job);
 };
 
 struct _EvJobLinks
@@ -194,6 +211,9 @@
 struct _EvJobFontsClass
 {
         EvJobClass parent_class;
+
+	/* Signals */
+	void (* updated)  (EvJobFonts *job);
 };
 
 struct _EvJobLoad
@@ -203,7 +223,6 @@
 	EvLinkDest *dest;
 	EvWindowRunMode mode;
 	gchar *search_string;
-	GError *error;
 	gchar *uri;
 };
 
@@ -216,7 +235,6 @@
 {
 	EvJob parent;
 
-	GError *error;
 	gchar *uri;
 	gchar *document_uri;
 };
@@ -230,7 +248,6 @@
 {
 	EvJob parent;
 
-	GError *error;
 	const gchar *format;
 	gchar  *temp_file;
 	EvPrintRange *ranges;
@@ -251,12 +268,26 @@
 
 /* Base job class */
 GType           ev_job_get_type           (void) G_GNUC_CONST;
-void            ev_job_finished           (EvJob          *job);
+gboolean        ev_job_run                (EvJob          *job);
+void            ev_job_cancel             (EvJob          *job);
+void            ev_job_failed             (EvJob          *job,
+					   GQuark          domain,
+					   gint            code,
+					   const gchar    *format,
+					   ...);
+void            ev_job_failed_from_error  (EvJob          *job,
+					   GError         *error);
+void            ev_job_succeeded          (EvJob          *job);
+gboolean        ev_job_is_cancelled       (EvJob          *job);
+gboolean        ev_job_is_finished        (EvJob          *job);
+gboolean        ev_job_is_failed          (EvJob          *job);
+EvJobRunMode    ev_job_get_run_mode       (EvJob          *job);
+void            ev_job_set_run_mode       (EvJob          *job,
+					   EvJobRunMode    run_mode);
 
 /* EvJobLinks */
 GType           ev_job_links_get_type     (void) G_GNUC_CONST;
 EvJob          *ev_job_links_new          (EvDocument     *document);
-void            ev_job_links_run          (EvJobLinks     *thumbnail);
 
 /* EvJobRender */
 GType           ev_job_render_get_type    (void) G_GNUC_CONST;
@@ -272,20 +303,15 @@
 					   EvSelectionStyle selection_style,
 					   GdkColor        *text,
 					   GdkColor        *base);
-void            ev_job_render_run         (EvJobRender     *thumbnail);
-
 /* EvJobThumbnail */
 GType           ev_job_thumbnail_get_type (void) G_GNUC_CONST;
 EvJob          *ev_job_thumbnail_new      (EvDocument      *document,
 					   gint             page,
 					   gint             rotation,
 					   gdouble          scale);
-void            ev_job_thumbnail_run      (EvJobThumbnail  *thumbnail);
-
 /* EvJobFonts */
 GType 		ev_job_fonts_get_type 	  (void) G_GNUC_CONST;
 EvJob 	       *ev_job_fonts_new 	  (EvDocument      *document);
-void		ev_job_fonts_run 	  (EvJobFonts 	   *fonts);
 
 /* EvJobLoad */
 GType 		ev_job_load_get_type 	  (void) G_GNUC_CONST;
@@ -295,14 +321,12 @@
 					   const gchar     *search_string);
 void            ev_job_load_set_uri       (EvJobLoad       *load,
 					   const gchar     *uri);
-void		ev_job_load_run 	  (EvJobLoad 	   *load);
 
 /* EvJobSave */
 GType           ev_job_save_get_type      (void) G_GNUC_CONST;
 EvJob          *ev_job_save_new           (EvDocument      *document,
 					   const gchar     *uri,
 					   const gchar     *document_uri);
-void            ev_job_save_run           (EvJobSave       *save);
 
 /* EvJobPrint */
 GType           ev_job_print_get_type     (void) G_GNUC_CONST;
@@ -317,7 +341,6 @@
 					   gint             copies,
 					   gdouble          collate,
 					   gdouble          reverse);
-void            ev_job_print_run          (EvJobPrint      *print);
 
 G_END_DECLS
 

Modified: trunk/shell/ev-page-cache.c
==============================================================================
--- trunk/shell/ev-page-cache.c	(original)
+++ trunk/shell/ev-page-cache.c	Sun Aug  3 11:01:28 2008
@@ -1,6 +1,5 @@
 #include <config.h>
 #include "ev-page-cache.h"
-#include "ev-job-queue.h"
 #include "ev-document-thumbnails.h"
 #include "ev-page.h"
 #include <stdlib.h>

Modified: trunk/shell/ev-pixbuf-cache.c
==============================================================================
--- trunk/shell/ev-pixbuf-cache.c	(original)
+++ trunk/shell/ev-pixbuf-cache.c	Sun Aug  3 11:01:28 2008
@@ -1,6 +1,6 @@
 #include <config.h>
 #include "ev-pixbuf-cache.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
 #include "ev-page-cache.h"
 #include "ev-document-images.h"
 #include "ev-document-forms.h"
@@ -163,8 +163,8 @@
 		g_signal_handlers_disconnect_by_func (job_info->job,
 						      G_CALLBACK (job_finished_cb),
 						      data);
-		ev_job_queue_remove_job (job_info->job);
-		g_object_unref (G_OBJECT (job_info->job));
+		ev_job_cancel (job_info->job);
+		g_object_unref (job_info->job);
 		job_info->job = NULL;
 	}
 	if (job_info->surface) {
@@ -313,7 +313,7 @@
 	g_signal_handlers_disconnect_by_func (job_info->job,
 					      G_CALLBACK (job_finished_cb),
 					      pixbuf_cache);
-	ev_job_queue_remove_job (job_info->job);
+	ev_job_cancel (job_info->job);
 	g_object_unref (job_info->job);
 	job_info->job = NULL;
 }
@@ -330,11 +330,11 @@
 	      CacheJobInfo  *new_next_job,
 	      int            start_page,
 	      int            end_page,
-	      EvJobPriority  priority)
+	      gint           priority)
 {
 	CacheJobInfo *target_page = NULL;
 	int page_offset;
-	EvJobPriority new_priority;
+	gint new_priority;
 
 	if (page < (start_page - pixbuf_cache->preload_cache_size) ||
 	    page > (end_page + pixbuf_cache->preload_cache_size)) {
@@ -361,7 +361,7 @@
 		page_offset = page - start_page;
 		g_assert (page_offset >= 0 &&
 			  page_offset <= ((end_page - start_page) + 1));
-		new_priority = EV_JOB_PRIORITY_HIGH;
+		new_priority = EV_JOB_PRIORITY_URGENT;
 		target_page = new_job_list + page_offset;
 	}
 
@@ -374,7 +374,7 @@
 	job_info->form_field_mapping = NULL;
 
 	if (new_priority != priority && target_page->job) {
-		ev_job_queue_update_job (target_page->job, new_priority);
+		ev_job_scheduler_update_job (target_page->job, new_priority);
 	}
 }
 
@@ -421,7 +421,7 @@
 		move_one_job (pixbuf_cache->job_list + i,
 			      pixbuf_cache, page,
 			      new_job_list, new_prev_job, new_next_job,
-			      start_page, end_page, EV_JOB_PRIORITY_HIGH);
+			      start_page, end_page, EV_JOB_PRIORITY_URGENT);
 		page ++;
 	}
 
@@ -529,8 +529,8 @@
 		g_signal_handlers_disconnect_by_func (job_info->job,
 						      G_CALLBACK (job_finished_cb),
 						      pixbuf_cache);
-		ev_job_queue_remove_job (job_info->job);
-		g_object_unref (G_OBJECT (job_info->job));
+		ev_job_cancel (job_info->job);
+		g_object_unref (job_info->job);
 		job_info->job = NULL;
 	}
 }
@@ -647,13 +647,13 @@
 						  text, base);
 	}
 
-	ev_job_queue_add_job (job_info->job, priority);
 	g_signal_connect (G_OBJECT (job_info->job), "page-ready",
 			  G_CALLBACK (job_page_ready_cb),
 			  pixbuf_cache);
 	g_signal_connect (G_OBJECT (job_info->job), "finished",
 			  G_CALLBACK (job_finished_cb),
 			  pixbuf_cache);
+	ev_job_scheduler_push_job (job_info->job, priority);
 }
 
 static void
@@ -701,7 +701,7 @@
 
 		add_job_if_needed (pixbuf_cache, job_info,
 				   page_cache, page, rotation, scale,
-				   EV_JOB_PRIORITY_HIGH);
+				   EV_JOB_PRIORITY_URGENT);
 	}
 
 	for (i = FIRST_VISABLE_PREV(pixbuf_cache); i < pixbuf_cache->preload_cache_size; i++) {
@@ -1235,7 +1235,7 @@
 
         add_job (pixbuf_cache, job_info, page_cache, region,
 		 width, height, page, rotation, scale,
-		 EV_JOB_PRIORITY_HIGH);
+		 EV_JOB_PRIORITY_URGENT);
 }
 
 

Modified: trunk/shell/ev-pixbuf-cache.h
==============================================================================
--- trunk/shell/ev-pixbuf-cache.h	(original)
+++ trunk/shell/ev-pixbuf-cache.h	Sun Aug  3 11:01:28 2008
@@ -27,7 +27,6 @@
 #include <gtk/gtkwidget.h>
 #include "ev-document.h"
 #include "ev-selection.h"
-#include "ev-job-queue.h"
 
 G_BEGIN_DECLS
 

Modified: trunk/shell/ev-properties-fonts.c
==============================================================================
--- trunk/shell/ev-properties-fonts.c	(original)
+++ trunk/shell/ev-properties-fonts.c	Sun Aug  3 11:01:28 2008
@@ -25,7 +25,7 @@
 #include "ev-properties-fonts.h"
 #include "ev-document-fonts.h"
 #include "ev-jobs.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
 
 #include <glib/gi18n.h>
 #include <gtk/gtktreeview.h>
@@ -63,12 +63,10 @@
 	}
 	
 	if (properties->fonts_job) {
-
-		g_signal_handlers_disconnect_by_func
-				(properties->fonts_job, 
-				 job_fonts_finished_cb, 
-				 properties);
-		ev_job_queue_remove_job (properties->fonts_job);
+		g_signal_handlers_disconnect_by_func (properties->fonts_job, 
+						      job_fonts_finished_cb, 
+						      properties);
+		ev_job_cancel (properties->fonts_job);
 
 		g_object_unref (properties->fonts_job);		
 		properties->fonts_job = NULL;
@@ -161,29 +159,23 @@
 
 static void
 job_fonts_finished_cb (EvJob *job, EvPropertiesFonts *properties)
-{	
-	EvDocumentFonts *document_fonts = EV_DOCUMENT_FONTS (job->document);
-	double progress;
-	
-	progress = ev_document_fonts_get_progress (document_fonts);
-	update_progress_label (properties->fonts_progress_label, progress);
+{
+	g_signal_handlers_disconnect_by_func (job, job_fonts_finished_cb, properties);
+	g_object_unref (properties->fonts_job);
+	properties->fonts_job = NULL;
+}
 
-	if (EV_JOB_FONTS (job)->scan_completed) {
-		g_signal_handlers_disconnect_by_func
-				(job, job_fonts_finished_cb, properties);
-		g_object_unref (properties->fonts_job);
-		properties->fonts_job = NULL;
-	} else {
-		GtkTreeModel *model;
+static void
+job_fonts_updated_cb (EvJobFonts *job, gdouble progress, EvPropertiesFonts *properties)
+{
+	GtkTreeModel *model;
+	EvDocumentFonts *document_fonts = EV_DOCUMENT_FONTS (properties->document);
 
-		model = gtk_tree_view_get_model
-				(GTK_TREE_VIEW (properties->fonts_treeview));
-		ev_document_doc_mutex_lock ();
-		ev_document_fonts_fill_model (document_fonts, model);
-		ev_document_doc_mutex_unlock ();
+	update_progress_label (properties->fonts_progress_label, progress);
 
-		ev_job_queue_add_job (job, EV_JOB_PRIORITY_LOW);
-	}
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (properties->fonts_treeview));
+	/* Documen lock is already held by the jop */
+	ev_document_fonts_fill_model (document_fonts, model);
 }
 
 void
@@ -200,10 +192,13 @@
 	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
 
 	properties->fonts_job = ev_job_fonts_new (properties->document);
+	g_signal_connect (properties->fonts_job, "updated",
+			  G_CALLBACK (job_fonts_updated_cb),
+			  properties);
 	g_signal_connect (properties->fonts_job, "finished",
 			  G_CALLBACK (job_fonts_finished_cb),
 			  properties);
-	ev_job_queue_add_job (properties->fonts_job, EV_JOB_PRIORITY_LOW);
+	ev_job_scheduler_push_job (properties->fonts_job, EV_JOB_PRIORITY_NONE);
 }
 
 GtkWidget *

Modified: trunk/shell/ev-sidebar-links.c
==============================================================================
--- trunk/shell/ev-sidebar-links.c	(original)
+++ trunk/shell/ev-sidebar-links.c	Sun Aug  3 11:01:28 2008
@@ -30,7 +30,7 @@
 
 #include "ev-sidebar-page.h"
 #include "ev-sidebar-links.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
 #include "ev-document-links.h"
 #include "ev-window.h"
 
@@ -145,7 +145,7 @@
 	if (sidebar->priv->job) {
 		g_signal_handlers_disconnect_by_func (sidebar->priv->job,
 						      job_finished_callback, sidebar);
-		ev_job_queue_remove_job (sidebar->priv->job);						      
+		ev_job_cancel (sidebar->priv->job);						      
 		g_object_unref (sidebar->priv->job);
 		sidebar->priv->job = NULL;
 	}
@@ -702,7 +702,7 @@
 			  G_CALLBACK (job_finished_callback),
 			  sidebar_links);
 	/* The priority doesn't matter for this job */
-	ev_job_queue_add_job (priv->job, EV_JOB_PRIORITY_LOW);
+	ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE);
 }
 
 static gboolean

Modified: trunk/shell/ev-sidebar-thumbnails.c
==============================================================================
--- trunk/shell/ev-sidebar-thumbnails.c	(original)
+++ trunk/shell/ev-sidebar-thumbnails.c	Sun Aug  3 11:01:28 2008
@@ -34,7 +34,7 @@
 #include "ev-sidebar-thumbnails.h"
 #include "ev-document-thumbnails.h"
 #include "ev-document-misc.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
 #include "ev-window.h"
 #include "ev-utils.h"
 
@@ -207,7 +207,7 @@
 
 		if (job) {
 			g_signal_handlers_disconnect_by_func (job, thumbnail_job_completed_callback, sidebar_thumbnails);
-			ev_job_queue_remove_job (EV_JOB (job));
+			ev_job_cancel (EV_JOB (job));
 			g_object_unref (job);
 		}
 
@@ -263,7 +263,7 @@
 			job = ev_job_thumbnail_new (priv->document,
 						    page, priv->rotation,
 						    get_scale_for_page (sidebar_thumbnails, page));
-			ev_job_queue_add_job (EV_JOB (job), EV_JOB_PRIORITY_HIGH);
+			ev_job_scheduler_push_job (EV_JOB (job), EV_JOB_PRIORITY_HIGH);
 			
 			g_object_set_data_full (G_OBJECT (job), "tree_iter",
 						gtk_tree_iter_copy (&iter),
@@ -688,8 +688,8 @@
 
 static gboolean
 ev_sidebar_thumbnails_clear_job (GtkTreeModel *model,                                             
-			         GtkTreePath *path, 					                                                 
-			         GtkTreeIter *iter, 											                                              
+			         GtkTreePath *path,
+			         GtkTreeIter *iter,
 				 gpointer data)
 {
 	EvJob *job;
@@ -697,7 +697,7 @@
 	gtk_tree_model_get (model, iter, COLUMN_JOB, &job, -1);
 	
 	if (job != NULL) {
-		ev_job_queue_remove_job (job);
+		ev_job_cancel (job);
 		g_signal_handlers_disconnect_by_func (job, thumbnail_job_completed_callback, data);
 		g_object_unref (job);
 	}

Modified: trunk/shell/ev-view-private.h
==============================================================================
--- trunk/shell/ev-view-private.h	(original)
+++ trunk/shell/ev-view-private.h	Sun Aug  3 11:01:28 2008
@@ -24,6 +24,7 @@
 #include "ev-view.h"
 #include "ev-pixbuf-cache.h"
 #include "ev-page-cache.h"
+#include "ev-jobs.h"
 #include "ev-image.h"
 #include "ev-form-field.h"
 #include "ev-selection.h"

Modified: trunk/shell/ev-view.c
==============================================================================
--- trunk/shell/ev-view.c	(original)
+++ trunk/shell/ev-view.c	Sun Aug  3 11:01:28 2008
@@ -39,7 +39,6 @@
 #include "ev-document-transition.h"
 #include "ev-document-forms.h"
 #include "ev-document-misc.h"
-#include "ev-job-queue.h"
 #include "ev-page-cache.h"
 #include "ev-pixbuf-cache.h"
 #include "ev-transition-animation.h"

Modified: trunk/shell/ev-window.c
==============================================================================
--- trunk/shell/ev-window.c	(original)
+++ trunk/shell/ev-window.c	Sun Aug  3 11:01:28 2008
@@ -49,7 +49,7 @@
 #include "ev-document-images.h"
 #include "ev-document-security.h"
 #include "ev-document-factory.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
 #include "ev-jobs.h"
 #include "ev-sidebar-page.h"
 #include "eggfindbar.h"
@@ -221,16 +221,16 @@
 							 EvWindow         *ev_window);
 static void     ev_window_set_page_mode                 (EvWindow         *window,
 							 EvWindowPageMode  page_mode);
-static void	ev_window_load_job_cb  			(EvJobLoad        *job,
+static void	ev_window_load_job_cb  			(EvJob            *job,
 							 gpointer          data);
 static void     ev_window_reload_document               (EvWindow         *window);
-static void     ev_window_reload_job_cb                 (EvJobLoad        *job,
+static void     ev_window_reload_job_cb                 (EvJob            *job,
 							 EvWindow         *window);
 static void     ev_window_set_icon_from_thumbnail       (EvJobThumbnail   *job,
 							 EvWindow         *ev_window);
-static void     ev_window_print_job_cb                  (EvJobPrint       *job,
+static void     ev_window_print_job_cb                  (EvJob            *job,
 							 EvWindow         *window);
-static void     ev_window_save_job_cb                   (EvJobSave        *save,
+static void     ev_window_save_job_cb                   (EvJob            *save,
 							 EvWindow         *window);
 static void     ev_window_sizing_mode_changed_cb        (EvView           *view,
 							 GParamSpec       *pspec,
@@ -1080,8 +1080,9 @@
 ev_window_clear_thumbnail_job (EvWindow *ev_window)
 {
 	if (ev_window->priv->thumbnail_job != NULL) {
-		ev_job_queue_remove_job (ev_window->priv->thumbnail_job);
-
+		if (!ev_job_is_finished (ev_window->priv->thumbnail_job))
+			ev_job_cancel (ev_window->priv->thumbnail_job);
+		
 		g_signal_handlers_disconnect_by_func (ev_window->priv->thumbnail_job,
 						      ev_window_set_icon_from_thumbnail,
 						      ev_window);
@@ -1125,7 +1126,7 @@
 	g_signal_connect (ev_window->priv->thumbnail_job, "finished",
 			  G_CALLBACK (ev_window_set_icon_from_thumbnail),
 			  ev_window);
-	ev_job_queue_add_job (EV_JOB (ev_window->priv->thumbnail_job), EV_JOB_PRIORITY_LOW);
+	ev_job_scheduler_push_job (ev_window->priv->thumbnail_job, EV_JOB_PRIORITY_NONE);
 }
 
 static gboolean
@@ -1231,7 +1232,7 @@
 		ev_password_dialog_save_password (EV_PASSWORD_DIALOG (password_dialog));
 
 		ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_DOCUMENT);
-		ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+		ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
 		
 		gtk_widget_destroy (password_dialog);
 			
@@ -1277,9 +1278,8 @@
 ev_window_clear_load_job (EvWindow *ev_window)
 {
 	if (ev_window->priv->load_job != NULL) {
-		
-		if (!ev_window->priv->load_job->finished)
-			ev_job_queue_remove_job (ev_window->priv->load_job);
+		if (!ev_job_is_finished (ev_window->priv->load_job))
+			ev_job_cancel (ev_window->priv->load_job);
 		
 		g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
 		g_object_unref (ev_window->priv->load_job);
@@ -1291,9 +1291,8 @@
 ev_window_clear_reload_job (EvWindow *ev_window)
 {
 	if (ev_window->priv->reload_job != NULL) {
-		
-		if (!ev_window->priv->reload_job->finished)
-			ev_job_queue_remove_job (ev_window->priv->reload_job);
+		if (!ev_job_is_finished (ev_window->priv->reload_job))
+			ev_job_cancel (ev_window->priv->reload_job);
 		
 		g_signal_handlers_disconnect_by_func (ev_window->priv->reload_job, ev_window_reload_job_cb, ev_window);
 		g_object_unref (ev_window->priv->reload_job);
@@ -1349,21 +1348,22 @@
  * function should _not_ necessarily expect those to exist after being
  * called. */
 static void
-ev_window_load_job_cb  (EvJobLoad *job,
+ev_window_load_job_cb  (EvJob *job,
 			gpointer data)
 {
 	EvWindow *ev_window = EV_WINDOW (data);
 	EvDocument *document = EV_JOB (job)->document;
+	EvJobLoad *job_load = EV_JOB_LOAD (job);
 
-	g_assert (job->uri);
+	g_assert (job_load->uri);
 
 	ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
 
 	/* Success! */
-	if (job->error == NULL) {
+	if (!ev_job_is_failed (job)) {
 		ev_window_set_document (ev_window, document);
 		
-		if (job->mode != EV_WINDOW_MODE_PREVIEW) {
+		if (job_load->mode != EV_WINDOW_MODE_PREVIEW) {
 			setup_view_from_metadata (ev_window);
 		}
 
@@ -1371,17 +1371,17 @@
 			ev_window_add_recent (ev_window, ev_window->priv->uri);
 		}
 
-		if (job->dest) {
+		if (job_load->dest) {
 			EvLink *link;
 			EvLinkAction *link_action;
 	
-			link_action = ev_link_action_new_dest (g_object_ref (job->dest));
+			link_action = ev_link_action_new_dest (g_object_ref (job_load->dest));
 			link = ev_link_new (NULL, link_action);
 			ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
 		    	g_object_unref (link);
 		}
 
-		switch (job->mode) {
+		switch (job_load->mode) {
 		        case EV_WINDOW_MODE_FULLSCREEN:
 				ev_window_run_fullscreen (ev_window);
 				break;
@@ -1395,14 +1395,23 @@
 				break;
 		}
 
-		if (job->search_string && EV_IS_DOCUMENT_FIND (document)) {
+		/* Restart the search after reloading */
+		if (ev_window->priv->in_reload) {
+			GtkWidget *widget;
+			
+			widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
+			if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
+				find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar),
+							    NULL, ev_window);
+			}
+		} else if (job_load->search_string && EV_IS_DOCUMENT_FIND (document)) {
 			ev_window_cmd_edit_find (NULL, ev_window);
 			egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
-							job->search_string);
+							job_load->search_string);
 		}
 
 		/* Create a monitor for the document */
-		ev_window->priv->monitor = ev_file_monitor_new (job->uri);
+		ev_window->priv->monitor = ev_file_monitor_new (job_load->uri);
 		g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed",
 					  G_CALLBACK (ev_window_document_changed),
 					  ev_window);
@@ -1418,7 +1427,7 @@
 
 		setup_view_from_metadata (ev_window);
 
-		file = g_file_new_for_uri (job->uri);
+		file = g_file_new_for_uri (job_load->uri);
 		base_name = g_file_get_basename (file);
 		ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view),
 						base_name);
@@ -1436,18 +1445,18 @@
 }
 
 static void
-ev_window_reload_job_cb (EvJobLoad *job,
-			 EvWindow  *ev_window)
+ev_window_reload_job_cb (EvJob    *job,
+			 EvWindow *ev_window)
 {
 	GtkWidget *widget;
-	
-	if (job->error) {
+
+	if (ev_job_is_failed (job)) {
 		ev_window_clear_reload_job (ev_window);
 		ev_window->priv->in_reload = FALSE;
 		return;
 	}
 
-	ev_window_set_document (ev_window, EV_JOB (job)->document);
+	ev_window_set_document (ev_window, job->document);
 
 	/* Restart the search after reloading */
 	widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
@@ -1539,7 +1548,7 @@
 	
 	g_file_copy_finish (source, async_result, &error);
 	if (!error) {
-		ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+		ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
 		g_object_unref (source);
 		
 		return;
@@ -1649,7 +1658,7 @@
 		ev_window_load_file_remote (ev_window, source_file);
 	} else {
 		g_object_unref (source_file);
-		ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+		ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
 	}
 }
 
@@ -1666,7 +1675,7 @@
 	g_signal_connect (ev_window->priv->reload_job, "finished",
 			  G_CALLBACK (ev_window_reload_job_cb),
 			  ev_window);
-	ev_job_queue_add_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_LOW);
+	ev_job_scheduler_push_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_NONE);
 }
 
 static void
@@ -2067,8 +2076,8 @@
 ev_window_clear_save_job (EvWindow *ev_window)
 {
 	if (ev_window->priv->save_job != NULL) {
-		if (!ev_window->priv->save_job->finished)
-			ev_job_queue_remove_job (ev_window->priv->save_job);
+		if (!ev_job_is_finished (ev_window->priv->save_job))
+			ev_job_cancel (ev_window->priv->save_job);
 		
 		g_signal_handlers_disconnect_by_func (ev_window->priv->save_job,
 						      ev_window_save_job_cb,
@@ -2079,13 +2088,14 @@
 }
 
 static void
-ev_window_save_job_cb (EvJobSave *job,
+ev_window_save_job_cb (EvJob     *job,
 		       EvWindow  *window)
 {
-	if (job->error) {
+	if (ev_job_is_failed (job)) {
 		gchar *msg;
 		
-		msg = g_strdup_printf (_("The file could not be saved as â%sâ."), job->uri);
+		msg = g_strdup_printf (_("The file could not be saved as â%sâ."),
+				       EV_JOB_SAVE (job)->uri);
 		ev_window_error_message (GTK_WINDOW (window), msg, job->error);
 		g_free (msg);
 	}
@@ -2114,10 +2124,9 @@
 			  G_CALLBACK (ev_window_save_job_cb),
 			  ev_window);
 	/* The priority doesn't matter for this job */
-	ev_job_queue_add_job (ev_window->priv->save_job, EV_JOB_PRIORITY_LOW);
+	ev_job_scheduler_push_job (ev_window->priv->save_job, EV_JOB_PRIORITY_NONE);
 
 	g_free (uri);
-
 	gtk_widget_destroy (fc);
 }
 
@@ -2187,8 +2196,8 @@
 ev_window_clear_print_job (EvWindow *window)
 {
 	if (window->priv->print_job) {
-		if (!window->priv->print_job->finished)
-			ev_job_queue_remove_job (window->priv->print_job);
+		if (!ev_job_is_finished (window->priv->print_job))
+			ev_job_cancel (window->priv->print_job);
 
 		g_signal_handlers_disconnect_by_func (window->priv->print_job,
 						      ev_window_print_job_cb,
@@ -2349,18 +2358,18 @@
 }
 
 static void
-ev_window_print_job_cb (EvJobPrint *job,
-			EvWindow   *window)
+ev_window_print_job_cb (EvJob    *job,
+			EvWindow *window)
 {
-	if (job->error) {
+	if (ev_job_is_failed (job)) {
 		g_warning ("%s", job->error->message);
 		ev_window_clear_print_job (window);
 		return;
 	}
 
-	g_assert (job->temp_file != NULL);
+	g_assert (EV_JOB_PRINT (job)->temp_file != NULL);
 
-	ev_window_print_send (window, job->temp_file);
+	ev_window_print_send (window, EV_JOB_PRINT (job)->temp_file);
 }
 
 static gboolean
@@ -2494,7 +2503,7 @@
 			  G_CALLBACK (ev_window_print_job_cb),
 			  window);
 	/* The priority doesn't matter for this job */
-	ev_job_queue_add_job (window->priv->print_job, EV_JOB_PRIORITY_LOW);
+	ev_job_scheduler_push_job (window->priv->print_job, EV_JOB_PRIORITY_NONE);
 	
 	gtk_widget_destroy (GTK_WIDGET (dialog));
 	window->priv->print_dialog = NULL;

Modified: trunk/shell/main.c
==============================================================================
--- trunk/shell/main.c	(original)
+++ trunk/shell/main.c	Sun Aug  3 11:01:28 2008
@@ -41,7 +41,6 @@
 #endif
 
 #include "ev-stock-icons.h"
-#include "ev-job-queue.h"
 #include "ev-file-helpers.h"
 #include "ev-backends-manager.h"
 
@@ -391,7 +390,6 @@
 		ev_metadata_manager_init ();
 	}
 
-	ev_job_queue_init ();
 	g_set_application_name (_("Evince Document Viewer"));
 
 	ev_file_helpers_init ();



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