evince r3092 - in trunk: . libdocument shell
- From: carlosgc svn gnome org
- To: svn-commits-list gnome org
- Subject: evince r3092 - in trunk: . libdocument shell
- Date: Sun, 3 Aug 2008 11:01:29 +0000 (UTC)
Author: carlosgc
Date: Sun Aug 3 11:01:28 2008
New Revision: 3092
URL: http://svn.gnome.org/viewvc/evince?rev=3092&view=rev
Log:
2008-08-03 Carlos Garcia Campos <carlosgc gnome org>
* libdocument/ev-document.[ch]: (ev_document_doc_mutex_trylock),
(ev_document_fc_mutex_trylock):
* shell/Makefile.am:
* shell/ev-job-queue.[ch]:
* shell/ev-job-scheduler.[ch]:
* shell/ev-jobs.[ch]: (ev_job_init), (ev_job_dispose),
(ev_job_class_init), (emit_finished), (ev_job_emit_finished),
(ev_job_run), (ev_job_cancel), (ev_job_failed),
(ev_job_failed_from_error), (ev_job_succeeded),
(ev_job_is_finished), (ev_job_is_failed), (ev_job_get_run_mode),
(ev_job_set_run_mode), (ev_job_links_init), (ev_job_links_run),
(ev_job_links_class_init), (ev_job_render_init),
(notify_page_ready), (ev_job_render_page_ready),
(ev_job_render_run), (ev_job_render_class_init),
(ev_job_thumbnail_init), (ev_job_thumbnail_run),
(ev_job_thumbnail_class_init), (ev_job_fonts_init),
(ev_job_fonts_run), (ev_job_fonts_class_init), (ev_job_load_init),
(ev_job_load_run), (ev_job_load_class_init), (ev_job_save_init),
(ev_job_save_dispose), (ev_job_save_run),
(ev_job_save_class_init), (ev_job_print_init),
(ev_job_print_dispose), (ev_job_print_run),
(ev_job_print_class_init):
* shell/ev-page-cache.c:
* shell/ev-pixbuf-cache.[ch]: (dispose_cache_job_info),
(check_job_size_and_unref), (move_one_job),
(copy_job_to_job_info), (add_job),
(ev_pixbuf_cache_add_jobs_if_needed):
* shell/ev-properties-fonts.c: (ev_properties_fonts_dispose),
(job_fonts_finished_cb), (job_fonts_updated_cb),
(ev_properties_fonts_set_document):
* shell/ev-sidebar-links.c: (ev_sidebar_links_dispose),
(ev_sidebar_links_set_document):
* shell/ev-sidebar-thumbnails.c: (clear_range), (add_range),
(ev_sidebar_thumbnails_set_document),
(ev_sidebar_thumbnails_clear_job):
* shell/ev-view-private.h:
* shell/ev-view.c:
* shell/ev-window.c: (ev_window_clear_thumbnail_job),
(ev_window_refresh_window_thumbnail), (password_dialog_response),
(ev_window_clear_load_job), (ev_window_clear_reload_job),
(ev_window_load_job_cb), (ev_window_reload_job_cb),
(window_open_file_copy_ready_cb), (ev_window_open_uri),
(ev_window_reload_document), (ev_window_clear_save_job),
(ev_window_save_job_cb), (file_save_dialog_response_cb),
(ev_window_clear_print_job), (ev_window_print_job_cb),
(ev_window_print_dialog_response_cb):
* shell/main.c: (main):
Rework the jobs system in order to make it simpler and more
extensible. It allows to run jobs in the main loop instead of
using a thread when it's appropriate like the fonts job. Now it's
also possible to cancel jobs that are currently running.
Added:
trunk/shell/ev-job-scheduler.c
trunk/shell/ev-job-scheduler.h
- copied, changed from r3091, /trunk/shell/ev-job-queue.h
Removed:
trunk/shell/ev-job-queue.c
trunk/shell/ev-job-queue.h
Modified:
trunk/ChangeLog
trunk/libdocument/ev-document.c
trunk/libdocument/ev-document.h
trunk/shell/Makefile.am
trunk/shell/ev-jobs.c
trunk/shell/ev-jobs.h
trunk/shell/ev-page-cache.c
trunk/shell/ev-pixbuf-cache.c
trunk/shell/ev-pixbuf-cache.h
trunk/shell/ev-properties-fonts.c
trunk/shell/ev-sidebar-links.c
trunk/shell/ev-sidebar-thumbnails.c
trunk/shell/ev-view-private.h
trunk/shell/ev-view.c
trunk/shell/ev-window.c
trunk/shell/main.c
Modified: trunk/libdocument/ev-document.c
==============================================================================
--- trunk/libdocument/ev-document.c (original)
+++ trunk/libdocument/ev-document.c Sun Aug 3 11:01:28 2008
@@ -89,6 +89,12 @@
g_mutex_unlock (ev_document_get_doc_mutex ());
}
+gboolean
+ev_document_doc_mutex_trylock (void)
+{
+ return g_mutex_trylock (ev_document_get_doc_mutex ());
+}
+
GMutex *
ev_document_get_fc_mutex (void)
{
@@ -111,6 +117,12 @@
}
gboolean
+ev_document_fc_mutex_trylock (void)
+{
+ return g_mutex_trylock (ev_document_get_fc_mutex ());
+}
+
+gboolean
ev_document_load (EvDocument *document,
const char *uri,
GError **error)
Modified: trunk/libdocument/ev-document.h
==============================================================================
--- trunk/libdocument/ev-document.h (original)
+++ trunk/libdocument/ev-document.h Sun Aug 3 11:01:28 2008
@@ -101,11 +101,13 @@
GMutex *ev_document_get_doc_mutex (void);
void ev_document_doc_mutex_lock (void);
void ev_document_doc_mutex_unlock (void);
+gboolean ev_document_doc_mutex_trylock(void);
/* FontConfig mutex */
GMutex *ev_document_get_fc_mutex (void);
void ev_document_fc_mutex_lock (void);
void ev_document_fc_mutex_unlock (void);
+gboolean ev_document_fc_mutex_trylock (void);
EvDocumentInfo *ev_document_get_info (EvDocument *document);
gboolean ev_document_load (EvDocument *document,
Modified: trunk/shell/Makefile.am
==============================================================================
--- trunk/shell/Makefile.am (original)
+++ trunk/shell/Makefile.am Sun Aug 3 11:01:28 2008
@@ -28,8 +28,8 @@
eggfindbar.h \
ev-application.c \
ev-application.h \
- ev-job-queue.h \
- ev-job-queue.c \
+ ev-job-scheduler.h \
+ ev-job-scheduler.c \
ev-jobs.h \
ev-jobs.c \
ev-file-monitor.h \
Added: trunk/shell/ev-job-scheduler.c
==============================================================================
--- (empty file)
+++ trunk/shell/ev-job-scheduler.c Sun Aug 3 11:01:28 2008
@@ -0,0 +1,305 @@
+/* ev-job-scheduler.c
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ev-debug.h"
+#include "ev-job-scheduler.h"
+
+typedef struct _EvSchedulerJob {
+ EvJob *job;
+ EvJobPriority priority;
+ GSList *job_link;
+} EvSchedulerJob;
+
+G_LOCK_DEFINE_STATIC(job_list);
+static GSList *job_list = NULL;
+
+static gpointer ev_job_thread_proxy (gpointer data);
+static void ev_scheduler_thread_job_cancelled (EvSchedulerJob *job,
+ GCancellable *cancellable);
+
+/* EvJobQueue */
+static GQueue queue_urgent = G_QUEUE_INIT;
+static GQueue queue_high = G_QUEUE_INIT;
+static GQueue queue_low = G_QUEUE_INIT;
+static GQueue queue_none = G_QUEUE_INIT;
+
+static GCond *job_queue_cond = NULL;
+static GMutex *job_queue_mutex = NULL;
+static GQueue *job_queue[EV_JOB_N_PRIORITIES] = {
+ &queue_urgent,
+ &queue_high,
+ &queue_low,
+ &queue_none
+};
+
+static void
+ev_job_queue_push (EvSchedulerJob *job,
+ EvJobPriority priority)
+{
+ ev_debug_message (DEBUG_JOBS, "%s priority %d", EV_GET_TYPE_NAME (job->job), priority);
+
+ g_mutex_lock (job_queue_mutex);
+
+ g_queue_push_tail (job_queue[priority], job);
+ g_cond_broadcast (job_queue_cond);
+
+ g_mutex_unlock (job_queue_mutex);
+}
+
+static EvSchedulerJob *
+ev_job_queue_get_next_unlocked (void)
+{
+ gint i;
+ EvSchedulerJob *job = NULL;
+
+ for (i = EV_JOB_PRIORITY_URGENT; i < EV_JOB_N_PRIORITIES; i++) {
+ job = (EvSchedulerJob *) g_queue_pop_head (job_queue[i]);
+ if (job)
+ break;
+ }
+
+ ev_debug_message (DEBUG_JOBS, "%s", job ? EV_GET_TYPE_NAME (job->job) : "No jobs in queue");
+
+ return job;
+}
+
+static gpointer
+ev_job_scheduler_init (gpointer data)
+{
+ job_queue_cond = g_cond_new ();
+ job_queue_mutex = g_mutex_new ();
+ g_thread_create (ev_job_thread_proxy, NULL, FALSE, NULL);
+
+ return NULL;
+}
+
+static void
+ev_scheduler_job_list_add (EvSchedulerJob *job)
+{
+ ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+
+ G_LOCK (job_list);
+
+ job_list = g_slist_prepend (job_list, job);
+ job->job_link = job_list;
+
+ G_UNLOCK (job_list);
+}
+
+static void
+ev_scheduler_job_list_remove (EvSchedulerJob *job)
+{
+ ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+
+ G_LOCK (job_list);
+
+ job_list = g_slist_delete_link (job_list, job->job_link);
+
+ G_UNLOCK (job_list);
+}
+
+static void
+ev_scheduler_job_free (EvSchedulerJob *job)
+{
+ if (!job)
+ return;
+
+ g_object_unref (job->job);
+ g_free (job);
+}
+
+static void
+ev_scheduler_job_destroy (EvSchedulerJob *job)
+{
+ ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+
+ if (job->job->run_mode == EV_JOB_RUN_MAIN_LOOP) {
+ g_signal_handlers_disconnect_by_func (job->job,
+ G_CALLBACK (ev_scheduler_job_destroy),
+ job);
+ } else {
+ g_signal_handlers_disconnect_by_func (job->job->cancellable,
+ G_CALLBACK (ev_scheduler_thread_job_cancelled),
+ job);
+ }
+
+ ev_scheduler_job_list_remove (job);
+ ev_scheduler_job_free (job);
+}
+
+static void
+ev_scheduler_thread_job_cancelled (EvSchedulerJob *job,
+ GCancellable *cancellable)
+{
+ GList *list;
+
+ ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job->job));
+
+ g_mutex_lock (job_queue_mutex);
+
+ /* If the job is not still running,
+ * remove it from the job queue and job list.
+ * If the job is currently running, it will be
+ * destroyed as soon as it finishes.
+ */
+ list = g_queue_find (job_queue[job->priority], job);
+ if (list) {
+ g_queue_delete_link (job_queue[job->priority], list);
+ g_mutex_unlock (job_queue_mutex);
+ ev_scheduler_job_destroy (job);
+ } else {
+ g_mutex_unlock (job_queue_mutex);
+ }
+}
+
+static void
+ev_job_thread (EvJob *job)
+{
+ gboolean result;
+
+ ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job));
+
+ do {
+ if (g_cancellable_is_cancelled (job->cancellable))
+ result = FALSE;
+ else
+ result = ev_job_run (job);
+ } while (result);
+}
+
+static gboolean
+ev_job_idle (EvJob *job)
+{
+ ev_debug_message (DEBUG_JOBS, "%s", EV_GET_TYPE_NAME (job));
+
+ if (g_cancellable_is_cancelled (job->cancellable))
+ return FALSE;
+
+ return ev_job_run (job);
+}
+
+static gpointer
+ev_job_thread_proxy (gpointer data)
+{
+ while (TRUE) {
+ EvSchedulerJob *job;
+
+ g_mutex_lock (job_queue_mutex);
+ job = ev_job_queue_get_next_unlocked ();
+ if (!job) {
+ g_cond_wait (job_queue_cond, job_queue_mutex);
+ g_mutex_unlock (job_queue_mutex);
+ continue;
+ }
+ g_mutex_unlock (job_queue_mutex);
+
+ ev_job_thread (job->job);
+ ev_scheduler_job_destroy (job);
+ }
+
+ return NULL;
+}
+
+void
+ev_job_scheduler_push_job (EvJob *job,
+ EvJobPriority priority)
+{
+ static GOnce once_init = G_ONCE_INIT;
+ EvSchedulerJob *s_job;
+
+ g_once (&once_init, ev_job_scheduler_init, NULL);
+
+ ev_debug_message (DEBUG_JOBS, "%s pirority %d", EV_GET_TYPE_NAME (job), priority);
+
+ s_job = g_new0 (EvSchedulerJob, 1);
+ s_job->job = g_object_ref (job);
+ s_job->priority = priority;
+
+ ev_scheduler_job_list_add (s_job);
+
+ switch (ev_job_get_run_mode (job)) {
+ case EV_JOB_RUN_THREAD:
+ g_signal_connect_swapped (job->cancellable, "cancelled",
+ G_CALLBACK (ev_scheduler_thread_job_cancelled),
+ s_job);
+ ev_job_queue_push (s_job, priority);
+ break;
+ case EV_JOB_RUN_MAIN_LOOP:
+ g_signal_connect_swapped (job, "finished",
+ G_CALLBACK (ev_scheduler_job_destroy),
+ s_job);
+ g_signal_connect_swapped (job, "cancelled",
+ G_CALLBACK (ev_scheduler_job_destroy),
+ s_job);
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc)ev_job_idle,
+ g_object_ref (job),
+ (GDestroyNotify)g_object_unref);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+void
+ev_job_scheduler_update_job (EvJob *job,
+ EvJobPriority priority)
+{
+ GSList *l;
+ EvSchedulerJob *s_job = NULL;
+ gboolean need_resort = FALSE;
+
+ /* Main loop jobs are scheduled inmediately */
+ if (ev_job_get_run_mode (job) == EV_JOB_RUN_MAIN_LOOP)
+ return;
+
+ ev_debug_message (DEBUG_JOBS, "%s pirority %d", EV_GET_TYPE_NAME (job), priority);
+
+ G_LOCK (job_list);
+
+ for (l = job_list; l; l = l->next) {
+ s_job = (EvSchedulerJob *)l->data;
+
+ if (s_job->job == job) {
+ need_resort = (s_job->priority != priority);
+ break;
+ }
+ }
+
+ G_UNLOCK (job_list);
+
+ if (need_resort) {
+ GList *list;
+
+ g_mutex_lock (job_queue_mutex);
+
+ list = g_queue_find (job_queue[s_job->priority], s_job);
+ if (list) {
+ ev_debug_message (DEBUG_JOBS, "Moving job %s from pirority %d to %d",
+ EV_GET_TYPE_NAME (job), s_job->priority, priority);
+ g_queue_delete_link (job_queue[s_job->priority], list);
+ g_queue_push_tail (job_queue[priority], s_job);
+ g_cond_broadcast (job_queue_cond);
+ }
+
+ g_mutex_unlock (job_queue_mutex);
+ }
+}
+
Copied: trunk/shell/ev-job-scheduler.h (from r3091, /trunk/shell/ev-job-queue.h)
==============================================================================
--- /trunk/shell/ev-job-queue.h (original)
+++ trunk/shell/ev-job-scheduler.h Sun Aug 3 11:01:28 2008
@@ -1,6 +1,7 @@
-/* this file is part of evince, a gnome document viewer
+/* ev-job-scheduler.h
+ * this file is part of evince, a gnome document viewer
*
- * Copyright (C) 2005 Red Hat, Inc
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
*
* Evince is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
@@ -17,23 +18,27 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifndef __EV_JOB_QUEUE_H__
-#define __EV_JOB_QUEUE_H__
+#ifndef EV_JOB_SCHEDULER_H
+#define EV_JOB_SCHEDULER_H
-#include <gtk/gtk.h>
+#include <glib.h>
#include "ev-jobs.h"
G_BEGIN_DECLS
-
-void ev_job_queue_init (void);
-
-void ev_job_queue_add_job (EvJob *job,
- EvJobPriority priority);
-gboolean ev_job_queue_update_job (EvJob *job,
- EvJobPriority new_priority);
-gboolean ev_job_queue_remove_job (EvJob *job);
+typedef enum {
+ EV_JOB_PRIORITY_URGENT, /* Rendering current page range */
+ EV_JOB_PRIORITY_HIGH, /* Rendering current thumbnail range */
+ EV_JOB_PRIORITY_LOW, /* Rendering pages not in current range */
+ EV_JOB_PRIORITY_NONE, /* Any other job: load, save, print, ... */
+ EV_JOB_N_PRIORITIES
+} EvJobPriority;
+
+void ev_job_scheduler_push_job (EvJob *job,
+ EvJobPriority priority);
+void ev_job_scheduler_update_job (EvJob *job,
+ EvJobPriority priority);
G_END_DECLS
-#endif /* __EV_JOB_QUEUE_H__ */
+#endif /* EV_JOB_SCHEDULER_H */
Modified: trunk/shell/ev-jobs.c
==============================================================================
--- trunk/shell/ev-jobs.c (original)
+++ trunk/shell/ev-jobs.c Sun Aug 3 11:01:28 2008
@@ -1,6 +1,26 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
+ * Copyright (C) 2005 Red Hat, Inc
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
#include <config.h>
+
#include "ev-jobs.h"
-#include "ev-job-queue.h"
#include "ev-document-thumbnails.h"
#include "ev-document-links.h"
#include "ev-document-images.h"
@@ -34,6 +54,7 @@
static void ev_job_print_class_init (EvJobPrintClass *class);
enum {
+ CANCELLED,
FINISHED,
LAST_SIGNAL
};
@@ -43,10 +64,16 @@
RENDER_LAST_SIGNAL
};
+enum {
+ UPDATED,
+ FONTS_LAST_SIGNAL
+};
+
static guint job_signals[LAST_SIGNAL] = { 0 };
static guint job_render_signals[RENDER_LAST_SIGNAL] = { 0 };
+static guint job_fonts_signals[FONTS_LAST_SIGNAL] = { 0 };
-G_DEFINE_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
@@ -55,7 +82,12 @@
G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobPrint, ev_job_print, EV_TYPE_JOB)
-static void ev_job_init (EvJob *job) { /* Do Nothing */ }
+/* EvJob */
+static void
+ev_job_init (EvJob *job)
+{
+ job->cancellable = g_cancellable_new ();
+}
static void
ev_job_dispose (GObject *object)
@@ -69,6 +101,16 @@
job->document = NULL;
}
+ if (job->cancellable) {
+ g_object_unref (job->cancellable);
+ job->cancellable = NULL;
+ }
+
+ if (job->error) {
+ g_error_free (job->error);
+ job->error = NULL;
+ }
+
(* G_OBJECT_CLASS (ev_job_parent_class)->dispose) (object);
}
@@ -81,18 +123,173 @@
oclass->dispose = ev_job_dispose;
+ job_signals[CANCELLED] =
+ g_signal_new ("cancelled",
+ EV_TYPE_JOB,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvJobClass, cancelled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
job_signals [FINISHED] =
g_signal_new ("finished",
EV_TYPE_JOB,
- G_SIGNAL_RUN_LAST,
+ G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EvJobClass, finished),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
+static gboolean
+emit_finished (EvJob *job)
+{
+ ev_debug_message (DEBUG_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-static void ev_job_links_init (EvJobLinks *job) { /* Do Nothing */ }
+ job->idle_finished_id = 0;
+
+ if (job->cancelled) {
+ ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit finished", EV_GET_TYPE_NAME (job), job);
+ } else {
+ ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+ g_signal_emit (job, job_signals[FINISHED], 0);
+ }
+
+ return FALSE;
+}
+
+static void
+ev_job_emit_finished (EvJob *job)
+{
+ ev_debug_message (DEBUG_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ if (g_cancellable_is_cancelled (job->cancellable)) {
+ ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, returning", EV_GET_TYPE_NAME (job), job);
+ return;
+ }
+
+ job->finished = TRUE;
+
+ if (job->run_mode == EV_JOB_RUN_THREAD) {
+ job->idle_finished_id =
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc)emit_finished,
+ g_object_ref (job),
+ (GDestroyNotify)g_object_unref);
+ } else {
+ ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+ g_signal_emit (job, job_signals[FINISHED], 0);
+ }
+}
+
+gboolean
+ev_job_run (EvJob *job)
+{
+ EvJobClass *class = EV_JOB_GET_CLASS (job);
+
+ return class->run (job);
+}
+
+void
+ev_job_cancel (EvJob *job)
+{
+ if (job->cancelled || (job->finished && job->idle_finished_id == 0))
+ return;
+
+ ev_debug_message (DEBUG_JOBS, "job %s (%p) cancelled", EV_GET_TYPE_NAME (job), job);
+ ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ /* This should never be called from a thread */
+ job->cancelled = TRUE;
+ g_cancellable_cancel (job->cancellable);
+ g_signal_emit (job, job_signals[CANCELLED], 0);
+}
+
+void
+ev_job_failed (EvJob *job,
+ GQuark domain,
+ gint code,
+ const gchar *format,
+ ...)
+{
+ va_list args;
+ gchar *message;
+
+ if (job->failed || job->finished)
+ return;
+
+ ev_debug_message (DEBUG_JOBS, "job %s (%p) failed", EV_GET_TYPE_NAME (job), job);
+
+ job->failed = TRUE;
+
+ va_start (args, format);
+ message = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ job->error = g_error_new (domain, code, message);
+ g_free (message);
+
+ ev_job_emit_finished (job);
+}
+
+void
+ev_job_failed_from_error (EvJob *job,
+ GError *error)
+{
+ if (job->failed || job->finished)
+ return;
+
+ ev_debug_message (DEBUG_JOBS, "job %s (%p) failed", EV_GET_TYPE_NAME (job), job);
+
+ job->failed = TRUE;
+ job->error = g_error_copy (error);
+
+ ev_job_emit_finished (job);
+}
+
+void
+ev_job_succeeded (EvJob *job)
+{
+ if (job->finished)
+ return;
+
+ ev_debug_message (DEBUG_JOBS, "job %s (%p) succeeded", EV_GET_TYPE_NAME (job), job);
+
+ job->failed = FALSE;
+ ev_job_emit_finished (job);
+}
+
+gboolean
+ev_job_is_finished (EvJob *job)
+{
+ return job->finished;
+}
+
+gboolean
+ev_job_is_failed (EvJob *job)
+{
+ return job->failed;
+}
+
+EvJobRunMode
+ev_job_get_run_mode (EvJob *job)
+{
+ return job->run_mode;
+}
+
+void
+ev_job_set_run_mode (EvJob *job,
+ EvJobRunMode run_mode)
+{
+ job->run_mode = run_mode;
+}
+
+/* EvJobLinks */
+static void
+ev_job_links_init (EvJobLinks *job)
+{
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
static void
ev_job_links_dispose (GObject *object)
@@ -111,18 +308,52 @@
(* G_OBJECT_CLASS (ev_job_links_parent_class)->dispose) (object);
}
+static gboolean
+ev_job_links_run (EvJob *job)
+{
+ EvJobLinks *job_links = EV_JOB_LINKS (job);
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ ev_document_doc_mutex_lock ();
+ job_links->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (job->document));
+ ev_document_doc_mutex_unlock ();
+
+ ev_job_succeeded (job);
+
+ return FALSE;
+}
+
static void
ev_job_links_class_init (EvJobLinksClass *class)
{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (class);
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
oclass->dispose = ev_job_links_dispose;
+ job_class->run = ev_job_links_run;
}
+EvJob *
+ev_job_links_new (EvDocument *document)
+{
+ EvJob *job;
-static void ev_job_render_init (EvJobRender *job) { /* Do Nothing */ }
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
+ job->document = g_object_ref (document);
+
+ return job;
+}
+
+/* EvJobRender */
+static void
+ev_job_render_init (EvJobRender *job)
+{
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
static void
ev_job_render_dispose (GObject *object)
@@ -132,7 +363,7 @@
job = EV_JOB_RENDER (object);
if (job->ev_page) {
- ev_debug_message (DEBUG_JOBS, "page: %d", job->ev_page->index);
+ ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job->ev_page->index, job);
g_object_unref (job->ev_page);
job->ev_page = NULL;
}
@@ -155,132 +386,121 @@
(* G_OBJECT_CLASS (ev_job_render_parent_class)->dispose) (object);
}
-static void
-ev_job_render_class_init (EvJobRenderClass *class)
+static gboolean
+notify_page_ready (EvJobRender *job)
{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (class);
+ ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job);
+ ev_profiler_stop (EV_PROFILE_JOBS, "Rendering page %d", job->ev_page->index);
- job_render_signals [PAGE_READY] =
- g_signal_new ("page-ready",
- EV_TYPE_JOB_RENDER,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EvJobRenderClass, page_ready),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ if (EV_JOB (job)->cancelled) {
+ ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit page_ready", EV_GET_TYPE_NAME (job), job);
+ } else {
+ g_signal_emit (job, job_render_signals[PAGE_READY], 0);
+ }
- oclass->dispose = ev_job_render_dispose;
+ return FALSE;
}
-static void ev_job_thumbnail_init (EvJobThumbnail *job) { /* Do Nothing */ }
-
static void
-ev_job_thumbnail_dispose (GObject *object)
+ev_job_render_page_ready (EvJobRender *job)
{
- EvJobThumbnail *job;
-
- job = EV_JOB_THUMBNAIL (object);
-
- ev_debug_message (DEBUG_JOBS, "%d", job->page);
+ ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job);
- if (job->thumbnail) {
- g_object_unref (job->thumbnail);
- job->thumbnail = NULL;
- }
-
- (* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
+ job->page_ready = TRUE;
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+ (GSourceFunc)notify_page_ready,
+ g_object_ref (job),
+ (GDestroyNotify)g_object_unref);
}
-static void
-ev_job_thumbnail_class_init (EvJobThumbnailClass *class)
+static gboolean
+ev_job_render_run (EvJob *job)
{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (class);
-
- oclass->dispose = ev_job_thumbnail_dispose;
-}
-
-static void ev_job_print_init (EvJobPrint *job) { /* Do Nothing */ }
+ EvJobRender *job_render = EV_JOB_RENDER (job);
+ EvRenderContext *rc;
-static void
-ev_job_print_dispose (GObject *object)
-{
- EvJobPrint *job;
+ ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job_render->page, job);
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ ev_document_doc_mutex_lock ();
- job = EV_JOB_PRINT (object);
+ ev_profiler_start (EV_PROFILE_JOBS, "Rendering page %d", job_render->page);
+
+ ev_document_fc_mutex_lock ();
- ev_debug_message (DEBUG_JOBS, NULL);
-
- if (job->temp_file) {
- g_unlink (job->temp_file);
- g_free (job->temp_file);
- job->temp_file = NULL;
- }
+ job_render->ev_page = ev_document_get_page (job->document, job_render->page);
+ rc = ev_render_context_new (job_render->ev_page, job_render->rotation, job_render->scale);
+
+ job_render->surface = ev_document_render (job->document, rc);
+ /* If job was cancelled during the page rendering,
+ * we return now, so that the thread is finished ASAP
+ */
+ if (g_cancellable_is_cancelled (job->cancellable)) {
+ ev_document_fc_mutex_unlock ();
+ ev_document_doc_mutex_unlock ();
+ g_object_unref (rc);
- if (job->error) {
- g_error_free (job->error);
- job->error = NULL;
+ return FALSE;
}
-
- if (job->ranges) {
- g_free (job->ranges);
- job->ranges = NULL;
- job->n_ranges = 0;
+
+ if ((job_render->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (job->document)) {
+ ev_selection_render_selection (EV_SELECTION (job->document),
+ rc,
+ &(job_render->selection),
+ &(job_render->selection_points),
+ NULL,
+ job_render->selection_style,
+ &(job_render->text), &(job_render->base));
+ job_render->selection_region =
+ ev_selection_get_selection_region (EV_SELECTION (job->document),
+ rc,
+ job_render->selection_style,
+ &(job_render->selection_points));
}
- (* G_OBJECT_CLASS (ev_job_print_parent_class)->dispose) (object);
-}
-
-static void
-ev_job_print_class_init (EvJobPrintClass *class)
-{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (class);
-
- oclass->dispose = ev_job_print_dispose;
-}
-
-/* Public functions */
-void
-ev_job_finished (EvJob *job)
-{
- ev_debug_message (DEBUG_JOBS, EV_GET_TYPE_NAME (job));
- ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+ ev_job_render_page_ready (job_render);
+
+ ev_document_fc_mutex_unlock ();
+
+ if ((job_render->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (job->document))
+ job_render->text_mapping =
+ ev_selection_get_selection_map (EV_SELECTION (job->document), rc);
+ if ((job_render->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (job->document))
+ job_render->link_mapping =
+ ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), job_render->page);
+ if ((job_render->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (job->document))
+ job_render->form_field_mapping =
+ ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (job->document),
+ job_render->ev_page);
+ if ((job_render->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (job->document))
+ job_render->image_mapping =
+ ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (job->document),
+ job_render->page);
+ g_object_unref (rc);
+ ev_document_doc_mutex_unlock ();
- g_return_if_fail (EV_IS_JOB (job));
+ ev_job_succeeded (job);
- g_signal_emit (job, job_signals[FINISHED], 0);
+ return FALSE;
}
-EvJob *
-ev_job_links_new (EvDocument *document)
+static void
+ev_job_render_class_init (EvJobRenderClass *class)
{
- EvJob *job;
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
- ev_debug_message (DEBUG_JOBS, NULL);
-
- job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
- job->document = g_object_ref (document);
-
- return job;
-}
-
-void
-ev_job_links_run (EvJobLinks *job)
-{
- ev_debug_message (DEBUG_JOBS, NULL);
- ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-
- g_return_if_fail (EV_IS_JOB_LINKS (job));
+ job_render_signals [PAGE_READY] =
+ g_signal_new ("page-ready",
+ EV_TYPE_JOB_RENDER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvJobRenderClass, page_ready),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
- ev_document_doc_mutex_lock ();
- job->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (EV_JOB (job)->document));
- EV_JOB (job)->finished = TRUE;
- ev_document_doc_mutex_unlock ();
+ oclass->dispose = ev_job_render_dispose;
+ job_class->run = ev_job_render_run;
}
EvJob *
@@ -306,10 +526,6 @@
job->target_height = height;
job->flags = flags;
- if (EV_IS_ASYNC_RENDERER (document)) {
- EV_JOB (job)->async = TRUE;
- }
-
return EV_JOB (job);
}
@@ -328,111 +544,64 @@
job->base = *base;
}
+/* EvJobThumbnail */
static void
-render_finished_cb (EvDocument *document,
- GdkPixbuf *pixbuf,
- EvJobRender *job)
+ev_job_thumbnail_init (EvJobThumbnail *job)
{
- g_signal_handlers_disconnect_by_func (EV_JOB (job)->document,
- render_finished_cb, job);
-
- job->surface = ev_document_misc_surface_from_pixbuf (pixbuf);
- job->page_ready = TRUE;
- g_signal_emit (job, job_render_signals[PAGE_READY], 0);
- EV_JOB (job)->finished = TRUE;
- ev_job_finished (EV_JOB (job));
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
}
-static gboolean
-notify_page_ready (EvJobRender *job)
+static void
+ev_job_thumbnail_dispose (GObject *object)
{
- ev_debug_message (DEBUG_JOBS, "%d", job->ev_page->index);
- ev_profiler_stop (EV_PROFILE_JOBS, "Rendering page %d", job->ev_page->index);
-
- g_signal_emit (job, job_render_signals[PAGE_READY], 0);
+ EvJobThumbnail *job;
- return FALSE;
-}
+ job = EV_JOB_THUMBNAIL (object);
-static void
-ev_job_render_page_ready (EvJobRender *job)
-{
- ev_debug_message (DEBUG_JOBS, "%d", job->ev_page->index);
+ ev_debug_message (DEBUG_JOBS, "%d (%p)", job->page, job);
- job->page_ready = TRUE;
- g_idle_add_full (G_PRIORITY_HIGH_IDLE,
- (GSourceFunc)notify_page_ready,
- g_object_ref (job),
- (GDestroyNotify)g_object_unref);
+ if (job->thumbnail) {
+ g_object_unref (job->thumbnail);
+ job->thumbnail = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
}
-void
-ev_job_render_run (EvJobRender *job)
+static gboolean
+ev_job_thumbnail_run (EvJob *job)
{
- g_return_if_fail (EV_IS_JOB_RENDER (job));
+ EvJobThumbnail *job_thumb = EV_JOB_THUMBNAIL (job);
+ EvRenderContext *rc;
+ EvPage *page;
- ev_debug_message (DEBUG_JOBS, "page: %d", job->page);
+ ev_debug_message (DEBUG_JOBS, "%d (%p)", job_thumb->page, job);
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
ev_document_doc_mutex_lock ();
- if (EV_JOB (job)->async) {
- EvAsyncRenderer *renderer = EV_ASYNC_RENDERER (EV_JOB (job)->document);
- ev_async_renderer_render_pixbuf (renderer, job->page, job->scale,
- job->rotation);
- g_signal_connect (EV_JOB (job)->document, "render_finished",
- G_CALLBACK (render_finished_cb), job);
- } else {
- EvRenderContext *rc;
-
- ev_profiler_start (EV_PROFILE_JOBS, "Rendering page %d", job->page);
-
- ev_document_fc_mutex_lock ();
+ page = ev_document_get_page (job->document, job_thumb->page);
+ rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale);
+ g_object_unref (page);
- job->ev_page = ev_document_get_page (EV_JOB (job)->document, job->page);
+ job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document),
+ rc, TRUE);
+ g_object_unref (rc);
+ ev_document_doc_mutex_unlock ();
- rc = ev_render_context_new (job->ev_page, job->rotation, job->scale);
-
- job->surface = ev_document_render (EV_JOB (job)->document, rc);
- if ((job->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (EV_JOB (job)->document)) {
- ev_selection_render_selection (EV_SELECTION (EV_JOB (job)->document),
- rc,
- &(job->selection),
- &(job->selection_points),
- NULL,
- job->selection_style,
- &(job->text), &(job->base));
- job->selection_region =
- ev_selection_get_selection_region (EV_SELECTION (EV_JOB (job)->document),
- rc,
- job->selection_style,
- &(job->selection_points));
- }
+ ev_job_succeeded (job);
+
+ return FALSE;
+}
- ev_job_render_page_ready (job);
-
- ev_document_fc_mutex_unlock ();
-
- if ((job->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (EV_JOB (job)->document))
- job->text_mapping =
- ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document), rc);
- if ((job->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (EV_JOB (job)->document))
- job->link_mapping =
- ev_document_links_get_links (EV_DOCUMENT_LINKS (EV_JOB (job)->document), job->page);
- if ((job->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (EV_JOB (job)->document))
- job->form_field_mapping =
- ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (EV_JOB (job)->document),
- job->ev_page);
- if ((job->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (EV_JOB (job)->document))
- job->image_mapping =
- ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (EV_JOB (job)->document),
- job->page);
- g_object_unref (rc);
-
- EV_JOB (job)->finished = TRUE;
- }
+static void
+ev_job_thumbnail_class_init (EvJobThumbnailClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
- ev_document_doc_mutex_unlock ();
+ oclass->dispose = ev_job_thumbnail_dispose;
+ job_class->run = ev_job_thumbnail_run;
}
EvJob *
@@ -455,35 +624,64 @@
return EV_JOB (job);
}
-void
-ev_job_thumbnail_run (EvJobThumbnail *job)
+/* EvJobFonts */
+static void
+ev_job_fonts_init (EvJobFonts *job)
{
- EvRenderContext *rc;
- EvPage *page;
-
- ev_debug_message (DEBUG_JOBS, "%d", job->page);
- ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-
- g_return_if_fail (EV_IS_JOB_THUMBNAIL (job));
+ EV_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
+}
- ev_document_doc_mutex_lock ();
+static gboolean
+ev_job_fonts_run (EvJob *job)
+{
+ EvJobFonts *job_fonts = EV_JOB_FONTS (job);
+ EvDocumentFonts *fonts = EV_DOCUMENT_FONTS (job->document);
- page = ev_document_get_page (EV_JOB (job)->document, job->page);
- rc = ev_render_context_new (page, job->rotation, job->scale);
- g_object_unref (page);
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ /* Do not block the main loop */
+ if (!ev_document_doc_mutex_trylock ())
+ return TRUE;
+
+ if (!ev_document_fc_mutex_trylock ())
+ return TRUE;
+
+#ifdef EV_ENABLE_DEBUG
+ /* We use the #ifdef in this case because of the if */
+ if (ev_document_fonts_get_progress (fonts) == 0)
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+#endif
+
+ job_fonts->scan_completed = !ev_document_fonts_scan (fonts, 20);
+ g_signal_emit (job_fonts, job_fonts_signals[UPDATED], 0,
+ ev_document_fonts_get_progress (fonts));
- job->thumbnail =
- ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (EV_JOB (job)->document),
- rc, TRUE);
- g_object_unref (rc);
+ ev_document_fc_mutex_unlock ();
ev_document_doc_mutex_unlock ();
+
+ if (job_fonts->scan_completed)
+ ev_job_succeeded (job);
- EV_JOB (job)->finished = TRUE;
+ return !job_fonts->scan_completed;
}
-static void ev_job_fonts_init (EvJobFonts *job) { /* Do Nothing */ }
-
-static void ev_job_fonts_class_init (EvJobFontsClass *class) { /* Do Nothing */ }
+static void
+ev_job_fonts_class_init (EvJobFontsClass *class)
+{
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ job_class->run = ev_job_fonts_run;
+
+ job_fonts_signals[UPDATED] =
+ g_signal_new ("updated",
+ EV_TYPE_JOB_FONTS,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvJobFontsClass, updated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE,
+ 1, G_TYPE_DOUBLE);
+}
EvJob *
ev_job_fonts_new (EvDocument *document)
@@ -499,30 +697,13 @@
return EV_JOB (job);
}
-void
-ev_job_fonts_run (EvJobFonts *job)
+/* EvJobLoad */
+static void
+ev_job_load_init (EvJobLoad *job)
{
- EvDocumentFonts *fonts;
-
- ev_debug_message (DEBUG_JOBS, NULL);
- ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-
- g_return_if_fail (EV_IS_JOB_FONTS (job));
-
- ev_document_doc_mutex_lock ();
-
- fonts = EV_DOCUMENT_FONTS (EV_JOB (job)->document);
- ev_document_fc_mutex_lock ();
- job->scan_completed = !ev_document_fonts_scan (fonts, 20);
- ev_document_fc_mutex_unlock ();
-
- EV_JOB (job)->finished = TRUE;
-
- ev_document_doc_mutex_unlock ();
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
}
-static void ev_job_load_init (EvJobLoad *job) { /* Do Nothing */ }
-
static void
ev_job_load_dispose (GObject *object)
{
@@ -535,11 +716,6 @@
job->uri = NULL;
}
- if (job->error) {
- g_error_free (job->error);
- job->error = NULL;
- }
-
if (job->dest) {
g_object_unref (job->dest);
job->dest = NULL;
@@ -553,17 +729,52 @@
(* G_OBJECT_CLASS (ev_job_load_parent_class)->dispose) (object);
}
+static gboolean
+ev_job_load_run (EvJob *job)
+{
+ EvJobLoad *job_load = EV_JOB_LOAD (job);
+ GError *error = NULL;
+
+ ev_debug_message (DEBUG_JOBS, "%s", job_load->uri);
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ ev_document_fc_mutex_lock ();
+
+ /* TODO: reuse the job!!! */
+ /* This job may already have a document even if the job didn't complete
+ because, e.g., a password is required - if so, just reload rather than
+ creating a new instance */
+ if (job->document) {
+ ev_document_load (job->document,
+ job_load->uri,
+ &error);
+ } else {
+ job->document = ev_document_factory_get_document (job_load->uri,
+ &error);
+ }
+
+ ev_document_fc_mutex_unlock ();
+
+ if (error) {
+ ev_job_failed_from_error (job, error);
+ g_error_free (error);
+ } else {
+ ev_job_succeeded (job);
+ }
+
+ return FALSE;
+}
+
static void
ev_job_load_class_init (EvJobLoadClass *class)
{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (class);
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
oclass->dispose = ev_job_load_dispose;
+ job_class->run = ev_job_load_run;
}
-
EvJob *
ev_job_load_new (const gchar *uri,
EvLinkDest *dest,
@@ -577,12 +788,9 @@
job = g_object_new (EV_TYPE_JOB_LOAD, NULL);
job->uri = g_strdup (uri);
- if (dest)
- job->dest = g_object_ref (dest);
-
+ job->dest = dest ? g_object_ref (dest) : NULL;
job->mode = mode;
- if (search_string)
- job->search_string = g_strdup (search_string);
+ job->search_string = search_string ? g_strdup (search_string) : NULL;
return EV_JOB (job);
}
@@ -597,40 +805,13 @@
job->uri = g_strdup (uri);
}
-void
-ev_job_load_run (EvJobLoad *job)
+/* EvJobSave */
+static void
+ev_job_save_init (EvJobSave *job)
{
- g_return_if_fail (EV_IS_JOB_LOAD (job));
-
- ev_debug_message (DEBUG_JOBS, "%s", job->uri);
- ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-
- if (job->error) {
- g_error_free (job->error);
- job->error = NULL;
- }
-
- ev_document_fc_mutex_lock ();
-
- /* This job may already have a document even if the job didn't complete
- because, e.g., a password is required - if so, just reload rather than
- creating a new instance */
- if (EV_JOB (job)->document) {
- ev_document_load (EV_JOB (job)->document,
- job->uri,
- &job->error);
- } else {
- EV_JOB(job)->document =
- ev_document_factory_get_document (job->uri,
- &job->error);
- }
-
- ev_document_fc_mutex_unlock ();
- EV_JOB (job)->finished = TRUE;
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
}
-static void ev_job_save_init (EvJobSave *job) { /* Do Nothing */ }
-
static void
ev_job_save_dispose (GObject *object)
{
@@ -648,52 +829,20 @@
job->document_uri = NULL;
}
- if (job->error) {
- g_error_free (job->error);
- job->error = NULL;
- }
-
(* G_OBJECT_CLASS (ev_job_save_parent_class)->dispose) (object);
}
-static void
-ev_job_save_class_init (EvJobSaveClass *class)
-{
- GObjectClass *oclass;
-
- oclass = G_OBJECT_CLASS (class);
-
- oclass->dispose = ev_job_save_dispose;
-}
-
-EvJob *
-ev_job_save_new (EvDocument *document,
- const gchar *uri,
- const gchar *document_uri)
-{
- EvJobSave *job;
-
- ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", uri, document_uri);
-
- job = g_object_new (EV_TYPE_JOB_SAVE, NULL);
-
- EV_JOB (job)->document = g_object_ref (document);
- job->uri = g_strdup (uri);
- job->document_uri = g_strdup (document_uri);
- job->error = NULL;
-
- return EV_JOB (job);
-}
-
-void
-ev_job_save_run (EvJobSave *job)
+static gboolean
+ev_job_save_run (EvJob *job)
{
- gint fd;
- gchar *filename;
- gchar *tmp_filename;
- gchar *local_uri;
-
- ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job->uri, job->document_uri);
+ EvJobSave *job_save = EV_JOB_SAVE (job);
+ gint fd;
+ gchar *filename;
+ gchar *tmp_filename;
+ gchar *local_uri;
+ GError *error = NULL;
+
+ ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job_save->uri, job_save->document_uri);
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
filename = ev_tmp_filename ("saveacopy");
@@ -706,53 +855,55 @@
gint save_errno = errno;
display_name = g_filename_display_name (tmp_filename);
- g_set_error (&(job->error),
- G_FILE_ERROR,
- g_file_error_from_errno (save_errno),
- _("Failed to create file â%sâ: %s"),
- display_name, g_strerror (save_errno));
+ ev_job_failed (job,
+ G_FILE_ERROR,
+ g_file_error_from_errno (save_errno),
+ _("Failed to create file â%sâ: %s"),
+ display_name, g_strerror (save_errno));
g_free (display_name);
g_free (tmp_filename);
- return;
+ return FALSE;
}
ev_document_doc_mutex_lock ();
/* Save document to temp filename */
local_uri = g_filename_to_uri (tmp_filename, NULL, NULL);
- ev_document_save (EV_JOB (job)->document, local_uri, &(job->error));
+ ev_document_save (job->document, local_uri, &error);
close (fd);
ev_document_doc_mutex_unlock ();
- if (job->error) {
+ if (error) {
g_free (local_uri);
- return;
+ ev_job_failed_from_error (job, error);
+ g_error_free (error);
+
+ return FALSE;
}
/* If original document was compressed,
* compress it again before saving
*/
- if (g_object_get_data (G_OBJECT (EV_JOB (job)->document),
- "uri-uncompressed")) {
+ if (g_object_get_data (G_OBJECT (job->document), "uri-uncompressed")) {
EvCompressionType ctype = EV_COMPRESSION_NONE;
const gchar *ext;
gchar *uri_comp;
- ext = g_strrstr (job->document_uri, ".gz");
+ ext = g_strrstr (job_save->document_uri, ".gz");
if (ext && g_ascii_strcasecmp (ext, ".gz") == 0)
ctype = EV_COMPRESSION_GZIP;
- ext = g_strrstr (job->document_uri, ".bz2");
+ ext = g_strrstr (job_save->document_uri, ".bz2");
if (ext && g_ascii_strcasecmp (ext, ".bz2") == 0)
ctype = EV_COMPRESSION_BZIP2;
- uri_comp = ev_file_compress (local_uri, ctype, &(job->error));
+ uri_comp = ev_file_compress (local_uri, ctype, &error);
g_free (local_uri);
ev_tmp_filename_unlink (tmp_filename);
- if (!uri_comp || job->error) {
+ if (!uri_comp || error) {
local_uri = NULL;
} else {
local_uri = uri_comp;
@@ -761,63 +912,87 @@
g_free (tmp_filename);
- if (job->error) {
+ if (error) {
g_free (local_uri);
- return;
+ ev_job_failed_from_error (job, error);
+ g_error_free (error);
+
+ return FALSE;
}
if (!local_uri)
- return;
+ return FALSE;
- ev_xfer_uri_simple (local_uri, job->uri, &(job->error));
+ ev_xfer_uri_simple (local_uri, job_save->uri, &error);
ev_tmp_uri_unlink (local_uri);
+
+ if (error) {
+ ev_job_failed_from_error (job, error);
+ g_error_free (error);
+ } else {
+ ev_job_succeeded (job);
+ }
+
+ return FALSE;
+}
+
+static void
+ev_job_save_class_init (EvJobSaveClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ oclass->dispose = ev_job_save_dispose;
+ job_class->run = ev_job_save_run;
}
EvJob *
-ev_job_print_new (EvDocument *document,
- const gchar *format,
- gdouble width,
- gdouble height,
- EvPrintRange *ranges,
- gint n_ranges,
- EvPrintPageSet page_set,
- gint pages_per_sheet,
- gint copies,
- gdouble collate,
- gdouble reverse)
+ev_job_save_new (EvDocument *document,
+ const gchar *uri,
+ const gchar *document_uri)
{
- EvJobPrint *job;
+ EvJobSave *job;
- ev_debug_message (DEBUG_JOBS, "format: %s, width: %f, height:%f,"
- "n_ranges: %d, pages_per_sheet: %d, copies: %d,"
- "collate: %s, reverse: %s",
- format, width, height, n_ranges, pages_per_sheet, copies,
- collate ? "True" : "False", reverse ? "True" : "False");
+ ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", uri, document_uri);
- job = g_object_new (EV_TYPE_JOB_PRINT, NULL);
+ job = g_object_new (EV_TYPE_JOB_SAVE, NULL);
EV_JOB (job)->document = g_object_ref (document);
+ job->uri = g_strdup (uri);
+ job->document_uri = g_strdup (document_uri);
- job->format = format;
-
- job->temp_file = NULL;
- job->error = NULL;
+ return EV_JOB (job);
+}
- job->width = width;
- job->height = height;
+/* EvJobPrint */
+static void
+ev_job_print_init (EvJobPrint *job)
+{
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
- job->ranges = ranges;
- job->n_ranges = n_ranges;
+static void
+ev_job_print_dispose (GObject *object)
+{
+ EvJobPrint *job;
- job->page_set = page_set;
+ job = EV_JOB_PRINT (object);
- job->pages_per_sheet = CLAMP (pages_per_sheet, 1, 16);
-
- job->copies = copies;
- job->collate = collate;
- job->reverse = reverse;
+ ev_debug_message (DEBUG_JOBS, NULL);
- return EV_JOB (job);
+ if (job->temp_file) {
+ g_unlink (job->temp_file);
+ g_free (job->temp_file);
+ job->temp_file = NULL;
+ }
+
+ if (job->ranges) {
+ g_free (job->ranges);
+ job->ranges = NULL;
+ job->n_ranges = 0;
+ }
+
+ (* G_OBJECT_CLASS (ev_job_print_parent_class)->dispose) (object);
}
static gint
@@ -933,10 +1108,11 @@
return page_list;
}
-void
-ev_job_print_run (EvJobPrint *job)
+static gboolean
+ev_job_print_run (EvJob *job)
{
EvDocument *document = EV_JOB (job)->document;
+ EvJobPrint *job_print = EV_JOB_PRINT (job);
EvFileExporterContext fc;
EvRenderContext *rc;
gint fd;
@@ -946,68 +1122,67 @@
gint first_page;
gint i, j;
gchar *filename;
+ GError *error = NULL;
- g_return_if_fail (EV_IS_JOB_PRINT (job));
-
ev_debug_message (DEBUG_JOBS, NULL);
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
- if (job->temp_file)
- g_free (job->temp_file);
- job->temp_file = NULL;
+ if (job_print->temp_file)
+ g_free (job_print->temp_file);
+ job_print->temp_file = NULL;
- if (job->error)
- g_error_free (job->error);
- job->error = NULL;
-
- filename = g_strdup_printf ("evince_print.%s.XXXXXX", job->format);
- fd = g_file_open_tmp (filename, &job->temp_file, &job->error);
+ filename = g_strdup_printf ("evince_print.%s.XXXXXX", job_print->format);
+ fd = g_file_open_tmp (filename, &job_print->temp_file, &error);
g_free (filename);
if (fd <= -1) {
- EV_JOB (job)->finished = TRUE;
- return;
+ ev_job_failed_from_error (job, error);
+ g_error_free (error);
+
+ return FALSE;
}
- page_list = ev_job_print_get_page_list (job, &n_pages);
+ page_list = ev_job_print_get_page_list (job_print, &n_pages);
if (n_pages == 0) {
close (fd);
- EV_JOB (job)->finished = TRUE;
- return;
+ /* TODO: error */
+ ev_job_succeeded (job);
+
+ return FALSE;
}
- first_page = ev_print_job_get_first_page (job);
- last_page = ev_print_job_get_last_page (job);
+ first_page = ev_print_job_get_first_page (job_print);
+ last_page = ev_print_job_get_last_page (job_print);
- fc.format = g_ascii_strcasecmp (job->format, "pdf") == 0 ?
+ fc.format = g_ascii_strcasecmp (job_print->format, "pdf") == 0 ?
EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
- fc.filename = job->temp_file;
+ fc.filename = job_print->temp_file;
fc.first_page = MIN (first_page, last_page);
fc.last_page = MAX (first_page, last_page);
- fc.paper_width = job->width;
- fc.paper_height = job->height;
+ fc.paper_width = job_print->width;
+ fc.paper_height = job_print->height;
fc.duplex = FALSE;
- fc.pages_per_sheet = MAX (1, job->pages_per_sheet);
+ fc.pages_per_sheet = MAX (1, job_print->pages_per_sheet);
rc = ev_render_context_new (NULL, 0, 1.0);
ev_document_doc_mutex_lock ();
ev_file_exporter_begin (EV_FILE_EXPORTER (document), &fc);
- for (i = 0; i < job->copies; i++) {
+ for (i = 0; i < job_print->copies; i++) {
gint page, step;
gint n_copies;
- step = job->reverse ? -1 * job->pages_per_sheet : job->pages_per_sheet;
- page = job->reverse ? ((n_pages - 1) / job->pages_per_sheet) * job->pages_per_sheet : 0;
- n_copies = job->collate ? 1 : job->copies;
+ step = job_print->reverse ? -1 * job_print->pages_per_sheet : job_print->pages_per_sheet;
+ page = job_print->reverse ? ((n_pages - 1) / job_print->pages_per_sheet) * job_print->pages_per_sheet : 0;
+ n_copies = job_print->collate ? 1 : job_print->copies;
- while ((job->reverse && (page >= 0)) || (!job->reverse && (page < n_pages))) {
+ while ((job_print->reverse && (page >= 0)) || (!job_print->reverse && (page < n_pages))) {
gint k;
for (k = 0; k < n_copies; k++) {
ev_file_exporter_begin_page (EV_FILE_EXPORTER (document));
- for (j = 0; j < job->pages_per_sheet; j++) {
+ for (j = 0; j < job_print->pages_per_sheet; j++) {
EvPage *ev_page;
gint p = page + j;
@@ -1028,7 +1203,7 @@
page += step;
}
- if (!job->collate)
+ if (!job_print->collate)
break;
}
@@ -1039,5 +1214,64 @@
close (fd);
g_object_unref (rc);
- EV_JOB (job)->finished = TRUE;
+ ev_job_succeeded (job);
+
+ return FALSE;
+}
+
+static void
+ev_job_print_class_init (EvJobPrintClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ oclass->dispose = ev_job_print_dispose;
+ job_class->run = ev_job_print_run;
+}
+
+EvJob *
+ev_job_print_new (EvDocument *document,
+ const gchar *format,
+ gdouble width,
+ gdouble height,
+ EvPrintRange *ranges,
+ gint n_ranges,
+ EvPrintPageSet page_set,
+ gint pages_per_sheet,
+ gint copies,
+ gdouble collate,
+ gdouble reverse)
+{
+ EvJobPrint *job;
+
+ ev_debug_message (DEBUG_JOBS, "format: %s, width: %f, height:%f,"
+ "n_ranges: %d, pages_per_sheet: %d, copies: %d,"
+ "collate: %s, reverse: %s",
+ format, width, height, n_ranges, pages_per_sheet, copies,
+ collate ? "True" : "False", reverse ? "True" : "False");
+
+ job = g_object_new (EV_TYPE_JOB_PRINT, NULL);
+
+ EV_JOB (job)->document = g_object_ref (document);
+
+ job->format = format;
+
+ job->temp_file = NULL;
+
+ job->width = width;
+ job->height = height;
+
+ job->ranges = ranges;
+ job->n_ranges = n_ranges;
+
+ job->page_set = page_set;
+
+ job->pages_per_sheet = CLAMP (pages_per_sheet, 1, 16);
+
+ job->copies = copies;
+ job->collate = collate;
+ job->reverse = reverse;
+
+ return EV_JOB (job);
}
+
Modified: trunk/shell/ev-jobs.h
==============================================================================
--- trunk/shell/ev-jobs.h (original)
+++ trunk/shell/ev-jobs.h Sun Aug 3 11:01:28 2008
@@ -1,5 +1,6 @@
/* this file is part of evince, a gnome document viewer
*
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc gnome org>
* Copyright (C) 2005 Red Hat, Inc
*
* Evince is free software; you can redistribute it and/or modify it
@@ -55,6 +56,7 @@
#define EV_JOB(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB, EvJob))
#define EV_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB, EvJobClass))
#define EV_IS_JOB(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB))
+#define EV_JOB_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_JOB, EvJobClass))
#define EV_TYPE_JOB_LINKS (ev_job_links_get_type())
#define EV_JOB_LINKS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_LINKS, EvJobLinks))
@@ -92,23 +94,38 @@
#define EV_IS_JOB_PRINT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_PRINT))
typedef enum {
- EV_JOB_PRIORITY_LOW,
- EV_JOB_PRIORITY_HIGH,
-} EvJobPriority;
+ EV_JOB_RUN_THREAD,
+ EV_JOB_RUN_MAIN_LOOP
+} EvJobRunMode;
struct _EvJob
{
GObject parent;
+
EvDocument *document;
- gboolean finished;
- gboolean async;
+
+ EvJobRunMode run_mode;
+
+ guint cancelled : 1;
+ guint finished : 1;
+ guint failed : 1;
+
+ GError *error;
+ GCancellable *cancellable;
+
+ guint idle_finished_id;
+ guint idle_cancelled_id;
};
struct _EvJobClass
{
GObjectClass parent_class;
- void (* finished) (EvJob *job);
+ gboolean (*run) (EvJob *job);
+
+ /* Signals */
+ void (* cancelled) (EvJob *job);
+ void (* finished) (EvJob *job);
};
struct _EvJobLinks
@@ -194,6 +211,9 @@
struct _EvJobFontsClass
{
EvJobClass parent_class;
+
+ /* Signals */
+ void (* updated) (EvJobFonts *job);
};
struct _EvJobLoad
@@ -203,7 +223,6 @@
EvLinkDest *dest;
EvWindowRunMode mode;
gchar *search_string;
- GError *error;
gchar *uri;
};
@@ -216,7 +235,6 @@
{
EvJob parent;
- GError *error;
gchar *uri;
gchar *document_uri;
};
@@ -230,7 +248,6 @@
{
EvJob parent;
- GError *error;
const gchar *format;
gchar *temp_file;
EvPrintRange *ranges;
@@ -251,12 +268,26 @@
/* Base job class */
GType ev_job_get_type (void) G_GNUC_CONST;
-void ev_job_finished (EvJob *job);
+gboolean ev_job_run (EvJob *job);
+void ev_job_cancel (EvJob *job);
+void ev_job_failed (EvJob *job,
+ GQuark domain,
+ gint code,
+ const gchar *format,
+ ...);
+void ev_job_failed_from_error (EvJob *job,
+ GError *error);
+void ev_job_succeeded (EvJob *job);
+gboolean ev_job_is_cancelled (EvJob *job);
+gboolean ev_job_is_finished (EvJob *job);
+gboolean ev_job_is_failed (EvJob *job);
+EvJobRunMode ev_job_get_run_mode (EvJob *job);
+void ev_job_set_run_mode (EvJob *job,
+ EvJobRunMode run_mode);
/* EvJobLinks */
GType ev_job_links_get_type (void) G_GNUC_CONST;
EvJob *ev_job_links_new (EvDocument *document);
-void ev_job_links_run (EvJobLinks *thumbnail);
/* EvJobRender */
GType ev_job_render_get_type (void) G_GNUC_CONST;
@@ -272,20 +303,15 @@
EvSelectionStyle selection_style,
GdkColor *text,
GdkColor *base);
-void ev_job_render_run (EvJobRender *thumbnail);
-
/* EvJobThumbnail */
GType ev_job_thumbnail_get_type (void) G_GNUC_CONST;
EvJob *ev_job_thumbnail_new (EvDocument *document,
gint page,
gint rotation,
gdouble scale);
-void ev_job_thumbnail_run (EvJobThumbnail *thumbnail);
-
/* EvJobFonts */
GType ev_job_fonts_get_type (void) G_GNUC_CONST;
EvJob *ev_job_fonts_new (EvDocument *document);
-void ev_job_fonts_run (EvJobFonts *fonts);
/* EvJobLoad */
GType ev_job_load_get_type (void) G_GNUC_CONST;
@@ -295,14 +321,12 @@
const gchar *search_string);
void ev_job_load_set_uri (EvJobLoad *load,
const gchar *uri);
-void ev_job_load_run (EvJobLoad *load);
/* EvJobSave */
GType ev_job_save_get_type (void) G_GNUC_CONST;
EvJob *ev_job_save_new (EvDocument *document,
const gchar *uri,
const gchar *document_uri);
-void ev_job_save_run (EvJobSave *save);
/* EvJobPrint */
GType ev_job_print_get_type (void) G_GNUC_CONST;
@@ -317,7 +341,6 @@
gint copies,
gdouble collate,
gdouble reverse);
-void ev_job_print_run (EvJobPrint *print);
G_END_DECLS
Modified: trunk/shell/ev-page-cache.c
==============================================================================
--- trunk/shell/ev-page-cache.c (original)
+++ trunk/shell/ev-page-cache.c Sun Aug 3 11:01:28 2008
@@ -1,6 +1,5 @@
#include <config.h>
#include "ev-page-cache.h"
-#include "ev-job-queue.h"
#include "ev-document-thumbnails.h"
#include "ev-page.h"
#include <stdlib.h>
Modified: trunk/shell/ev-pixbuf-cache.c
==============================================================================
--- trunk/shell/ev-pixbuf-cache.c (original)
+++ trunk/shell/ev-pixbuf-cache.c Sun Aug 3 11:01:28 2008
@@ -1,6 +1,6 @@
#include <config.h>
#include "ev-pixbuf-cache.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
#include "ev-page-cache.h"
#include "ev-document-images.h"
#include "ev-document-forms.h"
@@ -163,8 +163,8 @@
g_signal_handlers_disconnect_by_func (job_info->job,
G_CALLBACK (job_finished_cb),
data);
- ev_job_queue_remove_job (job_info->job);
- g_object_unref (G_OBJECT (job_info->job));
+ ev_job_cancel (job_info->job);
+ g_object_unref (job_info->job);
job_info->job = NULL;
}
if (job_info->surface) {
@@ -313,7 +313,7 @@
g_signal_handlers_disconnect_by_func (job_info->job,
G_CALLBACK (job_finished_cb),
pixbuf_cache);
- ev_job_queue_remove_job (job_info->job);
+ ev_job_cancel (job_info->job);
g_object_unref (job_info->job);
job_info->job = NULL;
}
@@ -330,11 +330,11 @@
CacheJobInfo *new_next_job,
int start_page,
int end_page,
- EvJobPriority priority)
+ gint priority)
{
CacheJobInfo *target_page = NULL;
int page_offset;
- EvJobPriority new_priority;
+ gint new_priority;
if (page < (start_page - pixbuf_cache->preload_cache_size) ||
page > (end_page + pixbuf_cache->preload_cache_size)) {
@@ -361,7 +361,7 @@
page_offset = page - start_page;
g_assert (page_offset >= 0 &&
page_offset <= ((end_page - start_page) + 1));
- new_priority = EV_JOB_PRIORITY_HIGH;
+ new_priority = EV_JOB_PRIORITY_URGENT;
target_page = new_job_list + page_offset;
}
@@ -374,7 +374,7 @@
job_info->form_field_mapping = NULL;
if (new_priority != priority && target_page->job) {
- ev_job_queue_update_job (target_page->job, new_priority);
+ ev_job_scheduler_update_job (target_page->job, new_priority);
}
}
@@ -421,7 +421,7 @@
move_one_job (pixbuf_cache->job_list + i,
pixbuf_cache, page,
new_job_list, new_prev_job, new_next_job,
- start_page, end_page, EV_JOB_PRIORITY_HIGH);
+ start_page, end_page, EV_JOB_PRIORITY_URGENT);
page ++;
}
@@ -529,8 +529,8 @@
g_signal_handlers_disconnect_by_func (job_info->job,
G_CALLBACK (job_finished_cb),
pixbuf_cache);
- ev_job_queue_remove_job (job_info->job);
- g_object_unref (G_OBJECT (job_info->job));
+ ev_job_cancel (job_info->job);
+ g_object_unref (job_info->job);
job_info->job = NULL;
}
}
@@ -647,13 +647,13 @@
text, base);
}
- ev_job_queue_add_job (job_info->job, priority);
g_signal_connect (G_OBJECT (job_info->job), "page-ready",
G_CALLBACK (job_page_ready_cb),
pixbuf_cache);
g_signal_connect (G_OBJECT (job_info->job), "finished",
G_CALLBACK (job_finished_cb),
pixbuf_cache);
+ ev_job_scheduler_push_job (job_info->job, priority);
}
static void
@@ -701,7 +701,7 @@
add_job_if_needed (pixbuf_cache, job_info,
page_cache, page, rotation, scale,
- EV_JOB_PRIORITY_HIGH);
+ EV_JOB_PRIORITY_URGENT);
}
for (i = FIRST_VISABLE_PREV(pixbuf_cache); i < pixbuf_cache->preload_cache_size; i++) {
@@ -1235,7 +1235,7 @@
add_job (pixbuf_cache, job_info, page_cache, region,
width, height, page, rotation, scale,
- EV_JOB_PRIORITY_HIGH);
+ EV_JOB_PRIORITY_URGENT);
}
Modified: trunk/shell/ev-pixbuf-cache.h
==============================================================================
--- trunk/shell/ev-pixbuf-cache.h (original)
+++ trunk/shell/ev-pixbuf-cache.h Sun Aug 3 11:01:28 2008
@@ -27,7 +27,6 @@
#include <gtk/gtkwidget.h>
#include "ev-document.h"
#include "ev-selection.h"
-#include "ev-job-queue.h"
G_BEGIN_DECLS
Modified: trunk/shell/ev-properties-fonts.c
==============================================================================
--- trunk/shell/ev-properties-fonts.c (original)
+++ trunk/shell/ev-properties-fonts.c Sun Aug 3 11:01:28 2008
@@ -25,7 +25,7 @@
#include "ev-properties-fonts.h"
#include "ev-document-fonts.h"
#include "ev-jobs.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
#include <glib/gi18n.h>
#include <gtk/gtktreeview.h>
@@ -63,12 +63,10 @@
}
if (properties->fonts_job) {
-
- g_signal_handlers_disconnect_by_func
- (properties->fonts_job,
- job_fonts_finished_cb,
- properties);
- ev_job_queue_remove_job (properties->fonts_job);
+ g_signal_handlers_disconnect_by_func (properties->fonts_job,
+ job_fonts_finished_cb,
+ properties);
+ ev_job_cancel (properties->fonts_job);
g_object_unref (properties->fonts_job);
properties->fonts_job = NULL;
@@ -161,29 +159,23 @@
static void
job_fonts_finished_cb (EvJob *job, EvPropertiesFonts *properties)
-{
- EvDocumentFonts *document_fonts = EV_DOCUMENT_FONTS (job->document);
- double progress;
-
- progress = ev_document_fonts_get_progress (document_fonts);
- update_progress_label (properties->fonts_progress_label, progress);
+{
+ g_signal_handlers_disconnect_by_func (job, job_fonts_finished_cb, properties);
+ g_object_unref (properties->fonts_job);
+ properties->fonts_job = NULL;
+}
- if (EV_JOB_FONTS (job)->scan_completed) {
- g_signal_handlers_disconnect_by_func
- (job, job_fonts_finished_cb, properties);
- g_object_unref (properties->fonts_job);
- properties->fonts_job = NULL;
- } else {
- GtkTreeModel *model;
+static void
+job_fonts_updated_cb (EvJobFonts *job, gdouble progress, EvPropertiesFonts *properties)
+{
+ GtkTreeModel *model;
+ EvDocumentFonts *document_fonts = EV_DOCUMENT_FONTS (properties->document);
- model = gtk_tree_view_get_model
- (GTK_TREE_VIEW (properties->fonts_treeview));
- ev_document_doc_mutex_lock ();
- ev_document_fonts_fill_model (document_fonts, model);
- ev_document_doc_mutex_unlock ();
+ update_progress_label (properties->fonts_progress_label, progress);
- ev_job_queue_add_job (job, EV_JOB_PRIORITY_LOW);
- }
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (properties->fonts_treeview));
+ /* Documen lock is already held by the jop */
+ ev_document_fonts_fill_model (document_fonts, model);
}
void
@@ -200,10 +192,13 @@
gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
properties->fonts_job = ev_job_fonts_new (properties->document);
+ g_signal_connect (properties->fonts_job, "updated",
+ G_CALLBACK (job_fonts_updated_cb),
+ properties);
g_signal_connect (properties->fonts_job, "finished",
G_CALLBACK (job_fonts_finished_cb),
properties);
- ev_job_queue_add_job (properties->fonts_job, EV_JOB_PRIORITY_LOW);
+ ev_job_scheduler_push_job (properties->fonts_job, EV_JOB_PRIORITY_NONE);
}
GtkWidget *
Modified: trunk/shell/ev-sidebar-links.c
==============================================================================
--- trunk/shell/ev-sidebar-links.c (original)
+++ trunk/shell/ev-sidebar-links.c Sun Aug 3 11:01:28 2008
@@ -30,7 +30,7 @@
#include "ev-sidebar-page.h"
#include "ev-sidebar-links.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
#include "ev-document-links.h"
#include "ev-window.h"
@@ -145,7 +145,7 @@
if (sidebar->priv->job) {
g_signal_handlers_disconnect_by_func (sidebar->priv->job,
job_finished_callback, sidebar);
- ev_job_queue_remove_job (sidebar->priv->job);
+ ev_job_cancel (sidebar->priv->job);
g_object_unref (sidebar->priv->job);
sidebar->priv->job = NULL;
}
@@ -702,7 +702,7 @@
G_CALLBACK (job_finished_callback),
sidebar_links);
/* The priority doesn't matter for this job */
- ev_job_queue_add_job (priv->job, EV_JOB_PRIORITY_LOW);
+ ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE);
}
static gboolean
Modified: trunk/shell/ev-sidebar-thumbnails.c
==============================================================================
--- trunk/shell/ev-sidebar-thumbnails.c (original)
+++ trunk/shell/ev-sidebar-thumbnails.c Sun Aug 3 11:01:28 2008
@@ -34,7 +34,7 @@
#include "ev-sidebar-thumbnails.h"
#include "ev-document-thumbnails.h"
#include "ev-document-misc.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
#include "ev-window.h"
#include "ev-utils.h"
@@ -207,7 +207,7 @@
if (job) {
g_signal_handlers_disconnect_by_func (job, thumbnail_job_completed_callback, sidebar_thumbnails);
- ev_job_queue_remove_job (EV_JOB (job));
+ ev_job_cancel (EV_JOB (job));
g_object_unref (job);
}
@@ -263,7 +263,7 @@
job = ev_job_thumbnail_new (priv->document,
page, priv->rotation,
get_scale_for_page (sidebar_thumbnails, page));
- ev_job_queue_add_job (EV_JOB (job), EV_JOB_PRIORITY_HIGH);
+ ev_job_scheduler_push_job (EV_JOB (job), EV_JOB_PRIORITY_HIGH);
g_object_set_data_full (G_OBJECT (job), "tree_iter",
gtk_tree_iter_copy (&iter),
@@ -688,8 +688,8 @@
static gboolean
ev_sidebar_thumbnails_clear_job (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
gpointer data)
{
EvJob *job;
@@ -697,7 +697,7 @@
gtk_tree_model_get (model, iter, COLUMN_JOB, &job, -1);
if (job != NULL) {
- ev_job_queue_remove_job (job);
+ ev_job_cancel (job);
g_signal_handlers_disconnect_by_func (job, thumbnail_job_completed_callback, data);
g_object_unref (job);
}
Modified: trunk/shell/ev-view-private.h
==============================================================================
--- trunk/shell/ev-view-private.h (original)
+++ trunk/shell/ev-view-private.h Sun Aug 3 11:01:28 2008
@@ -24,6 +24,7 @@
#include "ev-view.h"
#include "ev-pixbuf-cache.h"
#include "ev-page-cache.h"
+#include "ev-jobs.h"
#include "ev-image.h"
#include "ev-form-field.h"
#include "ev-selection.h"
Modified: trunk/shell/ev-view.c
==============================================================================
--- trunk/shell/ev-view.c (original)
+++ trunk/shell/ev-view.c Sun Aug 3 11:01:28 2008
@@ -39,7 +39,6 @@
#include "ev-document-transition.h"
#include "ev-document-forms.h"
#include "ev-document-misc.h"
-#include "ev-job-queue.h"
#include "ev-page-cache.h"
#include "ev-pixbuf-cache.h"
#include "ev-transition-animation.h"
Modified: trunk/shell/ev-window.c
==============================================================================
--- trunk/shell/ev-window.c (original)
+++ trunk/shell/ev-window.c Sun Aug 3 11:01:28 2008
@@ -49,7 +49,7 @@
#include "ev-document-images.h"
#include "ev-document-security.h"
#include "ev-document-factory.h"
-#include "ev-job-queue.h"
+#include "ev-job-scheduler.h"
#include "ev-jobs.h"
#include "ev-sidebar-page.h"
#include "eggfindbar.h"
@@ -221,16 +221,16 @@
EvWindow *ev_window);
static void ev_window_set_page_mode (EvWindow *window,
EvWindowPageMode page_mode);
-static void ev_window_load_job_cb (EvJobLoad *job,
+static void ev_window_load_job_cb (EvJob *job,
gpointer data);
static void ev_window_reload_document (EvWindow *window);
-static void ev_window_reload_job_cb (EvJobLoad *job,
+static void ev_window_reload_job_cb (EvJob *job,
EvWindow *window);
static void ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
EvWindow *ev_window);
-static void ev_window_print_job_cb (EvJobPrint *job,
+static void ev_window_print_job_cb (EvJob *job,
EvWindow *window);
-static void ev_window_save_job_cb (EvJobSave *save,
+static void ev_window_save_job_cb (EvJob *save,
EvWindow *window);
static void ev_window_sizing_mode_changed_cb (EvView *view,
GParamSpec *pspec,
@@ -1080,8 +1080,9 @@
ev_window_clear_thumbnail_job (EvWindow *ev_window)
{
if (ev_window->priv->thumbnail_job != NULL) {
- ev_job_queue_remove_job (ev_window->priv->thumbnail_job);
-
+ if (!ev_job_is_finished (ev_window->priv->thumbnail_job))
+ ev_job_cancel (ev_window->priv->thumbnail_job);
+
g_signal_handlers_disconnect_by_func (ev_window->priv->thumbnail_job,
ev_window_set_icon_from_thumbnail,
ev_window);
@@ -1125,7 +1126,7 @@
g_signal_connect (ev_window->priv->thumbnail_job, "finished",
G_CALLBACK (ev_window_set_icon_from_thumbnail),
ev_window);
- ev_job_queue_add_job (EV_JOB (ev_window->priv->thumbnail_job), EV_JOB_PRIORITY_LOW);
+ ev_job_scheduler_push_job (ev_window->priv->thumbnail_job, EV_JOB_PRIORITY_NONE);
}
static gboolean
@@ -1231,7 +1232,7 @@
ev_password_dialog_save_password (EV_PASSWORD_DIALOG (password_dialog));
ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_DOCUMENT);
- ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
gtk_widget_destroy (password_dialog);
@@ -1277,9 +1278,8 @@
ev_window_clear_load_job (EvWindow *ev_window)
{
if (ev_window->priv->load_job != NULL) {
-
- if (!ev_window->priv->load_job->finished)
- ev_job_queue_remove_job (ev_window->priv->load_job);
+ if (!ev_job_is_finished (ev_window->priv->load_job))
+ ev_job_cancel (ev_window->priv->load_job);
g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
g_object_unref (ev_window->priv->load_job);
@@ -1291,9 +1291,8 @@
ev_window_clear_reload_job (EvWindow *ev_window)
{
if (ev_window->priv->reload_job != NULL) {
-
- if (!ev_window->priv->reload_job->finished)
- ev_job_queue_remove_job (ev_window->priv->reload_job);
+ if (!ev_job_is_finished (ev_window->priv->reload_job))
+ ev_job_cancel (ev_window->priv->reload_job);
g_signal_handlers_disconnect_by_func (ev_window->priv->reload_job, ev_window_reload_job_cb, ev_window);
g_object_unref (ev_window->priv->reload_job);
@@ -1349,21 +1348,22 @@
* function should _not_ necessarily expect those to exist after being
* called. */
static void
-ev_window_load_job_cb (EvJobLoad *job,
+ev_window_load_job_cb (EvJob *job,
gpointer data)
{
EvWindow *ev_window = EV_WINDOW (data);
EvDocument *document = EV_JOB (job)->document;
+ EvJobLoad *job_load = EV_JOB_LOAD (job);
- g_assert (job->uri);
+ g_assert (job_load->uri);
ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
/* Success! */
- if (job->error == NULL) {
+ if (!ev_job_is_failed (job)) {
ev_window_set_document (ev_window, document);
- if (job->mode != EV_WINDOW_MODE_PREVIEW) {
+ if (job_load->mode != EV_WINDOW_MODE_PREVIEW) {
setup_view_from_metadata (ev_window);
}
@@ -1371,17 +1371,17 @@
ev_window_add_recent (ev_window, ev_window->priv->uri);
}
- if (job->dest) {
+ if (job_load->dest) {
EvLink *link;
EvLinkAction *link_action;
- link_action = ev_link_action_new_dest (g_object_ref (job->dest));
+ link_action = ev_link_action_new_dest (g_object_ref (job_load->dest));
link = ev_link_new (NULL, link_action);
ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
g_object_unref (link);
}
- switch (job->mode) {
+ switch (job_load->mode) {
case EV_WINDOW_MODE_FULLSCREEN:
ev_window_run_fullscreen (ev_window);
break;
@@ -1395,14 +1395,23 @@
break;
}
- if (job->search_string && EV_IS_DOCUMENT_FIND (document)) {
+ /* Restart the search after reloading */
+ if (ev_window->priv->in_reload) {
+ GtkWidget *widget;
+
+ widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
+ if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
+ find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar),
+ NULL, ev_window);
+ }
+ } else if (job_load->search_string && EV_IS_DOCUMENT_FIND (document)) {
ev_window_cmd_edit_find (NULL, ev_window);
egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
- job->search_string);
+ job_load->search_string);
}
/* Create a monitor for the document */
- ev_window->priv->monitor = ev_file_monitor_new (job->uri);
+ ev_window->priv->monitor = ev_file_monitor_new (job_load->uri);
g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed",
G_CALLBACK (ev_window_document_changed),
ev_window);
@@ -1418,7 +1427,7 @@
setup_view_from_metadata (ev_window);
- file = g_file_new_for_uri (job->uri);
+ file = g_file_new_for_uri (job_load->uri);
base_name = g_file_get_basename (file);
ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view),
base_name);
@@ -1436,18 +1445,18 @@
}
static void
-ev_window_reload_job_cb (EvJobLoad *job,
- EvWindow *ev_window)
+ev_window_reload_job_cb (EvJob *job,
+ EvWindow *ev_window)
{
GtkWidget *widget;
-
- if (job->error) {
+
+ if (ev_job_is_failed (job)) {
ev_window_clear_reload_job (ev_window);
ev_window->priv->in_reload = FALSE;
return;
}
- ev_window_set_document (ev_window, EV_JOB (job)->document);
+ ev_window_set_document (ev_window, job->document);
/* Restart the search after reloading */
widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
@@ -1539,7 +1548,7 @@
g_file_copy_finish (source, async_result, &error);
if (!error) {
- ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
g_object_unref (source);
return;
@@ -1649,7 +1658,7 @@
ev_window_load_file_remote (ev_window, source_file);
} else {
g_object_unref (source_file);
- ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
}
}
@@ -1666,7 +1675,7 @@
g_signal_connect (ev_window->priv->reload_job, "finished",
G_CALLBACK (ev_window_reload_job_cb),
ev_window);
- ev_job_queue_add_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_LOW);
+ ev_job_scheduler_push_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_NONE);
}
static void
@@ -2067,8 +2076,8 @@
ev_window_clear_save_job (EvWindow *ev_window)
{
if (ev_window->priv->save_job != NULL) {
- if (!ev_window->priv->save_job->finished)
- ev_job_queue_remove_job (ev_window->priv->save_job);
+ if (!ev_job_is_finished (ev_window->priv->save_job))
+ ev_job_cancel (ev_window->priv->save_job);
g_signal_handlers_disconnect_by_func (ev_window->priv->save_job,
ev_window_save_job_cb,
@@ -2079,13 +2088,14 @@
}
static void
-ev_window_save_job_cb (EvJobSave *job,
+ev_window_save_job_cb (EvJob *job,
EvWindow *window)
{
- if (job->error) {
+ if (ev_job_is_failed (job)) {
gchar *msg;
- msg = g_strdup_printf (_("The file could not be saved as â%sâ."), job->uri);
+ msg = g_strdup_printf (_("The file could not be saved as â%sâ."),
+ EV_JOB_SAVE (job)->uri);
ev_window_error_message (GTK_WINDOW (window), msg, job->error);
g_free (msg);
}
@@ -2114,10 +2124,9 @@
G_CALLBACK (ev_window_save_job_cb),
ev_window);
/* The priority doesn't matter for this job */
- ev_job_queue_add_job (ev_window->priv->save_job, EV_JOB_PRIORITY_LOW);
+ ev_job_scheduler_push_job (ev_window->priv->save_job, EV_JOB_PRIORITY_NONE);
g_free (uri);
-
gtk_widget_destroy (fc);
}
@@ -2187,8 +2196,8 @@
ev_window_clear_print_job (EvWindow *window)
{
if (window->priv->print_job) {
- if (!window->priv->print_job->finished)
- ev_job_queue_remove_job (window->priv->print_job);
+ if (!ev_job_is_finished (window->priv->print_job))
+ ev_job_cancel (window->priv->print_job);
g_signal_handlers_disconnect_by_func (window->priv->print_job,
ev_window_print_job_cb,
@@ -2349,18 +2358,18 @@
}
static void
-ev_window_print_job_cb (EvJobPrint *job,
- EvWindow *window)
+ev_window_print_job_cb (EvJob *job,
+ EvWindow *window)
{
- if (job->error) {
+ if (ev_job_is_failed (job)) {
g_warning ("%s", job->error->message);
ev_window_clear_print_job (window);
return;
}
- g_assert (job->temp_file != NULL);
+ g_assert (EV_JOB_PRINT (job)->temp_file != NULL);
- ev_window_print_send (window, job->temp_file);
+ ev_window_print_send (window, EV_JOB_PRINT (job)->temp_file);
}
static gboolean
@@ -2494,7 +2503,7 @@
G_CALLBACK (ev_window_print_job_cb),
window);
/* The priority doesn't matter for this job */
- ev_job_queue_add_job (window->priv->print_job, EV_JOB_PRIORITY_LOW);
+ ev_job_scheduler_push_job (window->priv->print_job, EV_JOB_PRIORITY_NONE);
gtk_widget_destroy (GTK_WIDGET (dialog));
window->priv->print_dialog = NULL;
Modified: trunk/shell/main.c
==============================================================================
--- trunk/shell/main.c (original)
+++ trunk/shell/main.c Sun Aug 3 11:01:28 2008
@@ -41,7 +41,6 @@
#endif
#include "ev-stock-icons.h"
-#include "ev-job-queue.h"
#include "ev-file-helpers.h"
#include "ev-backends-manager.h"
@@ -391,7 +390,6 @@
ev_metadata_manager_init ();
}
- ev_job_queue_init ();
g_set_application_name (_("Evince Document Viewer"));
ev_file_helpers_init ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]