]> www.fi.muni.cz Git - evince.git/commitdiff
Do file transfer asynchronously in the main thread instead of
authorCarlos Garcia Campos <carlosgc@gnome.org>
Wed, 24 Jan 2007 18:14:06 +0000 (18:14 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Wed, 24 Jan 2007 18:14:06 +0000 (18:14 +0000)
2007-01-24  Carlos Garcia Campos  <carlosgc@gnome.org>
* shell/ev-job-queue.c: (handle_job), (search_for_jobs_unlocked),
(no_jobs_available_unlocked), (ev_job_queue_init), (find_queue),
(ev_job_queue_remove_job):
* shell/ev-jobs.[ch]: (ev_job_load_init), (ev_job_load_class_init),
(ev_job_load_dispose), (ev_job_load_new), (ev_job_load_set_uri),
(ev_job_load_run):
* shell/ev-window.c: (ev_window_is_empty), (password_dialog_response),
(ev_window_popup_password_dialog), (ev_window_clear_load_job),
(ev_window_load_job_cb), (xfer_update_progress_callback),
(ev_window_open_uri), (ev_window_dispose):
* shell/main.c: (main):
Do file transfer asynchronously in the main thread instead of
synchronously in the load thread. Fixes bugs #399694, #398307 and
#343542.

svn path=/trunk/; revision=2248

ChangeLog
shell/ev-job-queue.c
shell/ev-jobs.c
shell/ev-jobs.h
shell/ev-window.c
shell/main.c

index e7d57a8233ea936925eda4ec30abdf8f46be40e6..961a68f48bdbae02517ae6a3db6d1c75ac62d59a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2007-01-24  Carlos Garcia Campos  <carlosgc@gnome.org>
+
+       * shell/ev-job-queue.c: (handle_job), (search_for_jobs_unlocked),
+       (no_jobs_available_unlocked), (ev_job_queue_init), (find_queue),
+       (ev_job_queue_remove_job):
+       * shell/ev-jobs.[ch]: (ev_job_load_init), (ev_job_load_class_init),
+       (ev_job_load_dispose), (ev_job_load_new), (ev_job_load_set_uri),
+       (ev_job_load_run):
+       * shell/ev-window.c: (ev_window_is_empty), (password_dialog_response),
+       (ev_window_popup_password_dialog), (ev_window_clear_load_job),
+       (ev_window_load_job_cb), (xfer_update_progress_callback),
+       (ev_window_open_uri), (ev_window_dispose):
+       * shell/main.c: (main):
+
+       Do file transfer asynchronously in the main thread instead of
+       synchronously in the load thread. Fixes bugs #399694, #398307 and
+       #343542.
+
 2007-01-24  Carlos Garcia Campos  <carlosgc@gnome.org>
 
        * shell/ev-jobs.c: (ev_job_xfer_run):
index 09e7bb895606c190955b2b1cc5c75d60c7caa510..d2733d6f28575051856ccad08db634470c67d592 100644 (file)
@@ -12,7 +12,7 @@ static GQueue *render_queue_high = NULL;
 static GQueue *render_queue_low = NULL;
 static GQueue *thumbnail_queue_high = NULL;
 static GQueue *thumbnail_queue_low = NULL;
-static GQueue *xfer_queue = NULL;
+static GQueue *load_queue = NULL;
 static GQueue *fonts_queue = NULL;
 static GQueue *print_queue = NULL;
 
@@ -96,8 +96,8 @@ handle_job (EvJob *job)
                ev_job_thumbnail_run (EV_JOB_THUMBNAIL (job));
        else if (EV_IS_JOB_LINKS (job))
                ev_job_links_run (EV_JOB_LINKS (job));
-       else if (EV_IS_JOB_XFER (job))
-               ev_job_xfer_run (EV_JOB_XFER (job));
+       else if (EV_IS_JOB_LOAD (job))
+               ev_job_load_run (EV_JOB_LOAD (job));
        else if (EV_IS_JOB_RENDER (job))
                ev_job_render_run (EV_JOB_RENDER (job));
        else if (EV_IS_JOB_FONTS (job))
@@ -135,7 +135,7 @@ search_for_jobs_unlocked (void)
        if (job)
                return job;
 
-       job = (EvJob *) g_queue_pop_head (xfer_queue);
+       job = (EvJob *) g_queue_pop_head (load_queue);
        if (job)
                return job;
 
@@ -160,7 +160,7 @@ no_jobs_available_unlocked (void)
        return g_queue_is_empty (render_queue_high)
                && g_queue_is_empty (render_queue_low)
                && g_queue_is_empty (links_queue)
-               && g_queue_is_empty (xfer_queue)
+               && g_queue_is_empty (load_queue)
                && g_queue_is_empty (thumbnail_queue_high)
                && g_queue_is_empty (thumbnail_queue_low)
                && g_queue_is_empty (fonts_queue)
@@ -220,7 +220,7 @@ ev_job_queue_init (void)
        ev_queue_mutex = g_mutex_new ();
 
        links_queue = g_queue_new ();
-       xfer_queue = g_queue_new ();
+       load_queue = g_queue_new ();
        render_queue_high = g_queue_new ();
        render_queue_low = g_queue_new ();
        async_render_queue_high = g_queue_new ();
@@ -256,9 +256,9 @@ find_queue (EvJob         *job,
                                return thumbnail_queue_high;
                        else
                                return thumbnail_queue_low;
-               } else if (EV_IS_JOB_XFER (job)) {
-                       /* the priority doesn't effect xfer */
-                       return xfer_queue;
+               } else if (EV_IS_JOB_LOAD (job)) {
+                       /* the priority doesn't effect load */
+                       return load_queue;
                } else if (EV_IS_JOB_LINKS (job)) {
                        /* the priority doesn't effect links */
                        return links_queue;
@@ -403,8 +403,8 @@ ev_job_queue_remove_job (EvJob *job)
                        retval = retval || remove_job_from_queue_locked (render_queue_low, job);
                } else if (EV_IS_JOB_LINKS (job)) {
                        retval = remove_job_from_queue_locked (links_queue, job);
-               } else if (EV_IS_JOB_XFER (job)) {
-                       retval = remove_job_from_queue_locked (xfer_queue, job);
+               } else if (EV_IS_JOB_LOAD (job)) {
+                       retval = remove_job_from_queue_locked (load_queue, job);
                } else if (EV_IS_JOB_FONTS (job)) {
                        retval = remove_job_from_queue_locked (fonts_queue, job);
                } else if (EV_IS_JOB_PRINT (job)) {
index 8c26ca806d83435eae5660bc24f5452f8baebfc2..9fb242a0c6cd5a35dd2559f7e48c366a3c7afc08 100644 (file)
@@ -16,7 +16,6 @@
 #include <libgnomevfs/gnome-vfs-uri.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 #include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-xfer.h>
 
 static void ev_job_init                 (EvJob               *job);
 static void ev_job_class_init           (EvJobClass          *class);
@@ -26,8 +25,8 @@ static void ev_job_render_init          (EvJobRender         *job);
 static void ev_job_render_class_init    (EvJobRenderClass    *class);
 static void ev_job_thumbnail_init       (EvJobThumbnail      *job);
 static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class);
-static void ev_job_xfer_init           (EvJobXfer           *job);
-static void ev_job_xfer_class_init     (EvJobXferClass      *class);
+static void ev_job_load_init           (EvJobLoad           *job);
+static void ev_job_load_class_init     (EvJobLoadClass      *class);
 static void ev_job_print_init           (EvJobPrint          *job);
 static void ev_job_print_class_init     (EvJobPrintClass     *class);
 
@@ -44,7 +43,7 @@ G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
-G_DEFINE_TYPE (EvJobXfer, ev_job_xfer, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobPrint, ev_job_print, EV_TYPE_JOB)
 
 static void ev_job_init (EvJob *job) { /* Do Nothing */ }
@@ -425,23 +424,18 @@ ev_job_fonts_run (EvJobFonts *job)
        ev_document_doc_mutex_unlock ();
 }
 
-static void ev_job_xfer_init (EvJobXfer *job) { /* Do Nothing */ }
+static void ev_job_load_init (EvJobLoad *job) { /* Do Nothing */ }
 
 static void
-ev_job_xfer_dispose (GObject *object)
+ev_job_load_dispose (GObject *object)
 {
-       EvJobXfer *job = EV_JOB_XFER (object);
+       EvJobLoad *job = EV_JOB_LOAD (object);
 
        if (job->uri) {
                g_free (job->uri);
                job->uri = NULL;
        }
 
-       if (job->local_uri) {
-               g_free (job->local_uri);
-               job->local_uri = NULL;
-       }
-
        if (job->error) {
                g_error_free (job->error);
                job->error = NULL;
@@ -452,26 +446,26 @@ ev_job_xfer_dispose (GObject *object)
                job->dest = NULL;
        }
 
-       (* G_OBJECT_CLASS (ev_job_xfer_parent_class)->dispose) (object);
+       (* G_OBJECT_CLASS (ev_job_load_parent_class)->dispose) (object);
 }
 
 static void
-ev_job_xfer_class_init (EvJobXferClass *class)
+ev_job_load_class_init (EvJobLoadClass *class)
 {
        GObjectClass *oclass;
 
        oclass = G_OBJECT_CLASS (class);
 
-       oclass->dispose = ev_job_xfer_dispose;
+       oclass->dispose = ev_job_load_dispose;
 }
 
 
 EvJob *
-ev_job_xfer_new (const gchar *uri, EvLinkDest *dest, EvWindowRunMode mode)
+ev_job_load_new (const gchar *uri, EvLinkDest *dest, EvWindowRunMode mode)
 {
-       EvJobXfer *job;
+       EvJobLoad *job;
 
-       job = g_object_new (EV_TYPE_JOB_XFER, NULL);
+       job = g_object_new (EV_TYPE_JOB_LOAD, NULL);
 
        job->uri = g_strdup (uri);
        if (dest)
@@ -483,63 +477,40 @@ ev_job_xfer_new (const gchar *uri, EvLinkDest *dest, EvWindowRunMode mode)
 }
 
 void
-ev_job_xfer_run (EvJobXfer *job)
+ev_job_load_set_uri (EvJobLoad *job, const gchar *uri)
 {
-       GnomeVFSURI *source_uri;
-       GnomeVFSURI *target_uri;
+       if (job->uri)
+               g_free (job->uri);
+       job->uri = g_strdup (uri);
+}
 
-       g_return_if_fail (EV_IS_JOB_XFER (job));
+void
+ev_job_load_run (EvJobLoad *job)
+{
+       g_return_if_fail (EV_IS_JOB_LOAD (job));
        
        if (job->error) {
                g_error_free (job->error);
                job->error = NULL;
        }
+
+       ev_document_fc_mutex_lock ();
        
        /* This job may already have a document even if the job didn't complete
           because, e.g., a password is required - if so, just reload rather than
           creating a new instance */
        if (EV_JOB (job)->document) {
-               ev_document_fc_mutex_lock ();
                ev_document_load (EV_JOB (job)->document,
-                                 job->local_uri ? job->local_uri : job->uri,
+                                 job->uri,
                                  &job->error);
-               ev_document_fc_mutex_unlock ();
-               EV_JOB (job)->finished = TRUE;
-               return;
-       }
-
-       source_uri = gnome_vfs_uri_new (job->uri);
-       if (!gnome_vfs_uri_is_local (source_uri) && !job->local_uri) {
-               char *tmp_name;
-               char *base_name;
-               
-               /* We'd like to keep extension of source uri since
-                * it helps to resolve some mime types, say cbz */
-               
-               tmp_name = ev_tmp_filename (NULL);
-               base_name = gnome_vfs_uri_extract_short_name (source_uri);
-               job->local_uri = g_strconcat ("file:", tmp_name, "-", base_name, NULL);
-               g_free (base_name);
-               g_free (tmp_name);
-               
-               target_uri = gnome_vfs_uri_new (job->local_uri);
-
-               gnome_vfs_xfer_uri (source_uri, target_uri, 
-                                   GNOME_VFS_XFER_DEFAULT | GNOME_VFS_XFER_FOLLOW_LINKS,
-                                   GNOME_VFS_XFER_ERROR_MODE_ABORT,
-                                   GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
-                                   NULL,
-                                   job);
-               gnome_vfs_uri_unref (target_uri);
+       } else {
+               EV_JOB(job)->document =
+                       ev_document_factory_get_document (job->uri,
+                                                         &job->error);
        }
-       gnome_vfs_uri_unref (source_uri);
 
-       ev_document_fc_mutex_lock ();
-       EV_JOB(job)->document = ev_document_factory_get_document (job->local_uri ? job->local_uri : job->uri, &job->error);
        ev_document_fc_mutex_unlock ();
        EV_JOB (job)->finished = TRUE;
-
-       return;
 }
 
 EvJob *
index bf37b673ea75597d9ab304c97c29dd29dca866ab..779c3736dbd9880913dab41e25b7edb80d864f4d 100644 (file)
@@ -41,8 +41,8 @@ typedef struct _EvJobLinksClass EvJobLinksClass;
 typedef struct _EvJobFonts EvJobFonts;
 typedef struct _EvJobFontsClass EvJobFontsClass;
 
-typedef struct _EvJobXfer EvJobXfer;
-typedef struct _EvJobXferClass EvJobXferClass;
+typedef struct _EvJobLoad EvJobLoad;
+typedef struct _EvJobLoadClass EvJobLoadClass;
 
 typedef struct _EvJobPrint EvJobPrint;
 typedef struct _EvJobPrintClass EvJobPrintClass;
@@ -72,10 +72,10 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
 #define EV_JOB_FONTS_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_FONTS, EvJobFontsClass))
 #define EV_IS_JOB_FONTS(object)                     (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_FONTS))
 
-#define EV_TYPE_JOB_XFER                    (ev_job_xfer_get_type())
-#define EV_JOB_XFER(object)                 (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_XFER, EvJobXfer))
-#define EV_JOB_XFER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_XFER, EvJobXferClass))
-#define EV_IS_JOB_XFER(object)              (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_XFER))
+#define EV_TYPE_JOB_LOAD                    (ev_job_load_get_type())
+#define EV_JOB_LOAD(object)                 (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_LOAD, EvJobLoad))
+#define EV_JOB_LOAD_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_LOAD, EvJobLoadClass))
+#define EV_IS_JOB_LOAD(object)              (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_LOAD))
 
 #define EV_TYPE_JOB_PRINT                     (ev_job_print_get_type())
 #define EV_JOB_PRINT(object)                  (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_PRINT, EvJobPrint))
@@ -170,17 +170,17 @@ struct _EvJobFontsClass
         EvJobClass parent_class;
 };
 
-struct _EvJobXfer
+struct _EvJobLoad
 {
        EvJob parent;
+       
        EvLinkDest *dest;
        EvWindowRunMode mode;
        GError *error;
-       char *uri;
-       char *local_uri;
+       gchar *uri;
 };
 
-struct _EvJobXferClass
+struct _EvJobLoadClass
 {
        EvJobClass parent_class;
 };
@@ -244,12 +244,14 @@ GType             ev_job_fonts_get_type     (void) G_GNUC_CONST;
 EvJob         *ev_job_fonts_new          (EvDocument      *document);
 void           ev_job_fonts_run          (EvJobFonts      *fonts);
 
-/* EvJobXfer */
-GType          ev_job_xfer_get_type      (void) G_GNUC_CONST;
-EvJob         *ev_job_xfer_new           (const gchar     *uri,
+/* EvJobLoad */
+GType          ev_job_load_get_type      (void) G_GNUC_CONST;
+EvJob         *ev_job_load_new           (const gchar     *uri,
                                           EvLinkDest      *dest,
                                           EvWindowRunMode  mode);
-void           ev_job_xfer_run           (EvJobXfer       *xfer);
+void            ev_job_load_set_uri       (EvJobLoad       *load,
+                                          const gchar     *uri);
+void           ev_job_load_run           (EvJobLoad       *load);
 
 /* EvJobPrint */
 GType           ev_job_print_get_type     (void) G_GNUC_CONST;
index 8f5468489ddc0577425f2c991a407be7b745ae91..832ce45963972a72ff0f1945e499fc50f5c2c975 100644 (file)
@@ -89,6 +89,7 @@
 #include <gtk/gtk.h>
 #include <gnome.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-async-ops.h>
 #include <gconf/gconf-client.h>
 
 #include <string.h>
@@ -175,7 +176,7 @@ struct _EvWindowPrivate {
        EggRecentViewUIManager *recent_view;
 #endif
 
-       EvJob *xfer_job;
+       EvJob *load_job;
 #ifdef WITH_GNOME_PRINT
        GnomePrintJob *print_job;
 #endif
@@ -214,7 +215,7 @@ static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_si
                                                         EvWindow         *ev_window);
 static void     ev_window_set_page_mode                 (EvWindow         *window,
                                                         EvWindowPageMode  page_mode);
-static void    ev_window_xfer_job_cb                   (EvJobXfer        *job,
+static void    ev_window_load_job_cb                   (EvJobLoad        *job,
                                                         gpointer          data);
 #ifdef WITH_GTK_PRINT
 static void     ev_window_print_job_cb                  (EvJobPrint       *job,
@@ -594,7 +595,7 @@ ev_window_is_empty (const EvWindow *ev_window)
        g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
 
        return (ev_window->priv->document == NULL) && 
-               (ev_window->priv->xfer_job == NULL);
+               (ev_window->priv->load_job == NULL);
 }
 
 static void
@@ -956,7 +957,7 @@ password_dialog_response (GtkWidget *password_dialog,
                password = ev_password_dialog_get_password (EV_PASSWORD_DIALOG (password_dialog));
                if (password) {
                        ev_document_doc_mutex_lock ();
-                       ev_document_security_set_password (EV_DOCUMENT_SECURITY (ev_window->priv->xfer_job->document),
+                       ev_document_security_set_password (EV_DOCUMENT_SECURITY (ev_window->priv->load_job->document),
                                                           password);
                        ev_document_doc_mutex_unlock ();
                }
@@ -965,7 +966,7 @@ password_dialog_response (GtkWidget *password_dialog,
                ev_password_dialog_save_password (EV_PASSWORD_DIALOG (password_dialog));
 
                ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_DOCUMENT);
-               ev_job_queue_add_job (ev_window->priv->xfer_job, EV_JOB_PRIORITY_HIGH);
+               ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
                
                gtk_widget_destroy (password_dialog);
                        
@@ -976,14 +977,14 @@ password_dialog_response (GtkWidget *password_dialog,
        gtk_widget_destroy (password_dialog);
 }
 
-/* Called either by ev_window_xfer_job_cb or by the "unlock" callback on the
+/* Called either by ev_window_load_job_cb or by the "unlock" callback on the
  * password_view page.  It assumes that ev_window->priv->password_* has been set
  * correctly.  These are cleared by password_dialog_response() */
 
 static void
 ev_window_popup_password_dialog (EvWindow *ev_window)
 {
-       g_assert (ev_window->priv->xfer_job);
+       g_assert (ev_window->priv->load_job);
 
        gtk_widget_set_sensitive (ev_window->priv->password_view, FALSE);
 
@@ -1008,16 +1009,16 @@ ev_window_popup_password_dialog (EvWindow *ev_window)
 }
 
 static void
-ev_window_clear_xfer_job (EvWindow *ev_window)
+ev_window_clear_load_job (EvWindow *ev_window)
 {
-    if (ev_window->priv->xfer_job != NULL) {
+    if (ev_window->priv->load_job != NULL) {
 
-       if (!ev_window->priv->xfer_job->finished)
-               ev_job_queue_remove_job (ev_window->priv->xfer_job);
+       if (!ev_window->priv->load_job->finished)
+               ev_job_queue_remove_job (ev_window->priv->load_job);
 
-       g_signal_handlers_disconnect_by_func (ev_window->priv->xfer_job, ev_window_xfer_job_cb, ev_window);
-       g_object_unref (ev_window->priv->xfer_job);
-       ev_window->priv->xfer_job = NULL;
+       g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
+       g_object_unref (ev_window->priv->load_job);
+       ev_window->priv->load_job = NULL;
     }
 }
 
@@ -1075,7 +1076,7 @@ ev_window_clear_temp_file (EvWindow *ev_window)
  * function should _not_ necessarily expect those to exist after being
  * called. */
 static void
-ev_window_xfer_job_cb  (EvJobXfer *job,
+ev_window_load_job_cb  (EvJobLoad *job,
                        gpointer data)
 {
        EvWindow *ev_window = EV_WINDOW (data);
@@ -1087,16 +1088,6 @@ ev_window_xfer_job_cb  (EvJobXfer *job,
 
        /* Success! */
        if (job->error == NULL) {
-
-               if (ev_window->priv->uri)
-                       g_free (ev_window->priv->uri);
-               ev_window->priv->uri = g_strdup (job->uri);
-
-               if (ev_window->priv->local_uri)
-                       g_free (ev_window->priv->local_uri);
-               ev_window->priv->local_uri = 
-                   job->local_uri ? g_strdup (job->local_uri) : NULL;
-               
                if (ev_window->priv->document)
                        g_object_unref (ev_window->priv->document);
                ev_window->priv->document = g_object_ref (document);
@@ -1125,7 +1116,7 @@ ev_window_xfer_job_cb  (EvJobXfer *job,
                                break;
                }
 
-               ev_window_clear_xfer_job (ev_window);           
+               ev_window_clear_load_job (ev_window);           
                return;
        }
 
@@ -1133,8 +1124,6 @@ ev_window_xfer_job_cb  (EvJobXfer *job,
            job->error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
                gchar *base_name, *file_name;
 
-               g_free (ev_window->priv->uri);
-               ev_window->priv->uri = g_strdup (job->uri);
                setup_view_from_metadata (ev_window);
 
                file_name = gnome_vfs_format_uri_for_display (job->uri);
@@ -1150,7 +1139,7 @@ ev_window_xfer_job_cb  (EvJobXfer *job,
                ev_window_error_dialog (GTK_WINDOW (ev_window), 
                                        _("Unable to open document"),
                                        job->error);
-               ev_window_clear_xfer_job (ev_window);
+               ev_window_clear_load_job (ev_window);
        }       
 
        return;
@@ -1186,6 +1175,29 @@ ev_window_close_dialogs (EvWindow *ev_window)
        ev_window->priv->properties = NULL;
 }
 
+static gint
+xfer_update_progress_callback (GnomeVFSAsyncHandle      *handle,
+                              GnomeVFSXferProgressInfo *info,
+                              EvWindow                 *ev_window)
+{
+       switch (info->status) {
+               case GNOME_VFS_XFER_PROGRESS_STATUS_OK:
+                       if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) {
+                               ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+                       }
+
+                       return 1;
+               case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR:
+               case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE:
+               case GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE:
+                       return 1;
+               default:
+                       g_assert_not_reached ();
+       }
+
+       return 0;
+}
+
 void
 ev_window_open_uri (EvWindow       *ev_window,
                    const char     *uri,
@@ -1193,19 +1205,68 @@ ev_window_open_uri (EvWindow       *ev_window,
                    EvWindowRunMode mode,
                    gboolean        unlink_temp_file)
 {
+       GnomeVFSURI *source_uri;
+       GnomeVFSURI *target_uri;
+       
        ev_window_close_dialogs (ev_window);
-       ev_window_clear_xfer_job (ev_window);
+       ev_window_clear_load_job (ev_window);
        ev_window_clear_local_uri (ev_window);
        ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
 
        ev_window->priv->unlink_temp_file = unlink_temp_file;
+
+       if (ev_window->priv->uri)
+               g_free (ev_window->priv->uri);
+       ev_window->priv->uri = g_strdup (uri);
        
-       ev_window->priv->xfer_job = ev_job_xfer_new (uri, dest, mode);
-       g_signal_connect (ev_window->priv->xfer_job,
+       ev_window->priv->load_job = ev_job_load_new (uri, dest, mode);
+       g_signal_connect (ev_window->priv->load_job,
                          "finished",
-                         G_CALLBACK (ev_window_xfer_job_cb),
+                         G_CALLBACK (ev_window_load_job_cb),
                          ev_window);
-       ev_job_queue_add_job (ev_window->priv->xfer_job, EV_JOB_PRIORITY_HIGH);
+
+       source_uri = gnome_vfs_uri_new (uri);
+       if (!gnome_vfs_uri_is_local (source_uri) && !ev_window->priv->local_uri) {
+               GnomeVFSAsyncHandle *handle;
+               GList               *slist = NULL;
+               GList               *tlist = NULL;
+               char                *tmp_name;
+               char                *base_name;
+
+               /* We'd like to keep extension of source uri since
+                * it helps to resolve some mime types, say cbz */
+
+               tmp_name = ev_tmp_filename (NULL);
+               base_name = gnome_vfs_uri_extract_short_name (source_uri);
+               ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-", base_name, NULL);
+               ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job),
+                                    ev_window->priv->local_uri);
+               g_free (base_name);
+               g_free (tmp_name);
+               
+               target_uri = gnome_vfs_uri_new (ev_window->priv->local_uri);
+               
+               slist = g_list_prepend (slist, source_uri);
+               tlist = g_list_prepend (tlist, target_uri);
+               gnome_vfs_async_xfer (&handle, slist, tlist,
+                                     GNOME_VFS_XFER_DEFAULT | GNOME_VFS_XFER_FOLLOW_LINKS,
+                                     GNOME_VFS_XFER_ERROR_MODE_ABORT,
+                                     GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
+                                     GNOME_VFS_PRIORITY_DEFAULT,
+                                     (GnomeVFSAsyncXferProgressCallback)xfer_update_progress_callback,
+                                     ev_window,
+                                     NULL, NULL); 
+               
+               g_list_free (slist);
+               g_list_free (tlist);
+               gnome_vfs_uri_unref (target_uri);
+               gnome_vfs_uri_unref (source_uri);
+               
+               return;
+       }
+
+       gnome_vfs_uri_unref (source_uri);
+       ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
 }
 
 void
@@ -3673,8 +3734,8 @@ ev_window_dispose (GObject *object)
                priv->password_view = NULL;
        }
 
-       if (priv->xfer_job) {
-               ev_window_clear_xfer_job (window);
+       if (priv->load_job) {
+               ev_window_clear_load_job (window);
        }
        
        if (priv->local_uri) {
index 0a653d1a8f76c9b125a5b6b1b027f8a299c3aea0..273f29284b7a3e62d867b603f46ff860dccc0a6d 100644 (file)
@@ -300,7 +300,6 @@ main (int argc, char *argv[])
        }
 #endif
        
-       gdk_threads_init ();
        gnome_authentication_manager_init ();
 
        if (enable_metadata) {