]> www.fi.muni.cz Git - evince.git/commitdiff
Rework the jobs system in order to make it simpler and more extensible. It
authorCarlos Garcia Campos <carlosgc@gnome.org>
Sun, 3 Aug 2008 11:01:28 +0000 (11:01 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Sun, 3 Aug 2008 11:01:28 +0000 (11:01 +0000)
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.

svn path=/trunk/; revision=3092

19 files changed:
ChangeLog
libdocument/ev-document.c
libdocument/ev-document.h
shell/Makefile.am
shell/ev-job-queue.c [deleted file]
shell/ev-job-scheduler.c [new file with mode: 0644]
shell/ev-job-scheduler.h [moved from shell/ev-job-queue.h with 51% similarity]
shell/ev-jobs.c
shell/ev-jobs.h
shell/ev-page-cache.c
shell/ev-pixbuf-cache.c
shell/ev-pixbuf-cache.h
shell/ev-properties-fonts.c
shell/ev-sidebar-links.c
shell/ev-sidebar-thumbnails.c
shell/ev-view-private.h
shell/ev-view.c
shell/ev-window.c
shell/main.c

index efd08f1764e9641cbec220d83041baa81eda7e77..1f45cec09a2fba54a0b8eeb28c013c698cd91b53 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+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. 
+       
 2008-07-27  Carlos Garcia Campos  <carlosgc@gnome.org>
 
        * libdocument/ev-debug.c: (profile_init):
index 7bb86be93db6b54e9fd515d05dd9161d7fb3679a..1171509a3587ec8c29d259671821079c73967bca 100644 (file)
@@ -89,6 +89,12 @@ ev_document_doc_mutex_unlock (void)
        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)
 {
@@ -110,6 +116,12 @@ ev_document_fc_mutex_unlock (void)
        g_mutex_unlock (ev_document_get_fc_mutex ());
 }
 
+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,
index cfcccdbec72be67bbbc090aabf8e4ba8ac1c4358..367d6e6af39a518ab304fc98954c3ef05aeb8e9b 100644 (file)
@@ -101,11 +101,13 @@ GQuark           ev_document_error_quark      (void);
 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,
index 3d857716858fa66c75760a9605d87d7cd4d8e56b..d2c14a9deb6c164650ad0d708a05d1d36e24fb4d 100644 (file)
@@ -28,8 +28,8 @@ evince_SOURCES=                               \
        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               \
diff --git a/shell/ev-job-queue.c b/shell/ev-job-queue.c
deleted file mode 100644 (file)
index 8280aab..0000000
+++ /dev/null
@@ -1,517 +0,0 @@
-#include <config.h>
-#include "ev-job-queue.h"
-
-/* Like glib calling convention, all functions with _locked in their name assume
- * that we've already locked the doc mutex and can freely and safely access
- * data.
- */
-GCond *render_cond = NULL;
-GMutex *ev_queue_mutex = NULL;
-
-static GQueue *links_queue = NULL;
-static GQueue *render_queue_high = NULL;
-static GQueue *render_queue_low = NULL;
-static GQueue *thumbnail_queue_high = NULL;
-static GQueue *thumbnail_queue_low = NULL;
-static GQueue *load_queue = NULL;
-static GQueue *save_queue = NULL;
-static GQueue *fonts_queue = NULL;
-static GQueue *print_queue = NULL;
-
-/* Queues used for backends supporting EvAsyncRender interface,
-   they are executed on the main thread */
-static GQueue *async_render_queue_high = NULL;
-static GQueue *async_render_queue_low = NULL;
-static gboolean async_rendering = FALSE;
-
-static void ev_job_queue_run_next (void);
-
-static gboolean
-remove_job_from_queue_locked (GQueue *queue, EvJob *job)
-{
-       GList *list;
-
-       list = g_queue_find (queue, job);
-       if (list) {
-               g_object_unref (G_OBJECT (job));
-               g_queue_delete_link (queue, list);
-
-               return TRUE;
-       }
-       return FALSE;
-}
-
-static gboolean
-remove_job_from_async_queue (GQueue *queue, EvJob *job)
-{
-       return remove_job_from_queue_locked (queue, job);
-}
-
-static void
-add_job_to_async_queue (GQueue *queue, EvJob *job)
-{
-       g_object_ref (job);
-       g_queue_push_tail (queue, job);
-}
-
-/**
- * add_job_to_queue_locked:
- * @queue: a #GQueue where the #EvJob will be added.
- * @job: an #EvJob to be added to the specified #GQueue.
- *
- * Add the #EvJob to the specified #GQueue and woke up the ev_render_thread who
- * is waiting for render_cond.
- */
-static void
-add_job_to_queue_locked (GQueue *queue,
-                        EvJob  *job)
-{
-       g_object_ref (job);
-       g_queue_push_tail (queue, job);
-       g_cond_broadcast (render_cond);
-}
-
-/**
- * notify_finished:
- * @job: the object that signal will be reseted.
- *
- * It does emit the job finished signal and returns %FALSE.
- *
- * Returns: %FALSE.
- */
-static gboolean
-notify_finished (GObject *job)
-{
-       ev_job_finished (EV_JOB (job));
-
-       return FALSE;
-}
-
-/**
- * job_finished_cb:
- * @job: the #EvJob that has been handled.
- *
- * It does finish the job last work and look if there is any more job to be
- * handled.
- */
-static void
-job_finished_cb (EvJob *job)
-{
-       g_object_unref (job);
-       async_rendering = FALSE;
-       ev_job_queue_run_next ();
-}
-
-/**
- * handle_job:
- * @job: the #EvJob to be handled.
- *
- * First, it does check if the job is async and then it does attend it if
- * possible giving a failed assertion otherwise. If the job isn't async it does
- * attend it and notify that the job has been finished.
- */
-static void
-handle_job (EvJob *job)
-{
-       g_object_ref (G_OBJECT (job));
-
-       if (EV_JOB (job)->async) {
-               async_rendering = TRUE;
-               if (EV_IS_JOB_RENDER (job)) {
-                       g_signal_connect (job, "finished",
-                                         G_CALLBACK (job_finished_cb), NULL);
-               } else {
-                       g_assert_not_reached ();
-               }
-       }
-
-       if (EV_IS_JOB_THUMBNAIL (job))
-               ev_job_thumbnail_run (EV_JOB_THUMBNAIL (job));
-       else if (EV_IS_JOB_LINKS (job))
-               ev_job_links_run (EV_JOB_LINKS (job));
-       else if (EV_IS_JOB_LOAD (job))
-               ev_job_load_run (EV_JOB_LOAD (job));
-       else if (EV_IS_JOB_SAVE (job))
-               ev_job_save_run (EV_JOB_SAVE (job));
-       else if (EV_IS_JOB_RENDER (job))
-               ev_job_render_run (EV_JOB_RENDER (job));
-       else if (EV_IS_JOB_FONTS (job))
-               ev_job_fonts_run (EV_JOB_FONTS (job));
-       else if (EV_IS_JOB_PRINT (job))
-               ev_job_print_run (EV_JOB_PRINT (job));
-
-       if (!EV_JOB (job)->async) {
-               /* We let the idle own a ref, as we (the queue) are done with the job. */
-               g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
-                                (GSourceFunc) notify_finished,
-                                job,
-                                g_object_unref);
-       }
-}
-
-/**
- * search_for_jobs_unlocked:
- *
- * Check if there is any job at the synchronized queues and return any existing
- * job in them taking in account the next priority:
- *
- *  render_queue_high       >
- *  thumbnail_queue_high    >
- *  render_queue_low        >
- *  links_queue             >
- *  load_queue              >
- *  thumbnail_queue_low     >
- *  fonts_queue             >
- *  print_queue             >
- *
- * Returns: an available #EvJob in the queues taking in account stablished queue
- *          priorities.
- */
-static EvJob *
-search_for_jobs_unlocked (void)
-{
-       EvJob *job;
-
-       job = (EvJob *) g_queue_pop_head (render_queue_high);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (thumbnail_queue_high);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (render_queue_low);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (links_queue);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (load_queue);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (save_queue);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (thumbnail_queue_low);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (fonts_queue);
-       if (job)
-               return job;
-
-       job = (EvJob *) g_queue_pop_head (print_queue);
-       if (job)
-               return job;
-
-       return NULL;
-}
-
-/**
- * no_jobs_available_unlocked:
- *
- * Looks if there is any job at render, links, load, thumbnail. fonts and print
- * queues.
- *
- * Returns: %TRUE if the render, links, load, thumbnail, fonts and print queues
- *          are empty, %FALSE in other case.
- */
-static gboolean
-no_jobs_available_unlocked (void)
-{
-       return g_queue_is_empty (render_queue_high)
-               && g_queue_is_empty (render_queue_low)
-               && g_queue_is_empty (links_queue)
-               && g_queue_is_empty (load_queue)
-               && g_queue_is_empty (save_queue)
-               && g_queue_is_empty (thumbnail_queue_high)
-               && g_queue_is_empty (thumbnail_queue_low)
-               && g_queue_is_empty (fonts_queue)
-               && g_queue_is_empty (print_queue);
-}
-
-/* the thread mainloop function */
-/**
- * ev_render_thread:
- * @data: data passed to the thread.
- *
- * The thread mainloop function. It does wait for any available job in synced
- * queues to handle it.
- *
- * Returns: the return value of the thread, which will be returned by
- *          g_thread_join().
- */
-static gpointer
-ev_render_thread (gpointer data)
-{
-       while (TRUE) {
-               EvJob *job;
-
-               g_mutex_lock (ev_queue_mutex);
-               if (no_jobs_available_unlocked ()) {
-                       g_cond_wait (render_cond, ev_queue_mutex);
-               }
-
-               job = search_for_jobs_unlocked ();
-               g_mutex_unlock (ev_queue_mutex);
-
-               /* Now that we have our job, we handle it */
-               if (job) {
-                       handle_job (job);
-                       g_object_unref (G_OBJECT (job));
-               }
-       }
-       return NULL;
-
-}
-
-/**
- * ev_job_queue_run_next:
- *
- * It does look for any job on the render high priority queue first and after
- * in the render low priority one, and then it does handle it.
- */
-static void
-ev_job_queue_run_next (void)
-{
-       EvJob *job;
-
-       job = (EvJob *) g_queue_pop_head (async_render_queue_high);
-
-       if (job == NULL) {
-               job = (EvJob *) g_queue_pop_head (async_render_queue_low);
-       }
-
-       /* Now that we have our job, we handle it */
-       if (job) {
-               handle_job (job);
-               g_object_unref (G_OBJECT (job));
-       }
-}
-
-/* Public Functions */
-/**
- * ev_job_queue_init:
- *
- * Creates a new cond, new mutex, a thread for evince job handling and inits
- * every queue.
- */
-void
-ev_job_queue_init (void)
-{
-       if (!g_thread_supported ()) g_thread_init (NULL);
-
-       render_cond = g_cond_new ();
-       ev_queue_mutex = g_mutex_new ();
-
-       links_queue = g_queue_new ();
-       load_queue = g_queue_new ();
-       save_queue = g_queue_new ();
-       render_queue_high = g_queue_new ();
-       render_queue_low = g_queue_new ();
-       async_render_queue_high = g_queue_new ();
-       async_render_queue_low = g_queue_new ();
-       thumbnail_queue_high = g_queue_new ();
-       thumbnail_queue_low = g_queue_new ();
-       fonts_queue = g_queue_new ();
-       print_queue = g_queue_new ();
-
-       g_thread_create (ev_render_thread, NULL, FALSE, NULL);
-
-}
-
-static GQueue *
-find_queue (EvJob         *job,
-           EvJobPriority  priority)
-{
-       if (EV_JOB (job)->async) {
-               if (EV_IS_JOB_RENDER (job)) {
-                       if (priority == EV_JOB_PRIORITY_HIGH)
-                               return async_render_queue_high;
-                       else
-                               return async_render_queue_low;
-               }
-       } else {
-               if (EV_IS_JOB_RENDER (job)) {
-                       if (priority == EV_JOB_PRIORITY_HIGH)
-                               return render_queue_high;
-                       else
-                               return render_queue_low;
-               } else if (EV_IS_JOB_THUMBNAIL (job)) {
-                       if (priority == EV_JOB_PRIORITY_HIGH)
-                               return thumbnail_queue_high;
-                       else
-                               return thumbnail_queue_low;
-               } else if (EV_IS_JOB_LOAD (job)) {
-                       /* the priority doesn't effect load */
-                       return load_queue;
-               } else if (EV_IS_JOB_SAVE (job)) {
-                       /* the priority doesn't effect save */
-                       return save_queue;
-               } else if (EV_IS_JOB_LINKS (job)) {
-                       /* the priority doesn't effect links */
-                       return links_queue;
-               } else if (EV_IS_JOB_FONTS (job)) {
-                       /* the priority doesn't effect fonts */
-                       return fonts_queue;
-               } else if (EV_IS_JOB_PRINT (job)) {
-                       /* the priority doesn't effect print */
-                       return print_queue;
-               }
-       }
-
-       g_assert_not_reached ();
-       return NULL;
-}
-
-void
-ev_job_queue_add_job (EvJob         *job,
-                     EvJobPriority  priority)
-{
-       GQueue *queue;
-
-       g_return_if_fail (EV_IS_JOB (job));
-
-       queue = find_queue (job, priority);
-
-       if (!EV_JOB (job)->async) {
-               g_mutex_lock (ev_queue_mutex);
-               add_job_to_queue_locked (queue, job);
-               g_mutex_unlock (ev_queue_mutex);
-       } else {
-               add_job_to_async_queue (queue, job);
-               if (!async_rendering) {
-                       ev_job_queue_run_next ();
-               }
-       }
-}
-
-static gboolean
-move_job_async (EvJob *job, GQueue *old_queue, GQueue *new_queue)
-{
-       gboolean retval = FALSE;
-
-       g_object_ref (job);
-
-       if (remove_job_from_queue_locked (old_queue, job)) {
-               add_job_to_async_queue (new_queue, job);
-               retval = TRUE;
-       }
-
-       g_object_unref (job);
-
-       return retval;
-}
-
-static gboolean
-move_job (EvJob *job, GQueue *old_queue, GQueue *new_queue)
-{
-       gboolean retval = FALSE;
-
-       g_mutex_lock (ev_queue_mutex);
-       g_object_ref (job);
-
-       if (remove_job_from_queue_locked (old_queue, job)) {
-               add_job_to_queue_locked (new_queue, job);
-               retval = TRUE;
-       }
-
-       g_object_unref (job);
-       g_mutex_unlock (ev_queue_mutex);
-
-       return retval;
-}
-
-gboolean
-ev_job_queue_update_job (EvJob         *job,
-                        EvJobPriority  new_priority)
-{
-       gboolean retval = FALSE;
-       
-       g_return_val_if_fail (EV_IS_JOB (job), FALSE);
-
-       if (EV_JOB (job)->async) {
-               if (EV_IS_JOB_RENDER (job)) {
-                       if (new_priority == EV_JOB_PRIORITY_LOW) {
-                               retval = move_job_async (job, async_render_queue_high,
-                                                        async_render_queue_low);
-                       } else if (new_priority == EV_JOB_PRIORITY_HIGH) {
-                               retval = move_job_async (job, async_render_queue_low,
-                                                        async_render_queue_high);
-                       }
-               } else {
-                       g_assert_not_reached ();
-               }
-       } else {
-               if (EV_IS_JOB_THUMBNAIL (job)) {
-                       if (new_priority == EV_JOB_PRIORITY_LOW) {
-                               retval = move_job (job, thumbnail_queue_high,
-                                                  thumbnail_queue_low);
-                       } else if (new_priority == EV_JOB_PRIORITY_HIGH) {
-                               retval = move_job (job, thumbnail_queue_low,
-                                                  thumbnail_queue_high);
-                       }
-               } else if (EV_IS_JOB_RENDER (job)) {
-                       if (new_priority == EV_JOB_PRIORITY_LOW) {
-                               retval = move_job (job, render_queue_high,
-                                                  render_queue_low);
-                       } else if (new_priority == EV_JOB_PRIORITY_HIGH) {
-                               retval = move_job (job, render_queue_low,
-                                                  render_queue_high);
-                       }
-               } else {
-                       g_assert_not_reached ();
-               }
-       }       
-
-       return retval;
-}
-
-gboolean
-ev_job_queue_remove_job (EvJob *job)
-{
-       gboolean retval = FALSE;
-
-       g_return_val_if_fail (EV_IS_JOB (job), FALSE);
-
-       if (EV_JOB (job)->async) {
-               if (EV_IS_JOB_RENDER (job)) {
-                       retval = remove_job_from_async_queue (async_render_queue_high, job);
-                       retval = retval || remove_job_from_async_queue (async_render_queue_low, job);
-               } else {
-                       g_assert_not_reached ();
-               }
-       } else {
-               g_mutex_lock (ev_queue_mutex);
-
-               if (EV_IS_JOB_THUMBNAIL (job)) {
-                       retval = remove_job_from_queue_locked (thumbnail_queue_high, job);
-                       retval = retval || remove_job_from_queue_locked (thumbnail_queue_low, job);
-               } else if (EV_IS_JOB_RENDER (job)) {
-                       retval = remove_job_from_queue_locked (render_queue_high, job);
-                       retval = retval || remove_job_from_queue_locked (render_queue_low, job);
-               } else if (EV_IS_JOB_LINKS (job)) {
-                       retval = remove_job_from_queue_locked (links_queue, job);
-               } else if (EV_IS_JOB_LOAD (job)) {
-                       retval = remove_job_from_queue_locked (load_queue, job);
-               } else if (EV_IS_JOB_SAVE (job)) {
-                       retval = remove_job_from_queue_locked (save_queue, job);
-               } else if (EV_IS_JOB_FONTS (job)) {
-                       retval = remove_job_from_queue_locked (fonts_queue, job);
-               } else if (EV_IS_JOB_PRINT (job)) {
-                       retval = remove_job_from_queue_locked (print_queue, job);
-               } else {
-                       g_assert_not_reached ();
-               }
-
-               g_mutex_unlock (ev_queue_mutex);
-       }
-       
-       return retval;
-}
-
-
diff --git a/shell/ev-job-scheduler.c b/shell/ev-job-scheduler.c
new file mode 100644 (file)
index 0000000..900714e
--- /dev/null
@@ -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);
+       }
+}
+
similarity index 51%
rename from shell/ev-job-queue.h
rename to shell/ev-job-scheduler.h
index e6e4c0ef6ee063f93e6ced387f5f8ef95981895c..66f9f80c5ddd2ec36791000d9c32a39db117d6fb 100644 (file)
@@ -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
  * 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
 
+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_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);
+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 */
index 196bad682a2e7c4445cbf522d3bf49f864a923f5..7371dd1a0eb69a15f78ecc83cc53531209dc837f 100644 (file)
@@ -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_init           (EvJobPrint          *job);
 static void ev_job_print_class_init     (EvJobPrintClass     *class);
 
 enum {
+       CANCELLED,
        FINISHED,
        LAST_SIGNAL
 };
@@ -43,10 +64,16 @@ enum {
        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 (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)
 
-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 @@ ev_job_dispose (GObject *object)
                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 @@ ev_job_class_init (EvJobClass *class)
 
        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 @@ ev_job_links_dispose (GObject *object)
        (* 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 @@ ev_job_render_dispose (GObject *object)
        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 @@ ev_job_render_dispose (GObject *object)
        (* 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;
-
-       ev_debug_message (DEBUG_JOBS, NULL);
-       
-       job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
-       job->document = g_object_ref (document);
-
-       return job;
-}
+       GObjectClass *oclass = G_OBJECT_CLASS (class);
+       EvJobClass   *job_class = EV_JOB_CLASS (class);
 
-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 @@ ev_job_render_new (EvDocument   *document,
        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 @@ ev_job_render_set_selection_info (EvJobRender     *job,
        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 @@ ev_job_thumbnail_new (EvDocument *document,
        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_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
+}
 
-       ev_debug_message (DEBUG_JOBS, "%d", job->page);
-       ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+static gboolean
+ev_job_fonts_run (EvJob *job)
+{
+       EvJobFonts      *job_fonts = EV_JOB_FONTS (job);
+       EvDocumentFonts *fonts = EV_DOCUMENT_FONTS (job->document);
+
+       ev_debug_message (DEBUG_JOBS, NULL);
+       
+       /* Do not block the main loop */
+       if (!ev_document_doc_mutex_trylock ())
+               return TRUE;
        
-       g_return_if_fail (EV_IS_JOB_THUMBNAIL (job));
+       if (!ev_document_fc_mutex_trylock ())
+               return TRUE;
 
-       ev_document_doc_mutex_lock ();
+#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
 
-       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);
+       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 @@ ev_job_fonts_new (EvDocument *document)
        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 @@ ev_job_load_dispose (GObject *object)
                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 @@ ev_job_load_dispose (GObject *object)
        (* 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 @@ ev_job_load_new (const gchar    *uri,
        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 @@ ev_job_load_set_uri (EvJobLoad *job, const gchar *uri)
        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 @@ ev_job_save_dispose (GObject *object)
                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 @@ ev_job_save_run (EvJobSave *job)
                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 @@ ev_job_save_run (EvJobSave *job)
 
        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 @@ ev_job_print_get_page_list (EvJobPrint *job,
        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 @@ ev_job_print_run (EvJobPrint *job)
        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 @@ ev_job_print_run (EvJobPrint *job)
                        page += step;
                }
 
-               if (!job->collate)
+               if (!job_print->collate)
                        break;
        }
 
@@ -1039,5 +1214,64 @@ ev_job_print_run (EvJobPrint *job)
        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);
 }
+
index c63a32c449408d885d209c32ce3732b272219268..c0f95721de8b0898bd72b16ded779520cd6d25de 100644 (file)
@@ -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 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
 #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 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
 #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 _EvJobFonts
 struct _EvJobFontsClass
 {
         EvJobClass parent_class;
+
+       /* Signals */
+       void (* updated)  (EvJobFonts *job);
 };
 
 struct _EvJobLoad
@@ -203,7 +223,6 @@ struct _EvJobLoad
        EvLinkDest *dest;
        EvWindowRunMode mode;
        gchar *search_string;
-       GError *error;
        gchar *uri;
 };
 
@@ -216,7 +235,6 @@ struct _EvJobSave
 {
        EvJob parent;
 
-       GError *error;
        gchar *uri;
        gchar *document_uri;
 };
@@ -230,7 +248,6 @@ struct _EvJobPrint
 {
        EvJob parent;
 
-       GError *error;
        const gchar *format;
        gchar  *temp_file;
        EvPrintRange *ranges;
@@ -251,12 +268,26 @@ struct _EvJobPrintClass
 
 /* 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 @@ void     ev_job_render_set_selection_info (EvJobRender     *job,
                                           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 @@ EvJob            *ev_job_load_new           (const gchar     *uri,
                                           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 @@ EvJob          *ev_job_print_new          (EvDocument      *document,
                                           gint             copies,
                                           gdouble          collate,
                                           gdouble          reverse);
-void            ev_job_print_run          (EvJobPrint      *print);
 
 G_END_DECLS
 
index 8b8bedc971355c6479450818d729c8af0a2a6352..bbddbbc0882e4d33e49f108a29be0e8fb36c6559 100644 (file)
@@ -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>
index 25b6f2cf883dfc3631d0c64c78a717ee73144880..91c24780aa6a542501b0fa1ec622b40550991c5e 100644 (file)
@@ -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 @@ dispose_cache_job_info (CacheJobInfo *job_info,
                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 @@ check_job_size_and_unref (EvPixbufCache *pixbuf_cache,
        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 @@ move_one_job (CacheJobInfo  *job_info,
              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 @@ move_one_job (CacheJobInfo  *job_info,
                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 @@ move_one_job (CacheJobInfo  *job_info,
        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 @@ ev_pixbuf_cache_update_range (EvPixbufCache *pixbuf_cache,
                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 @@ copy_job_to_job_info (EvJobRender   *job_render,
                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 @@ add_job (EvPixbufCache *pixbuf_cache,
                                                  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 @@ ev_pixbuf_cache_add_jobs_if_needed (EvPixbufCache *pixbuf_cache,
 
                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 @@ ev_pixbuf_cache_reload_page (EvPixbufCache *pixbuf_cache,
 
         add_job (pixbuf_cache, job_info, page_cache, region,
                 width, height, page, rotation, scale,
-                EV_JOB_PRIORITY_HIGH);
+                EV_JOB_PRIORITY_URGENT);
 }
 
 
index ed1c1ec9885c54b8f25703327577c1411f825130..0b65bf8cba24f1cee6c87c28a9e69ea260987704 100644 (file)
@@ -27,7 +27,6 @@
 #include <gtk/gtkwidget.h>
 #include "ev-document.h"
 #include "ev-selection.h"
-#include "ev-job-queue.h"
 
 G_BEGIN_DECLS
 
index 54ed063d15eb6be900bfb521746034a0b949d129..385cda10ba4462058c03f8c170167b9e2da75a92 100644 (file)
@@ -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 @@ ev_properties_fonts_dispose (GObject *object)
        }
        
        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 @@ update_progress_label (GtkWidget *label, double progress)
 
 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 @@ ev_properties_fonts_set_document (EvPropertiesFonts *properties,
        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 *
index f623f1e2174ead95a538e7510cc1f827508d585f..1389edd46e10fca8b842e1e79bbc6d31c49e730f 100644 (file)
@@ -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 @@ ev_sidebar_links_dispose (GObject *object)
        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 @@ ev_sidebar_links_set_document (EvSidebarPage  *sidebar_page,
                          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
index 74b4ab73d00b1609f8fc28674e0a892c9dda10d4..7fe62f16c065ca3c280d3fbe44fcefd879b04e9d 100644 (file)
@@ -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 @@ clear_range (EvSidebarThumbnails *sidebar_thumbnails,
 
                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 @@ add_range (EvSidebarThumbnails *sidebar_thumbnails,
                        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 @@ ev_sidebar_thumbnails_set_document (EvSidebarPage   *sidebar_page,
 
 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 @@ ev_sidebar_thumbnails_clear_job (GtkTreeModel *model,
        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);
        }
index 3e72e82af6482a783cdc285ce76c31b5e39ea619..1618417d084f16c9837eee7e0c6dcf41367ab430 100644 (file)
@@ -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"
index bc3cb980daf295efb03aad5d20d5f0fb6b504b65..49b604b08322518a3a849370a3742a88859698d0 100644 (file)
@@ -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"
index 7d08ebf4704c367bbf50ce6c36646e4c71286df8..4c312ea408167c11e843cdd344c717c2e1cf37e0 100644 (file)
@@ -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 @@ static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_si
                                                         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 @@ static void
 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 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation)
        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 @@ password_dialog_response (GtkWidget *password_dialog,
                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 @@ static void
 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 @@ static void
 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 @@ ev_window_clear_temp_file (EvWindow *ev_window)
  * 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_load_job_cb  (EvJobLoad *job,
                        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 @@ ev_window_load_job_cb  (EvJobLoad *job,
                                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 @@ ev_window_load_job_cb  (EvJobLoad *job,
 
                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 @@ ev_window_load_job_cb  (EvJobLoad *job,
 }
 
 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 @@ window_open_file_copy_ready_cb (GFile        *source,
        
        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_open_uri (EvWindow       *ev_window,
                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 @@ ev_window_reload_document (EvWindow *ev_window)
        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 @@ static void
 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 @@ ev_window_clear_save_job (EvWindow *ev_window)
 }
 
 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 @@ file_save_dialog_response_cb (GtkWidget *fc,
                          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 @@ static void
 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 @@ ev_window_print_send (EvWindow    *window,
 }
 
 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 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
                          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;
index f230ea860b9177835fdfeef7568f7ea6502e3df8..eb5c08ab1b7c654e619661d4120982de039258dd 100644 (file)
@@ -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 @@ main (int argc, char *argv[])
                ev_metadata_manager_init ();
        }
 
-       ev_job_queue_init ();
        g_set_application_name (_("Evince Document Viewer"));
 
        ev_file_helpers_init ();