[gimp] app: separate the mount logic from uploading/downloading



commit 7e7c22fc326cbb5c0b35b406ff8f10fc10d49381
Author: Michael Natterer <mitch gimp org>
Date:   Tue Jul 22 20:29:52 2014 +0200

    app: separate the mount logic from uploading/downloading
    
    We need to mount every non-native GFile's volume, regardless of
    whether the file procedure uses GIO directly or needs file-remote to
    download/upload the file. Move the entire mount logic to a new
    file-remote function and change gimp-gui.c and gui-vtable.c to only
    return a GMountOperation. Try to mount every non-native file in
    file-open.c and file-save.c and bail out if mounting fails. Simplify
    the uploading and downloading code accordingly.

 app/core/gimp-gui.c    |   18 ++--
 app/core/gimp-gui.h    |   12 +--
 app/file/file-open.c   |   23 +++--
 app/file/file-remote.c |  258 +++++++++++++++++++++++++-----------------------
 app/file/file-remote.h |    8 +-
 app/file/file-save.c   |   24 +++--
 app/gui/gui-vtable.c   |   49 ++--------
 7 files changed, 187 insertions(+), 205 deletions(-)
---
diff --git a/app/core/gimp-gui.c b/app/core/gimp-gui.c
index b355c23..7903ba8 100644
--- a/app/core/gimp-gui.c
+++ b/app/core/gimp-gui.c
@@ -64,7 +64,7 @@ gimp_gui_init (Gimp *gimp)
   gimp->gui.pdb_dialog_close       = NULL;
   gimp->gui.recent_list_add_file   = NULL;
   gimp->gui.recent_list_load       = NULL;
-  gimp->gui.mount_enclosing_volume = NULL;
+  gimp->gui.get_mount_operation    = NULL;
 }
 
 void
@@ -494,19 +494,15 @@ gimp_recent_list_load (Gimp *gimp)
     gimp->gui.recent_list_load (gimp);
 }
 
-gboolean
-gimp_mount_enclosing_volume (Gimp          *gimp,
-                             GFile         *file,
-                             GimpProgress  *progress,
-                             GError       **error)
+GMountOperation *
+gimp_get_mount_operation (Gimp         *gimp,
+                          GimpProgress *progress)
 {
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
-  g_return_val_if_fail (G_IS_FILE (file), FALSE);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
-  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-  if (gimp->gui.mount_enclosing_volume)
-    return gimp->gui.mount_enclosing_volume (gimp, file, progress, error);
+  if (gimp->gui.get_mount_operation)
+    return gimp->gui.get_mount_operation (gimp, progress);
 
-  return FALSE;
+  return g_mount_operation_new ();
 }
diff --git a/app/core/gimp-gui.h b/app/core/gimp-gui.h
index 63cb241..7150f36 100644
--- a/app/core/gimp-gui.h
+++ b/app/core/gimp-gui.h
@@ -93,10 +93,8 @@ struct _GimpGui
                                              const gchar         *mime_type);
   void           (* recent_list_load)       (Gimp                *gimp);
 
-  gboolean       (* mount_enclosing_volume) (Gimp                *gimp,
-                                             GFile               *file,
-                                             GimpProgress        *progress,
-                                             GError             **error);
+  GMountOperation * (* get_mount_operation) (Gimp                *gimp,
+                                             GimpProgress        *progress);
 };
 
 
@@ -175,10 +173,8 @@ gboolean       gimp_recent_list_add_file   (Gimp                *gimp,
                                             const gchar         *mime_type);
 void           gimp_recent_list_load       (Gimp                *gimp);
 
-gboolean       gimp_mount_enclosing_volume (Gimp                *gimp,
-                                            GFile               *file,
-                                            GimpProgress        *progress,
-                                            GError             **error);
+GMountOperation * gimp_get_mount_operation (Gimp                *gimp,
+                                            GimpProgress        *progress);
 
 
 #endif  /* __GIMP_GUI_H__ */
diff --git a/app/file/file-open.c b/app/file/file-open.c
index ce6778a..7e21fbc 100644
--- a/app/file/file-open.c
+++ b/app/file/file-open.c
@@ -93,9 +93,9 @@ file_open_image (Gimp                *gimp,
   GimpValueArray *return_vals;
   GimpImage      *image       = NULL;
   GFile          *local_file  = NULL;
-  gboolean        mounted     = TRUE;
   gchar          *path        = NULL;
   gchar          *entered_uri = NULL;
+  GError         *my_error    = NULL;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
@@ -144,16 +144,25 @@ file_open_image (Gimp                *gimp,
         }
     }
 
+  if (! g_file_is_native (file) &&
+      ! file_remote_mount_file (gimp, file, progress, &my_error))
+    {
+      if (my_error)
+        g_propagate_error (error, my_error);
+      else
+        *status = GIMP_PDB_CANCEL;
+
+      return NULL;
+    }
+
   if (! file_proc->handles_uri)
     {
       path = g_file_get_path (file);
 
       if (! path)
         {
-          GError *my_error = NULL;
-
-          local_file = file_remote_download_image (gimp, file, &mounted,
-                                                   progress, &my_error);
+          local_file = file_remote_download_image (gimp, file, progress,
+                                                   &my_error);
 
           if (! local_file)
             {
@@ -200,9 +209,7 @@ file_open_image (Gimp                *gimp,
       if (image)
         gimp_image_set_file (image, file);
 
-      if (! mounted)
-        g_file_delete (local_file, NULL, NULL);
-
+      g_file_delete (local_file, NULL, NULL);
       g_object_unref (local_file);
     }
 
diff --git a/app/file/file-remote.c b/app/file/file-remote.c
index 7a6cab5..c2efcb5 100644
--- a/app/file/file-remote.c
+++ b/app/file/file-remote.c
@@ -48,6 +48,15 @@ typedef enum
 
 typedef struct
 {
+  GimpProgress *progress;
+  GCancellable *cancellable;
+  gboolean      cancel;
+  GMainLoop    *main_loop;
+  GError       *error;
+} RemoteMount;
+
+typedef struct
+{
   RemoteCopyMode  mode;
   GimpProgress   *progress;
   GCancellable   *cancellable;
@@ -56,31 +65,101 @@ typedef struct
 } RemoteProgress;
 
 
-static GFile    * file_remote_get_temp_file     (Gimp            *gimp,
-                                                 GFile           *file);
-static GFile    * file_remote_mount_file        (Gimp            *gimp,
-                                                 GFile           *file,
-                                                 GimpProgress    *progress);
-static gboolean   file_remote_copy_file         (Gimp            *gimp,
-                                                 GFile           *src_file,
-                                                 GFile           *dest_file,
-                                                 RemoteCopyMode   mode,
-                                                 GimpProgress    *progress,
-                                                 GError         **error);
-static void       file_remote_copy_file_cancel  (GimpProgress    *progress,
-                                                 RemoteProgress  *remote_progress);
+static void       file_remote_mount_volume_ready (GFile           *file,
+                                                  GAsyncResult    *result,
+                                                  RemoteMount     *mount);
+static void       file_remote_mount_file_cancel  (GimpProgress    *progress,
+                                                  RemoteMount     *mount);
+
+static GFile    * file_remote_get_temp_file      (Gimp            *gimp,
+                                                  GFile           *file);
+static gboolean   file_remote_copy_file          (Gimp            *gimp,
+                                                  GFile           *src_file,
+                                                  GFile           *dest_file,
+                                                  RemoteCopyMode   mode,
+                                                  GimpProgress    *progress,
+                                                  GError         **error);
+static void       file_remote_copy_file_cancel   (GimpProgress    *progress,
+                                                  RemoteProgress  *remote_progress);
 
-static void       file_remote_progress_callback (goffset          current_num_bytes,
-                                                 goffset          total_num_bytes,
-                                                 gpointer         user_data);
+static void       file_remote_progress_callback  (goffset          current_num_bytes,
+                                                  goffset          total_num_bytes,
+                                                  gpointer         user_data);
 
 
 /*  public functions  */
 
+gboolean
+file_remote_mount_file (Gimp          *gimp,
+                        GFile         *file,
+                        GimpProgress  *progress,
+                        GError       **error)
+{
+  GMountOperation *operation;
+  RemoteMount      mount = { 0, };
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
+  g_return_val_if_fail (G_IS_FILE (file), FALSE);
+  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  mount.progress  = progress;
+  mount.main_loop = g_main_loop_new (NULL, FALSE);
+
+  operation = gimp_get_mount_operation (gimp, progress);
+
+  if (progress)
+    {
+      gimp_progress_start (progress, TRUE, _("Mounting remote volume"));
+
+      mount.cancellable = g_cancellable_new ();
+
+      g_signal_connect (progress, "cancel",
+                        G_CALLBACK (file_remote_mount_file_cancel),
+                        &mount);
+    }
+
+  g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
+                                 operation, mount.cancellable,
+                                 (GAsyncReadyCallback) file_remote_mount_volume_ready,
+                                 &mount);
+
+  g_main_loop_run (mount.main_loop);
+  g_main_loop_unref (mount.main_loop);
+
+  if (progress)
+    {
+      g_signal_handlers_disconnect_by_func (progress,
+                                            file_remote_mount_file_cancel,
+                                            &mount);
+
+      g_object_unref (mount.cancellable);
+
+      gimp_progress_end (progress);
+    }
+
+  g_object_unref (operation);
+
+  if (mount.error)
+    {
+      if (mount.error->domain != G_IO_ERROR ||
+          mount.error->code   != G_IO_ERROR_ALREADY_MOUNTED)
+        {
+          g_propagate_error (error, mount.error);
+          return FALSE;
+        }
+      else
+        {
+          g_clear_error (&mount.error);
+        }
+    }
+
+  return TRUE;
+}
+
 GFile *
 file_remote_download_image (Gimp          *gimp,
                             GFile         *file,
-                            gboolean      *mounted,
                             GimpProgress  *progress,
                             GError       **error)
 {
@@ -88,28 +167,16 @@ file_remote_download_image (Gimp          *gimp,
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (G_IS_FILE (file), NULL);
-  g_return_val_if_fail (mounted != NULL, NULL);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  local_file = file_remote_mount_file (gimp, file, progress);
+  local_file = file_remote_get_temp_file (gimp, file);
 
-  if (local_file)
-    {
-      *mounted = TRUE;
-    }
-  else
+  if (! file_remote_copy_file (gimp, file, local_file, DOWNLOAD,
+                               progress, error))
     {
-      *mounted = FALSE;
-
-      local_file = file_remote_get_temp_file (gimp, file);
-
-      if (! file_remote_copy_file (gimp, file, local_file, DOWNLOAD,
-                                   progress, error))
-        {
-          g_object_unref (local_file);
-          return NULL;
-        }
+      g_object_unref (local_file);
+      return NULL;
     }
 
   return local_file;
@@ -118,7 +185,6 @@ file_remote_download_image (Gimp          *gimp,
 GFile *
 file_remote_upload_image_prepare (Gimp          *gimp,
                                   GFile         *file,
-                                  gboolean      *mounted,
                                   GimpProgress  *progress,
                                   GError       **error)
 {
@@ -126,22 +192,10 @@ file_remote_upload_image_prepare (Gimp          *gimp,
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (G_IS_FILE (file), NULL);
-  g_return_val_if_fail (mounted != NULL, NULL);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  local_file = file_remote_mount_file (gimp, file, progress);
-
-  if (local_file)
-    {
-      *mounted = TRUE;
-    }
-  else
-    {
-      *mounted = FALSE;
-
-      local_file = file_remote_get_temp_file (gimp, file);
-    }
+  local_file = file_remote_get_temp_file (gimp, file);
 
   return local_file;
 }
@@ -150,7 +204,6 @@ gboolean
 file_remote_upload_image_finish (Gimp          *gimp,
                                  GFile         *file,
                                  GFile         *local_file,
-                                 gboolean       mounted,
                                  GimpProgress  *progress,
                                  GError       **error)
 {
@@ -160,13 +213,10 @@ file_remote_upload_image_finish (Gimp          *gimp,
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  if (! mounted)
+  if (! file_remote_copy_file (gimp, local_file, file, UPLOAD,
+                               progress, error))
     {
-      if (! file_remote_copy_file (gimp, local_file, file, UPLOAD,
-                                   progress, error))
-        {
-          return FALSE;
-        }
+      return FALSE;
     }
 
   return TRUE;
@@ -175,6 +225,25 @@ file_remote_upload_image_finish (Gimp          *gimp,
 
 /*  private functions  */
 
+static void
+file_remote_mount_volume_ready (GFile        *file,
+                                GAsyncResult *result,
+                                RemoteMount  *mount)
+{
+  g_file_mount_enclosing_volume_finish (file, result, &mount->error);
+
+  g_main_loop_quit (mount->main_loop);
+}
+
+static void
+file_remote_mount_file_cancel (GimpProgress *progress,
+                               RemoteMount  *mount)
+{
+  mount->cancel = TRUE;
+
+  g_cancellable_cancel (mount->cancellable);
+}
+
 static GFile *
 file_remote_get_temp_file (Gimp  *gimp,
                            GFile *file)
@@ -200,33 +269,6 @@ file_remote_get_temp_file (Gimp  *gimp,
   return temp_file;
 }
 
-static GFile *
-file_remote_mount_file (Gimp         *gimp,
-                        GFile        *file,
-                        GimpProgress *progress)
-{
-  gboolean success = TRUE;
-
-  if (! gimp->no_interface)
-    {
-      GError *error = NULL;
-
-      if (! gimp_mount_enclosing_volume (gimp, file, progress, &error))
-        {
-          if (error->domain != G_IO_ERROR ||
-              error->code   != G_IO_ERROR_ALREADY_MOUNTED)
-            success = FALSE;
-
-          g_clear_error (&error);
-        }
-    }
-
-  if (success && g_file_is_native (file))
-    return g_object_ref (file);
-
-  return NULL;
-}
-
 static gboolean
 file_remote_copy_file (Gimp            *gimp,
                        GFile           *src_file,
@@ -244,9 +286,9 @@ file_remote_copy_file (Gimp            *gimp,
 
   if (progress)
     {
-      remote_progress.cancellable = g_cancellable_new ();
+      gimp_progress_start (progress, TRUE, _("Opening remote file"));
 
-      gimp_progress_start (progress, TRUE, _("Connecting to server"));
+      remote_progress.cancellable = g_cancellable_new ();
 
       g_signal_connect (progress, "cancel",
                         G_CALLBACK (file_remote_copy_file_cancel),
@@ -257,7 +299,14 @@ file_remote_copy_file (Gimp            *gimp,
                              file_remote_progress_callback, &remote_progress,
                              &my_error);
 
+      g_signal_handlers_disconnect_by_func (progress,
+                                            file_remote_copy_file_cancel,
+                                            &remote_progress);
+
+      g_object_unref (remote_progress.cancellable);
+
       gimp_progress_set_value (progress, 1.0);
+      gimp_progress_end (progress);
     }
   else
     {
@@ -266,47 +315,6 @@ file_remote_copy_file (Gimp            *gimp,
                              &my_error);
     }
 
-  if (! success                      &&
-      ! gimp->no_interface           &&
-      my_error                       &&
-      my_error->domain == G_IO_ERROR &&
-      my_error->code   == G_IO_ERROR_NOT_MOUNTED)
-    {
-      g_clear_error (&my_error);
-
-      if (gimp_mount_enclosing_volume (gimp,
-                                       mode == DOWNLOAD ? src_file : dest_file,
-                                       progress,
-                                       error))
-        {
-          if (progress)
-            {
-              success = g_file_copy (src_file, dest_file, 0,
-                                     remote_progress.cancellable,
-                                     file_remote_progress_callback,
-                                     &remote_progress,
-                                     error);
-            }
-          else
-            {
-              success = g_file_copy (src_file, dest_file, 0,
-                                     NULL, NULL, NULL,
-                                     error);
-            }
-        }
-    }
-
-  if (progress)
-    {
-      g_signal_handlers_disconnect_by_func (progress,
-                                            file_remote_copy_file_cancel,
-                                            &remote_progress);
-
-      gimp_progress_end (progress);
-
-      g_object_unref (remote_progress.cancellable);
-    }
-
   return success;
 }
 
diff --git a/app/file/file-remote.h b/app/file/file-remote.h
index 3edc1ae..c95d941 100644
--- a/app/file/file-remote.h
+++ b/app/file/file-remote.h
@@ -25,21 +25,23 @@
 #define __FILE_REMOTE_H__
 
 
+gboolean   file_remote_mount_file           (Gimp          *gimp,
+                                             GFile         *file,
+                                             GimpProgress  *progress,
+                                             GError       **error);
+
 GFile    * file_remote_download_image       (Gimp          *gimp,
                                              GFile         *file,
-                                             gboolean      *mounted,
                                              GimpProgress  *progress,
                                              GError       **error);
 
 GFile    * file_remote_upload_image_prepare (Gimp          *gimp,
                                              GFile         *file,
-                                             gboolean      *mounted,
                                              GimpProgress  *progress,
                                              GError       **error);
 gboolean   file_remote_upload_image_finish  (Gimp          *gimp,
                                              GFile         *file,
                                              GFile         *local_file,
-                                             gboolean       mounted,
                                              GimpProgress  *progress,
                                              GError       **error);
 
diff --git a/app/file/file-save.c b/app/file/file-save.c
index 32d34b2..99714aa 100644
--- a/app/file/file-save.c
+++ b/app/file/file-save.c
@@ -68,11 +68,11 @@ file_save (Gimp                *gimp,
   GimpValueArray    *return_vals;
   GimpPDBStatusType  status     = GIMP_PDB_EXECUTION_ERROR;
   GFile             *local_file = NULL;
-  gboolean           mounted    = TRUE;
   gchar             *path       = NULL;
   gchar             *uri        = NULL;
   gint32             image_ID;
   gint32             drawable_ID;
+  GError            *my_error   = NULL;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR);
   g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR);
@@ -125,16 +125,25 @@ file_save (Gimp                *gimp,
         }
     }
 
+  if (! g_file_is_native (file) &&
+      ! file_remote_mount_file (gimp, file, progress, &my_error))
+    {
+      if (my_error)
+        g_propagate_error (error, my_error);
+      else
+        status = GIMP_PDB_CANCEL;
+
+      goto out;
+    }
+
   if (! file_proc->handles_uri)
     {
       path = g_file_get_path (file);
 
       if (! path)
         {
-          GError *my_error = NULL;
-
-          local_file = file_remote_upload_image_prepare (gimp, file, &mounted,
-                                                         progress, &my_error);
+          local_file = file_remote_upload_image_prepare (gimp, file, progress,
+                                                         &my_error);
 
           if (! local_file)
             {
@@ -181,7 +190,6 @@ file_save (Gimp                *gimp,
           GError *my_error = NULL;
 
           if (! file_remote_upload_image_finish (gimp, file, local_file,
-                                                 mounted,
                                                  progress, &my_error))
             {
               status = GIMP_PDB_EXECUTION_ERROR;
@@ -193,9 +201,7 @@ file_save (Gimp                *gimp,
             }
         }
 
-      if (! mounted)
-        g_file_delete (local_file, NULL, NULL);
-
+      g_file_delete (local_file, NULL, NULL);
       g_object_unref (local_file);
     }
 
diff --git a/app/gui/gui-vtable.c b/app/gui/gui-vtable.c
index 11ae9d4..70dca10 100644
--- a/app/gui/gui-vtable.c
+++ b/app/gui/gui-vtable.c
@@ -144,10 +144,8 @@ static gboolean       gui_recent_list_add_file   (Gimp                *gimp,
                                                   const gchar         *mime_type);
 static void           gui_recent_list_load       (Gimp                *gimp);
 
-static gboolean       gui_mount_enclosing_volume (Gimp                *gimp,
-                                                  GFile               *file,
-                                                  GimpProgress        *progress,
-                                                  GError             **error);
+static GMountOperation * gui_get_mount_operation (Gimp                *gimp,
+                                                  GimpProgress        *progress);
 
 
 /*  public functions  */
@@ -183,7 +181,7 @@ gui_vtable_init (Gimp *gimp)
   gimp->gui.pdb_dialog_close       = gui_pdb_dialog_close;
   gimp->gui.recent_list_add_file   = gui_recent_list_add_file;
   gimp->gui.recent_list_load       = gui_recent_list_load;
-  gimp->gui.mount_enclosing_volume = gui_mount_enclosing_volume;
+  gimp->gui.get_mount_operation    = gui_get_mount_operation;
 }
 
 
@@ -741,45 +739,14 @@ gui_recent_list_load (Gimp *gimp)
   gimp_container_thaw (gimp->documents);
 }
 
-static void
-mount_volume_ready (GFile         *file,
-                    GAsyncResult  *res,
-                    GError       **error)
+static GMountOperation *
+gui_get_mount_operation (Gimp         *gimp,
+                         GimpProgress *progress)
 {
-  g_file_mount_enclosing_volume_finish (file, res, error);
-
-  gtk_main_quit ();
-}
-
-static gboolean
-gui_mount_enclosing_volume (Gimp          *gimp,
-                            GFile         *file,
-                            GimpProgress  *progress,
-                            GError       **error)
-{
-  GMountOperation *operation;
-  GtkWidget       *toplevel = NULL;
-  GError          *my_error = NULL;
+  GtkWidget *toplevel = NULL;
 
   if (GTK_IS_WIDGET (progress))
     toplevel = gtk_widget_get_toplevel (GTK_WIDGET (progress));
 
-  operation = gtk_mount_operation_new (GTK_WINDOW (toplevel));
-
-  g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
-                                 operation,
-                                 NULL,
-                                 (GAsyncReadyCallback) mount_volume_ready,
-                                 &my_error);
-  gtk_main ();
-
-  g_object_unref (operation);
-
-  if (my_error)
-    {
-      g_propagate_error (error, my_error);
-      return FALSE;
-    }
-
-  return TRUE;
+  return gtk_mount_operation_new (GTK_WINDOW (toplevel));
 }


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