? .hg
? autom4te.cache
? clean-includes.diff
? depcomp
? eog.desktop.in
? includes.diff
? install-sh
? missing
? mkinstalldirs
? omf.make
? partial-patch-jobs-2006-12-12.diff
? patch-current-changes.diff
? stamp-h1
? xmldocs.make
? help/de/eog-de.omf.out
? help/es/.xml2po.mo
? help/es/eog.xml
? help/eu/Makefile
? help/eu/Makefile.in
? help/eu/eog-eu.omf.out
? help/eu/omf_timestamp
? help/fr/.xml2po.mo
? help/fr/eog.xml
? help/it/eog-it.omf.out
? help/ja/eog-ja.omf.out
? help/ko/eog-ko.omf.out
? help/sv/.xml2po.mo
? help/sv/eog.xml
? help/uk/.xml2po.mo
? help/uk/eog.xml
? help/zh_CN/eog-zh_CN.omf.out
? help/zh_TW/eog-zh_TW.omf.out
? libeog/eog-job-queue.c
? libeog/eog-job-queue.h
? libeog/eog-jobs.c
? libeog/eog-jobs.h
? po/stamp-it
Index: libeog/Makefile.am
===================================================================
RCS file: /cvs/gnome/eog/libeog/Makefile.am,v
retrieving revision 1.53
diff -u -p -r1.53 Makefile.am
--- libeog/Makefile.am	18 May 2006 03:06:15 -0000	1.53
+++ libeog/Makefile.am	12 Dec 2006 15:37:46 -0000
@@ -29,7 +29,7 @@ MARSHAL_OUTPUT = 		\
 
 noinst_LIBRARIES = libeog.a
 
-noinst_PROGRAMS = test-eog-job test-image-load
+## noinst_PROGRAMS = test-eog-job test-image-load
 
 libeog_a_SOURCES =			\
 	$(MARSHAL_OUTPUT)		\
@@ -56,10 +56,10 @@ libeog_a_SOURCES =			\
 	eog-image-cache.c		\
 	eog-image-list.c		\
 	eog-image-list.h		\
-	eog-job-manager.c		\
-	eog-job-manager.h		\
-	eog-job.c			\
-	eog-job.h			\
+	eog-job-queue.h			\
+	eog-job-queue.c			\
+	eog-jobs.c			\
+	eog-jobs.h			\
 	eog-uri-converter.h		\
 	eog-uri-converter.c		\
 	eog-scroll-view.c		\
@@ -93,32 +93,32 @@ libeog_a_SOURCES =			\
 BUILT_SOURCES = 			\
 	$(MARSHAL_OUTPUT)
 
-test_eog_job_DEPENDENCIES = libeog.a
+# test_eog_job_DEPENDENCIES = libeog.a
 
-test_eog_job_SOURCES = test-eog-job.c
+# test_eog_job_SOURCES = test-eog-job.c
 
-test_eog_job_LDADD = \
-	-L$(top_builddir)/libeog 	\
-	-leog				\
-	$(jpeg_LIB)			\
-	$(EOG_LIBS)			\
-	$(LIBJPEG)			\
-	$(X_LIBS)
+# test_eog_job_LDADD = \
+# 	-L$(top_builddir)/libeog 	\
+# 	-leog				\
+# 	$(jpeg_LIB)			\
+# 	$(EOG_LIBS)			\
+# 	$(LIBJPEG)			\
+# 	$(X_LIBS)
 
 
 
 
-test_image_load_DEPENDENCIES = libeog.a
+# test_image_load_DEPENDENCIES = libeog.a
 
-test_image_load_SOURCES = test-image-load.c
+# test_image_load_SOURCES = test-image-load.c
 
-test_image_load_LDADD = \
-	-L$(top_builddir)/libeog 	\
-	-leog				\
-	$(jpeg_LIB)			\
-	$(EOG_LIBS)			\
-	$(LIBJPEG)			\
-	$(X_LIBS)
+# test_image_load_LDADD = \
+# 	-L$(top_builddir)/libeog 	\
+# 	-leog				\
+# 	$(jpeg_LIB)			\
+# 	$(EOG_LIBS)			\
+# 	$(LIBJPEG)			\
+# 	$(X_LIBS)
 
 CLEANFILES = $(BUILT_SOURCES)
 
Index: libeog/eog-collection-item.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-collection-item.c,v
retrieving revision 1.13
diff -u -p -r1.13 eog-collection-item.c
--- libeog/eog-collection-item.c	20 Nov 2006 20:53:05 -0000	1.13
+++ libeog/eog-collection-item.c	12 Dec 2006 15:37:47 -0000
@@ -11,7 +11,7 @@
 #include "eog-collection-item.h"
 #include "eog-image.h"
 #include "eog-canvas-pixbuf.h"
-#include "eog-job-manager.h"
+#include "eog-job-queue.h"
 #include "eog-thumbnail.h"
 
 struct _EogCollectionItemPrivate {
@@ -274,61 +274,23 @@ get_stipple_bitmap (void)
 }
 
 static void
-job_thumb_finished (EogJob *job, gpointer data, GError *error)
+eog_job_thumbnail_finished (EogJobThumbnail *job, gpointer data)
 {
-	EogCollectionItemPrivate *priv;
-	GdkPixbuf *pixbuf = NULL;
-	gboolean show_frame = FALSE;
-	
-	priv = EOG_COLLECTION_ITEM (data)->priv;
-
-	if (!priv)
-		return;
-		
-	if (eog_job_get_success (job)) {
-		/* success */
-		pixbuf = eog_image_get_pixbuf_thumbnail (priv->image);
-		show_frame = TRUE;
-	}
-	
-	if (pixbuf == NULL) {
-		pixbuf = get_failed_pixbuf ();
-	}
-	
-	g_assert (pixbuf != NULL);
-	
-	set_pixbuf (EOG_COLLECTION_ITEM (data), pixbuf, show_frame);
-	g_object_unref (pixbuf);
-}
-
-static void 
-job_thumb_create (EogJob *job, gpointer data, GError **error)
-{
-	EogCollectionItemPrivate *priv;
+	EogCollectionItem *item;
 	EogImage *image;
-	GdkPixbuf *pixbuf;
-	GnomeVFSURI *uri;
 
-	priv = EOG_COLLECTION_ITEM (data)->priv;
+	g_return_if_fail (EOG_IS_COLLECTION_ITEM (data));
 
-	image = priv->image; 
-	if (!EOG_IS_IMAGE (image))
-		return;
+	item = EOG_COLLECTION_ITEM (data);
 
-	uri = eog_image_get_uri (image);
-	if (uri == NULL)
-		return;
-		
-	pixbuf = eog_thumbnail_load (uri, job, error);
+	image = item->priv->image;
 
-	if (pixbuf == NULL) 
-		g_assert (*error != NULL);
-	else {
-		eog_image_set_thumbnail (image, pixbuf);
-		g_object_unref (pixbuf);
+	if (job->thumbnail == NULL) {
+		job->thumbnail = get_failed_pixbuf ();
 	}
 	
-	gnome_vfs_uri_unref (uri);
+	eog_image_set_thumbnail (image, job->thumbnail);
+	set_pixbuf (item, job->thumbnail, TRUE);
 }
 
 static void
@@ -615,6 +577,7 @@ eog_collection_item_load (EogCollectionI
 	EogCollectionItemPrivate *priv;
 	EogJob *job;
 	GdkPixbuf *thumb = NULL;
+	GnomeVFSURI *uri;
 
 	g_return_if_fail (EOG_IS_COLLECTION_ITEM (item));
 
@@ -626,12 +589,14 @@ eog_collection_item_load (EogCollectionI
 	thumb = eog_image_get_pixbuf_thumbnail (priv->image);
 	if (thumb == NULL) {
 		/* try to create thumbnail */
-		job = eog_job_new (G_OBJECT (item),
-				   job_thumb_create,
-				   job_thumb_finished,
-				   NULL, /* cancel */
-				   NULL); /* progress */
-		eog_job_manager_add (job);
+		uri = eog_image_get_uri (priv->image);
+		job = eog_job_thumbnail_new (uri);
+		g_signal_connect (job, 
+				  "finished", 
+				  G_CALLBACK (eog_job_thumbnail_finished),
+				  item);
+		gnome_vfs_uri_unref (uri);
+		eog_job_queue_add_job (job);
 		g_object_unref (G_OBJECT (job));
 	}
 	else {
Index: libeog/eog-full-screen.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-full-screen.c,v
retrieving revision 1.40
diff -u -p -r1.40 eog-full-screen.c
--- libeog/eog-full-screen.c	20 Nov 2006 20:53:05 -0000	1.40
+++ libeog/eog-full-screen.c	12 Dec 2006 15:37:47 -0000
@@ -35,7 +35,7 @@
 #include "eog-scroll-view.h"
 #include "cursors.h"
 #include "eog-config-keys.h"
-#include "eog-job-manager.h"
+#include "eog-job-queue.h"
 #include "eog-image-cache.h"
 
 G_DEFINE_TYPE (EogFullScreen, eog_full_screen, GTK_TYPE_WINDOW)
@@ -94,6 +94,7 @@ struct _EogFullScreenPrivate
 };
 
 static guint prepare_load_image (EogFullScreen *fs, EogIter *iter);
+static void load_finished_cb  (EogJobLoad *job, gpointer data);
 
 static gboolean
 check_cursor_hide (gpointer data)
@@ -157,20 +158,33 @@ eog_full_screen_motion (GtkWidget *widge
 }
 
 static void
-cancel_load_by_iter (EogImageList *list, EogIter *iter)
+eog_full_screen_clear_load_job (EogFullScreen *fs, EogJob *job)
+{
+	if (job != NULL) {
+		if (!job->finished)
+			eog_job_queue_remove_job (job);
+		eog_image_cancel_load (EOG_JOB_LOAD (job)->image);
+		
+		g_signal_handlers_disconnect_by_func (job, 
+						      load_finished_cb,
+						      fs);
+		g_object_unref (job);
+	}
+}
+
+static void
+cancel_load_by_iter (EogImageList *list, EogIter *iter, EogFullScreen *fs)
 {
 	EogImage *image;
-	guint job_id = 0;
+	EogJob *job = NULL;
 	
 	image = eog_image_list_get_img_by_iter (list, iter);
 	if (image != NULL) {
-		job_id = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (image), JOB_ID_QUARK));
+		job = EOG_JOB (g_object_get_qdata (G_OBJECT (image), JOB_ID_QUARK));
+		eog_full_screen_clear_load_job (fs, job);
+		g_object_set_qdata (G_OBJECT (image), JOB_ID_QUARK, NULL);
 		g_object_unref (image);
 	}
-	
-	if (job_id > 0) {
-		eog_job_manager_cancel_job (job_id);
-	}
 }
 
 static EogIter*
@@ -227,7 +241,7 @@ display_image_on_screen (EogFullScreen *
 		if (next_preload != NULL && 
 		    !eog_image_list_iter_equal (priv->list, priv->preload, next_preload))
 		{
-			cancel_load_by_iter (priv->list, priv->preload);
+			cancel_load_by_iter (priv->list, priv->preload, fs);
 			
 			if (priv->preload != NULL)
 				g_free (priv->preload);
@@ -413,8 +427,8 @@ eog_full_screen_hide (GtkWidget *widget)
 	if (fs->priv->slide_show) {
 		g_source_remove (fs->priv->switch_timeout_id);
 		fs->priv->switch_timeout_id = 0;
-	}
-	
+	}	
+
 	if (fs->priv->activity_timeout_id > 0) {
 		g_source_remove (fs->priv->activity_timeout_id);
 		fs->priv->activity_timeout_id = 0;
@@ -538,7 +552,7 @@ eog_full_screen_key_press (GtkWidget *wi
 	}
 
 	if (do_hide) {
-		cancel_load_by_iter (priv->list, priv->preload);
+		cancel_load_by_iter (priv->list, priv->preload, fs);
 		if (priv->preload != NULL) {
 			g_free (priv->preload);
 			priv->preload = NULL;
@@ -571,6 +585,11 @@ eog_full_screen_destroy (GtkObject *obje
 		g_source_remove (priv->hide_timeout_id);
 		priv->hide_timeout_id = 0;
 	}
+	
+	if (priv->display_id != 0) {
+		g_source_remove (priv->display_id);
+		priv->display_id = 0;
+	}
 
 	if (priv->current != NULL) {
 		g_free (priv->current);
@@ -675,44 +694,24 @@ eog_full_screen_set_geometry (EogFullScr
 	gtk_window_move (GTK_WINDOW (fs), geometry.x, geometry.y);
 }
 
-typedef struct {
-	EogFullScreen *fs;
-	EogImage      *image;
-} JobImageLoadData;
-
 static void
-job_image_load_do (EogJob *job, gpointer data, GError **error)
+load_finished_cb  (EogJobLoad *job, gpointer data)
 {
-	EogImage *image = ((JobImageLoadData*) data)->image;
-
-	eog_image_load (image, EOG_IMAGE_DATA_IMAGE, job, error);
-}
-
-static void
-job_image_load_finished  (EogJob *job, gpointer data, GError *error)
-{
-	EogFullScreen *fs = ((JobImageLoadData*) data)->fs;
+	EogFullScreen *fs = (EogFullScreen*) data;
 	EogFullScreenPrivate *priv = fs->priv;
-	EogImage *image = ((JobImageLoadData*) data)->image;
+	EogImage *image = job->image;
 	EogImage *current_img;
 	EogImage *preload_img;
 
-	if (eog_job_get_status (job) == EOG_JOB_STATUS_CANCELED) {
-		g_object_set_qdata (G_OBJECT (image), JOB_ID_QUARK, NULL);
-		eog_image_data_unref (image);
-		return;
-	}
-
-	if (eog_job_get_success (job))
-		eog_image_cache_add (priv->cache, image);
+	eog_image_cache_add (priv->cache, image);
 
 	/* check if the finished image is the one we want to display now */
 	current_img = eog_image_list_get_img_by_iter (priv->list, priv->current);
 	if (current_img == image) {
-		if (eog_job_get_success (job))
+		if (EOG_JOB (job)->finished)
 			eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), image);
-		else 
-			eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), NULL);
+ 		else 
+ 			eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), NULL);
 	}
 	if (current_img != NULL) 
 		g_object_unref (current_img);
@@ -731,14 +730,6 @@ job_image_load_finished  (EogJob *job, g
 	eog_image_data_unref (image);
 }
 
-static void
-job_image_load_cancel (EogJob *job, gpointer data)
-{
-	EogImage *image = ((JobImageLoadData*) data)->image;
-
-	eog_image_cancel_load (image);
-}
-
 static guint
 prepare_load_image (EogFullScreen *fs, EogIter *iter)
 {
@@ -746,7 +737,6 @@ prepare_load_image (EogFullScreen *fs, E
 	EogImage *image;
 	EogJob *job;
 	guint job_id = 0;
-	JobImageLoadData *ld;
 
 	priv = fs->priv;
 	
@@ -758,23 +748,18 @@ prepare_load_image (EogFullScreen *fs, E
 		eog_image_data_unref (image);
 		return 0;
 	}
-
-	ld = g_new0 (JobImageLoadData, 1);
-	ld->image = image;
-	ld->fs = fs;
-	
-	job = eog_job_new_full (ld,
-				job_image_load_do,
-				job_image_load_finished,
-				job_image_load_cancel,
-				NULL,
-				g_free);
 	
-	job_id = eog_job_get_id (job);
-	g_object_set_qdata (G_OBJECT (image), JOB_ID_QUARK, GUINT_TO_POINTER (job_id));
+	job = eog_job_load_new (image);
+	g_signal_connect (G_OBJECT (job), 
+			  "finished", 
+			  G_CALLBACK (load_finished_cb), 
+			  fs);
+	g_object_set_qdata (G_OBJECT (image), JOB_ID_QUARK,
+			    g_object_ref (job));
+	eog_job_queue_add_job (job);
+	g_object_unref (job);
+	
 	
-	eog_job_manager_add (job);
-
 	return job_id;
 }
 
Index: libeog/eog-image-list.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image-list.h,v
retrieving revision 1.7
diff -u -p -r1.7 eog-image-list.h
--- libeog/eog-image-list.h	13 Nov 2005 18:25:08 -0000	1.7
+++ libeog/eog-image-list.h	12 Dec 2006 15:37:47 -0000
@@ -8,6 +8,11 @@
 
 G_BEGIN_DECLS
 
+#ifndef __EOG_IMAGE_DECLR__
+#define __EOG_IMAGE_DECLR__
+  typedef struct _EogImage EogImage;
+#endif
+
 
 #define EOG_TYPE_IMAGE_LIST            (eog_image_list_get_type ())
 #define EOG_IMAGE_LIST(o)         (G_TYPE_CHECK_INSTANCE_CAST ((o), EOG_TYPE_IMAGE_LIST, EogImageList))
@@ -16,7 +21,10 @@ G_BEGIN_DECLS
 #define EOG_IS_IMAGE_LIST_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), EOG_TYPE_IMAGE_LIST))
 #define EOG_IMAGE_LIST_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), EOG_TYPE_IMAGE_LIST, EogImageListClass))
 
-typedef struct _EogImageList EogImageList;
+#ifndef __EOG_IMAGE_LIST_DECLR__
+#define __EOG_IMAGE_LIST_DECLR__
+  typedef struct _EogImageList EogImageList;
+#endif
 typedef struct _EogImageListClass EogImageListClass;
 typedef struct _EogImageListPrivate EogImageListPrivate;
 
Index: libeog/eog-image-private.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image-private.h,v
retrieving revision 1.18
diff -u -p -r1.18 eog-image-private.h
--- libeog/eog-image-private.h	27 Sep 2006 10:14:26 -0000	1.18
+++ libeog/eog-image-private.h	12 Dec 2006 15:37:47 -0000
@@ -50,7 +50,6 @@ struct _EogImagePrivate {
 	gchar *caption_key;
 
 	GThread *load_thread;
-	GMutex *mutex;
 	GMutex *status_mutex;
 	GCond  *load_finished;
 	gboolean cancel_loading;
Index: libeog/eog-image.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image.c,v
retrieving revision 1.76
diff -u -p -r1.76 eog-image.c
--- libeog/eog-image.c	20 Nov 2006 20:53:05 -0000	1.76
+++ libeog/eog-image.c	12 Dec 2006 15:37:47 -0000
@@ -100,11 +100,6 @@ eog_image_dispose (GObject *object)
 		priv->error_message = NULL;
 	}
 
-	if (priv->mutex) {
-		g_mutex_free (priv->mutex);
-		priv->mutex = NULL;
-	}
-	
 	if (priv->status_mutex) {
 		g_mutex_free (priv->status_mutex);
 		priv->status_mutex = NULL;
@@ -252,7 +247,6 @@ eog_image_init (EogImage *img)
 	priv->thumbnail = NULL;
 	priv->width = priv->height = -1;
 	priv->modified = FALSE;
-	priv->mutex = g_mutex_new ();
 	priv->status_mutex = g_mutex_new ();
 	priv->load_finished = NULL;
 	priv->error_message = NULL;
@@ -267,24 +261,6 @@ eog_image_init (EogImage *img)
 	img->priv = priv;
 }
 
-void eog_image_lock (EogImage *image)
-{
-        g_return_if_fail (EOG_IS_IMAGE (image));
-	g_return_if_fail (image->priv != NULL);
-	g_return_if_fail (image->priv->mutex != NULL);
-
-	g_mutex_lock (image->priv->mutex);
-}
-
-void eog_image_unlock (EogImage *image)
-{
-        g_return_if_fail (EOG_IS_IMAGE (image));
-	g_return_if_fail (image->priv != NULL);
-	g_return_if_fail (image->priv->mutex != NULL);
-
-	g_mutex_unlock (image->priv->mutex);
-}
-
 EogImage* 
 eog_image_new_uri (GnomeVFSURI *uri)
 {
@@ -855,21 +831,8 @@ eog_image_load (EogImage *img, guint dat
 			   eog_image_get_caption (img));
 	}
 
-	if (priv->status == EOG_IMAGE_STATUS_FAILED) {
-		g_set_error (error, EOG_IMAGE_ERROR, EOG_IMAGE_ERROR_NOT_LOADED, 
-			     priv->error_message);
-		return FALSE;
-	}
-	
 	priv->status = EOG_IMAGE_STATUS_LOADING;
 
-	/* if transformations will be need, the number of job parts should be increased */
-	if (eog_image_needs_transformation (img) && job != NULL) {
-		guint n_parts;
-		g_object_get (G_OBJECT (job), "progress-n-parts", &n_parts, NULL);
-		g_object_set (G_OBJECT (job), "progress-n-parts", ++n_parts, NULL);
-	}
-
 	/* Read the requested data from the image */
 	success = eog_image_real_load (img, data2read, job, error);
 
@@ -879,9 +842,6 @@ eog_image_load (EogImage *img, guint dat
 
 	/* perform required transformation */
 	if (eog_image_needs_transformation (img)) {
-		if (job != NULL) {
-			eog_job_part_finished (job);
-		}
 		if (success) {
 			success = eog_image_apply_transformations (img, job, error);
 		}
@@ -895,10 +855,11 @@ eog_image_load (EogImage *img, guint dat
 		priv->status = EOG_IMAGE_STATUS_FAILED;
 
 		/* set the image error message */
-		if (priv->error_message != NULL) {
-			g_free (priv->error_message);
-		}
-		priv->error_message = g_strdup((*error)->message);
+		/* FIXME: This exists no longer in eog-ng */
+/* 		if (priv->error_message != NULL) { */
+/* 			g_free (priv->error_message); */
+/* 		} */
+/* 		priv->error_message = g_strdup((*error)->message); */
 	}
 
 	return success;
@@ -1583,7 +1544,7 @@ eog_image_free_mem_private (EogImage *im
 
 #ifdef HAVE_LCMS
 		if (priv->profile != NULL) {
-		  cmsCloseProfile (priv->profile);
+			cmsCloseProfile (priv->profile);
 		}
 #endif
 		
Index: libeog/eog-image.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-image.h,v
retrieving revision 1.30
diff -u -p -r1.30 eog-image.h
--- libeog/eog-image.h	18 Nov 2006 19:51:03 -0000	1.30
+++ libeog/eog-image.h	12 Dec 2006 15:37:48 -0000
@@ -7,7 +7,7 @@
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include "eog-transform.h"
 #include "eog-image-save-info.h"
-#include "eog-job.h"
+#include "eog-jobs.h"
 
 #ifdef HAVE_LCMS
 #include <lcms.h>
@@ -22,7 +22,10 @@ G_BEGIN_DECLS
 #define EOG_IS_IMAGE_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), EOG_TYPE_IMAGE))
 #define EOG_IMAGE_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), EOG_TYPE_IMAGE, EogImageClass))
 
-typedef struct _EogImage EogImage;
+#ifndef __EOG_IMAGE_DECLR__
+#define __EOG_IMAGE_DECLR__
+  typedef struct _EogImage EogImage;
+#endif
 typedef struct _EogImageClass EogImageClass;
 typedef struct _EogImagePrivate EogImagePrivate;
 
Index: libeog/eog-thumbnail.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-thumbnail.c,v
retrieving revision 1.8
diff -u -p -r1.8 eog-thumbnail.c
--- libeog/eog-thumbnail.c	20 Nov 2006 20:53:05 -0000	1.8
+++ libeog/eog-thumbnail.c	12 Dec 2006 15:37:49 -0000
@@ -176,7 +176,7 @@ eog_thumb_data_new (GnomeVFSURI *uri, GE
 
 
 GdkPixbuf*
-eog_thumbnail_load (GnomeVFSURI *uri, EogJob *job, GError **error)
+eog_thumbnail_load (GnomeVFSURI *uri, GError **error)
 {
 	GdkPixbuf *thumb = NULL;
 	EogThumbData *data;
Index: libeog/eog-thumbnail.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-thumbnail.h,v
retrieving revision 1.3
diff -u -p -r1.3 eog-thumbnail.h
--- libeog/eog-thumbnail.h	20 Nov 2006 20:53:05 -0000	1.3
+++ libeog/eog-thumbnail.h	12 Dec 2006 15:37:49 -0000
@@ -2,13 +2,13 @@
 #define _EOG_THUMBNAIL_H_
 
 #include <libgnomevfs/gnome-vfs.h>
-#include "eog-job.h"
+#include "eog-jobs.h"
 
 G_BEGIN_DECLS
 
 void          eog_thumbnail_init (void);
 
-GdkPixbuf*    eog_thumbnail_load (GnomeVFSURI *uri, EogJob *job, GError **error);
+GdkPixbuf*    eog_thumbnail_load (GnomeVFSURI *uri, GError **error);
 
 
 G_END_DECLS
Index: libeog/eog-transform.c
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-transform.c,v
retrieving revision 1.10
diff -u -p -r1.10 eog-transform.c
--- libeog/eog-transform.c	20 Nov 2006 20:53:05 -0000	1.10
+++ libeog/eog-transform.c	12 Dec 2006 15:37:49 -0000
@@ -7,6 +7,7 @@
 #include <math.h>
 #include <libart_lgpl/art_affine.h>
 #include "eog-transform.h"
+#include "eog-jobs.h"
 
 #define PROFILE 1
 
Index: libeog/eog-transform.h
===================================================================
RCS file: /cvs/gnome/eog/libeog/eog-transform.h,v
retrieving revision 1.4
diff -u -p -r1.4 eog-transform.h
--- libeog/eog-transform.h	14 Mar 2005 20:35:13 -0000	1.4
+++ libeog/eog-transform.h	12 Dec 2006 15:37:49 -0000
@@ -3,7 +3,6 @@
 
 #include <glib-object.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include "eog-job.h"
 
 G_BEGIN_DECLS
 
@@ -29,7 +28,14 @@ typedef enum {
 
    ----------------------------------------*/
 
-typedef struct _EogTransform EogTransform;
+#ifndef __EOG_TRANSFORM_DECLR__
+#define __EOG_TRANSFORM_DECLR__
+  typedef struct _EogTransform EogTransform;
+#endif
+#ifndef __EOG_JOB_DECLR__
+#define __EOG_JOB_DECLR__
+  typedef struct _EogJob EogJob;
+#endif
 typedef struct _EogTransformClass EogTransformClass;
 typedef struct _EogTransformPrivate EogTransformPrivate;
 
Index: shell/eog-window.c
===================================================================
RCS file: /cvs/gnome/eog/shell/eog-window.c,v
retrieving revision 1.210
diff -u -p -r1.210 eog-window.c
--- shell/eog-window.c	20 Nov 2006 20:53:06 -0000	1.210
+++ shell/eog-window.c	12 Dec 2006 15:38:03 -0000
@@ -56,7 +56,7 @@
 #include "eog-save-dialog-helper.h"
 #include "eog-save-as-dialog-helper.h"
 #include "eog-pixbuf-util.h"
-#include "eog-job-manager.h"
+#include "eog-job-queue.h"
 
 #if HAVE_LCMS
 #include <X11/Xlib.h>
@@ -66,7 +66,6 @@
 
 #include <gtk/gtkprintunixdialog.h>
 
-
 #ifdef G_OS_WIN32
 
 #define getgid() 0
@@ -98,9 +97,6 @@ struct _EogWindowPrivate {
 	EogImageList        *image_list;
 	EogImage            *displayed_image;
 
-        /* The next image to display. */
-        EogImage            *next_image;
-
 	/* ui/widget stuff */
 	GtkUIManager        *ui_mgr;
 	GtkWidget           *box;
@@ -145,6 +141,10 @@ struct _EogWindowPrivate {
 	guint sig_id_progress;
 	guint sig_id_loading_finished;
 	guint sig_id_loading_failed;
+
+	/* jobs we may wish to cancel at some stage */
+	EogJob *load_job;
+	EogJob *transform_job;
 };
 
 enum {
@@ -173,7 +173,9 @@ static void eog_window_drag_data_receive
 static void adapt_window_size (EogWindow *window, int width, int height);
 #endif
 static void update_status_bar (EogWindow *window);
-static void job_default_progress (EogJob *job, gpointer data, float progress);
+static void job_default_progress_cb (EogJob *job, float progress, gpointer data);
+static void eog_job_transform_cb (EogJobTransform *job, gpointer data);
+static void eog_job_load_cb (EogJobLoad *job, gpointer data);
 static void add_uri_to_recent_files (EogWindow *window, GnomeVFSURI *uri);
 
 static GtkWindowClass *parent_class;
@@ -999,1057 +1001,121 @@ verb_ShowHideAnyBar_cb (GtkAction *actio
 	}
 }
 
-/* ================================================
- *
- *             Save functions 
- * 
- * -----------------------------------------------*/
-
-typedef enum {
-	EOG_SAVE_RESPONSE_NONE,
-	EOG_SAVE_RESPONSE_RETRY,
-	EOG_SAVE_RESPONSE_SKIP,
-	EOG_SAVE_RESPONSE_OVERWRITE,
-	EOG_SAVE_RESPONSE_CANCEL
-} EogSaveResponse;
-
-typedef struct {
-	/* all images */
-	GList     *images;
-	int        n_images;
-	int        n_processed;
-
-	/* image currently processed */
-	EogImage         *current;
-	EogImageSaveInfo *source; 
-	EogImageSaveInfo *dest; /* destination */
-	EogURIConverter  *conv;
-
-	/* dialog handling */
-	EogWindow  *window;
-	GtkWindow  *dlg;
-
-	gboolean   cancel_save;
-	GMutex     *lock;
-	guint      job_id;
-} SaveData;
-
-typedef struct {
-	EogWindow   *window;
-	EogImage    *image;
-	EogImageSaveInfo *dest;
-	
-	GError      *error;
-	EogSaveResponse response;
-	GCond       *wait;
-	GMutex      *lock;
-} SaveErrorData;
-
-static gboolean
-save_dialog_update_finished (SaveData *data)
-{
-	eog_save_dialog_finished_image (data->dlg);
-	return FALSE;
-}
-
-static gboolean
-save_dialog_update_start_image (SaveData *data)
-{
-	GnomeVFSURI* uri = NULL;
-	EogImage *image = NULL;
-
-	g_mutex_lock (data->lock);
-	if (data->current != NULL) {
-		image = g_object_ref (data->current);
-	} 
-	if (data->dest != NULL) {
-		uri = gnome_vfs_uri_ref (data->dest->uri);
-	}
-	g_mutex_unlock (data->lock);
-
-	eog_save_dialog_start_image (data->dlg,
-				     image, uri);
-		
-	if (image != NULL) 
-		g_object_unref (image);
-	if (uri != NULL) 
-		gnome_vfs_uri_unref (uri);
-
-	return FALSE;
-}
-
 static void
-save_dialog_cancel_cb (GtkWidget *button, SaveData *data)
-{
-	eog_job_manager_cancel_job (data->job_id);
-}
-
-#if 0
-static gboolean
-save_update_image (EogImage *image)
-{
-	if (EOG_IS_IMAGE (image)) {
-		eog_image_modified (image);
-		g_object_unref (image);
-	}
-	
-	return FALSE;
-}
-#endif
-
-static gboolean
-save_error (SaveErrorData *edata)
-{
-	GtkWidget *dlg;
-	char *header;
-	char *detail = NULL;
-	int   response;
-	gint  err_code = 0;
-	
-	g_mutex_lock (edata->lock);
-	if (edata->error != NULL) {
-		detail   = edata->error->message;
-		err_code = edata->error->code;
-	}
-	g_mutex_unlock (edata->lock);
-
-	/* display generic error dialog, except for FILE_EXISTS error */
-	if (err_code == EOG_IMAGE_ERROR_FILE_EXISTS) {
-		char *str;
-
-	       	str = gnome_vfs_uri_to_string (edata->dest->uri, 
-					       GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD);
-		
-		header = g_strdup_printf (_("Overwrite file %s?"), str);
-		detail = _("File exists. Do you want to overwrite it?");
-		g_free (str);
-
-		dlg = gtk_message_dialog_new (GTK_WINDOW (edata->window),
-					      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					      GTK_MESSAGE_ERROR,
-					      GTK_BUTTONS_NONE,
-					      header);
-		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
-							  detail);
-
-		gtk_dialog_add_button (GTK_DIALOG (dlg), _("Skip"), EOG_SAVE_RESPONSE_SKIP);
-		gtk_dialog_add_button (GTK_DIALOG (dlg), _("Overwrite"), EOG_SAVE_RESPONSE_OVERWRITE);
-		gtk_dialog_add_button (GTK_DIALOG (dlg), GTK_STOCK_CANCEL, EOG_SAVE_RESPONSE_CANCEL);
-		gtk_dialog_set_default_response (GTK_DIALOG (dlg), EOG_SAVE_RESPONSE_SKIP);
-	}
-	else {
-		header = g_strdup_printf (_("Error on saving %s."), eog_image_get_caption (edata->image));
-
-		dlg = gtk_message_dialog_new (GTK_WINDOW (edata->window),
-					      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					      GTK_MESSAGE_ERROR,
-					      GTK_BUTTONS_NONE,
-					      header);
-		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
-							  detail);
-	
-		gtk_dialog_add_button (GTK_DIALOG (dlg), _("Skip"), EOG_SAVE_RESPONSE_SKIP);
-		gtk_dialog_add_button (GTK_DIALOG (dlg), _("Retry"), EOG_SAVE_RESPONSE_RETRY);
-		gtk_dialog_add_button (GTK_DIALOG (dlg), GTK_STOCK_CANCEL, EOG_SAVE_RESPONSE_CANCEL);
-		gtk_dialog_set_default_response (GTK_DIALOG (dlg), EOG_SAVE_RESPONSE_SKIP);
-	}
-	
-	gtk_widget_show_all (dlg);
-
-	response = gtk_dialog_run (GTK_DIALOG (dlg));
-	gtk_widget_destroy (dlg);
-	g_free (header);
-	
-	g_mutex_lock (edata->lock);
-	edata->response = (EogSaveResponse) response;
-	g_mutex_unlock (edata->lock);
-	g_cond_broadcast (edata->wait);
-
-	return FALSE;
-}
-
-static void
-job_save_image_finished (EogJob *job, gpointer user_data, GError *error)
-{
-	SaveData *data = (SaveData*) user_data;
-	
-	eog_save_dialog_close (data->dlg, !data->cancel_save);
-
-	/* enable image modification functions */
-	gtk_action_group_set_sensitive (data->window->priv->actions_image,  TRUE);
-
-	/* Only set window title on "Save As" with a single image */
-	g_mutex_lock (data->lock);
-	if (data->dest != NULL && data->n_images == 1) {
-		gtk_window_set_title (GTK_WINDOW (data->window), 
-				      eog_image_get_caption (EOG_IMAGE (data->images->data)));
-	}
-
-	gtk_window_set_icon (GTK_WINDOW (data->window), 
-			     eog_image_get_pixbuf_thumbnail (EOG_IMAGE (data->images->data)));
-
-	g_mutex_unlock (data->lock);
-}
-
-static SaveData*
-save_data_new (EogWindow *window, GList *images)
-{
-	SaveData *data;
-
-	g_return_val_if_fail (EOG_IS_WINDOW (window), NULL);
-	g_return_val_if_fail (images != NULL, NULL);
-
-	data = g_new0 (SaveData, 1);
-	g_assert (data != NULL);
-
-	/* initialise data struct */
-	data->images      = images; 
-	data->n_images    = g_list_length (images);
-	data->n_processed = 0;
-	
-	data->current = NULL;
-	data->source  = NULL;
-	data->dest    = NULL;
-	data->conv    = NULL;
-
-	data->cancel_save = FALSE;
-
-	data->lock = g_mutex_new ();
-
-	data->window = window;
-	data->dlg = GTK_WINDOW (eog_save_dialog_new (GTK_WINDOW (window), data->n_images));
-
-	return data;
-}
-
-static void
-job_save_data_free (gpointer user_data)
-{
-	SaveData *data = (SaveData*) user_data;
-
-	g_mutex_lock (data->lock);
-
-	g_list_foreach (data->images, (GFunc) g_object_unref, NULL);
-	g_list_free (data->images);
-
-	if (data->source)
-		g_object_unref (data->source);
-
-	if (data->dest)
-		g_object_unref (data->dest);
-
-	if (data->conv)
-		g_object_unref (data->conv);
-	g_mutex_unlock (data->lock);
-
-	g_mutex_free (data->lock);
-	g_free (data);
-}
-
-static void
-job_save_image_cancel (EogJob *job, gpointer user_data)
+verb_Save_cb (GtkAction *action, gpointer user_data)
 {
-	SaveData *data = (SaveData*) user_data;
-
-	g_mutex_lock (data->lock);
-	data->cancel_save = TRUE;
-	if (data->current != NULL) {
-		eog_image_cancel_load (EOG_IMAGE (data->current));
-	}
-	g_mutex_unlock (data->lock);
-
-	eog_save_dialog_cancel (data->dlg);
+	g_print ("this is a partial patch... "
+		 "don't expect everything to work!\n");
 }
 
 static void
-job_save_image_progress (EogJob *job, gpointer user_data, float progress)
-{
-	SaveData *data = (SaveData*) user_data;
-
-	eog_save_dialog_set_progress (data->dlg, progress);
-}
-
-static SaveErrorData*
-save_error_data_new (GError *error, EogWindow *window, EogImage *image, EogImageSaveInfo *dest)
+verb_PageSetup_cb (GtkAction *action, gpointer data)
 {
-	SaveErrorData *edata;
-
-	g_return_val_if_fail (EOG_IS_WINDOW (window), NULL);
-	g_return_val_if_fail (EOG_IS_IMAGE (image), NULL);
-
-	edata = g_new0 (SaveErrorData, 1);
-	edata->error    = NULL;
-	edata->response = EOG_SAVE_RESPONSE_NONE;
-	edata->wait     = g_cond_new ();
-	edata->lock     = g_mutex_new ();
-	edata->window   = window;
-	edata->image    = g_object_ref (image);
-	edata->dest     = dest;
-
-	if (error != NULL) {
-		edata->error    = g_error_copy (error); 
-	}
+	EogWindow *window = EOG_WINDOW (data);
 	
-	return edata;
+	eog_window_page_setup (window);
 }
 
 static void
-save_error_data_free (SaveErrorData *edata)
-{
-	if (edata == NULL)
-		return;
-
-	if (edata->error != NULL) {
-		g_error_free (edata->error);
-	}
-	g_cond_free  (edata->wait);
-	g_mutex_free (edata->lock);
-	g_object_unref (edata->image);
-	g_free (edata);
-}
-
-static gboolean
-job_save_handle_error (SaveData *data, EogImage *image, GError *error)
-{
-	SaveErrorData *edata;
-	gboolean success = FALSE;
-
-	edata = save_error_data_new (error, data->window, image, data->dest);
-	
-	g_mutex_lock (edata->lock);
-	g_idle_add ((GSourceFunc) save_error, edata);
-	/* wait for error dialog response */
-	g_cond_wait (edata->wait, edata->lock);
-	g_mutex_unlock (edata->lock);
-	
-	/* handle results */
-	switch (edata->response) {
-	case EOG_SAVE_RESPONSE_SKIP:
-		success = TRUE;
-		break;
-	case EOG_SAVE_RESPONSE_CANCEL:
-		data->cancel_save = TRUE;
-		break;
-	case EOG_SAVE_RESPONSE_OVERWRITE:
-		g_assert (data->dest != NULL);
-		if (data->dest != NULL) {
-			data->dest->overwrite = TRUE;
-		}
-		break;
-	case EOG_SAVE_RESPONSE_RETRY:
-		success = FALSE;
-		break;
-	default:
-		g_assert_not_reached ();
-	}
-	save_error_data_free (edata);
-
-	return success;
-}
-
-static gboolean
-job_save_image_single (EogJob *job, SaveData *data, EogImage *image, GError **error)
+verb_Print_cb (GtkAction *action, gpointer data)
 {
-	EogImageSaveInfo *info = NULL;
-	gboolean success = FALSE;
-
-	g_return_val_if_fail (EOG_IS_IMAGE (image), FALSE);
-	g_return_val_if_fail (EOG_IS_JOB (job), FALSE);
-
-	/* increase object and data ref count */
-	eog_image_data_ref (image);
-
-	while (!success && !data->cancel_save) {
-		if (*error != NULL) {
-			g_error_free (*error);
-			*error = NULL;
-		}
-
-		success = eog_image_has_data (image, EOG_IMAGE_DATA_ALL);
-		if (!success) {
-			success = eog_image_load (image, EOG_IMAGE_DATA_ALL, job, error);
-		}
-
-		if (info == NULL) 
-			info = eog_image_save_info_from_image (image);
-#ifdef SAVE_DEBUG
-		g_print ("Save image at %s ", 
-			 gnome_vfs_uri_to_string (info->uri, GNOME_VFS_URI_HIDE_NONE));
-#endif
-
-		if (success) {
-			success = eog_image_save_by_info (image, info, job, error);
-		}
-#ifdef SAVE_DEBUG
-		g_print ("successful: %i\n", success);
-#endif
-		
-		/* handle errors, let user decide how to proceede */
-		if (!success && !data->cancel_save) {
-			success = job_save_handle_error (data, image, *error);
-		}
-	}
-
-	if (info != NULL)
-		g_object_unref (info);
-	
-	eog_image_data_unref (image);
+	EogWindow *window = EOG_WINDOW (data);
 
-	return (success && !data->cancel_save);
+	eog_window_print (window);
 }
 
-/* this runs in its own thread */
 static void
-job_save_image_list (EogJob *job, gpointer user_data, GError **error)
+verb_SaveAs_cb (GtkAction *action, gpointer data)
 {
-	SaveData *data; 
-	GList *it;
-	EogImage *image;
-	gboolean success;
-
-	data = (SaveData*) user_data;
-
-	for (it = data->images; it != NULL && !data->cancel_save; it = it->next) {
-		image = EOG_IMAGE (it->data);
-
-		g_mutex_lock (data->lock);
-		data->current = image;
-		g_mutex_unlock (data->lock);
-
-		save_dialog_update_start_image (data);
-
-		success = job_save_image_single (job, data, image, error);
-
-		g_mutex_lock (data->lock);
-		data->current = NULL;
-		g_mutex_unlock (data->lock);
-
-		save_dialog_update_finished (data);
-
-		eog_job_part_finished (job);
-	}
+	g_print ("this is a partial patch... "
+		 "don't expect everything to work!\n");
 }
 
-
 static void
-verb_Save_cb (GtkAction *action, gpointer user_data)
+eog_window_clear_load_job (EogWindow *window)
 {
-	EogWindowPrivate *priv;
-	int n_images;
-	SaveData *data;
-	EogJob *job;
-	GtkWidget *button;
-
-	priv = EOG_WINDOW (user_data)->priv;
-
-	n_images = eog_wrap_list_get_n_selected (EOG_WRAP_LIST (priv->wraplist));
-	if (n_images == 0) return;
-
-	/* init save data */
-	data = save_data_new (EOG_WINDOW (user_data), 
-			      eog_wrap_list_get_selected_images (EOG_WRAP_LIST (priv->wraplist)));
-	g_assert (data != NULL);
-	g_assert (GTK_IS_WINDOW (data->dlg));
-
-	/* connect to cancel button */
-	button = eog_save_dialog_get_button (GTK_WINDOW (data->dlg));
-	g_signal_connect (G_OBJECT (button), "clicked", (GCallback) save_dialog_cancel_cb, data);
-
-	/* disable image modification functions */
-	gtk_action_group_set_sensitive (priv->actions_image,  FALSE);
-
-	/* show dialog */
-	gtk_widget_show_all (GTK_WIDGET (data->dlg));
-	gtk_widget_show_now (GTK_WIDGET (data->dlg));
-
-	/* start job */
-	job = eog_job_new_full (data,
-				job_save_image_list,
-				job_save_image_finished,
-				job_save_image_cancel,
-				job_save_image_progress,
-				job_save_data_free);
-	g_object_set (G_OBJECT (job), "progress-n-parts", data->n_images, NULL);
-
-	data->job_id = eog_job_manager_add (job);
-	g_object_unref (G_OBJECT (job));
-}
-
-static gboolean
-job_save_as_image_single (EogJob *job, EogImage *image, SaveData *data, GError **error)
-{
-	EogImageSaveInfo *source = NULL;
-	EogImageSaveInfo *dest;
-	gboolean success;
+	EogWindowPrivate *priv = window->priv;
 	
-	g_return_val_if_fail (EOG_IS_JOB (job), FALSE);
-	g_return_val_if_fail (EOG_IS_IMAGE (image), FALSE);
-	g_return_val_if_fail (data != NULL, FALSE);
-	g_return_val_if_fail (error != NULL, FALSE);
+	if (priv->load_job != NULL) {
+		if (!priv->load_job->finished)
+			eog_job_queue_remove_job (priv->load_job);
 
-	dest = data->dest;
-	g_return_val_if_fail (EOG_IS_IMAGE_SAVE_INFO (dest), FALSE);
+		g_signal_handlers_disconnect_by_func (priv->load_job, 
+						      eog_job_load_cb, 
+						      window);
 
-	eog_image_data_ref (image);
+		g_signal_handlers_disconnect_by_func (priv->load_job, 
+						      job_default_progress_cb, 
+						      window);
 
-	/* try to save image source to destination */
-	success = FALSE;
-	while (!success && !data->cancel_save) {
-		if (*error != NULL) {
-			g_error_free (*error);
-			*error = NULL;
-		}
+		eog_image_cancel_load (EOG_JOB_LOAD (priv->load_job)->image);
 
-		success = eog_image_has_data (image, EOG_IMAGE_DATA_ALL);
-		if (!success) {
-			success = eog_image_load (image, EOG_IMAGE_DATA_ALL, job, error);
-		}
-		
-		if (success && source == NULL) {
-			source = eog_image_save_info_from_image (image);
-			success = (source != NULL);
-		}
-
-#ifdef SAVE_DEBUG
-		g_print ("Saving image from: %s to: %s\n", 
-			 (source != NULL) ?
-			 gnome_vfs_uri_to_string (source->uri, GNOME_VFS_URI_HIDE_NONE) : "NULL",
-			 (dest != NULL) ? 
-			 gnome_vfs_uri_to_string (dest->uri, GNOME_VFS_URI_HIDE_NONE) : "NULL");
-#endif
-
-		if (success) {
-			success = eog_image_save_as_by_info (image, source, dest, job, error);
-		}
-#ifdef SAVE_DEBUG
-		g_print ("successful: %i\n", success);
-#endif
-		if (source != NULL) {
-			g_object_unref (source);
-			source = NULL;
-		}
-
-		if (!success && !data->cancel_save) {
-			/* handle error case */
-			success = job_save_handle_error (data, image, *error);
-		}
+		g_object_unref (priv->load_job);
+		priv->load_job = NULL;
+		/* Hide statusbar */
+ 		eog_statusbar_set_progress (EOG_STATUSBAR (priv->statusbar), 1);
 	}
-	
-	eog_image_data_unref (image);
-	eog_job_set_progress (job, 1.0);
-
-	return success;
 }
 
-/* this runs in its own thread */
-/* does the actual work */
 static void
-job_save_as_image_list (EogJob *job, gpointer user_data, GError **error)
+eog_window_clear_transform_job (EogWindow *window)
 {
-	SaveData *data;
-	GList *it;
-	EogImage *image;
-
-	data = (SaveData*) user_data;
+	EogWindowPrivate *priv = window->priv;
 	
-	g_assert (data->conv != NULL || data->dest != NULL);
+	if (priv->transform_job != NULL) {
+		if (!priv->transform_job->finished)
+			eog_job_queue_remove_job (priv->transform_job);
 	
-	for (it = data->images; it != NULL && !data->cancel_save; it = it->next) {
-		
-		image = EOG_IMAGE (it->data);
-
-		g_mutex_lock (data->lock);
-		data->current = image;
-		g_mutex_unlock (data->lock);
-
-		save_dialog_update_start_image (data);
-	
-		/* obtain destination information */
-		if (data->conv != NULL) {
-			GdkPixbufFormat *format;
-			GnomeVFSURI *dest_uri;
-			gboolean result;
-
-			result = eog_uri_converter_do (data->conv,
-						       image, 
-						       &dest_uri,
-						       &format,
-						       error);
-
-			if (result == FALSE) {
-				g_set_error (error, 
-					     EOG_WINDOW_ERROR, EOG_WINDOW_ERROR_GENERIC,
-					     _("Couldn't determine destination uri."));
-				break; /* will leave for-loop */
-			}
-#ifdef SAVE_DEBUG
-			g_print ("convert uri: %s\n", gnome_vfs_uri_to_string (dest_uri, GNOME_VFS_URI_HIDE_NONE));
-#endif
-			
-			g_mutex_lock (data->lock);
-			/* set destination info for current image */
-			if (data->dest != NULL) {
-				g_object_unref (data->dest);
-				data->dest = NULL;
-			}
+		g_signal_handlers_disconnect_by_func (priv->transform_job, 
+						      eog_job_transform_cb, 
+						      window);
+		g_signal_handlers_disconnect_by_func (priv->transform_job, 
+						      job_default_progress_cb, 
+						      window);
 
-			data->dest = eog_image_save_info_from_vfs_uri (dest_uri, format);
-			g_mutex_unlock (data->lock);
-				
-			if (dest_uri)
-				gnome_vfs_uri_unref (dest_uri);
-		}
-
-		g_assert (data->dest != NULL);
-
-		/* try to save image */
-		if (!job_save_as_image_single (job, image, data, error)) {
-			g_warning ("no save_as success\n");
-		}
-
-		/* update job status */
-		save_dialog_update_finished (data);
-		eog_job_part_finished (job);
-
-		g_mutex_lock (data->lock);
-		data->current = NULL;
-		g_mutex_unlock (data->lock);
+		g_object_unref (priv->transform_job);
+		priv->transform_job = NULL;
 	}
 }
 
-static char* 
-get_folder_uri_from_image (EogImage *image)
-{
-	GnomeVFSURI *img_uri;
-	GnomeVFSURI *parent;
-	char *folder_uri = NULL;
-
-	g_return_val_if_fail (EOG_IS_IMAGE (image), NULL);
-
-	img_uri = eog_image_get_uri (image);
-
-	if (gnome_vfs_uri_has_parent (img_uri)) {
-		parent = gnome_vfs_uri_get_parent (img_uri);
-		folder_uri = gnome_vfs_uri_to_string (parent, GNOME_VFS_URI_HIDE_NONE);
-		gnome_vfs_uri_unref (parent);
-	}
-
-	gnome_vfs_uri_unref (img_uri);
-	return folder_uri;
-}
-
-/* Asks user for a file location to save an image there. Returns the save target uri
- * and the image format. The uri parameter is set to NULL if the user canceled the
- * dialog.
- */
-static void
-save_as_uri_selection_dialog (EogWindow *window, EogImage *image, char **uri, GdkPixbufFormat **format)
-{
-	GtkWidget *dlg;
-	gboolean success = FALSE;
-	gint response;
-	char *folder_uri = NULL;
-
-	g_return_if_fail (uri != NULL);
-	g_return_if_fail (format != NULL);
-	
-	*uri = NULL;
-	*format = NULL;
-
-	g_return_if_fail (EOG_IS_IMAGE (image));
-	g_return_if_fail (EOG_IS_WINDOW (window));
-
-	folder_uri = get_folder_uri_from_image (image);
-	if (folder_uri == NULL) {
-		g_warning ("Parent uri for %s not available.\n", eog_image_get_caption (image));
-		return;
-	}
-
-	dlg = eog_file_chooser_new (GTK_FILE_CHOOSER_ACTION_SAVE);
-	gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg),
-						 folder_uri);
-	while (!success) {
-		success = TRUE;
-		if (*uri != NULL) {
-			g_free (*uri);
-			*uri = NULL;
-		}
-
-		gtk_widget_show_all (dlg);
-		response = gtk_dialog_run (GTK_DIALOG (dlg));
-		gtk_widget_hide (dlg);
-
-		if (response == GTK_RESPONSE_OK) {
-			/* try to determine uri and image format */
-			*format = eog_file_chooser_get_format (EOG_FILE_CHOOSER (dlg));
-			*uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg));
-
-			if (*format == NULL && *uri != NULL) {
-				*format = eog_pixbuf_get_format_by_uri (*uri);
-			}
-				
-			success = (*format != NULL && *uri != NULL);
-		}
-		
-		if (!success) {
-			GtkWidget *err_dlg;
-			char *header;
-			char *detail;
-			char *short_name;
-			char *uesc_uri;
-
-			uesc_uri = gnome_vfs_unescape_string_for_display (*uri);
-			short_name = g_path_get_basename (uesc_uri);
-
-			header = g_strdup_printf (_("Couldn't determine file format of %s"), short_name);
-			detail = _("Please use an appropriate filename suffix or select a file format.");
-			
-			g_free (uesc_uri);
-			g_free (short_name);
-
-			err_dlg = gtk_message_dialog_new (GTK_WINDOW (window),
-							  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-							  GTK_MESSAGE_ERROR,
-							  GTK_BUTTONS_NONE,
-							  header);
-			gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dlg),
-							  	  detail);
-
-			gtk_dialog_add_button (GTK_DIALOG (err_dlg), _("Retry"), GTK_RESPONSE_OK);
-			gtk_dialog_add_button (GTK_DIALOG (err_dlg), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
-			gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
-			gtk_widget_show_all (err_dlg);
-			
-			response = gtk_dialog_run (GTK_DIALOG (err_dlg));
-			gtk_widget_destroy (err_dlg);
-			g_free (header);
-
-			if (response == GTK_RESPONSE_CANCEL) {
-				if (*uri != NULL) {
-					g_free (*uri);
-					*uri = NULL;
-				}
-				success = TRUE;
-			}
-		}
-	}
-
-	gtk_widget_destroy (dlg);
-}
-
-
-/* prepare load for a single image */
 static void
-save_as_single_image (EogWindow *window, EogImage *image)
-{
-	EogWindowPrivate *priv;
-	char *uri = NULL;
-	SaveData *data;
-	GdkPixbufFormat *format = NULL;
-	GtkWidget *button;
-	EogJob *job;
-
-	g_return_if_fail (EOG_IS_WINDOW (window));
-	g_return_if_fail (EOG_IS_IMAGE (image));
-
-	priv = window->priv;
-
-	save_as_uri_selection_dialog (window, image, &uri, &format);
-	if (uri == NULL)
-		return;
-
-	g_assert (uri != NULL && format != NULL);
-
-	data = save_data_new (window, g_list_append (NULL, image));
-	g_assert (data != NULL);
-	g_assert (GTK_IS_WINDOW (data->dlg));
-
-	data->dest = eog_image_save_info_from_uri (uri, format);
-	g_free (uri);
-
-	button = eog_save_dialog_get_button (GTK_WINDOW (data->dlg));
-	g_signal_connect (G_OBJECT (button), "clicked", (GCallback) save_dialog_cancel_cb, data);
-
-	/* disable image modification functions */
-	gtk_action_group_set_sensitive (priv->actions_image,  FALSE);
-
-	gtk_widget_show_all (GTK_WIDGET (data->dlg));
-	gtk_widget_show_now (GTK_WIDGET (data->dlg));
-
-	/* start job */
-	job = eog_job_new_full (data,
-				job_save_as_image_list, /* Save As for multiple images */
-				job_save_image_finished,
-				job_save_image_cancel,
-				job_save_image_progress,
-				job_save_data_free);
-	g_object_set (G_OBJECT (job), "progress-n-parts", data->n_images, NULL);
-
-	data->job_id = eog_job_manager_add (job);
-	g_object_unref (G_OBJECT (job));
-}
-
-static EogURIConverter*
-save_as_uri_converter_dialog (EogWindow *window, GList *images)
-{
-	EogURIConverter *conv = NULL;
-	GtkWidget *dlg;
-	char *base_dir;
-	GnomeVFSURI *base_uri;
-	gint response; 
-	gboolean success = FALSE;
-
-	g_return_val_if_fail (EOG_IS_WINDOW (window), NULL);
-	g_return_val_if_fail (images != NULL, NULL);
-	
-	if (g_list_length (images) < 2) return NULL;
-
-	base_dir = g_get_current_dir ();
-	base_uri = gnome_vfs_uri_new (base_dir);
-	g_free (base_dir);
-
-	/* function defined in ../libeog/eog-save-as-dialog-helper.h */
-	dlg = eog_save_as_dialog_new (GTK_WINDOW (window), images, 
-				      base_uri);
-
-	while (!success) {
-		GError *error = NULL;
-
-		if (conv != NULL) {
-			g_object_unref (conv);
-			conv = NULL;
-		}
-
-		gtk_widget_show_all (dlg);
-		response = gtk_dialog_run (GTK_DIALOG (dlg));
-		gtk_widget_hide (dlg);
-		
-		if (response != GTK_RESPONSE_OK) {
-			break;
-		}
-
-		conv = eog_save_as_dialog_get_converter (dlg);
-		g_assert (conv != NULL);
-
-		success = eog_uri_converter_check (conv, images, &error);
-
-		if (!success) {
-			GtkWidget *err_dlg;
-
-			err_dlg = gtk_message_dialog_new (GTK_WINDOW (window),
-							  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-							  GTK_MESSAGE_ERROR,
-							  GTK_BUTTONS_OK,
-							  _("Error on saving images."));
-			gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dlg),
-							  	  error->message);
-
-			gtk_dialog_run (GTK_DIALOG (err_dlg));
-			gtk_widget_destroy (err_dlg);
-
-			g_object_unref (conv);
-			conv = NULL;
-		}
-	}
-
-	gtk_widget_destroy (dlg);
-	gnome_vfs_uri_unref (base_uri);
-
-	return conv;
-}
-
-/* prepare load for multiple images */
-static void
-save_as_multiple_images (EogWindow *window, GList *images)
-{
-	EogURIConverter *conv = NULL;
-	GtkWidget *button;
-	SaveData *data;
-	EogJob *job;
-	
-	g_return_if_fail (EOG_IS_WINDOW (window));
-	g_return_if_fail (images != NULL);
-	
-	/* obtain uri converter for translating source uris
-	 *  to target uris 
-	 */
-	conv = save_as_uri_converter_dialog (window, images);
-	if (conv == NULL) {
-		return;
-	}
-#ifdef SAVE_DEBUG
-	eog_uri_converter_print_list (conv);
-#endif
-
-	/* prepare data */
-	data = save_data_new (window, images); 
-	data->conv = conv;
-	
-	g_assert (GTK_IS_WINDOW (data->dlg));
-	button = eog_save_dialog_get_button (GTK_WINDOW (data->dlg));
-	g_signal_connect (G_OBJECT (button), "clicked", (GCallback) save_dialog_cancel_cb, data);
-	
-	/* disable image modification functions */
-	gtk_action_group_set_sensitive (window->priv->actions_image,  FALSE);
-	
-	gtk_widget_show_all (GTK_WIDGET (data->dlg));
-	gtk_widget_show_now (GTK_WIDGET (data->dlg));
-	
-	/* start job */
-	job = eog_job_new_full (data,
-				job_save_as_image_list, /* Save As for multiple images */
-				job_save_image_finished,
-				job_save_image_cancel,
-				job_save_image_progress,
-				job_save_data_free);
-	g_object_set (G_OBJECT (job), "progress-n-parts", data->n_images, NULL);
-
-	data->job_id = eog_job_manager_add (job);
-	g_object_unref (G_OBJECT (job));
-}
-
-static void
-verb_PageSetup_cb (GtkAction *action, gpointer data)
-{
-	EogWindow *window = EOG_WINDOW (data);
-	
-	eog_window_page_setup (window);
-}
-
-static void
-verb_Print_cb (GtkAction *action, gpointer data)
+eog_job_transform_cb (EogJobTransform *job, gpointer data)
 {
-	EogWindow *window = EOG_WINDOW (data);
-
-	eog_window_print (window);
-}
-
-static void
-verb_SaveAs_cb (GtkAction *action, gpointer data)
-{
-	EogWindowPrivate *priv;
 	EogWindow *window;
-	int n_images;
 
 	window = EOG_WINDOW (data);
-	priv = window->priv;
-
-	n_images = eog_wrap_list_get_n_selected (EOG_WRAP_LIST (priv->wraplist));
-	if (n_images <= 0) return;
-
-	if (n_images == 1) {
-		EogImage *image;
-
-		image = eog_wrap_list_get_first_selected_image (EOG_WRAP_LIST (priv->wraplist));
-		save_as_single_image (window, image);
-	}
-	else {
-		GList *images;
-
-		images = eog_wrap_list_get_selected_images (EOG_WRAP_LIST (priv->wraplist));
-		save_as_multiple_images (window, images);
-	}
-}
-
-/* ================================================
- *
- *     Transformation functions 
- * 
- * -----------------------------------------------*/
-
-typedef struct {
-	EogJobData    generic;
-	GList        *image_list;
-	EogTransform *trans;
-} EogJobTransformData;
-
-static gboolean
-job_transform_image_modified (gpointer data)
-{
-	g_return_val_if_fail (EOG_IS_IMAGE (data), FALSE);
-
-	eog_image_modified (EOG_IMAGE (data));
-	g_object_unref (G_OBJECT (data));
-
-	return FALSE;
-}
-
-/* runs in its own thread */
-/* If there is no EogTransform object, an Undo function is performed */
-static void
-job_transform_action (EogJob *job, gpointer data, GError **error)
-{
-	GList *it;
-	EogJobTransformData *td;
-
-	td = (EogJobTransformData*) data;
-
-	for (it = td->image_list; it != NULL; it = it->next) {
-		EogImage *image = EOG_IMAGE (it->data);
-		
-		if (td->trans == NULL) {
-			eog_image_undo (image);
-		}
-		else {
-			eog_image_transform (image, td->trans, job);
-		}
-		
-		eog_job_part_finished (job);
-		
-		if (eog_image_is_modified (image) || td->trans == NULL) {
-			g_object_ref (image);
-			g_idle_add (job_transform_image_modified, image);
-		}
-	}
-}
-
-static void 
-job_transform_free_data (gpointer data)
-{
-	EogJobTransformData *td = (EogJobTransformData*) data;
-
-	g_list_foreach (td->image_list, (GFunc) g_object_unref, NULL);
-	g_list_free (td->image_list);
-
-	if (td->trans != NULL) 
-		g_object_unref (td->trans);	
 
-	g_free (td);
+	eog_window_clear_transform_job (window);
 }
 
 static void 
 apply_transformation (EogWindow *window, EogTransform *trans)
 {
+	EogWindowPrivate *priv;
 	GList *images;
-	EogJobTransformData *data;
-	EogJob *job;
 
 	g_return_if_fail (EOG_IS_WINDOW (window));
 
+	priv = window->priv;
+	
 	images = eog_wrap_list_get_selected_images (EOG_WRAP_LIST (window->priv->wraplist));	
 	if (images == NULL)
 		return;
 
-	/* setup job data */
-	data = g_new0 (EogJobTransformData, 1);
-	EOG_JOB_DATA (data)->window = window;
-	data->image_list = images;
-	data->trans = trans;
-	
-	/* create job */
-	job = eog_job_new_full (data, 
-				job_transform_action,
-				NULL, /* FIXME: Finished func should call save dialog */
-				NULL, /* FIXME: Let this be cancelable */
-				job_default_progress,
-				job_transform_free_data);
-	g_object_set (G_OBJECT (job), "progress-n-parts", 
-		      (guint) g_list_length (data->image_list),
-		      NULL);
-
-	/* run job */
-	eog_job_manager_add (job);
-	g_object_unref (G_OBJECT (job));
+	eog_window_clear_transform_job (window);
+	
+	priv->transform_job = eog_job_transform_new (images, trans);
+
+	g_signal_connect (priv->transform_job,
+			  "finished",
+			  G_CALLBACK (eog_job_transform_cb),
+			  window);
+	g_signal_connect (priv->transform_job,
+			  "progress",
+			  G_CALLBACK (job_default_progress_cb),
+			  window);
+	
+	eog_job_queue_add_job (priv->transform_job);
 }
 
 static void
@@ -2497,6 +1563,10 @@ eog_window_destroy (GtkObject *object)
 		priv->client = NULL;
 	}
 
+	eog_window_clear_load_job (window);
+
+	eog_window_clear_transform_job (window);
+	
 	if (GTK_OBJECT_CLASS (parent_class)->destroy)
 		GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }
@@ -2613,7 +1683,6 @@ eog_window_init (EogWindow *window)
 
 	priv->image_list = NULL;
 	priv->displayed_image = NULL;
-	priv->next_image = NULL;
 	priv->sig_id_list_prepared = 0;
 
 	g_object_set (G_OBJECT (window), "allow_shrink", TRUE, NULL);
@@ -3148,34 +2217,6 @@ view_zoom_changed_cb (GtkWidget *widget,
 			!eog_scroll_view_get_zoom_is_min (EOG_SCROLL_VIEW (window->priv->scroll_view)));
 }
 
-static void
-show_error_dialog (EogWindow *window, char *header, GError *error) 
-{
-	GtkWidget *dlg;
-	char *detail = NULL;
-
-	g_return_if_fail (EOG_IS_WINDOW (window));
-
-	if (header == NULL)
-		return;
-	
-	if (error != NULL) {
-		detail = g_strdup_printf (_("Reason: %s"), error->message);
-	}
-
-	dlg = gtk_message_dialog_new (GTK_WINDOW (window),
-				      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-				      GTK_MESSAGE_ERROR,
-				      GTK_BUTTONS_OK,
-				      header);
-	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg),
-						  detail);
-
-	g_signal_connect_swapped (G_OBJECT (dlg), "response",
-				  G_CALLBACK (gtk_widget_destroy),
-				  dlg);
-	gtk_widget_show_all (dlg);
-}
 
 #ifdef HAVE_LCMS
 /* TODO: move into library */
@@ -3254,119 +2295,30 @@ display_image_data (EogWindow *window, E
 	add_uri_to_recent_files (window, eog_image_get_uri (image));
 }
 
-/* this runs in its own thread */
 static void
-job_image_load_action (EogJob *job, gpointer data, GError **error)
+eog_job_load_cb (EogJobLoad *job, gpointer data)
 {
-	EogJobImageLoadData *job_data;
 	EogWindow *window;
-	EogImage *image;
-
-	job_data = (EogJobImageLoadData*) data;
-	window = EOG_JOB_DATA (job_data)->window;
-	image = job_data->image;
-
-	/* The companion unlock is in job_image_load_finished. This doesn't
-	 * dead-lock because both functions are called sequentially by the 
-	 * same thread. This seems too much like a miracle for my tastes. */
-	eog_image_lock (image);
-
-	/* Check to see if the job is still relevant. */
-	if (window->priv->next_image != image) {
-        	  eog_image_unlock (image);
-	          return;
-	}
-
-	if (!eog_image_is_loaded (image)) {	  
-	        eog_image_load (EOG_IMAGE (job_data->image),
-				EOG_IMAGE_DATA_ALL,
-				job,
-				error);
-	} else {
-	        /* We still want to display the image with the finished
-		 * handler so we keep an extra ref to it to make sure it 
-		 * isn't released early. */
-	        g_object_ref (image);
-	}
-}
-
-static void
-job_image_load_finished (EogJob *job, gpointer data, GError *error)
-{
-	EogJobImageLoadData *job_data;
-	EogWindow *window;
-	EogImage *image;
 	
-	job_data = (EogJobImageLoadData*) data;
-	window = EOG_JOB_DATA (job_data)->window;
-	image = job_data->image;
-
-	/* Check to see if the job is still relevant. */
-	if (window->priv->next_image != image) {
-        	  eog_image_unlock (image);
-	          return;
-	}
-
-	if (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED) {
-		if (eog_job_get_success (job)) { 
-			/* This is a hack to get around a very rare race condition
-			 * where the first half of the job has decided that the
-			 * image has data and doesn't need to be reloaded, but the
-			 * image data has gone AWOL by this point. This does not
-			 * fix the cause, but I'm damned if I can find it. */
-			if (!eog_image_has_data (image, EOG_IMAGE_DATA_ALL)) {
-			        eog_image_unlock (image);
-				return;
-			}
+	window = EOG_WINDOW (data);
 
-			/* successfull */
+	if (!EOG_JOB (job)->error) {
 #ifdef HAVE_LCMS
-			eog_image_apply_display_profile (image, get_screen_profile (window));
+ 		eog_image_apply_display_profile (job->image,
+ 						 get_screen_profile (window));
 #endif
-			display_image_data (window, image);
-		}
-		else {  /* failed */
-			char *header; 
-
-			display_image_data (window, NULL);			
-
-			header = g_strdup_printf (_("Image loading failed for %s"),
-						  eog_image_get_caption (image));
-			show_error_dialog (window, header, error);
-			g_free (header);
-		}
-	}
-	else if (eog_job_get_status (job) == EOG_JOB_STATUS_CANCELED) {
-		/* actually nothing to do */
-	}
-	else {
-		g_assert_not_reached ();
+		display_image_data (window, job->image);
 	}
 
-	g_object_unref (image);
-
-	/* The companion lock is in job_image_load_action. */
-	eog_image_unlock (image);
-}
-
-static void
-job_image_load_cancel_job (EogJob *job, gpointer data)
-{
-	EogJobImageLoadData *job_data;
-
-	job_data = (EogJobImageLoadData*) data;
-	
-	eog_image_cancel_load (EOG_IMAGE (job_data->image));
+	eog_window_clear_load_job (window);
 }
 
 static void 
-job_default_progress (EogJob *job, gpointer data, float progress)
+job_default_progress_cb (EogJob *job, float progress, gpointer data)
 {
-	EogJobData *job_data;
-	EogWindow *window;
+	g_return_if_fail (EOG_IS_WINDOW (data));
 	
-	job_data = EOG_JOB_DATA (data);
-	window = job_data->window;
+	EogWindow *window = EOG_WINDOW (data);
 
 	eog_statusbar_set_progress (EOG_STATUSBAR (window->priv->statusbar), progress);
 }
@@ -3398,8 +2350,6 @@ handle_image_selection_changed (EogWrapL
 {
 	EogWindowPrivate *priv;
 	EogImage *image;
-	EogJob *job;
-	EogJobImageLoadData *data;
 
 	priv = window->priv;
 
@@ -3411,33 +2361,27 @@ handle_image_selection_changed (EogWrapL
 	image = eog_wrap_list_get_first_selected_image (EOG_WRAP_LIST (priv->wraplist));
 	g_assert (EOG_IS_IMAGE (image));
 
-	window->priv->next_image = image;
+	eog_window_clear_load_job (window);
 
 	if (eog_image_has_data (image, EOG_IMAGE_DATA_ALL)) {
 		display_image_data (window, image);
+		g_object_unref (image);
 		return;
 	}
 
-	data = g_new0 (EogJobImageLoadData, 1);
-	EOG_JOB_DATA (data)->window = window;
-	data->image = image; /* no additional ref required, since 
-			      * its already increased by 
-			      * eog_wrap_list_get_first_selected_image
-			      */	
-
-	job = eog_job_new_full (data,
-				job_image_load_action,
-				job_image_load_finished,
-				job_image_load_cancel_job,
-				job_default_progress,
-				(EogJobFreeDataFunc) g_free);
-	g_object_set (G_OBJECT (job), 
-		      "progress-threshold", 0.25,
-		      "priority", EOG_JOB_PRIORITY_HIGH, 
-		      NULL);
+	priv->load_job = eog_job_load_new (image);
+	g_signal_connect (G_OBJECT (priv->load_job),
+			  "finished",
+			  G_CALLBACK (eog_job_load_cb),
+			  window);
+
+	g_signal_connect (G_OBJECT (priv->load_job),
+			  "progress",
+			  G_CALLBACK (job_default_progress_cb),
+			  window);
 
-	eog_job_manager_add (job); 
-	g_object_unref (G_OBJECT (job));
+	g_object_unref (image);
+	eog_job_queue_add_job (priv->load_job);
 }
 
 /* FIXME: The action and ui creation stuff should be moved to a separate file */
Index: shell/main.c
===================================================================
RCS file: /cvs/gnome/eog/shell/main.c,v
retrieving revision 1.64
diff -u -p -r1.64 main.c
--- shell/main.c	20 Nov 2006 20:53:10 -0000	1.64
+++ shell/main.c	12 Dec 2006 15:38:03 -0000
@@ -12,8 +12,8 @@
 #include "eog-thumbnail.h"
 #include "session.h"
 #include "eog-config-keys.h"
+#include "eog-job-queue.h"
 #include "eog-image-list.h"
-#include "eog-job-manager.h"
 
 static char **startup_files = NULL;
 
@@ -25,12 +25,6 @@ static const GOptionEntry goption_option
 
 static void open_uri_list_cb (EogWindow *window, GSList *uri_list, gpointer data); 
 
-typedef struct {
-	EogWindow *window;
-	GList     *uri_list;
-	EogImageList  *img_list;
-} LoadContext;
-
 #ifdef G_OS_WIN32
 
 #include <windows.h>
@@ -117,32 +111,6 @@ free_string_list (GList *list)
 		g_list_free (list);
 }
 
-static void
-load_context_free (LoadContext *ctx)
-{
-	if (ctx == NULL) return;
-
-	gnome_vfs_uri_list_free (ctx->uri_list);
-	if (ctx->img_list != NULL)
-			g_object_unref (ctx->img_list);
-	ctx->img_list = NULL;
-	
-	g_free (ctx);
-}
-
-static LoadContext*
-load_context_new (EogWindow *window, GList *uri_list)
-{
-	LoadContext *ctx;
-	
-	ctx = g_new0 (LoadContext, 1);
-	ctx->window = window;
-	ctx->uri_list = uri_list;
-	ctx->img_list = NULL;
-
-	return ctx;
-}
-
 static GtkWidget*
 create_new_window (void)
 {
@@ -374,71 +342,34 @@ string_array_to_list (const gchar **file
 }
 
 static void
-job_prepare_model_do (EogJob *job, gpointer data, GError **error)
+eog_job_model_cb (EogJobModel *job, gpointer user_data)
 {
-	LoadContext *ctx = (LoadContext*) data;
-	int initial_pos;
+	EogWindow *window;
 	
-	ctx->img_list = eog_image_list_new ();
+	window = EOG_WINDOW (user_data);
 	
-	/* prepare the image list */
-	eog_image_list_add_uris (ctx->img_list, ctx->uri_list);
-
-	initial_pos = eog_image_list_get_initial_pos (ctx->img_list);
-
-	if (initial_pos != -1) {
-		EogImage *img;
-
-		img = eog_image_list_get_img_by_pos (ctx->img_list, initial_pos);
-		if (EOG_IS_IMAGE (img)) {
-			eog_image_load (img, EOG_IMAGE_DATA_ALL, job, error);
-			g_object_unref (img);
-		}
-	}
+	g_object_ref (job->img_list);
+	assign_model_to_window (window, job->img_list);
 }
 
 static void
-job_prepare_model_finished (EogJob *job, gpointer data, GError *error)
-{
-	LoadContext *ctx = (LoadContext*) data;
-	
-	if (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED &&
-		eog_job_get_success (job))
-	{
-		g_object_ref (ctx->img_list);
-		
-		assign_model_to_window (ctx->window, ctx->img_list);
-	} 
-	else {
-		g_error_free (error);
-		gtk_main_quit ();
-	}
-}
-
-static void 
-job_prepare_model_free (gpointer data)
-{
-	load_context_free ((LoadContext*) data);
-	data = NULL;
-}
-	
-static void
 load_uris_in_single_model (EogWindow *window, GList *uri_list)
 {
 	GList *it;
-	LoadContext *ctx;
 	
 	for (it = uri_list; it != NULL; it = it->next) {
 		GList *singleton = NULL;
 		EogJob *job;
 		
-		singleton = g_list_prepend (singleton, it->data);		
-		ctx = load_context_new (window, singleton);
-	
-		job = eog_job_new_full (ctx, job_prepare_model_do, job_prepare_model_finished,
-						NULL,
-				        NULL, job_prepare_model_free);
-		eog_job_manager_add (job);
+		singleton = g_list_prepend (singleton, it->data);
+		job = eog_job_model_new (singleton);
+
+		g_signal_connect (job,
+				  "finished",
+				  G_CALLBACK (eog_job_model_cb),
+				  window);
+
+		eog_job_queue_add_job (job);
 		g_object_unref (job);
 		
 		window = NULL;
@@ -488,15 +419,16 @@ open_uri_list_cb (EogWindow *window, GSL
 	
 	/* open regular files */
 	if (file_list) {
-		LoadContext *ctx;				
 		EogJob *job;
-		ctx = load_context_new (window, file_list);
-		window = NULL;
-	
-		job = eog_job_new_full (ctx, job_prepare_model_do, job_prepare_model_finished, 
-					NULL, NULL, job_prepare_model_free);
 
-		eog_job_manager_add (job);
+		job = eog_job_model_new (file_list);
+		g_signal_connect (job,
+				  "finished",
+				  G_CALLBACK (eog_job_model_cb),
+				  window);
+
+		window = NULL;
+		eog_job_queue_add_job (job);
 		g_object_unref (job);
 	}
 		
@@ -605,6 +537,7 @@ main (int argc, char **argv)
 	gnome_authentication_manager_init ();
 #endif
 	eog_thumbnail_init ();
+	eog_job_queue_init ();
 
 	gtk_window_set_default_icon_name ("image-viewer");
 
--- /dev/null	2006-12-12 07:37:33.396075749 -0300
+++ libeog/eog-jobs.c	2006-11-27 22:48:01.000000000 -0300
@@ -0,0 +1,477 @@
+/* Eye Of Gnome - Jobs  
+ *
+ * Copyright (C) 2006 The Free Software Foundation
+ *
+ * Author: Lucas Rocha <lucasr@gnome.org>
+ *
+ * Based on evince code (shell/ev-jobs.c) by: 
+ * 	- Martin Kretzschmar <martink@gnome.org>
+ *
+ * This program 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.
+ *
+ * This program 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 "eog-jobs.h"
+#include "eog-job-queue.h"
+#include "eog-image.h"
+#include "eog-transform.h"
+#include "eog-image-list.h"
+#include "eog-thumbnail.h"
+
+#include <libgnomeui/gnome-thumbnail.h>
+
+#define EOG_JOB_GET_PRIVATE(object) \
+	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_JOB, EogJobPrivate))
+
+G_DEFINE_TYPE (EogJob, eog_job, G_TYPE_OBJECT);
+G_DEFINE_TYPE (EogJobThumbnail, eog_job_thumbnail, EOG_TYPE_JOB);
+G_DEFINE_TYPE (EogJobLoad, eog_job_load, EOG_TYPE_JOB);
+G_DEFINE_TYPE (EogJobModel, eog_job_model, EOG_TYPE_JOB);
+G_DEFINE_TYPE (EogJobTransform, eog_job_transform, EOG_TYPE_JOB);
+
+enum
+{
+	SIGNAL_FINISHED,
+	SIGNAL_PROGRESS,
+	SIGNAL_LAST_SIGNAL
+};
+
+static guint job_signals[SIGNAL_LAST_SIGNAL] = { 0 };
+
+static void eog_job_init (EogJob *job) 
+{
+	job->mutex = g_mutex_new();
+	job->progress = 0.0;
+}
+
+static void
+eog_job_dispose (GObject *object)
+{
+	EogJob *job;
+
+	job = EOG_JOB (object);
+
+	if (job->error) {
+		g_error_free (job->error);
+		job->error = NULL;
+	}
+
+	if (job->mutex) {
+		g_mutex_free (job->mutex);
+		job->mutex = NULL;
+	}
+
+	(* G_OBJECT_CLASS (eog_job_parent_class)->dispose) (object);
+}
+
+static void
+eog_job_class_init (EogJobClass *class)
+{
+	GObjectClass *oclass;
+
+	oclass = G_OBJECT_CLASS (class);
+
+	oclass->dispose = eog_job_dispose;
+
+	job_signals [SIGNAL_FINISHED] =
+		g_signal_new ("finished",
+			      EOG_TYPE_JOB,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EogJobClass, finished),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+
+	job_signals [SIGNAL_PROGRESS] =
+		g_signal_new ("progress",
+			      EOG_TYPE_JOB,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EogJobClass, progress),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__FLOAT,
+			      G_TYPE_NONE, 1,
+			      G_TYPE_FLOAT);
+}
+
+void
+eog_job_finished (EogJob *job)
+{
+	g_return_if_fail (EOG_IS_JOB (job));
+
+	g_signal_emit (job, job_signals[SIGNAL_FINISHED], 0);
+}
+
+static gboolean
+notify_progress (gpointer data)
+{
+	EogJob *job = EOG_JOB (data);
+
+	g_signal_emit (job, job_signals[SIGNAL_PROGRESS], 0, job->progress);
+
+	return FALSE;
+}
+
+void
+eog_job_set_progress (EogJob *job, float progress)
+{
+	g_return_if_fail (EOG_IS_JOB (job));
+	g_return_if_fail (progress >= 0.0 && progress <= 1.0);
+
+	g_mutex_lock (job->mutex);
+	job->progress = progress;
+	g_mutex_unlock (job->mutex);
+
+	g_idle_add (notify_progress, job);
+}
+
+static void eog_job_thumbnail_init (EogJobThumbnail *job) { /* Do Nothing */ }
+
+static void
+eog_job_thumbnail_dispose (GObject *object)
+{
+	EogJobThumbnail *job;
+
+	job = EOG_JOB_THUMBNAIL (object);
+
+	if (job->uri_entry) {
+		gnome_vfs_uri_unref (job->uri_entry);
+		job->uri_entry = NULL;
+	}
+	
+	if (job->thumbnail) {
+		g_object_unref (job->thumbnail);
+		job->thumbnail = NULL;
+	}
+
+	(* G_OBJECT_CLASS (eog_job_thumbnail_parent_class)->dispose) (object);
+}
+
+static void
+eog_job_thumbnail_class_init (EogJobThumbnailClass *class)
+{
+	GObjectClass *oclass;
+
+	oclass = G_OBJECT_CLASS (class);
+
+	oclass->dispose = eog_job_thumbnail_dispose;
+}
+
+static void eog_job_load_init (EogJobLoad *job) { /* Do Nothing */ }
+
+static void
+eog_job_load_dispose (GObject *object)
+{
+	EogJobLoad *job;
+
+	job = EOG_JOB_LOAD (object);
+
+	if (job->image) {
+		g_object_unref (job->image);
+		job->image = NULL;
+	}
+
+	(* G_OBJECT_CLASS (eog_job_load_parent_class)->dispose) (object);
+}
+
+static void
+eog_job_load_class_init (EogJobLoadClass *class)
+{
+	GObjectClass *oclass;
+
+	oclass = G_OBJECT_CLASS (class);
+
+	oclass->dispose = eog_job_load_dispose;
+}
+
+static void eog_job_model_init (EogJobModel *job) { /* Do Nothing */ }
+
+static void
+eog_job_model_dispose (GObject *object)
+{
+	EogJobModel *job;
+
+	job = EOG_JOB_MODEL (object);
+
+	(* G_OBJECT_CLASS (eog_job_model_parent_class)->dispose) (object);
+}
+
+static void
+eog_job_model_class_init (EogJobModelClass *class)
+{
+	GObjectClass *oclass;
+
+	oclass = G_OBJECT_CLASS (class);
+
+	oclass->dispose = eog_job_model_dispose;
+}
+
+static void eog_job_transform_init (EogJobTransform *job) { /* Do Nothing */ }
+
+static void
+eog_job_transform_dispose (GObject *object)
+{
+	EogJobTransform *job;
+
+	job = EOG_JOB_TRANSFORM (object);
+
+	if (job->trans) {
+		g_object_unref (job->trans);
+		job->trans = NULL;
+	}
+
+	g_list_foreach (job->images, (GFunc) g_object_unref, NULL);
+	g_list_free (job->images);
+
+	(* G_OBJECT_CLASS (eog_job_transform_parent_class)->dispose) (object);
+}
+
+static void
+eog_job_transform_class_init (EogJobTransformClass *class)
+{
+	GObjectClass *oclass;
+
+	oclass = G_OBJECT_CLASS (class);
+
+	oclass->dispose = eog_job_transform_dispose;
+}
+
+EogJob *
+eog_job_thumbnail_new (GnomeVFSURI *uri_entry)
+{
+	EogJobThumbnail *job;
+
+	job = g_object_new (EOG_TYPE_JOB_THUMBNAIL, NULL);
+
+	if (uri_entry) {
+		gnome_vfs_uri_ref (uri_entry);
+		job->uri_entry = uri_entry;
+	}
+
+	return EOG_JOB (job);
+}
+
+void
+eog_job_thumbnail_run (EogJobThumbnail *job)
+{
+	g_return_if_fail (EOG_IS_JOB_THUMBNAIL (job));
+	
+	if (EOG_JOB (job)->error) {
+	        g_error_free (EOG_JOB (job)->error);
+		EOG_JOB (job)->error = NULL;
+	}
+
+	job->thumbnail = eog_thumbnail_load (job->uri_entry,
+					     &EOG_JOB (job)->error);
+
+
+	if (EOG_JOB (job)->error) {
+		g_warning ("%s\n", EOG_JOB (job)->error->message);
+	}
+
+	EOG_JOB (job)->finished = TRUE;
+}
+
+EogJob *
+eog_job_load_new (EogImage *image)
+{
+	EogJobLoad *job;
+
+	job = g_object_new (EOG_TYPE_JOB_LOAD, NULL);
+
+	if (image) {
+		job->image = g_object_ref (image);
+	}
+	
+	return EOG_JOB (job);
+}
+
+void
+eog_job_load_run (EogJobLoad *job)
+{
+	g_return_if_fail (EOG_IS_JOB_LOAD (job));
+
+	if (EOG_JOB (job)->error) {
+	        g_error_free (EOG_JOB (job)->error);
+		EOG_JOB (job)->error = NULL;
+	}
+
+	eog_image_load (EOG_IMAGE (job->image),
+			EOG_IMAGE_DATA_ALL,
+			EOG_JOB (job),
+			&EOG_JOB (job)->error);
+	
+	EOG_JOB (job)->finished = TRUE;
+}
+
+EogJob *
+eog_job_model_new (GList *uri_list)
+{
+	EogJobModel *job;
+
+	job = g_object_new (EOG_TYPE_JOB_MODEL, NULL);
+
+	job->img_list = eog_image_list_new ();
+	job->uri_list = uri_list;
+
+	return EOG_JOB (job);
+}
+
+static GnomeVFSFileType
+check_uri_file_type (GnomeVFSURI *uri, GnomeVFSFileInfo *info)
+{
+	GnomeVFSResult result;
+	GnomeVFSFileType type = GNOME_VFS_FILE_TYPE_UNKNOWN;
+
+	g_return_val_if_fail (uri != NULL, GNOME_VFS_FILE_TYPE_UNKNOWN);
+	g_return_val_if_fail (info != NULL, GNOME_VFS_FILE_TYPE_UNKNOWN);
+
+	gnome_vfs_file_info_clear (info);
+	
+	result = gnome_vfs_get_file_info_uri (uri, info,
+					      GNOME_VFS_FILE_INFO_DEFAULT |
+					      GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+	
+	if (result == GNOME_VFS_OK &&
+	    (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) != 0) {
+		type = info->type;
+	}
+
+	return type;
+}
+
+static void
+filter_files (GSList *files, GList **file_list, GList **error_list)
+{
+	GSList *it;
+	GnomeVFSFileInfo *info;
+	
+	info = gnome_vfs_file_info_new ();
+
+	for (it = files; it != NULL; it = it->next) {
+		GnomeVFSURI *uri;
+		GnomeVFSFileType type = GNOME_VFS_FILE_TYPE_UNKNOWN;
+
+		uri = (GnomeVFSURI *) it->data;
+
+		if (uri != NULL) {
+			type = check_uri_file_type (uri, info);
+		}
+
+		switch (type) {
+		case GNOME_VFS_FILE_TYPE_REGULAR:
+		case GNOME_VFS_FILE_TYPE_DIRECTORY:
+			*file_list = g_list_prepend (*file_list, gnome_vfs_uri_ref (uri));
+			break;
+		default:
+			*error_list = g_list_prepend (*error_list, 
+						      gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE));
+			break;
+		}
+
+		gnome_vfs_uri_unref (uri);
+	}
+
+	*file_list  = g_list_reverse (*file_list);
+	*error_list = g_list_reverse (*error_list);
+
+	gnome_vfs_file_info_unref (info);
+}
+
+void
+eog_job_model_run (EogJobModel *job)
+{
+	g_return_if_fail (EOG_IS_JOB_MODEL (job));
+
+	int initial_pos;
+	
+	/* prepare the image list */
+	eog_image_list_add_uris (job->img_list, job->uri_list);
+
+	initial_pos = eog_image_list_get_initial_pos (job->img_list);
+
+	if (initial_pos != -1) {
+		EogImage *img;
+
+		img = eog_image_list_get_img_by_pos (job->img_list, initial_pos);
+		if (EOG_IS_IMAGE (img)) {
+			eog_image_load (img,
+					EOG_IMAGE_DATA_ALL,
+					EOG_JOB (job),
+					&EOG_JOB(job)->error);
+			g_object_unref (img);
+		}
+	}
+
+	EOG_JOB (job)->finished = TRUE;
+}
+
+EogJob *
+eog_job_transform_new (GList *images, EogTransform *trans)
+{
+	EogJobTransform *job;
+
+	job = g_object_new (EOG_TYPE_JOB_TRANSFORM, NULL);
+
+	if (trans) {
+		job->trans = g_object_ref (trans);
+	} else {
+		job->trans = NULL;
+	}
+
+	job->images = images;
+
+	return EOG_JOB (job);
+}
+
+static gboolean
+eog_job_transform_image_modified (gpointer data)
+{
+	g_return_val_if_fail (EOG_IS_IMAGE (data), FALSE);
+
+	eog_image_modified (EOG_IMAGE (data));
+	g_object_unref (G_OBJECT (data));
+
+	return FALSE;
+}
+
+void
+eog_job_transform_run (EogJobTransform *job)
+{
+	GList *it;
+
+	g_return_if_fail (EOG_IS_JOB_TRANSFORM (job));
+
+	if (EOG_JOB (job)->error) {
+	        g_error_free (EOG_JOB (job)->error);
+		EOG_JOB (job)->error = NULL;
+	}
+
+	for (it = job->images; it != NULL; it = it->next) {
+		EogImage *image = EOG_IMAGE (it->data);
+		
+		if (job->trans == NULL) {
+			eog_image_undo (image);
+		} else {
+			eog_image_transform (image, job->trans, EOG_JOB (job));
+		}
+		
+		if (eog_image_is_modified (image) || job->trans == NULL) {
+			g_object_ref (image);
+			g_idle_add (eog_job_transform_image_modified, image);
+		}
+	}
+	
+	EOG_JOB (job)->finished = TRUE;
+}
+
--- /dev/null	2006-12-12 07:37:33.396075749 -0300
+++ libeog/eog-jobs.h	2006-11-27 22:44:24.000000000 -0300
@@ -0,0 +1,187 @@
+/* Eye Of Gnome - Jobs  
+ *
+ * Copyright (C) 2006 The Free Software Foundation
+ *
+ * Author: Lucas Rocha <lucasr@gnome.org>
+ *
+ * Based on evince code (shell/ev-jobs.h) by: 
+ * 	- Martin Kretzschmar <martink@gnome.org>
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+#ifndef __EOG_JOBS_H__
+#define __EOG_JOBS_H__
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+
+G_BEGIN_DECLS
+
+#ifndef __EOG_IMAGE_DECLR__
+#define __EOG_IMAGE_DECLR__
+  typedef struct _EogImage EogImage;
+#endif
+
+#ifndef __EOG_TRANSFORM_DECLR__
+#define __EOG_TRANSFORM_DECLR__
+  typedef struct _EogTransform EogTransform;
+#endif
+
+#ifndef __EOG_IMAGE_LIST_DECLR__
+#define __EOG_IMAGE_LIST_DECLR__
+  typedef struct _EogImageList EogImageList;
+#endif
+
+#ifndef __EOG_JOB_DECLR__
+#define __EOG_JOB_DECLR__
+  typedef struct _EogJob EogJob;
+#endif
+typedef struct _EogJobClass EogJobClass;
+
+typedef struct _EogJobThumbnail EogJobThumbnail;
+typedef struct _EogJobThumbnailClass EogJobThumbnailClass;
+
+typedef struct _EogJobLoad EogJobLoad;
+typedef struct _EogJobLoadClass EogJobLoadClass;
+
+typedef struct _EogJobModel EogJobModel;
+typedef struct _EogJobModelClass EogJobModelClass;
+
+typedef struct _EogJobTransform EogJobTransform;
+typedef struct _EogJobTransformClass EogJobTransformClass;
+
+#define EOG_TYPE_JOB		       (eog_job_get_type())
+#define EOG_JOB(obj)		       (G_TYPE_CHECK_INSTANCE_CAST((obj), EOG_TYPE_JOB, EogJob))
+#define EOG_JOB_CLASS(klass)	       (G_TYPE_CHECK_CLASS_CAST((klass),  EOG_TYPE_JOB, EogJobClass))
+#define EOG_IS_JOB(obj)	               (G_TYPE_CHECK_INSTANCE_TYPE((obj), EOG_TYPE_JOB))
+
+#define EOG_TYPE_JOB_THUMBNAIL	       (eog_job_thumbnail_get_type())
+#define EOG_JOB_THUMBNAIL(obj)	       (G_TYPE_CHECK_INSTANCE_CAST((obj), EOG_TYPE_JOB_THUMBNAIL, EogJobThumbnail))
+#define EOG_JOB_THUMBNAIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),  EOG_TYPE_JOB_THUMBNAIL, EogJobThumbnailClass))
+#define EOG_IS_JOB_THUMBNAIL(obj)      (G_TYPE_CHECK_INSTANCE_TYPE((obj), EOG_TYPE_JOB_THUMBNAIL))
+
+#define EOG_TYPE_JOB_LOAD	       (eog_job_load_get_type())
+#define EOG_JOB_LOAD(obj)	       (G_TYPE_CHECK_INSTANCE_CAST((obj), EOG_TYPE_JOB_LOAD, EogJobLoad))
+#define EOG_JOB_LOAD_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass),  EOG_TYPE_JOB_LOAD, EogJobLoadClass))
+#define EOG_IS_JOB_LOAD(obj)	       (G_TYPE_CHECK_INSTANCE_TYPE((obj), EOG_TYPE_JOB_LOAD))
+
+#define EOG_TYPE_JOB_MODEL	       (eog_job_model_get_type())
+#define EOG_JOB_MODEL(obj)	       (G_TYPE_CHECK_INSTANCE_CAST((obj), EOG_TYPE_JOB_MODEL, EogJobModel))
+#define EOG_JOB_MODEL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),  EOG_TYPE_JOB_MODEL, EogJobModelClass))
+#define EOG_IS_JOB_MODEL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), EOG_TYPE_JOB_MODEL))
+
+#define EOG_TYPE_JOB_TRANSFORM	       (eog_job_transform_get_type())
+#define EOG_JOB_TRANSFORM(obj)	       (G_TYPE_CHECK_INSTANCE_CAST((obj), EOG_TYPE_JOB_TRANSFORM, EogJobTransform))
+#define EOG_JOB_TRANSFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),  EOG_TYPE_JOB_TRANSFORM, EogJobTransformClass))
+#define EOG_IS_JOB_TRANSFORM(obj)      (G_TYPE_CHECK_INSTANCE_TYPE((obj), EOG_TYPE_JOB_TRANSFORM))
+
+struct _EogJob
+{
+	GObject  parent;
+
+	GError   *error;
+	GMutex   *mutex;
+	float    progress;
+	gboolean finished;
+};
+
+struct _EogJobClass
+{
+	GObjectClass parent_class;
+
+	void    (* finished) (EogJob *job);
+	void    (* progress) (EogJob *job, float progress);
+};
+
+struct _EogJobThumbnail
+{
+	EogJob   parent;
+	GnomeVFSURI *uri_entry;
+	GdkPixbuf *thumbnail;
+};
+
+struct _EogJobThumbnailClass
+{
+	EogJobClass parent_class;
+};
+
+struct _EogJobLoad
+{
+	EogJob   parent;
+	EogImage *image;
+};
+
+struct _EogJobLoadClass
+{
+	EogJobClass parent_class;
+};
+
+struct _EogJobModel
+{
+	EogJob       parent;
+	EogImageList *img_list;
+	GList       *uri_list;
+};
+
+struct _EogJobModelClass
+{
+        EogJobClass parent_class;
+};
+
+struct _EogJobTransform
+{
+	EogJob       parent;
+	GList        *images;
+	EogTransform *trans;
+};
+
+struct _EogJobTransformClass
+{
+        EogJobClass parent_class;
+};
+
+/* Base job class */
+GType           eog_job_get_type           (void);
+void            eog_job_finished           (EogJob          *job);
+void            eog_job_set_progress       (EogJob          *job,
+					    float           progress);
+
+/* EogJobThumbnail */
+GType           eog_job_thumbnail_get_type (void);
+EogJob         *eog_job_thumbnail_new      (GnomeVFSURI     *uri_entry);
+void            eog_job_thumbnail_run      (EogJobThumbnail *thumbnail);
+
+/* EogJobLoad */
+GType           eog_job_load_get_type      (void);
+EogJob 	       *eog_job_load_new 	   (EogImage        *image);
+void		eog_job_load_run 	   (EogJobLoad 	    *load);					   
+
+/* EogJobModel */
+GType 		eog_job_model_get_type     (void);
+EogJob 	       *eog_job_model_new          (GList          *uri_list);
+void            eog_job_model_run          (EogJobModel     *model);
+
+/* EogJobTransform */
+GType 		eog_job_transform_get_type (void);
+EogJob 	       *eog_job_transform_new      (GList           *images,
+					    EogTransform    *trans);
+void            eog_job_transform_run      (EogJobTransform *model);
+
+G_END_DECLS
+
+#endif /* __EOG_JOBS_H__ */
--- /dev/null	2006-12-12 07:37:33.396075749 -0300
+++ libeog/eog-job-queue.c	2006-11-27 22:44:24.000000000 -0300
@@ -0,0 +1,222 @@
+/* Eye Of Gnome - Jobs Queue 
+ *
+ * Copyright (C) 2006 The Free Software Foundation
+ *
+ * Author: Lucas Rocha <lucasr@gnome.org>
+ *
+ * Based on evince code (shell/ev-job-queue.c) by: 
+ * 	- Martin Kretzschmar <martink@gnome.org>
+ *
+ * This program 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.
+ *
+ * This program 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 "eog-jobs.h"
+#include "eog-job-queue.h"
+
+GCond  *render_cond = NULL;
+GMutex *eog_queue_mutex = NULL;
+
+static GQueue *thumbnail_queue = NULL;
+static GQueue *load_queue = NULL;
+static GQueue *model_queue = NULL;
+static GQueue *transform_queue = NULL;
+
+static gboolean
+remove_job_from_queue (GQueue *queue, EogJob *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 void
+add_job_to_queue_locked (GQueue *queue, EogJob  *job)
+{
+	g_object_ref (job);
+	g_queue_push_tail (queue, job);
+	g_cond_broadcast (render_cond);
+}
+
+static gboolean
+notify_finished (GObject *job)
+{
+	eog_job_finished (EOG_JOB (job));
+
+	return FALSE;
+}
+
+static void
+handle_job (EogJob *job)
+{
+	g_object_ref (G_OBJECT (job));
+
+	if (EOG_IS_JOB_THUMBNAIL (job))
+		eog_job_thumbnail_run (EOG_JOB_THUMBNAIL (job));
+	else if (EOG_IS_JOB_LOAD (job))
+		eog_job_load_run (EOG_JOB_LOAD (job));
+	else if (EOG_IS_JOB_MODEL (job))
+		eog_job_model_run (EOG_JOB_MODEL (job));
+	else if (EOG_IS_JOB_TRANSFORM (job))
+		eog_job_transform_run (EOG_JOB_TRANSFORM (job));
+
+	g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+			 (GSourceFunc) notify_finished,
+			 job,
+			 g_object_unref);
+}
+
+static gboolean
+no_jobs_available_unlocked (void)
+{
+	return  g_queue_is_empty (load_queue)      &&
+		g_queue_is_empty (transform_queue) &&
+		g_queue_is_empty (thumbnail_queue) &&
+		g_queue_is_empty (model_queue);
+}
+
+static EogJob *
+search_for_jobs_unlocked (void)
+{
+	EogJob *job;
+
+	job = (EogJob *) g_queue_pop_head (load_queue);
+	if (job)
+		return job;
+
+	job = (EogJob *) g_queue_pop_head (transform_queue);
+	if (job)
+		return job;
+
+	job = (EogJob *) g_queue_pop_head (thumbnail_queue);
+	if (job)
+		return job;
+
+	job = (EogJob *) g_queue_pop_head (model_queue);
+	if (job)
+		return job;
+
+	return NULL;
+}
+
+static gpointer
+eog_render_thread (gpointer data)
+{
+	while (TRUE) {
+		EogJob *job;
+
+		g_mutex_lock (eog_queue_mutex);
+
+		if (no_jobs_available_unlocked ()) {
+			g_cond_wait (render_cond, eog_queue_mutex);
+		}
+
+		job = search_for_jobs_unlocked ();
+
+		g_mutex_unlock (eog_queue_mutex);
+
+		/* Now that we have our job, we handle it */
+		if (job) {
+			handle_job (job);
+			g_object_unref (G_OBJECT (job));
+		}
+	}
+	return NULL;
+
+}
+
+void
+eog_job_queue_init (void)
+{
+	if (!g_thread_supported ()) g_thread_init (NULL);
+
+	render_cond = g_cond_new ();
+	eog_queue_mutex = g_mutex_new ();
+
+	thumbnail_queue = g_queue_new ();
+	load_queue = g_queue_new ();
+	model_queue = g_queue_new ();
+	transform_queue = g_queue_new ();
+
+	g_thread_create (eog_render_thread, NULL, FALSE, NULL);
+}
+
+static GQueue *
+find_queue (EogJob *job)
+{
+	if (EOG_IS_JOB_THUMBNAIL (job)) {
+		return thumbnail_queue;
+	} else if (EOG_IS_JOB_LOAD (job)) {
+		return load_queue;
+	} else if (EOG_IS_JOB_MODEL (job)) {
+		return model_queue;
+	} else if (EOG_IS_JOB_TRANSFORM (job)) {
+		return transform_queue;
+	}
+
+	g_assert_not_reached ();
+
+	return NULL;
+}
+
+void
+eog_job_queue_add_job (EogJob *job)
+{
+	GQueue *queue;
+
+	g_return_if_fail (EOG_IS_JOB (job));
+
+	queue = find_queue (job);
+
+	g_mutex_lock (eog_queue_mutex);
+	
+	add_job_to_queue_locked (queue, job);
+
+	g_mutex_unlock (eog_queue_mutex);
+}
+
+gboolean
+eog_job_queue_remove_job (EogJob *job)
+{
+	gboolean retval = FALSE;
+
+	g_return_val_if_fail (EOG_IS_JOB (job), FALSE);
+
+	g_mutex_lock (eog_queue_mutex);
+
+	if (EOG_IS_JOB_THUMBNAIL (job)) {
+		retval = remove_job_from_queue (thumbnail_queue, job);
+	} else if (EOG_IS_JOB_LOAD (job)) {
+		retval = remove_job_from_queue (load_queue, job);
+	} else if (EOG_IS_JOB_MODEL (job)) {
+		retval = remove_job_from_queue (model_queue, job);
+	} else if (EOG_IS_JOB_TRANSFORM (job)) {
+		retval = remove_job_from_queue (transform_queue, job);
+	} else {
+		g_assert_not_reached ();
+	}
+
+	g_mutex_unlock (eog_queue_mutex);
+	
+	return retval;
+}
--- /dev/null	2006-12-12 07:37:33.396075749 -0300
+++ libeog/eog-job-queue.h	2006-11-27 22:44:24.000000000 -0300
@@ -0,0 +1,42 @@
+/* Eye Of Gnome - Jobs Queue 
+ *
+ * Copyright (C) 2006 The Free Software Foundation
+ *
+ * Author: Lucas Rocha <lucasr@gnome.org>
+ *
+ * Based on evince code (shell/ev-job-queue.h) by: 
+ * 	- Martin Kretzschmar <martink@gnome.org>
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+#ifndef __EOG_JOB_QUEUE_H__
+#define __EOG_JOB_QUEUE_H__
+
+#include "eog-jobs.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void     eog_job_queue_init       (void);
+
+void     eog_job_queue_add_job    (EogJob    *job);
+
+gboolean eog_job_queue_remove_job (EogJob    *job);
+
+G_END_DECLS
+
+#endif /* __EOG_JOB_QUEUE_H__ */
--- libeog/eog-job-manager.c	2006-11-27 22:44:24.000000000 -0300
+++ /dev/null	2006-12-12 07:37:33.396075749 -0300
@@ -1,310 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib-object.h>
-#include "eog-job-manager.h"
-
-typedef struct {
-	GThread *thread;
-	EogJob  *job;
-} ThreadData;
-
-#define MAX_THREADS  2
-#define DEBUG_JOB_MANAGER 0
-GMutex        *mutex       = NULL;
-static GCond  *cond        = NULL;
-static GQueue *job_list    = NULL;
-static guint  n_threads   = 0;
-static ThreadData threads[MAX_THREADS];
-static gboolean   init = FALSE;
-
-/* Utility function, which initializes static data first */
-static void
-eog_job_manager_init ()
-{
-	if (!init) {
-		int i;
-		
-		for (i = 0; i < MAX_THREADS; i++) {
-			threads[i].thread = NULL;
-			threads[i].job = NULL;
-		}
-		mutex = g_mutex_new ();
-		cond = g_cond_new ();
-
-		job_list = g_queue_new ();
-		
-		init = TRUE;
-	}
-}
-
-/* idle callback from separate thread, at this
- * point control is in the main thread again
- */
-static gboolean
-job_finished_cb (gpointer data)
-{
-	EogJob *job;
-
-	job = EOG_JOB (data);
-	g_assert (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED ||
-		  eog_job_get_status (job) == EOG_JOB_STATUS_CANCELED);
-
-	eog_job_call_finished (job);
-
-	g_assert (EOG_IS_JOB (job));
-
-	g_object_unref (G_OBJECT (job));
-	
-	return FALSE;
-}
-
-/* this runs in its own thread */
-static gpointer
-thread_start_func (gpointer data)
-{
-	EogJob *job;
-	guint thread_id = GPOINTER_TO_UINT (data);
-
-#if DEBUG_JOB_MANAGER
-	g_print ("Starting thread with id %u.\n", thread_id);
-#endif
-
-	while (TRUE) {
-		job = NULL;
-		
-		g_mutex_lock (mutex);
-		if (!g_queue_is_empty (job_list)) {
-			job = EOG_JOB (g_queue_pop_head (job_list));
-			threads[thread_id].job = job;
-		}
-		g_mutex_unlock (mutex);
-
-		if (job != NULL) {
-			if (eog_job_get_status (job) == EOG_JOB_STATUS_WAITING) {
-				eog_job_call_action (job);
-				
-				g_assert (eog_job_get_status (job) == EOG_JOB_STATUS_FINISHED ||
-					  eog_job_get_status (job) == EOG_JOB_STATUS_CANCELED);
-				g_idle_add (job_finished_cb, job);
-			}
-		}
-		else {
-			g_mutex_lock (mutex);
-			threads[thread_id].job = NULL;
-			g_cond_wait (cond, mutex);
-			g_mutex_unlock (mutex);
-		}
-	}
-
-#if DEBUG_JOB_MANAGER
-	g_print ("Stopping thread with id %u.\n", thread_id);
-#endif
-	/* This block will never be reached */
-	/* clean up and remove thread */
-	g_mutex_lock (mutex);
-	n_threads--;
-	threads[thread_id].thread = NULL;
-	threads[thread_id].job = NULL;
-	g_mutex_unlock (mutex);
-	
-	return NULL;
-}
-
-/* called from main thread */
-guint     
-eog_job_manager_add (EogJob *job)
-{
-	g_return_val_if_fail (EOG_IS_JOB (job), 0);
-	eog_job_manager_init ();
-	
-	g_mutex_lock (mutex);
-	
-	if (eog_job_get_priority (job) == EOG_JOB_PRIORITY_NORMAL)
-		g_queue_push_tail (job_list, g_object_ref (job));
-	else
-		g_queue_push_head (job_list, g_object_ref (job));
-
-	if (n_threads < MAX_THREADS) {
-		guint thread_id;
-
-		n_threads++;
-
-		for (thread_id = 0; thread_id < MAX_THREADS; thread_id++) {
-			if (threads[thread_id].thread == NULL) break;
-		}
-
-		if (thread_id < MAX_THREADS) {
-			threads[thread_id].thread =
-				g_thread_create (thread_start_func, GUINT_TO_POINTER (thread_id), FALSE, NULL);
-			threads[thread_id].job = NULL;
-		}
-	}
-	else {
-		g_cond_broadcast (cond);
-	}
-	g_mutex_unlock (mutex);
-
-	return eog_job_get_id (job);
-}
-
-static gint
-compare_job_id (gconstpointer a, gconstpointer b)
-{
-	EogJob *job;
-	guint job_id;
-
-	if (EOG_IS_JOB (a)) {
-		job = EOG_JOB (a);
-		job_id = GPOINTER_TO_UINT (b);
-	}
-	else {
-		job = EOG_JOB (b);
-		job_id = GPOINTER_TO_UINT (a);
-	}
-
-	return (job_id - eog_job_get_id (job));
-}
-
-/* this function doesn't lock the mutex! */
-static EogJob*
-eog_job_manager_get_job_private (guint id, GList **link)
-{
-	guint thread_id;
-	EogJob *job = NULL;
-
-	if (link != NULL) {
-		*link = NULL;
-	}
-
-	/* first see if the job we are looking for is under the ones currently
-	 * processed 
-	 */
-	for (thread_id = 0; thread_id < MAX_THREADS; thread_id++) {
-		if (threads[thread_id].job != NULL && 
-		    eog_job_get_id (threads[thread_id].job) == id) 
-		{
-			job = threads[thread_id].job;
-			break;
-		}
-	}
-	
-	if (job == NULL) {
-		GList *it;
-		
-		it = g_queue_find_custom (job_list,
-					  GUINT_TO_POINTER (id),
-					  (GCompareFunc) compare_job_id);
-
-		if (it != NULL) {
-			job = EOG_JOB (it->data);
-		}
-
-		if (link != NULL) {
-			*link = it;
-		}
-	}
-
-	return job;
-}
-
-/* called from main thread */
-gboolean
-eog_job_manager_cancel_job (guint id)
-{
-	EogJob *job;
-	GList *link = NULL;
-	gboolean success = FALSE;
-	gboolean call_finished = FALSE;
-
-	eog_job_manager_init ();
-
-	g_mutex_lock (mutex);
-	job = eog_job_manager_get_job_private (id, &link);
-	if (link != NULL) {
-		g_queue_delete_link (job_list, link);
-	}
-	g_mutex_unlock (mutex);
-
-	if (job != NULL) {
-		call_finished = (eog_job_get_status (job) == EOG_JOB_STATUS_WAITING);
-
-		/* we found the job, now cancel it */
-		/* This should stop the user specified action
-		 * function and leads to the return of the 
-		 * eog_job_call_action (job) in thread_start_func.
-		 */
-		success = eog_job_call_canceled (job);
-
-		/* if it's in the waiting queue (status == WAITING)
-		 * call the finished function also 
-		 */
-		if (success && call_finished) {
-			g_idle_add (job_finished_cb, job);
-		}
-	}
-
-	return success;
-}
-
-/* called from main thread */
-EogJob*
-eog_job_manager_get_job (guint id)
-{
-	EogJob *job;
-
-	eog_job_manager_init ();
-
-	g_mutex_lock (mutex);
-	job = eog_job_manager_get_job_private (id, NULL);
-	g_mutex_unlock (mutex);
-	
-	if (job != NULL) 
-		g_object_ref (job);
-	
-	return job;
-}
-
-static void
-cancel_each_job (gpointer data, gpointer user_data)
-{
-	EogJob *job = EOG_JOB (data);
-	gboolean success;
-
-	g_assert (eog_job_get_status (job) == EOG_JOB_STATUS_WAITING);
-
-	success = eog_job_call_canceled (job);
-	if (success) {
-		g_idle_add (job_finished_cb, job);
-	}
-	else {
-		g_object_unref (G_OBJECT (job));
-	}
-}
-
-/* called from main thread */
-void      
-eog_job_manager_cancel_all_jobs (void)
-{
-	guint thread_id;
-
-	eog_job_manager_init ();
-
-	g_mutex_lock (mutex);
-
-	/* stop all currently running threads */
-	for (thread_id = 0; thread_id < MAX_THREADS; thread_id++) {
-		if (threads[thread_id].job != NULL) {
-			eog_job_call_canceled (threads[thread_id].job);
-		}
-	}
-
-	/* remove all jobs from waiting list and free list structure
-	 * in one run */
-	g_queue_foreach (job_list, (GFunc) cancel_each_job, NULL);
-	g_queue_free (job_list);
-	job_list = g_queue_new ();
-		
-	g_mutex_unlock (mutex);
-}
--- libeog/eog-job-manager.h	2006-11-27 22:44:24.000000000 -0300
+++ /dev/null	2006-12-12 07:37:33.396075749 -0300
@@ -1,15 +0,0 @@
-#ifndef _EOG_JOB_MANAGER_H_
-#define _EOG_JOB_MANAGER_H_
-
-#include "eog-job.h"
-
-G_BEGIN_DECLS
-
-guint     eog_job_manager_add        (EogJob *job);
-EogJob*   eog_job_manager_get_job    (guint id);
-gboolean  eog_job_manager_cancel_job (guint id);
-void      eog_job_manager_cancel_all_jobs (void);
-
-G_END_DECLS
-
-#endif /* _EOG_JOB_MANAGER_H_ */
--- libeog/eog-job.c	2006-11-27 22:44:24.000000000 -0300
+++ /dev/null	2006-12-12 07:37:33.396075749 -0300
@@ -1,450 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "eog-job.h"
-
-static guint last_job_id = 0;
-#define DEBUG_EOG_JOB 0
-
-enum {
-	PROP_0,
-	PROP_PROGRESS_THRESHOLD,
-	PROP_PROGRESS_N_PARTS,
-	PROP_PRIORITY
-};
-
-struct _EogJobPrivate {
-	GMutex        *mutex;
-	guint         id;
-	gpointer      data;
-	EogJobStatus  status;
-	GError        *error;
-	float         progress;
-	float         progress_last_called;
-	guint         progress_idle_id;
-	guint         progress_nth_part;
-	guint         progress_n_parts;
-	float         progress_threshold;
-	guint         priority;
-	
-	EogJobActionFunc af;
-	EogJobCancelFunc cf;
-	EogJobFinishedFunc ff;
-	EogJobProgressFunc pf;
-	EogJobFreeDataFunc df;
-};
-
-static void
-eog_job_set_property (GObject      *object,
-		      guint         property_id,
-		      const GValue *value,
-		      GParamSpec   *pspec)
-{
-	EogJob *job;
-
-	g_return_if_fail (EOG_IS_JOB (object));
-
-	job = EOG_JOB (object);
-
-	switch (property_id) {
-	case PROP_PROGRESS_THRESHOLD:
-		job->priv->progress_threshold = 
-			g_value_get_float (value);
-		break;
-	case PROP_PROGRESS_N_PARTS:
-		job->priv->progress_n_parts = 
-			g_value_get_uint (value);
-		break;
-	case PROP_PRIORITY:
-		job->priv->priority = 
-			g_value_get_uint (value);
-		break;
-        default:
-                g_assert_not_reached ();
-	}
-}
-
-static void
-eog_job_get_property (GObject    *object,
-		      guint       property_id,
-		      GValue     *value,
-		      GParamSpec *pspec)
-{
-	EogJob *job;
-
-	g_return_if_fail (EOG_IS_JOB (object));
-
-	job = EOG_JOB (object);
-
-	switch (property_id) {
-	case PROP_PROGRESS_THRESHOLD:
-		g_value_set_float (value,
-				   job->priv->progress_threshold);
-		break;
-	case PROP_PROGRESS_N_PARTS:
-		g_value_set_uint (value,				  
-				  job->priv->progress_n_parts);
-		break;
-	case PROP_PRIORITY:
-		g_value_set_uint (value,
-				  job->priv->priority);
-		break;
-        default:
-                g_assert_not_reached ();
-	}
-}
-
-static void
-eog_job_finalize (GObject *object)
-{
-	EogJob *instance = EOG_JOB (object);
-	
-	g_free (instance->priv);
-	instance->priv = NULL;
-}
-
-static void
-eog_job_dispose (GObject *object)
-{
-	EogJobPrivate *priv;
-
-	priv = EOG_JOB (object)->priv;
-
-#if DEBUG_EOG_JOB
-	g_print ("Job %.3u: disposing ...\n", priv->id);
-#endif
-
-	if (priv->mutex != NULL) {
-		g_mutex_lock (priv->mutex);
-		if (priv->data != NULL)
-		{
-			if (priv->df != NULL) {
-				(*priv->df) (priv->data);
-			}
-			else if (G_IS_OBJECT (priv->data))
-				g_object_unref (G_OBJECT (priv->data));
-			
-			priv->data = NULL;
-		}
-		g_mutex_unlock (priv->mutex);
-		
-		g_mutex_free (priv->mutex);
-		priv->mutex = NULL;
-	}
-
-#if DEBUG_EOG_JOB
-	g_print ("Job %.3u: disposing end\n", priv->id);
-#endif
-}
-
-static void
-eog_job_init (EogJob *obj)
-{
-	EogJobPrivate *priv;
-	guint id;
-
-	id = ++last_job_id;
-	if (id == 0) { /* in overflow case */
-		++last_job_id;
-		++id; 
-	}
-
-#if DEBUG_EOG_JOB
-	g_print ("Instantiate job with id %u.\n", id);
-#endif
-
-	priv = g_new0 (EogJobPrivate, 1);
-	priv->id = id;
-	priv->mutex = g_mutex_new ();
-	priv->error = NULL;
-	priv->data = NULL;
-	priv->af = NULL;
-	priv->cf = NULL;
-	priv->ff = NULL;
-	priv->pf = NULL;
-	priv->df = NULL;
-	priv->progress = 0.0;
-	priv->progress_idle_id = 0;
-	priv->progress_threshold = 0.1;
-	priv->progress_n_parts = 1;
-	priv->priority = EOG_JOB_PRIORITY_NORMAL;
-
-	obj->priv = priv;
-}
-
-static void 
-eog_job_class_init (EogJobClass *klass)
-{
-	GObjectClass *object_class = (GObjectClass*) klass;
-
-	object_class->finalize = eog_job_finalize;
-	object_class->dispose = eog_job_dispose;
-        object_class->set_property = eog_job_set_property;
-        object_class->get_property = eog_job_get_property;
-
-        /* Properties */
-        g_object_class_install_property (
-                object_class,
-                PROP_PROGRESS_THRESHOLD,
-                g_param_spec_float ("progress-threshold", NULL, 
-				    "Difference threshold between two progress values"
-				    "before calling progress callback function again", 
-				    0.0, 1.0, 0.1,
-				    G_PARAM_READWRITE));
-
-        g_object_class_install_property (
-                object_class,
-                PROP_PROGRESS_N_PARTS,
-                g_param_spec_uint ("progress-n-parts", NULL,
-				   "Number of parts for this progress so that "
-				   "the total progress is the sum of progress "
-				   "for each part devided through number of parts.",
-				   0, G_MAXINT, 1,
-				   G_PARAM_READWRITE));
-
-        g_object_class_install_property (
-                object_class,
-                PROP_PRIORITY,
-                g_param_spec_uint ("priority", NULL,
-				   "Priority of the job.",
-				   0, G_MAXINT, 1,
-				   G_PARAM_WRITABLE));
-}
-
-
-G_DEFINE_TYPE (EogJob, eog_job,	G_TYPE_OBJECT)
-
-EogJob*             
-eog_job_new (GObject *data_obj, 
-	     EogJobActionFunc   af, 
-	     EogJobFinishedFunc ff,
-	     EogJobCancelFunc   cf,
-	     EogJobProgressFunc pf)
-{
-	g_return_val_if_fail (G_IS_OBJECT (data_obj), NULL);
-
-	return eog_job_new_full ((gpointer) data_obj, af, ff, cf, pf, NULL);
-}
-
-/* called from main thread */
-EogJob*             
-eog_job_new_full (gpointer data, 
-		  EogJobActionFunc   af, 
-		  EogJobFinishedFunc ff,
-		  EogJobCancelFunc   cf,
-		  EogJobProgressFunc pf,
-		  EogJobFreeDataFunc df)
-{
-	EogJob *job;
-	EogJobPrivate *priv;
-
-	g_return_val_if_fail (af != NULL, NULL);
-
-	job = g_object_new (EOG_TYPE_JOB, NULL);
-	priv = job->priv;
-
-	if (G_IS_OBJECT (data)) {
-		g_object_ref (G_OBJECT (data));
-	}
-	priv->data = data;
-	priv->status = EOG_JOB_STATUS_WAITING;
-	priv->af = af;
-	priv->ff = ff;
-	priv->cf = cf;
-	priv->pf = pf;
-	priv->df = df;
-	
-	return job;
-}
-
-/* called from main thread */
-EogJobStatus
-eog_job_get_status (EogJob *job)
-{
-	g_return_val_if_fail (EOG_IS_JOB (job), EOG_JOB_STATUS_ERROR);
-
-	return job->priv->status;
-}
-
-/* called from main thread */
-guint
-eog_job_get_id (EogJob *job)
-{
-	g_return_val_if_fail (EOG_IS_JOB (job), 0);
-
-	return job->priv->id;
-}
-
-/* called from main thread */
-gboolean
-eog_job_get_success (EogJob *job) 
-{
-	gboolean success;
-
-	g_return_val_if_fail (EOG_IS_JOB (job), FALSE);
-	
-	g_mutex_lock (job->priv->mutex);
-	
-	success = ((job->priv->status == EOG_JOB_STATUS_FINISHED) && 
-		   (job->priv->error == NULL));
-
-	g_mutex_unlock (job->priv->mutex);
-
-	return success;
-}
-
-void
-eog_job_part_finished (EogJob *job)
-{
-	g_return_if_fail (EOG_IS_JOB (job));
-
-	job->priv->progress_nth_part = 
-		MIN ((job->priv->progress_nth_part + 1),
-		     job->priv->progress_n_parts);
-}
-
-/* private func, called within main thread from idle loop */
-static gboolean
-eog_job_call_progress (gpointer data)
-{
-	EogJob *job = EOG_JOB (data);
-
-	g_assert (job->priv->pf != NULL);
-
-	g_mutex_lock (job->priv->mutex);
-	job->priv->progress_idle_id = 0;
-	g_mutex_unlock (job->priv->mutex);
-
-	/* call progress callback */
-	(*job->priv->pf) (job, job->priv->data, job->priv->progress);
-
-	return FALSE;
-}
-
-/* called from concurrent thread */
-void
-eog_job_set_progress (EogJob *job, float progress)
-{
-	EogJobPrivate *priv;
-
-	g_return_if_fail (EOG_IS_JOB (job));
-
-	priv = job->priv;
-
-	g_mutex_lock (job->priv->mutex);
-	/* calculate new progress */
-	priv->progress = ((float) priv->progress_nth_part + progress) /
-		priv->progress_n_parts;
-	
-	/* check if all preconditions are met for calling progress callback */
-	if ((priv->pf != NULL) && 
-	    (priv->progress_idle_id == 0) && 
-	    (priv->progress == 1.0 ||
-	     (priv->progress - priv->progress_last_called) >= priv->progress_threshold))
-	{
-		priv->progress_last_called = priv->progress;
-		priv->progress_idle_id = g_idle_add (eog_job_call_progress, job);
-	}
-	g_mutex_unlock (job->priv->mutex);
-}
-
-/* this runs in its own thread 
- * called by EogJobManager
- */
-void
-eog_job_call_action (EogJob *job)
-{
-	gboolean do_action = TRUE;
-
-	g_return_if_fail (EOG_IS_JOB (job));
-	
-	g_mutex_lock (job->priv->mutex);
-	if (job->priv->status != EOG_JOB_STATUS_WAITING)
-		do_action = FALSE;
-	
-	if (job->priv->af == NULL) {
-		job->priv->status = EOG_JOB_STATUS_ERROR;
-		do_action = FALSE;
-	}
-	
-	if (do_action) {
-		job->priv->status = EOG_JOB_STATUS_RUNNING;
-		job->priv->progress = 0.0;
-		job->priv->progress_last_called = 0.0;
-		job->priv->progress_nth_part = 0;
-	}
-
-	g_mutex_unlock (job->priv->mutex);
-
-	if (!do_action) {
-		return;
-	}
-
-	/* do the actual work */
-	(*job->priv->af) (job, job->priv->data, &job->priv->error);
-
-	g_mutex_lock (job->priv->mutex);
-	if (job->priv->status != EOG_JOB_STATUS_CANCELED)
-		job->priv->status = EOG_JOB_STATUS_FINISHED;
-	g_mutex_unlock (job->priv->mutex);
-}
-
-/* called within main thread from idle loop 
- * by EogJobManager
- */
-gboolean 
-eog_job_call_canceled (EogJob *job)
-{
-	gboolean do_cancel = FALSE;
-	gboolean valid_state = FALSE;
-
-	g_return_val_if_fail (EOG_IS_JOB (job), FALSE);
-
-	g_mutex_lock (job->priv->mutex);
-	valid_state = (job->priv->status == EOG_JOB_STATUS_WAITING  ||
-		       job->priv->status == EOG_JOB_STATUS_RUNNING); 
-	do_cancel = (job->priv->cf != NULL && valid_state);
-	if (valid_state) {
-		job->priv->status = EOG_JOB_STATUS_CANCELED;
-	}
-	g_mutex_unlock (job->priv->mutex);
-	
-	if (do_cancel) {
-		/* call cancel function */
-		(*job->priv->cf) (job, job->priv->data);
-	}
-
-	return valid_state;
-}
-
-/* called within main thread from idle loop 
- * by EogJobManager
- */
-void
-eog_job_call_finished (EogJob *job)
-{
-	gboolean call_finished = FALSE;
-
-	g_return_if_fail (EOG_IS_JOB (job));
-
-	g_mutex_lock (job->priv->mutex);
-	g_assert (job->priv->status == EOG_JOB_STATUS_FINISHED ||
-		  job->priv->status == EOG_JOB_STATUS_CANCELED);
-
-	call_finished = (job->priv->ff != NULL);
-	g_mutex_unlock (job->priv->mutex);
-
-	if (call_finished) {
-		/* call finished callback */
-		(*job->priv->ff) (job, job->priv->data, job->priv->error);
-	}
-}
-
-EogJobPriority      
-eog_job_get_priority (EogJob *job)
-{
-	g_return_val_if_fail (EOG_IS_JOB (job), EOG_JOB_PRIORITY_NORMAL);
-
-	return job->priv->priority;
-}
--- libeog/eog-job.h	2006-11-27 22:44:24.000000000 -0300
+++ /dev/null	2006-12-12 07:37:33.396075749 -0300
@@ -1,79 +0,0 @@
-#ifndef _EOG_JOB_H_
-#define _EOG_JOB_H_
-
-#include <glib-object.h>
-
-
-G_BEGIN_DECLS
-
-#define EOG_TYPE_JOB            (eog_job_get_type ())
-#define EOG_JOB(o)         (G_TYPE_CHECK_INSTANCE_CAST ((o), EOG_TYPE_JOB, EogJob))
-#define EOG_JOB_CLASS(k)   (G_TYPE_CHECK_CLASS_CAST((k), EOG_TYPE_JOB, EogJobClass))
-#define EOG_IS_JOB(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), EOG_TYPE_JOB))
-#define EOG_IS_JOB_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), EOG_TYPE_JOB))
-#define EOG_JOB_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), EOG_TYPE_JOB, EogJobClass))
-
-typedef struct _EogJob EogJob;
-typedef struct _EogJobClass EogJobClass;
-typedef struct _EogJobPrivate EogJobPrivate;
-
-struct _EogJob {
-	GObject parent;
-
-	EogJobPrivate *priv;
-};
-
-struct _EogJobClass {
-	GObjectClass parent_klass;
-};
-
-typedef enum {
-	EOG_JOB_STATUS_ERROR,
-	EOG_JOB_STATUS_WAITING,
-	EOG_JOB_STATUS_RUNNING,
-	EOG_JOB_STATUS_FINISHED,
-	EOG_JOB_STATUS_CANCELED
-} EogJobStatus;
-
-typedef enum {
-	EOG_JOB_PRIORITY_NORMAL = 0,
-	EOG_JOB_PRIORITY_HIGH   = 1
-} EogJobPriority;
-
-typedef void  ((* EogJobActionFunc)    (EogJob *job, gpointer data, GError **error));
-typedef void  ((* EogJobFinishedFunc)  (EogJob *job, gpointer data, GError *error));
-typedef void  ((* EogJobCancelFunc)    (EogJob *job, gpointer data));
-typedef void  ((* EogJobFreeDataFunc)  (gpointer data));
-typedef void  ((* EogJobProgressFunc)  (EogJob *job, gpointer data, float progress));
-
-/* Public API */
-GType               eog_job_get_type                       (void) G_GNUC_CONST;
-
-EogJob*             eog_job_new (GObject *data_obj, 
-				 EogJobActionFunc af,
-				 EogJobFinishedFunc ff,
-				 EogJobCancelFunc cf,
-				 EogJobProgressFunc pf);
-
-EogJob*             eog_job_new_full (gpointer data, 
-				      EogJobActionFunc af,
-				      EogJobFinishedFunc ff,
-				      EogJobCancelFunc cf,
-				      EogJobProgressFunc pf,
-				      EogJobFreeDataFunc df);
-void                eog_job_part_finished (EogJob *job);
-EogJobStatus        eog_job_get_status   (EogJob *job);
-guint               eog_job_get_id       (EogJob *job);
-gboolean            eog_job_get_success  (EogJob *job);
-void                eog_job_set_progress (EogJob *job, float progress);
-EogJobPriority      eog_job_get_priority (EogJob *job);
-
-/* API only used by the EogJobManager */
-void                eog_job_call_action   (EogJob *job);
-void                eog_job_call_finished (EogJob *job);
-gboolean            eog_job_call_canceled (EogJob *job);
-
-
-G_END_DECLS
-
-#endif /* _EOG_JOB_H_ */
