[gimp] app: port all file_open() and file_save() functions to GFile



commit 0f8d84d5e9e119639bcd41e04a85c76528a6096a
Author: Michael Natterer <mitch gimp org>
Date:   Mon Jul 7 00:46:25 2014 +0200

    app: port all file_open() and file_save() functions to GFile

 app/actions/data-commands.c             |   47 +++----
 app/actions/documents-commands.c        |   15 +--
 app/actions/file-actions.c              |   26 +++--
 app/actions/file-commands.c             |  105 +++++++++-------
 app/actions/file-commands.h             |    2 +-
 app/core/gimp.c                         |   12 +-
 app/core/gimp.h                         |    4 +-
 app/core/gimpimage-private.h            |    5 +
 app/core/gimpimagefile.c                |   28 ++--
 app/core/gimpimagefile.h                |    1 +
 app/dialogs/file-open-dialog.c          |   57 ++++-----
 app/dialogs/file-open-location-dialog.c |   27 +++--
 app/dialogs/file-save-dialog.c          |  122 ++++++++++---------
 app/dialogs/file-save-dialog.h          |    2 +-
 app/display/gimpdisplayshell-dnd.c      |   17 ++--
 app/file/file-open.c                    |  182 +++++++++++++--------------
 app/file/file-open.h                    |   14 +-
 app/file/file-procedure.c               |  209 ++++++++++++++++---------------
 app/file/file-procedure.h               |    6 +-
 app/file/file-save.c                    |   89 ++++++--------
 app/file/file-save.h                    |    2 +-
 app/file/file-utils.c                   |   29 ++++-
 app/file/file-utils.h                   |    3 +-
 app/file/gimp-file.h                    |    6 +-
 app/gui/gimpdbusservice.c               |    8 +-
 app/pdb/fileops-cmds.c                  |   35 ++++-
 app/plug-in/gimppluginmanager-file.c    |    6 +-
 app/plug-in/gimppluginmanager-file.h    |    4 +-
 app/widgets/gimpdnd-xds.c               |   34 ++---
 app/widgets/gimpfiledialog.c            |   32 ++++--
 app/widgets/gimpimagepropview.c         |   11 +-
 app/widgets/gimplayertreeview.c         |   11 +-
 app/widgets/gimpthumbbox.c              |    4 +-
 app/widgets/gimptoolbox-dnd.c           |   13 +-
 app/widgets/gimptoolbox.c               |   18 ++--
 tools/pdbgen/pdb/fileops.pdb            |   35 ++++-
 36 files changed, 656 insertions(+), 565 deletions(-)
---
diff --git a/app/actions/data-commands.c b/app/actions/data-commands.c
index 5d2dda8..60d22b5 100644
--- a/app/actions/data-commands.c
+++ b/app/actions/data-commands.c
@@ -20,6 +20,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "actions-types.h"
@@ -71,35 +72,25 @@ data_open_as_image_cmd_callback (GtkAction *action,
 
   if (data && gimp_data_get_file (data))
     {
-      gchar *uri = g_file_get_uri (gimp_data_get_file (data));
-
-      if (uri)
+      GFile             *file = gimp_data_get_file (data);
+      GtkWidget         *widget = GTK_WIDGET (view);
+      GimpImage         *image;
+      GimpPDBStatusType  status;
+      GError            *error = NULL;
+
+      image = file_open_with_display (context->gimp, context, NULL,
+                                      file, FALSE,
+                                      G_OBJECT (gtk_widget_get_screen (widget)),
+                                      gimp_widget_get_monitor (widget),
+                                      &status, &error);
+
+      if (! image && status != GIMP_PDB_CANCEL)
         {
-          GtkWidget         *widget = GTK_WIDGET (view);
-          GimpImage         *image;
-          GimpPDBStatusType  status;
-          GError            *error = NULL;
-
-          image = file_open_with_display (context->gimp, context, NULL,
-                                          uri, FALSE,
-                                          G_OBJECT (gtk_widget_get_screen (widget)),
-                                          gimp_widget_get_monitor (widget),
-                                          &status, &error);
-
-          if (! image && status != GIMP_PDB_CANCEL)
-            {
-              gchar *filename = file_utils_uri_display_name (uri);
-
-              gimp_message (context->gimp, G_OBJECT (view),
-                            GIMP_MESSAGE_ERROR,
-                            _("Opening '%s' failed:\n\n%s"),
-                            filename, error->message);
-              g_clear_error (&error);
-
-              g_free (filename);
-            }
-
-          g_free (uri);
+          gimp_message (context->gimp, G_OBJECT (view),
+                        GIMP_MESSAGE_ERROR,
+                        _("Opening '%s' failed:\n\n%s"),
+                        gimp_file_get_utf8_name (file), error->message);
+          g_clear_error (&error);
         }
     }
 }
diff --git a/app/actions/documents-commands.c b/app/actions/documents-commands.c
index e4c4de2..afe5870 100644
--- a/app/actions/documents-commands.c
+++ b/app/actions/documents-commands.c
@@ -22,6 +22,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpthumb/gimpthumb.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
@@ -145,7 +146,7 @@ documents_file_open_dialog_cmd_callback (GtkAction *action,
   if (imagefile && gimp_container_have (container, GIMP_OBJECT (imagefile)))
     {
       file_file_open_dialog (context->gimp,
-                             gimp_object_get_name (imagefile),
+                             gimp_imagefile_get_file (imagefile),
                              GTK_WIDGET (editor));
     }
 }
@@ -336,28 +337,24 @@ documents_open_image (GtkWidget     *editor,
                       GimpContext   *context,
                       GimpImagefile *imagefile)
 {
-  const gchar        *uri;
+  GFile              *file;
   GimpImage          *image;
   GimpPDBStatusType   status;
   GError             *error = NULL;
 
-  uri = gimp_object_get_name (imagefile);
+  file = gimp_imagefile_get_file (imagefile);
 
-  image = file_open_with_display (context->gimp, context, NULL, uri, FALSE,
+  image = file_open_with_display (context->gimp, context, NULL, file, FALSE,
                                   G_OBJECT (gtk_widget_get_screen (editor)),
                                   gimp_widget_get_monitor (editor),
                                   &status, &error);
 
   if (! image && status != GIMP_PDB_CANCEL)
     {
-      gchar *filename = file_utils_uri_display_name (uri);
-
       gimp_message (context->gimp, G_OBJECT (editor), GIMP_MESSAGE_ERROR,
                     _("Opening '%s' failed:\n\n%s"),
-                    filename, error->message);
+                    gimp_file_get_utf8_name (file), error->message);
       g_clear_error (&error);
-
-      g_free (filename);
     }
 }
 
diff --git a/app/actions/file-actions.c b/app/actions/file-actions.c
index d02bfdf..deef271 100644
--- a/app/actions/file-actions.c
+++ b/app/actions/file-actions.c
@@ -63,7 +63,7 @@ static void    file_actions_close_all_update    (GimpContainer   *images,
                                                  GimpObject      *unused,
                                                  GimpActionGroup *group);
 static gchar * file_actions_create_label        (const gchar     *format,
-                                                 const gchar     *uri);
+                                                 GFile           *file);
 
 
 static const GimpActionEntry file_actions[] =
@@ -256,21 +256,29 @@ file_actions_update (GimpActionGroup *group,
   Gimp         *gimp           = action_data_get_gimp (data);
   GimpImage    *image          = action_data_get_image (data);
   GimpDrawable *drawable       = NULL;
-  const gchar  *source         = NULL;
-  const gchar  *export         = NULL;
+  GFile        *source         = NULL;
+  GFile        *export         = NULL;
   gboolean      show_overwrite = FALSE;
 
   if (image)
     {
+      const gchar *uri;
+
       drawable = gimp_image_get_active_drawable (image);
-      source   = gimp_image_get_imported_uri (image);
-      export   = gimp_image_get_exported_uri (image);
+
+      uri = gimp_image_get_imported_uri (image);
+      if (uri)
+        source = g_file_new_for_uri (uri);
+
+      uri = gimp_image_get_exported_uri (image);
+      if (uri)
+        export = g_file_new_for_uri (uri);
     }
 
   show_overwrite =
     (source &&
-     gimp_plug_in_manager_uri_has_exporter (gimp->plug_in_manager,
-                                            source));
+     gimp_plug_in_manager_file_has_exporter (gimp->plug_in_manager,
+                                             source));
 
 #define SET_VISIBLE(action,condition) \
         gimp_action_group_set_action_visible (group, action, (condition) != 0)
@@ -413,9 +421,9 @@ file_actions_close_all_update (GimpContainer   *images,
 
 static gchar *
 file_actions_create_label (const gchar *format,
-                           const gchar *uri)
+                           GFile       *file)
 {
-  gchar *basename         = file_utils_uri_display_basename (uri);
+  gchar *basename         = g_path_get_basename (gimp_file_get_utf8_name (file));
   gchar *escaped_basename = gimp_escape_uline (basename);
   gchar *label            = g_strdup_printf (format, escaped_basename);
 
diff --git a/app/actions/file-commands.c b/app/actions/file-commands.c
index 9d8a817..c285070 100644
--- a/app/actions/file-commands.c
+++ b/app/actions/file-commands.c
@@ -22,6 +22,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "actions-types.h"
@@ -31,6 +32,7 @@
 #include "core/gimp.h"
 #include "core/gimpcontainer.h"
 #include "core/gimpimage.h"
+#include "core/gimpimagefile.h"
 #include "core/gimpprogress.h"
 #include "core/gimptemplate.h"
 
@@ -70,7 +72,7 @@ static void        file_open_dialog_show        (Gimp         *gimp,
                                                  GtkWidget    *parent,
                                                  const gchar  *title,
                                                  GimpImage    *image,
-                                                 const gchar  *uri,
+                                                 GFile        *file,
                                                  gboolean      open_as_layers);
 static GtkWidget * file_save_dialog_show        (Gimp         *gimp,
                                                  GimpImage    *image,
@@ -176,6 +178,7 @@ file_open_recent_cmd_callback (GtkAction *action,
 
   if (imagefile)
     {
+      GFile             *file;
       GimpDisplay       *display;
       GtkWidget         *widget;
       GimpProgress      *progress;
@@ -188,27 +191,24 @@ file_open_recent_cmd_callback (GtkAction *action,
       g_object_ref (display);
       g_object_ref (imagefile);
 
+      file = gimp_imagefile_get_file (imagefile);
+
       progress = gimp_display_get_image (display) ?
                  NULL : GIMP_PROGRESS (display);
 
       image = file_open_with_display (gimp, action_data_get_context (data),
                                       progress,
-                                      gimp_object_get_name (imagefile), FALSE,
+                                      file, FALSE,
                                       G_OBJECT (gtk_widget_get_screen (widget)),
                                       gimp_widget_get_monitor (widget),
                                       &status, &error);
 
       if (! image && status != GIMP_PDB_CANCEL)
         {
-          gchar *filename =
-            file_utils_uri_display_name (gimp_object_get_name (imagefile));
-
           gimp_message (gimp, G_OBJECT (display), GIMP_MESSAGE_ERROR,
                         _("Opening '%s' failed:\n\n%s"),
-                        filename, error->message);
+                        gimp_file_get_utf8_name (file), error->message);
           g_clear_error (&error);
-
-          g_free (filename);
         }
 
       g_object_unref (imagefile);
@@ -227,6 +227,7 @@ file_save_cmd_callback (GtkAction *action,
   GtkWidget    *widget;
   GimpSaveMode  save_mode;
   const gchar  *uri;
+  GFile        *file  = NULL;
   gboolean      saved = FALSE;
   return_if_no_gimp (gimp, data);
   return_if_no_display (display, data);
@@ -241,6 +242,9 @@ file_save_cmd_callback (GtkAction *action,
 
   uri = gimp_image_get_uri (image);
 
+  if (uri)
+    file = g_file_new_for_uri (uri);
+
   switch (save_mode)
     {
     case GIMP_SAVE_MODE_SAVE:
@@ -248,21 +252,21 @@ file_save_cmd_callback (GtkAction *action,
       /*  Only save if the image has been modified, or if it is new.  */
       if ((gimp_image_is_dirty (image) ||
            ! GIMP_GUI_CONFIG (image->gimp->config)->trust_dirty_flag) ||
-          uri == NULL)
+          file == NULL)
         {
           GimpPlugInProcedure *save_proc = gimp_image_get_save_proc (image);
 
-          if (uri && ! save_proc)
+          if (file && ! save_proc)
             {
               save_proc =
                 file_procedure_find (image->gimp->plug_in_manager->save_procs,
-                                     uri, NULL);
+                                     file, NULL);
             }
 
-          if (uri && save_proc)
+          if (file && save_proc)
             {
               saved = file_save_dialog_save_image (GIMP_PROGRESS (display),
-                                                   gimp, image, uri,
+                                                   gimp, image, file,
                                                    save_proc,
                                                    GIMP_RUN_WITH_LAST_VALS,
                                                    TRUE, FALSE, FALSE, TRUE);
@@ -300,6 +304,7 @@ file_save_cmd_callback (GtkAction *action,
     case GIMP_SAVE_MODE_OVERWRITE:
       {
         const gchar         *uri         = NULL;
+        GFile               *file        = NULL;
         GimpPlugInProcedure *export_proc = NULL;
         gboolean             overwrite   = FALSE;
 
@@ -324,33 +329,29 @@ file_save_cmd_callback (GtkAction *action,
             overwrite = TRUE;
           }
 
-        if (uri && ! export_proc)
+        if (uri)
+          file = g_file_new_for_uri (uri);
+
+        if (file && ! export_proc)
           {
             export_proc =
               file_procedure_find (image->gimp->plug_in_manager->export_procs,
-                                   uri, NULL);
+                                   file, NULL);
           }
 
-        if (uri && export_proc)
+        if (file && export_proc)
           {
-            char *uri_copy;
-
-            /* The memory that 'uri' points to can be freed by
-               file_save_dialog_save_image(), when it eventually calls
-               gimp_image_set_imported_uri() to reset the imported uri,
-               resulting in garbage. So make a duplicate of it here. */
-
-            uri_copy = g_strdup (uri);
-
             saved = file_save_dialog_save_image (GIMP_PROGRESS (display),
-                                                 gimp, image, uri_copy,
+                                                 gimp, image, file,
                                                  export_proc,
                                                  GIMP_RUN_WITH_LAST_VALS,
                                                  FALSE,
                                                  overwrite, ! overwrite,
                                                  TRUE);
-            g_free (uri_copy);
           }
+
+        if (file)
+          g_object_unref (file);
       }
       break;
     }
@@ -496,13 +497,13 @@ file_quit_cmd_callback (GtkAction *action,
 }
 
 void
-file_file_open_dialog (Gimp        *gimp,
-                       const gchar *uri,
-                       GtkWidget   *parent)
+file_file_open_dialog (Gimp      *gimp,
+                       GFile     *file,
+                       GtkWidget *parent)
 {
   file_open_dialog_show (gimp, parent,
                          _("Open Image"),
-                         NULL, uri, FALSE);
+                         NULL, file, FALSE);
 }
 
 
@@ -513,7 +514,7 @@ file_open_dialog_show (Gimp        *gimp,
                        GtkWidget   *parent,
                        const gchar *title,
                        GimpImage   *image,
-                       const gchar *uri,
+                       GFile       *file,
                        gboolean     open_as_layers)
 {
   GtkWidget *dialog;
@@ -524,16 +525,28 @@ file_open_dialog_show (Gimp        *gimp,
                                            NULL /*ui_manager*/,
                                            "gimp-file-open-dialog", -1, FALSE);
 
+  if (file)
+    g_object_ref (file);
+
   if (dialog)
     {
-      if (! uri && image)
-        uri = gimp_image_get_uri (image);
+      if (! file && image)
+        {
+          const gchar *uri = gimp_image_get_uri (image);
+          if (uri)
+            file = g_file_new_for_uri (uri);
+        }
 
-      if (! uri)
-        uri = g_object_get_data (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_URI_KEY);
+      if (! file)
+        {
+          file = g_object_get_data (G_OBJECT (gimp),
+                                    GIMP_FILE_OPEN_LAST_FILE_KEY);
+          if (file)
+            g_object_ref (file);
+        }
 
-      if (uri)
-        gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), uri);
+      if (file)
+        gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), file, NULL);
       else if (gimp->default_folder)
         gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
                                                  gimp->default_folder);
@@ -546,6 +559,9 @@ file_open_dialog_show (Gimp        *gimp,
 
       gtk_window_present (GTK_WINDOW (dialog));
     }
+
+  if (file)
+    g_object_unref (file);
 }
 
 static GtkWidget *
@@ -765,6 +781,7 @@ file_revert_confirm_response (GtkWidget   *dialog,
       Gimp              *gimp = old_image->gimp;
       GimpImage         *new_image;
       const gchar       *uri;
+      GFile             *file;
       GimpPDBStatusType  status;
       GError            *error = NULL;
 
@@ -773,9 +790,11 @@ file_revert_confirm_response (GtkWidget   *dialog,
       if (! uri)
         uri = gimp_image_get_imported_uri (old_image);
 
+      file = g_file_new_for_uri (uri);
+
       new_image = file_open_image (gimp, gimp_get_user_context (gimp),
                                    GIMP_PROGRESS (display),
-                                   uri, uri, FALSE, NULL,
+                                   file, file, FALSE, NULL,
                                    GIMP_RUN_INTERACTIVE,
                                    &status, NULL, &error);
 
@@ -789,14 +808,12 @@ file_revert_confirm_response (GtkWidget   *dialog,
         }
       else if (status != GIMP_PDB_CANCEL)
         {
-          gchar *filename = file_utils_uri_display_name (uri);
-
           gimp_message (gimp, G_OBJECT (display), GIMP_MESSAGE_ERROR,
                         _("Reverting to '%s' failed:\n\n%s"),
-                        filename, error->message);
+                        gimp_file_get_utf8_name (file), error->message);
           g_clear_error (&error);
-
-          g_free (filename);
         }
+
+      g_object_unref (file);
     }
 }
diff --git a/app/actions/file-commands.h b/app/actions/file-commands.h
index 95ef997..e249eff 100644
--- a/app/actions/file-commands.h
+++ b/app/actions/file-commands.h
@@ -43,7 +43,7 @@ void   file_quit_cmd_callback            (GtkAction   *action,
                                           gpointer     data);
 
 void   file_file_open_dialog             (Gimp        *gimp,
-                                          const gchar *uri,
+                                          GFile       *file,
                                           GtkWidget   *parent);
 
 
diff --git a/app/core/gimp.c b/app/core/gimp.c
index fc1df27..ff6c618 100644
--- a/app/core/gimp.c
+++ b/app/core/gimp.c
@@ -173,8 +173,8 @@ gimp_class_init (GimpClass *klass)
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GimpClass, image_opened),
                   NULL, NULL,
-                  gimp_marshal_VOID__STRING,
-                  G_TYPE_NONE, 1, G_TYPE_STRING);
+                  gimp_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, G_TYPE_FILE);
 
   object_class->dispose          = gimp_dispose;
   object_class->finalize         = gimp_finalize;
@@ -1298,13 +1298,13 @@ gimp_message_literal (Gimp                *gimp,
 }
 
 void
-gimp_image_opened (Gimp        *gimp,
-                  const gchar *uri)
+gimp_image_opened (Gimp  *gimp,
+                  GFile *file)
 {
   g_return_if_fail (GIMP_IS_GIMP (gimp));
-  g_return_if_fail (uri != NULL);
+  g_return_if_fail (G_IS_FILE (file));
 
-  g_signal_emit (gimp, gimp_signals[IMAGE_OPENED], 0, uri);
+  g_signal_emit (gimp, gimp_signals[IMAGE_OPENED], 0, file);
 }
 
 gchar *
diff --git a/app/core/gimp.h b/app/core/gimp.h
index b5c4fab..4040a07 100644
--- a/app/core/gimp.h
+++ b/app/core/gimp.h
@@ -138,7 +138,7 @@ struct _GimpClass
 
   /*  emitted if an image is loaded and opened with a display  */
   void     (* image_opened)   (Gimp               *gimp,
-                               const gchar        *uri);
+                               GFile              *file);
 };
 
 
@@ -215,7 +215,7 @@ void           gimp_message_literal      (Gimp                *gimp,
                                           const gchar         *message);
 
 void           gimp_image_opened         (Gimp                *gimp,
-                                          const gchar         *uri);
+                                          GFile               *file);
 
 gchar        * gimp_get_temp_filename    (Gimp                *gimp,
                                           const gchar         *extension);
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index 215bb18..35998a9 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -58,6 +58,11 @@ struct _GimpImagePrivate
 
   GimpMetadata      *metadata;              /*  image's metadata             */
 
+  GFile             *file;
+  GFile             *imported_file;
+  GFile             *exported_file;
+  GFile             *save_a_copy_file;
+
   gint               dirty;                 /*  dirty flag -- # of ops       */
   guint              dirty_time;            /*  time when image became dirty */
   gint               export_dirty;          /*  'dirty' but for export       */
diff --git a/app/core/gimpimagefile.c b/app/core/gimpimagefile.c
index ff49e76..2c98f56 100644
--- a/app/core/gimpimagefile.c
+++ b/app/core/gimpimagefile.c
@@ -248,6 +248,14 @@ gimp_imagefile_new (Gimp  *gimp,
   return imagefile;
 }
 
+GFile *
+gimp_imagefile_get_file (GimpImagefile *imagefile)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGEFILE (imagefile), NULL);
+
+  return GET_PRIVATE (imagefile)->file;
+}
+
 GimpThumbnail *
 gimp_imagefile_get_thumbnail (GimpImagefile *imagefile)
 {
@@ -356,7 +364,6 @@ gimp_imagefile_create_thumbnail (GimpImagefile  *imagefile,
   if (image_state == GIMP_THUMB_STATE_REMOTE ||
       image_state >= GIMP_THUMB_STATE_EXISTS)
     {
-      GFile         *file;
       GimpImage     *image;
       gboolean       success;
       gint           width      = 0;
@@ -365,16 +372,14 @@ gimp_imagefile_create_thumbnail (GimpImagefile  *imagefile,
       const Babl    *format     = NULL;
       gint           num_layers = -1;
 
-      file = g_file_new_for_uri (thumbnail->image_uri);
-
       /*  we only want to attempt thumbnailing on readable, regular files  */
-      if (g_file_is_native (file))
+      if (g_file_is_native (private->file))
         {
           GFileInfo *file_info;
           gboolean   regular;
           gboolean   readable;
 
-          file_info = g_file_query_info (file,
+          file_info = g_file_query_info (private->file,
                                          G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                                          G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
                                          G_FILE_QUERY_INFO_NONE,
@@ -387,21 +392,16 @@ gimp_imagefile_create_thumbnail (GimpImagefile  *imagefile,
           g_object_unref (file_info);
 
           if (! (regular && readable))
-            {
-              g_object_unref (file);
-              return TRUE;
-            }
+            return TRUE;
         }
 
-      g_object_unref (file);
-
       g_object_ref (imagefile);
 
       /* don't pass the error, we're only interested in errors from
        * actual thumbnail saving
        */
       image = file_open_thumbnail (private->gimp, context, progress,
-                                   thumbnail->image_uri, size,
+                                   private->file, size,
                                    &mime_type, &width, &height,
                                    &format, &num_layers, NULL);
 
@@ -419,8 +419,8 @@ gimp_imagefile_create_thumbnail (GimpImagefile  *imagefile,
            * from actual thumbnail saving
            */
           image = file_open_image (private->gimp, context, progress,
-                                   thumbnail->image_uri,
-                                   thumbnail->image_uri,
+                                   private->file,
+                                   private->file,
                                    FALSE, NULL, GIMP_RUN_NONINTERACTIVE,
                                    &status, &mime_type, NULL);
 
diff --git a/app/core/gimpimagefile.h b/app/core/gimpimagefile.h
index 9063883..c43cafd 100644
--- a/app/core/gimpimagefile.h
+++ b/app/core/gimpimagefile.h
@@ -58,6 +58,7 @@ GType           gimp_imagefile_get_type              (void) G_GNUC_CONST;
 GimpImagefile * gimp_imagefile_new                   (Gimp           *gimp,
                                                       GFile          *file);
 
+GFile         * gimp_imagefile_get_file              (GimpImagefile  *imagefile);
 GimpThumbnail * gimp_imagefile_get_thumbnail         (GimpImagefile  *imagefile);
 GIcon         * gimp_imagefile_get_gicon             (GimpImagefile  *imagefile);
 
diff --git a/app/dialogs/file-open-dialog.c b/app/dialogs/file-open-dialog.c
index 08550ac..ead83b4 100644
--- a/app/dialogs/file-open-dialog.c
+++ b/app/dialogs/file-open-dialog.c
@@ -23,6 +23,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "dialogs-types.h"
@@ -53,11 +54,11 @@ static void       file_open_dialog_response    (GtkWidget           *open_dialog
                                                 Gimp                *gimp);
 static GimpImage *file_open_dialog_open_image  (GtkWidget           *open_dialog,
                                                 Gimp                *gimp,
-                                                const gchar         *uri,
+                                                GFile               *file,
                                                 GimpPlugInProcedure *load_proc);
 static gboolean   file_open_dialog_open_layers (GtkWidget           *open_dialog,
                                                 GimpImage           *image,
-                                                const gchar         *uri,
+                                                GFile               *file,
                                                 GimpPlugInProcedure *load_proc);
 
 
@@ -100,7 +101,7 @@ file_open_dialog_response (GtkWidget *open_dialog,
                            Gimp      *gimp)
 {
   GimpFileDialog *dialog  = GIMP_FILE_DIALOG (open_dialog);
-  GSList         *uris;
+  GSList         *files;
   GSList         *list;
   gboolean        success = FALSE;
 
@@ -116,11 +117,12 @@ file_open_dialog_response (GtkWidget *open_dialog,
       return;
     }
 
-  uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (open_dialog));
+  files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (open_dialog));
 
-  if (uris)
-    g_object_set_data_full (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_URI_KEY,
-                            g_strdup (uris->data), (GDestroyNotify) g_free);
+  if (files)
+    g_object_set_data_full (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_FILE_KEY,
+                            g_object_ref (files->data),
+                            (GDestroyNotify) g_object_unref);
 
   gimp_file_dialog_set_sensitive (dialog, FALSE);
 
@@ -133,15 +135,16 @@ file_open_dialog_response (GtkWidget *open_dialog,
   if (! dialog->open_as_layers)
     gtk_window_set_transient_for (GTK_WINDOW (open_dialog), NULL);
 
-  for (list = uris; list; list = g_slist_next (list))
+  for (list = files; list; list = g_slist_next (files))
     {
-      gchar *filename = file_utils_filename_from_uri (list->data);
+      GFile *file = list->data;
+      gchar *path = g_file_get_path (file);
 
-      if (filename)
+      if (path)
         {
-          gboolean regular = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
+          gboolean regular = g_file_test (path, G_FILE_TEST_IS_REGULAR);
 
-          g_free (filename);
+          g_free (path);
 
           if (! regular)
             continue;
@@ -153,7 +156,7 @@ file_open_dialog_response (GtkWidget *open_dialog,
             {
               dialog->image = file_open_dialog_open_image (open_dialog,
                                                            gimp,
-                                                           list->data,
+                                                           file,
                                                            dialog->file_proc);
 
               if (dialog->image)
@@ -161,7 +164,7 @@ file_open_dialog_response (GtkWidget *open_dialog,
             }
           else if (file_open_dialog_open_layers (open_dialog,
                                                  dialog->image,
-                                                 list->data,
+                                                 file,
                                                  dialog->file_proc))
             {
               success = TRUE;
@@ -171,7 +174,7 @@ file_open_dialog_response (GtkWidget *open_dialog,
         {
           if (file_open_dialog_open_image (open_dialog,
                                            gimp,
-                                           list->data,
+                                           file,
                                            dialog->file_proc))
             {
               success = TRUE;
@@ -199,13 +202,13 @@ file_open_dialog_response (GtkWidget *open_dialog,
       gimp_file_dialog_set_sensitive (dialog, TRUE);
     }
 
-  g_slist_free_full (uris, (GDestroyNotify) g_free);
+  g_slist_free_full (files, (GDestroyNotify) g_object_unref);
 }
 
 static GimpImage *
 file_open_dialog_open_image (GtkWidget           *open_dialog,
                              Gimp                *gimp,
-                             const gchar         *uri,
+                             GFile               *file,
                              GimpPlugInProcedure *load_proc)
 {
   GimpImage         *image;
@@ -215,7 +218,7 @@ file_open_dialog_open_image (GtkWidget           *open_dialog,
   image = file_open_with_proc_and_display (gimp,
                                            gimp_get_user_context (gimp),
                                            GIMP_PROGRESS (open_dialog),
-                                           uri, uri, FALSE,
+                                           file, file, FALSE,
                                            load_proc,
                                            G_OBJECT (gtk_widget_get_screen (open_dialog)),
                                            gimp_widget_get_monitor (open_dialog),
@@ -223,13 +226,10 @@ file_open_dialog_open_image (GtkWidget           *open_dialog,
 
   if (! image && status != GIMP_PDB_CANCEL)
     {
-      gchar *filename = file_utils_uri_display_name (uri);
-
       gimp_message (gimp, G_OBJECT (open_dialog), GIMP_MESSAGE_ERROR,
-                    _("Opening '%s' failed:\n\n%s"), filename, error->message);
+                    _("Opening '%s' failed:\n\n%s"),
+                    gimp_file_get_utf8_name (file), error->message);
       g_clear_error (&error);
-
-      g_free (filename);
     }
 
   return image;
@@ -238,7 +238,7 @@ file_open_dialog_open_image (GtkWidget           *open_dialog,
 static gboolean
 file_open_dialog_open_layers (GtkWidget           *open_dialog,
                               GimpImage           *image,
-                              const gchar         *uri,
+                              GFile               *file,
                               GimpPlugInProcedure *load_proc)
 {
   GList             *new_layers;
@@ -249,7 +249,7 @@ file_open_dialog_open_layers (GtkWidget           *open_dialog,
                                  gimp_get_user_context (image->gimp),
                                  GIMP_PROGRESS (open_dialog),
                                  image, FALSE,
-                                 uri, GIMP_RUN_INTERACTIVE, load_proc,
+                                 file, GIMP_RUN_INTERACTIVE, load_proc,
                                  &status, &error);
 
   if (new_layers)
@@ -267,13 +267,10 @@ file_open_dialog_open_layers (GtkWidget           *open_dialog,
     }
   else if (status != GIMP_PDB_CANCEL)
     {
-      gchar *filename = file_utils_uri_display_name (uri);
-
       gimp_message (image->gimp, G_OBJECT (open_dialog), GIMP_MESSAGE_ERROR,
-                    _("Opening '%s' failed:\n\n%s"), filename, error->message);
+                    _("Opening '%s' failed:\n\n%s"),
+                    gimp_file_get_utf8_name (file), error->message);
       g_clear_error (&error);
-
-      g_free (filename);
     }
 
   return FALSE;
diff --git a/app/dialogs/file-open-location-dialog.c b/app/dialogs/file-open-location-dialog.c
index c7132a9..25d672e 100644
--- a/app/dialogs/file-open-location-dialog.c
+++ b/app/dialogs/file-open-location-dialog.c
@@ -23,6 +23,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "dialogs-types.h"
@@ -173,7 +174,8 @@ file_open_location_response (GtkDialog *dialog,
       gchar             *uri;
       gchar             *filename;
       gchar             *hostname;
-      GError            *error  = NULL;
+      GFile             *file  = NULL;
+      GError            *error = NULL;
       GimpPDBStatusType  status;
 
       filename = g_filename_from_uri (text, &hostname, NULL);
@@ -190,6 +192,12 @@ file_open_location_response (GtkDialog *dialog,
           uri = file_utils_filename_to_uri (gimp, text, &error);
         }
 
+      if (uri)
+        {
+          file = g_file_new_for_uri (uri);
+          g_free (uri);
+        }
+
       box = gimp_progress_box_new ();
       gtk_container_set_border_width (GTK_CONTAINER (box), 12);
       gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
@@ -197,31 +205,32 @@ file_open_location_response (GtkDialog *dialog,
 
       g_object_set_data (G_OBJECT (dialog), "progress-box", box);
 
-      if (uri)
+      if (file)
         {
+          GFile *entered_file = g_file_new_for_uri (text);
+
           gtk_widget_show (box);
 
           image = file_open_with_proc_and_display (gimp,
                                                    gimp_get_user_context (gimp),
                                                    GIMP_PROGRESS (box),
-                                                   uri, text, FALSE, NULL,
+                                                   file, entered_file,
+                                                   FALSE, NULL,
                                                    G_OBJECT (gtk_widget_get_screen (entry)),
                                                    gimp_widget_get_monitor (entry),
                                                    &status, &error);
 
+          g_object_unref (entered_file);
+
           if (image == NULL && status != GIMP_PDB_CANCEL)
             {
-              gchar *filename = file_utils_uri_display_name (uri);
-
               gimp_message (gimp, G_OBJECT (box), GIMP_MESSAGE_ERROR,
                             _("Opening '%s' failed:\n\n%s"),
-                            filename, error->message);
+                            gimp_file_get_utf8_name (file), error->message);
               g_clear_error (&error);
-
-              g_free (filename);
             }
 
-          g_free (uri);
+          g_object_unref (file);
         }
       else
         {
diff --git a/app/dialogs/file-save-dialog.c b/app/dialogs/file-save-dialog.c
index 8ed3cc3..416aa44 100644
--- a/app/dialogs/file-save-dialog.c
+++ b/app/dialogs/file-save-dialog.c
@@ -23,6 +23,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "dialogs-types.h"
@@ -70,9 +71,9 @@ static GtkFileChooserConfirmation
 static void      file_save_dialog_response                  (GtkWidget            *save_dialog,
                                                              gint                  response_id,
                                                              Gimp                 *gimp);
-static CheckUriResult file_save_dialog_check_uri            (GtkWidget            *save_dialog,
+static CheckUriResult file_save_dialog_check_file           (GtkWidget            *save_dialog,
                                                              Gimp                 *gimp,
-                                                             gchar               **ret_uri,
+                                                             GFile               **ret_file,
                                                              gchar               **ret_basename,
                                                              GimpPlugInProcedure **ret_save_proc);
 static gboolean  file_save_dialog_no_overwrite_confirmation (GimpFileDialog       *dialog,
@@ -157,7 +158,7 @@ file_save_dialog_response (GtkWidget *save_dialog,
                            Gimp      *gimp)
 {
   GimpFileDialog      *dialog = GIMP_FILE_DIALOG (save_dialog);
-  gchar               *uri;
+  GFile               *file;
   gchar               *basename;
   GimpPlugInProcedure *save_proc;
   gulong               handler_id;
@@ -187,8 +188,8 @@ file_save_dialog_response (GtkWidget *save_dialog,
                                  G_CALLBACK (gtk_widget_destroyed),
                                  &dialog);
 
-  switch (file_save_dialog_check_uri (save_dialog, gimp,
-                                      &uri, &basename, &save_proc))
+  switch (file_save_dialog_check_file (save_dialog, gimp,
+                                       &file, &basename, &save_proc))
     {
     case CHECK_URI_FAIL:
       break;
@@ -199,7 +200,7 @@ file_save_dialog_response (GtkWidget *save_dialog,
       if (file_save_dialog_save_image (GIMP_PROGRESS (save_dialog),
                                        gimp,
                                        dialog->image,
-                                       uri,
+                                       file,
                                        save_proc,
                                        GIMP_RUN_INTERACTIVE,
                                        ! dialog->save_a_copy && ! dialog->export,
@@ -213,16 +214,22 @@ file_save_dialog_response (GtkWidget *save_dialog,
            * file_save()
            */
           if (dialog->save_a_copy)
-            gimp_image_set_save_a_copy_uri (dialog->image, uri);
+            {
+              gchar *uri = g_file_get_uri (file);
+              gimp_image_set_save_a_copy_uri (dialog->image, uri);
+              g_free (uri);
+            }
 
           if (! dialog->export)
             g_object_set_data_full (G_OBJECT (dialog->image->gimp),
-                                    GIMP_FILE_SAVE_LAST_URI_KEY,
-                                    g_strdup (uri), (GDestroyNotify) g_free);
+                                    GIMP_FILE_SAVE_LAST_FILE_KEY,
+                                    g_object_ref (file),
+                                    (GDestroyNotify) g_object_unref);
           else
             g_object_set_data_full (G_OBJECT (dialog->image->gimp),
-                                    GIMP_FILE_EXPORT_LAST_URI_KEY,
-                                    g_strdup (uri), (GDestroyNotify) g_free);
+                                    GIMP_FILE_EXPORT_LAST_FILE_KEY,
+                                    g_object_ref (file),
+                                    (GDestroyNotify) g_object_unref);
 
           /*  make sure the menus are updated with the keys we've just set  */
           gimp_image_flush (dialog->image);
@@ -242,7 +249,7 @@ file_save_dialog_response (GtkWidget *save_dialog,
           gtk_widget_destroy (save_dialog);
         }
 
-      g_free (uri);
+      g_object_unref (file);
       g_free (basename);
 
       if (dialog)
@@ -269,14 +276,15 @@ file_save_dialog_response (GtkWidget *save_dialog,
  * implemented in GTK+ in combination with how we use it.
  */
 static CheckUriResult
-file_save_dialog_check_uri (GtkWidget            *save_dialog,
-                            Gimp                 *gimp,
-                            gchar               **ret_uri,
-                            gchar               **ret_basename,
-                            GimpPlugInProcedure **ret_save_proc)
+file_save_dialog_check_file (GtkWidget            *save_dialog,
+                             Gimp                 *gimp,
+                             GFile               **ret_file,
+                             gchar               **ret_basename,
+                             GimpPlugInProcedure **ret_save_proc)
 {
   GimpFileDialog      *dialog = GIMP_FILE_DIALOG (save_dialog);
   gchar               *uri;
+  GFile               *file;
   gchar               *basename;
   GimpPlugInProcedure *save_proc;
   GimpPlugInProcedure *uri_proc;
@@ -287,13 +295,16 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
   if (! uri)
     return CHECK_URI_FAIL;
 
-  basename      = file_utils_uri_display_basename (uri);
+  file = g_file_new_for_uri (uri);
+
+  basename      = g_path_get_basename (gimp_file_get_utf8_name (file));
 
   save_proc     = dialog->file_proc;
   uri_proc      = file_procedure_find (file_save_dialog_get_procs (dialog, gimp),
-                                       uri, NULL);
+                                       file, NULL);
   basename_proc = file_procedure_find (file_save_dialog_get_procs (dialog, gimp),
-                                       basename, NULL);
+                                       /* XXX fixme leak */
+                                       g_file_new_for_path (basename), NULL);
 
   GIMP_LOG (SAVE_DIALOG, "URI = %s", uri);
   GIMP_LOG (SAVE_DIALOG, "basename = %s", basename);
@@ -335,9 +346,7 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
 
               ext_basename = g_strconcat (basename, ".", ext, NULL);
 
-              g_free (uri);
               g_free (basename);
-
               basename = ext_basename;
 
               utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
@@ -354,9 +363,7 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
                */
               gtk_dialog_response (GTK_DIALOG (save_dialog), GTK_RESPONSE_OK);
 
-              g_free (basename);
-
-              return CHECK_URI_FAIL;
+              goto fail;
             }
           else
             {
@@ -379,16 +386,10 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
 
               if (file_save_dialog_switch_dialogs (dialog, gimp, basename))
                 {
-                  g_free (uri);
-                  g_free (basename);
-
-                  return CHECK_URI_SWITCH_DIALOGS;
+                  goto switch_dialogs;
                 }
 
-              g_free (uri);
-              g_free (basename);
-
-              return CHECK_URI_FAIL;
+              goto fail;
             }
         }
       else if (save_proc && ! save_proc->extensions_list)
@@ -419,16 +420,10 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
 
           if (file_save_dialog_switch_dialogs (dialog, gimp, basename))
             {
-              g_free (uri);
-              g_free (basename);
-
-              return CHECK_URI_SWITCH_DIALOGS;
+              goto switch_dialogs;
             }
 
-          g_free (uri);
-          g_free (basename);
-
-          return CHECK_URI_FAIL;
+          goto fail;
         }
 
       GIMP_LOG (SAVE_DIALOG, "use URI's proc '%s' so indirect saving works",
@@ -460,10 +455,8 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
                               "Please enter a file extension that matches "
                               "the selected file format or enter no file "
                               "extension at all."));
-              g_free (uri);
-              g_free (basename);
 
-              return CHECK_URI_FAIL;
+              goto fail;
             }
           else
             {
@@ -474,10 +467,7 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
 
               if (! file_save_dialog_use_extension (save_dialog, uri))
                 {
-                  g_free (uri);
-                  g_free (basename);
-
-                  return CHECK_URI_FAIL;
+                  goto fail;
                 }
             }
         }
@@ -501,11 +491,29 @@ file_save_dialog_check_uri (GtkWidget            *save_dialog,
       return CHECK_URI_FAIL;
     }
 
-  *ret_uri       = uri;
+  g_free (uri);
+
+  *ret_file      = file;
   *ret_basename  = basename;
   *ret_save_proc = save_proc;
 
   return CHECK_URI_OK;
+
+ fail:
+
+  g_object_unref (file);
+  g_free (uri);
+  g_free (basename);
+
+  return CHECK_URI_FAIL;
+
+ switch_dialogs:
+
+  g_object_unref (file);
+  g_free (uri);
+  g_free (basename);
+
+  return CHECK_URI_SWITCH_DIALOGS;
 }
 
 /*
@@ -530,7 +538,8 @@ file_save_dialog_no_overwrite_confirmation (GimpFileDialog *dialog,
   basename      = file_utils_uri_display_basename (uri);
   save_proc     = dialog->file_proc;
   basename_proc = file_procedure_find (file_save_dialog_get_procs (dialog, gimp),
-                                       basename, NULL);
+                                       /* XXX fixme leak */
+                                       g_file_new_for_path (basename), NULL);
 
   uri_will_change = (! basename_proc &&
                      ! strchr (basename, '.') &&
@@ -590,7 +599,8 @@ file_save_dialog_switch_dialogs (GimpFileDialog *file_dialog,
     file_procedure_find (file_dialog->export ?
                          gimp->plug_in_manager->save_procs :
                          gimp->plug_in_manager->export_procs,
-                         basename,
+                         /* XXX fixme leak */
+                         g_file_new_for_path (basename),
                          NULL);
 
   if (proc_in_other_group)
@@ -738,7 +748,7 @@ gboolean
 file_save_dialog_save_image (GimpProgress        *progress,
                              Gimp                *gimp,
                              GimpImage           *image,
-                             const gchar         *uri,
+                             GFile               *file,
                              GimpPlugInProcedure *save_proc,
                              GimpRunMode          run_mode,
                              gboolean             change_saved_state,
@@ -758,7 +768,7 @@ file_save_dialog_save_image (GimpProgress        *progress,
       gimp_action_group_set_action_sensitive (list->data, "file-quit", FALSE);
     }
 
-  status = file_save (gimp, image, progress, uri,
+  status = file_save (gimp, image, progress, file,
                       save_proc, run_mode,
                       change_saved_state, export_backward, export_forward,
                       &error);
@@ -778,12 +788,10 @@ file_save_dialog_save_image (GimpProgress        *progress,
 
     default:
       {
-        gchar *filename = file_utils_uri_display_name (uri);
-
         gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
-                      _("Saving '%s' failed:\n\n%s"), filename, error->message);
+                      _("Saving '%s' failed:\n\n%s"),
+                      gimp_file_get_utf8_name (file), error->message);
         g_clear_error (&error);
-        g_free (filename);
       }
       break;
     }
diff --git a/app/dialogs/file-save-dialog.h b/app/dialogs/file-save-dialog.h
index 81d2bb0..92649eb 100644
--- a/app/dialogs/file-save-dialog.h
+++ b/app/dialogs/file-save-dialog.h
@@ -28,7 +28,7 @@ GtkWidget * file_save_dialog_new        (Gimp                *gimp,
 gboolean    file_save_dialog_save_image (GimpProgress        *progress_and_handler,
                                          Gimp                *gimp,
                                          GimpImage           *image,
-                                         const gchar         *uri,
+                                         GFile               *file,
                                          GimpPlugInProcedure *write_proc,
                                          GimpRunMode          run_mode,
                                          gboolean             save_a_copy,
diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c
index ae2ea73..09cc18a 100644
--- a/app/display/gimpdisplayshell-dnd.c
+++ b/app/display/gimpdisplayshell-dnd.c
@@ -512,7 +512,7 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
 
   for (list = uri_list; list; list = g_list_next (list))
     {
-      const gchar       *uri   = list->data;
+      GFile             *file  = g_file_new_for_uri (list->data);
       GimpPDBStatusType  status;
       GError            *error = NULL;
       gboolean           warn  = FALSE;
@@ -520,6 +520,7 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
       if (! shell->display)
         {
           /* It seems as if GIMP is being torn down for quitting. Bail out. */
+          g_object_unref (file);
           return;
         }
 
@@ -530,7 +531,7 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
           new_layers = file_open_layers (shell->display->gimp, context,
                                          GIMP_PROGRESS (shell->display),
                                          image, FALSE,
-                                         uri, GIMP_RUN_INTERACTIVE, NULL,
+                                         file, GIMP_RUN_INTERACTIVE, NULL,
                                          &status, &error);
 
           if (new_layers)
@@ -560,7 +561,7 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
 
           new_image = file_open_with_display (shell->display->gimp, context,
                                               NULL,
-                                              uri, FALSE,
+                                              file, FALSE,
                                               G_OBJECT (gtk_widget_get_screen (widget)),
                                               gimp_widget_get_monitor (widget),
                                               &status, &error);
@@ -573,7 +574,7 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
           /*  open the first image in the empty display  */
           image = file_open_with_display (shell->display->gimp, context,
                                           GIMP_PROGRESS (shell->display),
-                                          uri, FALSE,
+                                          file, FALSE,
                                           G_OBJECT (gtk_widget_get_screen (widget)),
                                           gimp_widget_get_monitor (widget),
                                           &status, &error);
@@ -587,16 +588,14 @@ gimp_display_shell_drop_uri_list (GtkWidget *widget,
        * is being torn down for quitting. */
       if (warn && shell->display)
         {
-          gchar *filename = file_utils_uri_display_name (uri);
-
           gimp_message (shell->display->gimp, G_OBJECT (shell->display),
                         GIMP_MESSAGE_ERROR,
                         _("Opening '%s' failed:\n\n%s"),
-                        filename, error->message);
-
+                        gimp_file_get_utf8_name (file), error->message);
           g_clear_error (&error);
-          g_free (filename);
         }
+
+      g_object_unref (file);
     }
 
   if (image)
diff --git a/app/file/file-open.c b/app/file/file-open.c
index 2a34c71..a4e4808 100644
--- a/app/file/file-open.c
+++ b/app/file/file-open.c
@@ -20,27 +20,9 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include <glib/gstdio.h>
 #include <gegl.h>
 
-#ifdef G_OS_WIN32
-#include <io.h>
-#define R_OK 4
-#endif
-
 #include "libgimpbase/gimpbase.h"
 #include "libgimpconfig/gimpconfig.h"
 
@@ -98,8 +80,8 @@ GimpImage *
 file_open_image (Gimp                *gimp,
                  GimpContext         *context,
                  GimpProgress        *progress,
-                 const gchar         *uri,
-                 const gchar         *entered_filename,
+                 GFile               *file,
+                 GFile               *entered_file,
                  gboolean             as_new,
                  GimpPlugInProcedure *file_proc,
                  GimpRunMode          run_mode,
@@ -108,69 +90,76 @@ file_open_image (Gimp                *gimp,
                  GError             **error)
 {
   GimpValueArray *return_vals;
-  gchar          *filename;
-  GimpImage      *image = NULL;
+  GimpImage      *image       = NULL;
+  gchar          *path        = NULL;
+  gchar          *entered_uri = NULL;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
+  g_return_val_if_fail (G_IS_FILE (entered_file), NULL);
   g_return_val_if_fail (status != NULL, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   *status = GIMP_PDB_EXECUTION_ERROR;
 
   if (! file_proc)
-    file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, uri,
+    file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, file,
                                      error);
 
   if (! file_proc)
     return NULL;
 
-  filename = file_utils_filename_from_uri (uri);
-
-  if (filename)
+  if (g_file_query_exists (file, NULL))
     {
-      /* check if we are opening a file */
-      if (g_file_test (filename, G_FILE_TEST_EXISTS))
-        {
-          if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR))
-            {
-              g_free (filename);
-              g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                                  _("Not a regular file"));
-              return NULL;
-            }
+      GFileInfo *info;
 
-          if (g_access (filename, R_OK) != 0)
-            {
-              g_free (filename);
-              g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
-                                  g_strerror (errno));
-              return NULL;
-            }
+      info = g_file_query_info (file,
+                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+                                G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
+                                G_FILE_QUERY_INFO_NONE,
+                                NULL, error);
+      if (! info)
+        return NULL;
+
+      if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
+        {
+          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                               _("Not a regular file"));
+          return NULL;
         }
 
-      if (file_proc->handles_uri)
+      if (! g_file_info_get_attribute_boolean (info,
+                                               G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
         {
-          g_free (filename);
-          filename = g_strdup (uri);
+          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                               _("Premission denied"));
         }
     }
-  else
-    {
-      filename = g_strdup (uri);
-    }
+
+  if (! file_proc->handles_uri)
+    path = g_file_get_path (file);
+
+  if (! path)
+    path = g_file_get_uri (file);
+
+  entered_uri = g_file_get_uri (entered_file);
+
+  if (! entered_uri)
+    entered_uri = g_strdup (path);
 
   return_vals =
     gimp_pdb_execute_procedure_by_name (gimp->pdb,
                                         context, progress, error,
                                         gimp_object_get_name (file_proc),
                                         GIMP_TYPE_INT32, run_mode,
-                                        G_TYPE_STRING,   filename,
-                                        G_TYPE_STRING,   entered_filename,
+                                        G_TYPE_STRING,   path,
+                                        G_TYPE_STRING,   entered_uri,
                                         G_TYPE_NONE);
 
-  g_free (filename);
+  g_free (path);
+  g_free (entered_uri);
 
   *status = g_value_get_enum (gimp_value_array_index (return_vals, 0));
 
@@ -220,7 +209,9 @@ file_open_image (Gimp                *gimp,
       if (file_open_file_proc_is_import (file_proc))
         {
           /* Remember the import source */
+          gchar *uri = g_file_get_uri (file);
           gimp_image_set_imported_uri (image, uri);
+          g_free (uri);
 
           /* We shall treat this file as an Untitled file */
           gimp_image_set_uri (image, NULL);
@@ -235,7 +226,7 @@ file_open_image (Gimp                *gimp,
  * @gimp:
  * @context:
  * @progress:
- * @uri:          the URI of the image file
+ * @file:         an image file
  * @size:         requested size of the thumbnail
  * @mime_type:    return location for image MIME type
  * @image_width:  return location for image width
@@ -253,7 +244,7 @@ GimpImage *
 file_open_thumbnail (Gimp           *gimp,
                      GimpContext    *context,
                      GimpProgress   *progress,
-                     const gchar    *uri,
+                     GFile          *file,
                      gint            size,
                      const gchar   **mime_type,
                      gint           *image_width,
@@ -268,6 +259,7 @@ file_open_thumbnail (Gimp           *gimp,
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
   g_return_val_if_fail (mime_type != NULL, NULL);
   g_return_val_if_fail (image_width != NULL, NULL);
   g_return_val_if_fail (image_height != NULL, NULL);
@@ -280,7 +272,7 @@ file_open_thumbnail (Gimp           *gimp,
   *format       = NULL;
   *num_layers   = -1;
 
-  file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, uri,
+  file_proc = file_procedure_find (gimp->plug_in_manager->load_procs, file,
                                    NULL);
 
   if (! file_proc || ! file_proc->thumb_loader)
@@ -292,23 +284,24 @@ file_open_thumbnail (Gimp           *gimp,
     {
       GimpPDBStatusType  status;
       GimpValueArray    *return_vals;
-      gchar             *filename;
       GimpImage         *image = NULL;
+      gchar             *path  = NULL;
 
-      filename = file_utils_filename_from_uri (uri);
+      if (! file_proc->handles_uri)
+        path = g_file_get_path (file);
 
-      if (! filename)
-        filename = g_strdup (uri);
+      if (! path)
+        path = g_file_get_uri (file);
 
       return_vals =
         gimp_pdb_execute_procedure_by_name (gimp->pdb,
                                             context, progress, error,
                                             gimp_object_get_name (procedure),
-                                            G_TYPE_STRING,   filename,
+                                            G_TYPE_STRING,   path,
                                             GIMP_TYPE_INT32, size,
                                             G_TYPE_NONE);
 
-      g_free (filename);
+      g_free (path);
 
       status = g_value_get_enum (gimp_value_array_index (return_vals, 0));
 
@@ -414,7 +407,7 @@ GimpImage *
 file_open_with_display (Gimp               *gimp,
                         GimpContext        *context,
                         GimpProgress       *progress,
-                        const gchar        *uri,
+                        GFile              *file,
                         gboolean            as_new,
                         GObject            *screen,
                         gint                monitor,
@@ -422,7 +415,7 @@ file_open_with_display (Gimp               *gimp,
                         GError            **error)
 {
   return file_open_with_proc_and_display (gimp, context, progress,
-                                          uri, uri, as_new, NULL,
+                                          file, file, as_new, NULL,
                                           screen, monitor,
                                           status, error);
 }
@@ -431,8 +424,8 @@ GimpImage *
 file_open_with_proc_and_display (Gimp                *gimp,
                                  GimpContext         *context,
                                  GimpProgress        *progress,
-                                 const gchar         *uri,
-                                 const gchar         *entered_filename,
+                                 GFile               *file,
+                                 GFile               *entered_file,
                                  gboolean             as_new,
                                  GimpPlugInProcedure *file_proc,
                                  GObject             *screen,
@@ -446,12 +439,14 @@ file_open_with_proc_and_display (Gimp                *gimp,
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
+  g_return_val_if_fail (G_IS_FILE (entered_file), NULL);
   g_return_val_if_fail (screen == NULL || G_IS_OBJECT (screen), NULL);
   g_return_val_if_fail (status != NULL, NULL);
 
   image = file_open_image (gimp, context, progress,
-                           uri,
-                           entered_filename,
+                           file,
+                           entered_file,
                            as_new,
                            file_proc,
                            GIMP_RUN_INTERACTIVE,
@@ -475,8 +470,10 @@ file_open_with_proc_and_display (Gimp                *gimp,
       if (file_open_file_proc_is_import (file_proc) &&
           gimp_image_get_n_layers (image) == 1)
         {
-          GimpObject *layer    = gimp_image_get_layer_iter (image)->data;
-          gchar      *basename = file_utils_uri_display_basename (uri);
+          GimpObject *layer = gimp_image_get_layer_iter (image)->data;
+          gchar      *basename;
+
+          basename = g_path_get_basename (gimp_file_get_utf8_name (file));
 
           gimp_item_rename (GIMP_ITEM (layer), basename, NULL);
           gimp_image_undo_free (image);
@@ -497,17 +494,16 @@ file_open_with_proc_and_display (Gimp                *gimp,
           GimpDocumentList *documents = GIMP_DOCUMENT_LIST (gimp->documents);
           GimpImagefile    *imagefile;
           const gchar      *any_uri;
-          GFile            *file;
+          gchar            *uri;
 
-          file = g_file_new_for_uri (uri);
           imagefile = gimp_document_list_add_file (documents, file, mime_type);
-          g_object_unref (file);
 
           /*  can only create a thumbnail if the passed uri and the
            *  resulting image's uri match. Use any_uri() here so we
            *  create thumbnails for both XCF and imported images.
            */
           any_uri = gimp_image_get_any_uri (image);
+          uri     = g_file_get_uri (file);
 
           if (any_uri && ! strcmp (uri, any_uri))
             {
@@ -518,10 +514,12 @@ file_open_with_proc_and_display (Gimp                *gimp,
                                                  NULL);
                 }
             }
+
+          g_free (uri);
         }
 
       /*  announce that we opened this image  */
-      gimp_image_opened (image->gimp, uri);
+      gimp_image_opened (image->gimp, file);
     }
 
   return image;
@@ -533,7 +531,7 @@ file_open_layers (Gimp                *gimp,
                   GimpProgress        *progress,
                   GimpImage           *dest_image,
                   gboolean             merge_visible,
-                  const gchar         *uri,
+                  GFile               *file,
                   GimpRunMode          run_mode,
                   GimpPlugInProcedure *file_proc,
                   GimpPDBStatusType   *status,
@@ -547,12 +545,12 @@ file_open_layers (Gimp                *gimp,
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
   g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
-  g_return_val_if_fail (uri != NULL, NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
   g_return_val_if_fail (status != NULL, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   new_image = file_open_image (gimp, context, progress,
-                               uri, uri, FALSE,
+                               file, file, FALSE,
                                file_proc,
                                run_mode,
                                status, &mime_type, error);
@@ -580,16 +578,14 @@ file_open_layers (Gimp                *gimp,
 
       if (layers)
         {
-          gchar *basename = file_utils_uri_display_basename (uri);
-          GFile *file;
+          gchar *basename;
 
+          basename = g_path_get_basename (gimp_file_get_utf8_name (file));
           file_open_convert_items (dest_image, basename, layers);
           g_free (basename);
 
-          file = g_file_new_for_uri (uri);
           gimp_document_list_add_file (GIMP_DOCUMENT_LIST (gimp->documents),
                                        file, mime_type);
-          g_object_unref (file);
         }
       else
         {
@@ -616,18 +612,18 @@ file_open_from_command_line (Gimp        *gimp,
                              gint         monitor)
 
 {
-  GError   *error   = NULL;
-  gchar    *uri;
+  GFile    *file;
   gboolean  success = FALSE;
+  GError   *error   = NULL;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
   g_return_val_if_fail (filename != NULL, FALSE);
   g_return_val_if_fail (screen == NULL || G_IS_OBJECT (screen), FALSE);
 
   /* we accept URI or filename */
-  uri = file_utils_any_to_uri (gimp, filename, &error);
+  file = file_utils_any_to_file (gimp, filename, &error);
 
-  if (uri)
+  if (file)
     {
       GimpImage         *image;
       GimpObject        *display = gimp_get_empty_display (gimp);
@@ -643,7 +639,7 @@ file_open_from_command_line (Gimp        *gimp,
       image = file_open_with_display (gimp,
                                       gimp_get_user_context (gimp),
                                       GIMP_PROGRESS (display),
-                                      uri, as_new,
+                                      file, as_new,
                                       screen, monitor,
                                       &status, &error);
 
@@ -651,24 +647,22 @@ file_open_from_command_line (Gimp        *gimp,
         {
           success = TRUE;
 
-          g_object_set_data_full (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_URI_KEY,
-                                  uri, (GDestroyNotify) g_free);
+          g_object_set_data_full (G_OBJECT (gimp), GIMP_FILE_OPEN_LAST_FILE_KEY,
+                                  g_object_ref (file),
+                                  (GDestroyNotify) g_object_unref);
         }
       else if (status != GIMP_PDB_CANCEL && display)
         {
-          gchar *filename = file_utils_uri_display_name (uri);
-
           gimp_message (gimp, G_OBJECT (display), GIMP_MESSAGE_ERROR,
                         _("Opening '%s' failed: %s"),
-                        filename, error->message);
+                        gimp_file_get_utf8_name (file), error->message);
           g_clear_error (&error);
-
-          g_free (filename);
-          g_free (uri);
         }
 
       if (display)
         g_object_remove_weak_pointer (G_OBJECT (display), (gpointer) &display);
+
+      g_object_unref (file);
     }
   else
     {
diff --git a/app/file/file-open.h b/app/file/file-open.h
index 523a62d..b60bb04 100644
--- a/app/file/file-open.h
+++ b/app/file/file-open.h
@@ -24,8 +24,8 @@
 GimpImage * file_open_image                 (Gimp                *gimp,
                                              GimpContext         *context,
                                              GimpProgress        *progress,
-                                             const gchar         *uri,
-                                             const gchar         *entered_filename,
+                                             GFile               *file,
+                                             GFile               *entered_file,
                                              gboolean             as_new,
                                              GimpPlugInProcedure *file_proc,
                                              GimpRunMode          run_mode,
@@ -36,7 +36,7 @@ GimpImage * file_open_image                 (Gimp                *gimp,
 GimpImage * file_open_thumbnail             (Gimp                *gimp,
                                              GimpContext         *context,
                                              GimpProgress        *progress,
-                                             const gchar         *uri,
+                                             GFile               *file,
                                              gint                 size,
                                              const gchar        **mime_type,
                                              gint                *image_width,
@@ -47,7 +47,7 @@ GimpImage * file_open_thumbnail             (Gimp                *gimp,
 GimpImage * file_open_with_display          (Gimp                *gimp,
                                              GimpContext         *context,
                                              GimpProgress        *progress,
-                                             const gchar         *uri,
+                                             GFile               *file,
                                              gboolean             as_new,
                                              GObject             *screen,
                                              gint                 monitor,
@@ -57,8 +57,8 @@ GimpImage * file_open_with_display          (Gimp                *gimp,
 GimpImage * file_open_with_proc_and_display (Gimp                *gimp,
                                              GimpContext         *context,
                                              GimpProgress        *progress,
-                                             const gchar         *uri,
-                                             const gchar         *entered_filename,
+                                             GFile               *file,
+                                             GFile               *entered_file,
                                              gboolean             as_new,
                                              GimpPlugInProcedure *file_proc,
                                              GObject             *screen,
@@ -71,7 +71,7 @@ GList     * file_open_layers                (Gimp                *gimp,
                                              GimpProgress        *progress,
                                              GimpImage           *dest_image,
                                              gboolean             merge_visible,
-                                             const gchar         *uri,
+                                             GFile               *file,
                                              GimpRunMode          run_mode,
                                              GimpPlugInProcedure *file_proc,
                                              GimpPDBStatusType   *status,
diff --git a/app/file/file-procedure.c b/app/file/file-procedure.c
index 45d1f14..06bc56f 100644
--- a/app/file/file-procedure.c
+++ b/app/file/file-procedure.c
@@ -48,14 +48,14 @@ typedef enum
 /*  local function prototypes  */
 
 static GimpPlugInProcedure * file_proc_find_by_prefix    (GSList       *procs,
-                                                          const gchar  *uri,
+                                                          GFile        *file,
                                                           gboolean      skip_magic);
 static GimpPlugInProcedure * file_proc_find_by_extension (GSList       *procs,
-                                                          const gchar  *uri,
+                                                          GFile        *file,
                                                           gboolean      skip_magic,
                                                           gboolean      uri_procs_only);
 static GimpPlugInProcedure * file_proc_find_by_name      (GSList       *procs,
-                                                          const gchar  *uri,
+                                                          GFile        *file,
                                                           gboolean      skip_magic);
 
 static void                  file_convert_string         (const gchar  *instr,
@@ -79,130 +79,120 @@ static FileMatchType         file_check_magic_list       (GSList       *magics_l
 /*  public functions  */
 
 GimpPlugInProcedure *
-file_procedure_find (GSList       *procs,
-                     const gchar  *uri,
-                     GError      **error)
+file_procedure_find (GSList  *procs,
+                     GFile   *file,
+                     GError **error)
 {
   GimpPlugInProcedure *file_proc;
-  GFile               *file;
+  GSList              *list;
+  GimpPlugInProcedure *size_matched_proc = NULL;
+  GInputStream        *input             = NULL;
+  gboolean             opened            = FALSE;
+  gsize                head_size         = 0;
+  gint                 size_match_count  = 0;
+  guchar               head[256];
 
   g_return_val_if_fail (procs != NULL, NULL);
-  g_return_val_if_fail (uri != NULL, NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   /* First, check magicless prefixes/suffixes: */
 
-  if (! file_proc_find_by_extension (procs, uri, FALSE, TRUE))
+  if (! file_proc_find_by_extension (procs, file, FALSE, TRUE))
     {
       /* If there is not any (with or without magic) file proc that
-       * can load the URI by extension directly, try to find a proc
+       * can load the file by extension directly, try to find a proc
        * that can load the prefix
        */
-      file_proc = file_proc_find_by_prefix (procs, uri, TRUE);
+      file_proc = file_proc_find_by_prefix (procs, file, TRUE);
     }
   else
     {
       /* Otherwise try to find a magicless file proc that handles the
        * extension
        */
-      file_proc = file_proc_find_by_extension (procs, uri, TRUE, FALSE);
+      file_proc = file_proc_find_by_extension (procs, file, TRUE, FALSE);
     }
 
   if (file_proc)
     return file_proc;
 
-  file = g_file_new_for_uri (uri);
-
   /* Then look for magics */
-  if (file)
+  for (list = procs; list; list = g_slist_next (list))
     {
-      GSList              *list;
-      GimpPlugInProcedure *size_matched_proc = NULL;
-      GInputStream        *input             = NULL;
-      gboolean             opened            = FALSE;
-      gsize                head_size         = 0;
-      gint                 size_match_count  = 0;
-      guchar               head[256];
-
-      for (list = procs; list; list = g_slist_next (list))
-        {
-          file_proc = list->data;
+      file_proc = list->data;
 
-          if (file_proc->magics_list)
+      if (file_proc->magics_list)
+        {
+          if (G_UNLIKELY (! opened))
             {
-              if (G_UNLIKELY (! opened))
+              input = G_INPUT_STREAM (g_file_read (file, NULL, error));
+
+              if (input)
                 {
-                  input = G_INPUT_STREAM (g_file_read (file, NULL, error));
+                  g_input_stream_read_all (input,
+                                           head, sizeof (head),
+                                           &head_size, NULL, error);
 
-                  if (input)
+                  if (head_size < 4)
                     {
-                      g_input_stream_read_all (input,
-                                               head, sizeof (head),
-                                               &head_size, NULL, error);
-
-                      if (head_size < 4)
-                        {
-                          g_object_unref (input);
-                          input = NULL;
-                        }
-                      else
-                        {
-                          GDataInputStream *data_input;
-
-                          data_input = g_data_input_stream_new (input);
-                          g_object_unref (input);
-                          input = G_INPUT_STREAM (data_input);
-                        }
+                      g_object_unref (input);
+                      input = NULL;
                     }
+                  else
+                    {
+                      GDataInputStream *data_input;
 
-                  opened = TRUE;
+                      data_input = g_data_input_stream_new (input);
+                      g_object_unref (input);
+                      input = G_INPUT_STREAM (data_input);
+                    }
                 }
 
-              if (head_size >= 4)
-                {
-                  FileMatchType match_val;
+              opened = TRUE;
+            }
 
-                  match_val = file_check_magic_list (file_proc->magics_list,
-                                                     head, head_size,
-                                                     file, input);
+          if (head_size >= 4)
+            {
+              FileMatchType match_val;
 
-                  if (match_val == FILE_MATCH_SIZE)
-                    {
-                      /* Use it only if no other magic matches */
-                      size_match_count++;
-                      size_matched_proc = file_proc;
-                    }
-                  else if (match_val != FILE_MATCH_NONE)
-                    {
-                      g_object_unref (input);
-                      g_object_unref (file);
+              match_val = file_check_magic_list (file_proc->magics_list,
+                                                 head, head_size,
+                                                 file, input);
 
-                      return file_proc;
-                    }
+              if (match_val == FILE_MATCH_SIZE)
+                {
+                  /* Use it only if no other magic matches */
+                  size_match_count++;
+                  size_matched_proc = file_proc;
+                }
+              else if (match_val != FILE_MATCH_NONE)
+                {
+                  g_object_unref (input);
+
+                  return file_proc;
                 }
             }
         }
+    }
 
-      if (input)
-        {
+  if (input)
+    {
 #if 0
-          if (ferror (ifp))
-            g_set_error_literal (error, G_FILE_ERROR,
-                                 g_file_error_from_errno (errno),
-                                 g_strerror (errno));
+      if (ferror (ifp))
+        g_set_error_literal (error, G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             g_strerror (errno));
 #endif
 
-          g_object_unref (input);
-        }
-
-      g_object_unref (file);
-
-      if (size_match_count == 1)
-        return size_matched_proc;
+      g_object_unref (input);
     }
 
+  if (size_match_count == 1)
+    return size_matched_proc;
+
   /* As a last resort, try matching by name, not skipping magic procs */
-  file_proc = file_proc_find_by_name (procs, uri, FALSE);
+  file_proc = file_proc_find_by_name (procs, file, FALSE);
 
   if (file_proc)
     {
@@ -221,21 +211,21 @@ file_procedure_find (GSList       *procs,
 }
 
 GimpPlugInProcedure *
-file_procedure_find_by_prefix (GSList      *procs,
-                               const gchar *uri)
+file_procedure_find_by_prefix (GSList *procs,
+                               GFile  *file)
 {
-  g_return_val_if_fail (uri != NULL, NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
 
-  return file_proc_find_by_prefix (procs, uri, FALSE);
+  return file_proc_find_by_prefix (procs, file, FALSE);
 }
 
 GimpPlugInProcedure *
-file_procedure_find_by_extension (GSList      *procs,
-                                  const gchar *uri)
+file_procedure_find_by_extension (GSList *procs,
+                                  GFile  *file)
 {
-  g_return_val_if_fail (uri != NULL, NULL);
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
 
-  return file_proc_find_by_extension (procs, uri, FALSE, FALSE);
+  return file_proc_find_by_extension (procs, file, FALSE, FALSE);
 }
 
 GimpPlugInProcedure *
@@ -298,10 +288,11 @@ file_procedure_in_group (GimpPlugInProcedure *file_proc,
 /*  private functions  */
 
 static GimpPlugInProcedure *
-file_proc_find_by_prefix (GSList      *procs,
-                          const gchar *uri,
-                          gboolean     skip_magic)
+file_proc_find_by_prefix (GSList   *procs,
+                          GFile    *file,
+                          gboolean  skip_magic)
 {
+  gchar  *uri = g_file_get_uri (file);
   GSList *p;
 
   for (p = procs; p; p = g_slist_next (p))
@@ -317,26 +308,35 @@ file_proc_find_by_prefix (GSList      *procs,
            prefixes = g_slist_next (prefixes))
         {
           if (g_str_has_prefix (uri, prefixes->data))
-            return proc;
+            {
+              g_free (uri);
+              return proc;
+            }
         }
      }
 
+  g_free (uri);
+
   return NULL;
 }
 
 static GimpPlugInProcedure *
-file_proc_find_by_extension (GSList      *procs,
-                             const gchar *uri,
-                             gboolean     skip_magic,
-                             gboolean     uri_procs_only)
+file_proc_find_by_extension (GSList   *procs,
+                             GFile    *file,
+                             gboolean  skip_magic,
+                             gboolean  uri_procs_only)
 {
+  gchar       *uri = g_file_get_uri (file);
   GSList      *p;
   const gchar *ext;
 
   ext = file_utils_uri_get_ext (uri);
 
   if (! (ext && *ext == '.'))
-    return NULL;
+    {
+      g_free (uri);
+      return NULL;
+    }
 
   ext++;
 
@@ -354,27 +354,30 @@ file_proc_find_by_extension (GSList      *procs,
                                ext,
                                (GCompareFunc) g_ascii_strcasecmp))
         {
+          g_free (uri);
           return proc;
         }
     }
 
+  g_free (uri);
+
   return NULL;
 }
 
 static GimpPlugInProcedure *
-file_proc_find_by_name (GSList      *procs,
-                        const gchar *uri,
-                        gboolean     skip_magic)
+file_proc_find_by_name (GSList   *procs,
+                        GFile    *file,
+                        gboolean  skip_magic)
 {
   GimpPlugInProcedure *proc;
 
-  proc = file_proc_find_by_extension (procs, uri, skip_magic, TRUE);
+  proc = file_proc_find_by_extension (procs, file, skip_magic, TRUE);
 
   if (! proc)
-    proc = file_proc_find_by_prefix (procs, uri, skip_magic);
+    proc = file_proc_find_by_prefix (procs, file, skip_magic);
 
   if (! proc)
-    proc = file_proc_find_by_extension (procs, uri, skip_magic, FALSE);
+    proc = file_proc_find_by_extension (procs, file, skip_magic, FALSE);
 
   return proc;
 }
diff --git a/app/file/file-procedure.h b/app/file/file-procedure.h
index 6f4dd8a..1d4862f 100644
--- a/app/file/file-procedure.h
+++ b/app/file/file-procedure.h
@@ -31,12 +31,12 @@ typedef enum
 
 
 GimpPlugInProcedure *file_procedure_find              (GSList               *procs,
-                                                       const gchar          *filename,
+                                                       GFile                *file,
                                                        GError              **error);
 GimpPlugInProcedure *file_procedure_find_by_prefix    (GSList               *procs,
-                                                       const gchar          *uri);
+                                                       GFile                *file);
 GimpPlugInProcedure *file_procedure_find_by_extension (GSList               *procs,
-                                                       const gchar          *uri);
+                                                       GFile                *file);
 
 GimpPlugInProcedure *file_procedure_find_by_mime_type (GSList               *procs,
                                                        const gchar          *mime_type);
diff --git a/app/file/file-save.c b/app/file/file-save.c
index 62ad4db..bfc52c6 100644
--- a/app/file/file-save.c
+++ b/app/file/file-save.c
@@ -20,27 +20,9 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include <glib/gstdio.h>
 #include <gegl.h>
 
-#ifdef G_OS_WIN32
-#include <io.h>
-#define W_OK 2
-#endif
-
 #include "libgimpbase/gimpbase.h"
 
 #include "core/core-types.h"
@@ -73,7 +55,7 @@ GimpPDBStatusType
 file_save (Gimp                *gimp,
            GimpImage           *image,
            GimpProgress        *progress,
-           const gchar         *uri,
+           GFile               *file,
            GimpPlugInProcedure *file_proc,
            GimpRunMode          run_mode,
            gboolean             change_saved_state,
@@ -84,7 +66,8 @@ file_save (Gimp                *gimp,
   GimpDrawable      *drawable;
   GimpValueArray    *return_vals;
   GimpPDBStatusType  status;
-  gchar             *filename;
+  gchar             *filename = NULL;
+  gchar             *uri      = NULL;
   gint32             image_ID;
   gint32             drawable_ID;
 
@@ -92,7 +75,7 @@ file_save (Gimp                *gimp,
   g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress),
                         GIMP_PDB_CALLING_ERROR);
-  g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR);
+  g_return_val_if_fail (G_IS_FILE (file), GIMP_PDB_CALLING_ERROR);
   g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc),
                         GIMP_PDB_CALLING_ERROR);
   g_return_val_if_fail ((export_backward && export_forward) == FALSE,
@@ -105,40 +88,46 @@ file_save (Gimp                *gimp,
   if (! drawable)
     return GIMP_PDB_EXECUTION_ERROR;
 
-  filename = file_utils_filename_from_uri (uri);
-
-  if (filename)
+  if (g_file_query_exists (file, NULL))
     {
-      /* check if we are saving to a file */
-      if (g_file_test (filename, G_FILE_TEST_EXISTS))
+      GFileInfo *info;
+
+      info = g_file_query_info (file,
+                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+                                G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
+                                G_FILE_QUERY_INFO_NONE,
+                                NULL, error);
+      if (! info)
         {
-          if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR))
-            {
-              g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                                  _("Not a regular file"));
-              status = GIMP_PDB_EXECUTION_ERROR;
-              goto out;
-            }
-
-          if (g_access (filename, W_OK) != 0)
-            {
-              g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
-                                   g_strerror (errno));
-              status = GIMP_PDB_EXECUTION_ERROR;
-              goto out;
-            }
+          status = GIMP_PDB_EXECUTION_ERROR;
+          goto out;
         }
 
-      if (file_proc->handles_uri)
+      if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
         {
-          g_free (filename);
-          filename = g_strdup (uri);
+          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                               _("Not a regular file"));
+          status = GIMP_PDB_EXECUTION_ERROR;
+          goto out;
+        }
+
+      if (! g_file_info_get_attribute_boolean (info,
+                                               G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+        {
+          g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                               _("Premission denied"));
+          status = GIMP_PDB_EXECUTION_ERROR;
+          goto out;
         }
     }
-  else
-    {
-      filename = g_strdup (uri);
-    }
+
+  uri = g_file_get_uri (file);
+
+  if (! file_proc->handles_uri)
+    filename = g_file_get_path (file);
+
+  if (! filename)
+    filename = g_strdup (uri);
 
   /* ref the image, so it can't get deleted during save */
   g_object_ref (image);
@@ -166,7 +155,6 @@ file_save (Gimp                *gimp,
     {
       GimpDocumentList *documents;
       GimpImagefile    *imagefile;
-      GFile            *file;
 
       if (change_saved_state)
         {
@@ -217,10 +205,8 @@ file_save (Gimp                *gimp,
 
       documents = GIMP_DOCUMENT_LIST (image->gimp->documents);
 
-      file = g_file_new_for_uri (uri);
       imagefile = gimp_document_list_add_file (documents, file,
                                                file_proc->mime_type);
-      g_object_unref (file);
 
       /* only save a thumbnail if we are saving as XCF, see bug #25272 */
       if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL)
@@ -243,6 +229,7 @@ file_save (Gimp                *gimp,
 
  out:
   g_free (filename);
+  g_free (uri);
 
   return status;
 }
diff --git a/app/file/file-save.h b/app/file/file-save.h
index df6027f..ad2556d 100644
--- a/app/file/file-save.h
+++ b/app/file/file-save.h
@@ -24,7 +24,7 @@
 GimpPDBStatusType   file_save (Gimp                 *gimp,
                                GimpImage            *image,
                                GimpProgress         *progress,
-                               const gchar          *uri,
+                               GFile                *file,
                                GimpPlugInProcedure  *file_proc,
                                GimpRunMode           run_mode,
                                gboolean              change_saved_state,
diff --git a/app/file/file-utils.c b/app/file/file-utils.c
index d1b9754..9c31d4f 100644
--- a/app/file/file-utils.c
+++ b/app/file/file-utils.c
@@ -100,20 +100,25 @@ file_utils_filename_to_uri (Gimp         *gimp,
                             const gchar  *filename,
                             GError      **error)
 {
-  GError *temp_error = NULL;
+  GFile  *file;
   gchar  *absolute;
   gchar  *uri;
+  GError *temp_error = NULL;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (filename != NULL, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
+  file = g_file_new_for_uri (filename);
+
   /*  check for prefixes like http or ftp  */
   if (file_procedure_find_by_prefix (gimp->plug_in_manager->load_procs,
-                                     filename))
+                                     file))
     {
       if (g_utf8_validate (filename, -1, NULL))
         {
+          g_object_unref (file);
+
           return g_strdup (filename);
         }
       else
@@ -122,20 +127,26 @@ file_utils_filename_to_uri (Gimp         *gimp,
                               G_CONVERT_ERROR,
                               G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
                               _("Invalid character sequence in URI"));
+          g_object_unref (file);
           return NULL;
         }
     }
   else if (file_utils_filename_is_uri (filename, &temp_error))
     {
+      g_object_unref (file);
+
       return g_strdup (filename);
     }
   else if (temp_error)
     {
       g_propagate_error (error, temp_error);
+      g_object_unref (file);
 
       return NULL;
     }
 
+  g_object_unref (file);
+
   if (! g_path_is_absolute (filename))
     {
       gchar *current;
@@ -156,11 +167,12 @@ file_utils_filename_to_uri (Gimp         *gimp,
   return uri;
 }
 
-gchar *
-file_utils_any_to_uri (Gimp         *gimp,
-                       const gchar  *filename_or_uri,
-                       GError      **error)
+GFile *
+file_utils_any_to_file (Gimp         *gimp,
+                        const gchar  *filename_or_uri,
+                        GError      **error)
 {
+  GFile *file;
   gchar *uri;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
@@ -180,7 +192,10 @@ file_utils_any_to_uri (Gimp         *gimp,
       uri = file_utils_filename_to_uri (gimp, filename_or_uri, error);
     }
 
-  return uri;
+  file = g_file_new_for_uri (uri);
+  g_free (uri);
+
+  return file;
 }
 
 
diff --git a/app/file/file-utils.h b/app/file/file-utils.h
index ebfab64..379c5f4 100644
--- a/app/file/file-utils.h
+++ b/app/file/file-utils.h
@@ -26,10 +26,11 @@ gboolean      file_utils_filename_is_uri      (const gchar   *filename,
 gchar       * file_utils_filename_to_uri      (Gimp          *gimp,
                                                const gchar   *filename,
                                                GError       **error);
-gchar       * file_utils_any_to_uri           (Gimp          *gimp,
+GFile       * file_utils_any_to_file          (Gimp          *gimp,
                                                const gchar   *filename_or_uri,
                                                GError       **error);
 gchar       * file_utils_filename_from_uri    (const gchar   *uri);
+gchar       * file_utils_filename_from_file   (GFile         *file);
 gchar       * file_utils_uri_with_new_ext     (const gchar   *uri,
                                                const gchar   *uri_with_ext);
 const gchar * file_utils_uri_get_ext          (const gchar   *uri);
diff --git a/app/file/gimp-file.h b/app/file/gimp-file.h
index 6ef725f..fa283c3 100644
--- a/app/file/gimp-file.h
+++ b/app/file/gimp-file.h
@@ -22,9 +22,9 @@
 #define __GIMP_FILE_H__
 
 /* Data keys for Gimp */
-#define GIMP_FILE_OPEN_LAST_URI_KEY     "gimp-file-open-last-uri"
-#define GIMP_FILE_SAVE_LAST_URI_KEY     "gimp-file-save-last-uri"
-#define GIMP_FILE_EXPORT_LAST_URI_KEY   "gimp-file-export-last-uri"
+#define GIMP_FILE_OPEN_LAST_FILE_KEY     "gimp-file-open-last-file"
+#define GIMP_FILE_SAVE_LAST_FILE_KEY     "gimp-file-save-last-file"
+#define GIMP_FILE_EXPORT_LAST_FILE_KEY   "gimp-file-export-last-file"
 
 
 #endif /* __GIMP_FILE_H__ */
diff --git a/app/gui/gimpdbusservice.c b/app/gui/gimpdbusservice.c
index f9d00eb..cbf12f5 100644
--- a/app/gui/gimpdbusservice.c
+++ b/app/gui/gimpdbusservice.c
@@ -60,7 +60,7 @@ static gboolean   gimp_dbus_service_open_as_new    (GimpDBusServiceUI     *servi
                                                     const gchar           *uri);
 
 static void       gimp_dbus_service_gimp_opened    (Gimp                  *gimp,
-                                                   const gchar           *uri,
+                                                   GFile                 *file,
                                                    GimpDBusService       *service);
 
 static gboolean   gimp_dbus_service_queue_open     (GimpDBusService       *service,
@@ -212,10 +212,14 @@ gimp_dbus_service_open_as_new (GimpDBusServiceUI     *service,
 
 static void
 gimp_dbus_service_gimp_opened (Gimp            *gimp,
-                              const gchar     *uri,
+                              GFile           *file,
                               GimpDBusService *service)
 {
+  gchar *uri = g_file_get_uri (file);
+
   g_signal_emit_by_name (service, "opened", uri);
+
+  g_free (uri);
 }
 
 /*
diff --git a/app/pdb/fileops-cmds.c b/app/pdb/fileops-cmds.c
index f2a2dc5..214ef0d 100644
--- a/app/pdb/fileops-cmds.c
+++ b/app/pdb/fileops-cmds.c
@@ -62,6 +62,7 @@ file_load_invoker (GimpProcedure         *procedure,
   GimpPlugInProcedure *file_proc;
   GimpProcedure       *proc;
   gchar               *uri;
+  GFile               *file;
   gint                 i;
 
   uri = file_utils_filename_to_uri (gimp,
@@ -72,10 +73,13 @@ file_load_invoker (GimpProcedure         *procedure,
     return gimp_procedure_get_return_values (procedure, FALSE,
                                              error ? *error : NULL);
 
+  file = g_file_new_for_uri (uri);
+  g_free (uri);
+
   file_proc =
-    file_procedure_find (gimp->plug_in_manager->load_procs, uri, error);
+    file_procedure_find (gimp->plug_in_manager->load_procs, file, error);
 
-  g_free (uri);
+  g_object_unref (file);
 
   if (! file_proc)
     return gimp_procedure_get_return_values (procedure, FALSE,
@@ -142,12 +146,18 @@ file_load_layer_invoker (GimpProcedure         *procedure,
 
       if (uri)
         {
+          GFile             *file;
           GList             *layers;
           GimpPDBStatusType  status;
 
+          file = g_file_new_for_uri (uri);
+          g_free (uri);
+
           layers = file_open_layers (gimp, context, progress,
                                      image, FALSE,
-                                     uri, run_mode, NULL, &status, error);
+                                     file, run_mode, NULL, &status, error);
+
+          g_object_unref (file);
 
           if (layers)
             {
@@ -196,12 +206,18 @@ file_load_layers_invoker (GimpProcedure         *procedure,
 
       if (uri)
         {
+          GFile             *file;
           GList             *layers;
           GimpPDBStatusType  status;
 
+          file = g_file_new_for_uri (uri);
+          g_free (uri);
+
           layers = file_open_layers (gimp, context, progress,
                                      image, FALSE,
-                                     uri, run_mode, NULL, &status, error);
+                                     file, run_mode, NULL, &status, error);
+
+          g_object_unref (file);
 
           if (layers)
             {
@@ -251,6 +267,7 @@ file_save_invoker (GimpProcedure         *procedure,
   GimpPlugInProcedure *file_proc;
   GimpProcedure       *proc;
   gchar               *uri;
+  GFile               *file;
   gint                 i;
 
   uri = file_utils_filename_to_uri (gimp,
@@ -261,13 +278,17 @@ file_save_invoker (GimpProcedure         *procedure,
     return gimp_procedure_get_return_values (procedure, FALSE,
                                              error ? *error : NULL);
 
+  file = g_file_new_for_uri (uri);
+  g_free (uri);
+
   file_proc =
-    file_procedure_find (gimp->plug_in_manager->save_procs, uri, NULL);
+    file_procedure_find (gimp->plug_in_manager->save_procs, file, NULL);
 
   if (! file_proc)
-    file_proc = file_procedure_find (gimp->plug_in_manager->export_procs, uri, error);
+    file_proc = file_procedure_find (gimp->plug_in_manager->export_procs, file,
+                                     error);
 
-  g_free (uri);
+  g_object_unref (file);
 
   if (! file_proc)
     return gimp_procedure_get_return_values (procedure, FALSE,
diff --git a/app/plug-in/gimppluginmanager-file.c b/app/plug-in/gimppluginmanager-file.c
index b131d3f..5022d14 100644
--- a/app/plug-in/gimppluginmanager-file.c
+++ b/app/plug-in/gimppluginmanager-file.c
@@ -231,8 +231,8 @@ gimp_plug_in_manager_register_thumb_loader (GimpPlugInManager *manager,
 }
 
 gboolean
-gimp_plug_in_manager_uri_has_exporter (GimpPlugInManager *manager,
-                                       const gchar       *uri)
+gimp_plug_in_manager_file_has_exporter (GimpPlugInManager *manager,
+                                        GFile             *file)
 {
-  return file_procedure_find (manager->export_procs, uri, NULL) != NULL;
+  return file_procedure_find (manager->export_procs, file, NULL) != NULL;
 }
diff --git a/app/plug-in/gimppluginmanager-file.h b/app/plug-in/gimppluginmanager-file.h
index 6865cd8..f1dcc6f 100644
--- a/app/plug-in/gimppluginmanager-file.h
+++ b/app/plug-in/gimppluginmanager-file.h
@@ -41,8 +41,8 @@ gboolean   gimp_plug_in_manager_register_handles_uri  (GimpPlugInManager *manage
 gboolean   gimp_plug_in_manager_register_thumb_loader (GimpPlugInManager *manager,
                                                        const gchar       *load_proc,
                                                        const gchar       *thumb_proc);
-gboolean   gimp_plug_in_manager_uri_has_exporter      (GimpPlugInManager *manager,
-                                                       const gchar       *uri);
+gboolean   gimp_plug_in_manager_file_has_exporter     (GimpPlugInManager *manager,
+                                                       GFile             *file);
 
 
 #endif /* __GIMP_PLUG_IN_MANAGER_FILE_H__ */
diff --git a/app/widgets/gimpdnd-xds.c b/app/widgets/gimpdnd-xds.c
index 153e2d2..e9f8a53 100644
--- a/app/widgets/gimpdnd-xds.c
+++ b/app/widgets/gimpdnd-xds.c
@@ -33,6 +33,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "widgets-types.h"
@@ -122,6 +123,7 @@ gimp_dnd_xds_save_image (GdkDragContext   *context,
   gint                 length;
   guchar              *data;
   gchar               *uri;
+  GFile               *file;
   gboolean             export = FALSE;
   GError              *error  = NULL;
 
@@ -142,29 +144,25 @@ gimp_dnd_xds_save_image (GdkDragContext   *context,
   uri = g_strndup ((const gchar *) data, length);
   g_free (data);
 
-  proc = file_procedure_find (image->gimp->plug_in_manager->save_procs, uri,
-                              NULL);
+  file = g_file_new_for_uri (uri);
+
+  proc = file_procedure_find (image->gimp->plug_in_manager->save_procs,
+                              file, NULL);
   if (! proc)
     {
-      proc = file_procedure_find (image->gimp->plug_in_manager->export_procs, uri,
-                                  NULL);
-
+      proc = file_procedure_find (image->gimp->plug_in_manager->export_procs,
+                                  file, NULL);
       export = TRUE;
     }
 
   if (proc)
     {
-      gchar *filename = file_utils_filename_from_uri (uri);
-
-      /*  FIXME: shouldn't overwrite non-local files w/o confirmation  */
-
-      if (! filename ||
-          ! g_file_test (filename, G_FILE_TEST_EXISTS) ||
+      if (! g_file_query_exists (file, NULL) ||
           gimp_file_overwrite_dialog (NULL, uri))
         {
           if (file_save (image->gimp,
                          image, NULL,
-                         uri, proc, GIMP_RUN_INTERACTIVE,
+                         file, proc, GIMP_RUN_INTERACTIVE,
                          ! export, FALSE, export,
                          &error) == GIMP_PDB_SUCCESS)
             {
@@ -180,19 +178,14 @@ gimp_dnd_xds_save_image (GdkDragContext   *context,
 
               if (error)
                 {
-                  gchar *filename = file_utils_uri_display_name (uri);
-
                   gimp_message (image->gimp, NULL, GIMP_MESSAGE_ERROR,
                                 _("Saving '%s' failed:\n\n%s"),
-                                filename, error->message);
-
-                  g_free (filename);
-                  g_error_free (error);
+                                gimp_file_get_utf8_name (file),
+                                error->message);
+                  g_clear_error (&error);
                 }
             }
         }
-
-      g_free (filename);
     }
   else
     {
@@ -205,6 +198,7 @@ gimp_dnd_xds_save_image (GdkDragContext   *context,
                               "file extension."));
     }
 
+  g_object_unref (file);
   g_free (uri);
 }
 
diff --git a/app/widgets/gimpfiledialog.c b/app/widgets/gimpfiledialog.c
index 8b6b359..3d92540 100644
--- a/app/widgets/gimpfiledialog.c
+++ b/app/widgets/gimpfiledialog.c
@@ -536,8 +536,12 @@ gimp_file_dialog_set_save_image (GimpFileDialog *dialog,
         dir_uri = gimp_image_get_imported_uri (image);
 
       if (! dir_uri)
-        dir_uri = g_object_get_data (G_OBJECT (gimp),
-                                     GIMP_FILE_SAVE_LAST_URI_KEY);
+        {
+          GFile *file = g_object_get_data (G_OBJECT (gimp),
+                                           GIMP_FILE_SAVE_LAST_FILE_KEY);
+          if (file)
+            dir_uri = g_file_get_uri (file); /* FIXME leak */
+        }
 
       if (! dir_uri)
         dir_uri = default_uri;
@@ -604,12 +608,20 @@ gimp_file_dialog_set_save_image (GimpFileDialog *dialog,
         dir_uri = gimp_image_get_uri (image);
 
       if (! dir_uri)
-        dir_uri = g_object_get_data (G_OBJECT (gimp),
-                                     GIMP_FILE_SAVE_LAST_URI_KEY);
+        {
+          GFile *file = g_object_get_data (G_OBJECT (gimp),
+                                           GIMP_FILE_SAVE_LAST_FILE_KEY);
+          if (file)
+            dir_uri = g_file_get_uri (file); /* XXX fixme leak */
+        }
 
       if (! dir_uri)
-        dir_uri = g_object_get_data (G_OBJECT (gimp),
-                                     GIMP_FILE_EXPORT_LAST_URI_KEY);
+        {
+          GFile *file = g_object_get_data (G_OBJECT (gimp),
+                                           GIMP_FILE_EXPORT_LAST_FILE_KEY);
+          if (file)
+            dir_uri = g_file_get_uri (file); /* XXX fixme leak */
+        }
 
       if (! dir_uri)
         dir_uri = default_uri;
@@ -648,8 +660,12 @@ gimp_file_dialog_set_save_image (GimpFileDialog *dialog,
         ext_uri = gimp_image_get_imported_uri (image);
 
       if (! ext_uri)
-        ext_uri = g_object_get_data (G_OBJECT (gimp),
-                                     GIMP_FILE_EXPORT_LAST_URI_KEY);
+        {
+          GFile *file = g_object_get_data (G_OBJECT (gimp),
+                                           GIMP_FILE_EXPORT_LAST_FILE_KEY);
+          if (file)
+            ext_uri = g_file_get_uri (file); /* XXX fixme leak */
+        }
 
       if (! ext_uri)
         ext_uri = "file:///we/only/care/about/extension.png";
diff --git a/app/widgets/gimpimagepropview.c b/app/widgets/gimpimagepropview.c
index 7d4cb43..711a208 100644
--- a/app/widgets/gimpimagepropview.c
+++ b/app/widgets/gimpimagepropview.c
@@ -375,12 +375,15 @@ gimp_image_prop_view_label_set_filetype (GtkWidget *label,
 
   if (! proc)
     {
-      gchar *filename = gimp_image_get_filename (image);
+      const gchar *uri = gimp_image_get_uri (image);
 
-      if (filename)
+      if (uri)
         {
-          proc = file_procedure_find (manager->load_procs, filename, NULL);
-          g_free (filename);
+          GFile *file;
+
+          file = g_file_new_for_uri (uri);
+          proc = file_procedure_find (manager->load_procs, file, NULL);
+          g_object_unref (file);
         }
     }
 
diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c
index 1eb127b..417ed59 100644
--- a/app/widgets/gimplayertreeview.c
+++ b/app/widgets/gimplayertreeview.c
@@ -708,6 +708,7 @@ gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView   *view,
   for (list = uri_list; list; list = g_list_next (list))
     {
       const gchar       *uri   = list->data;
+      GFile             *file  = g_file_new_for_uri (uri);
       GList             *new_layers;
       GimpPDBStatusType  status;
       GError            *error = NULL;
@@ -716,7 +717,7 @@ gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView   *view,
                                      gimp_container_view_get_context (cont_view),
                                      NULL,
                                      image, FALSE,
-                                     uri, GIMP_RUN_INTERACTIVE, NULL,
+                                     file, GIMP_RUN_INTERACTIVE, NULL,
                                      &status, &error);
 
       if (new_layers)
@@ -733,15 +734,13 @@ gimp_layer_tree_view_drop_uri_list (GimpContainerTreeView   *view,
         }
       else if (status != GIMP_PDB_CANCEL)
         {
-          gchar *filename = file_utils_uri_display_name (uri);
-
           gimp_message (image->gimp, G_OBJECT (view), GIMP_MESSAGE_ERROR,
                         _("Opening '%s' failed:\n\n%s"),
-                        filename, error->message);
-
+                        gimp_file_get_utf8_name (file), error->message);
           g_clear_error (&error);
-          g_free (filename);
         }
+
+      g_object_unref (file);
     }
 
   gimp_image_flush (image);
diff --git a/app/widgets/gimpthumbbox.c b/app/widgets/gimpthumbbox.c
index 7ec113d..55149c5 100644
--- a/app/widgets/gimpthumbbox.c
+++ b/app/widgets/gimpthumbbox.c
@@ -699,7 +699,7 @@ gimp_thumb_box_auto_thumbnail (GimpThumbBox *box)
 {
   Gimp          *gimp  = box->context->gimp;
   GimpThumbnail *thumb = gimp_imagefile_get_thumbnail (box->imagefile);
-  const gchar   *uri   = gimp_object_get_name (box->imagefile);
+  GFile         *file  = gimp_imagefile_get_file (box->imagefile);
 
   box->idle_id = 0;
 
@@ -713,7 +713,7 @@ gimp_thumb_box_auto_thumbnail (GimpThumbBox *box)
       if (thumb->image_filesize < gimp->config->thumbnail_filesize_limit &&
           ! gimp_thumbnail_has_failed (thumb)                            &&
           file_procedure_find_by_extension (gimp->plug_in_manager->load_procs,
-                                            uri))
+                                            file))
         {
           if (thumb->image_filesize > 0)
             {
diff --git a/app/widgets/gimptoolbox-dnd.c b/app/widgets/gimptoolbox-dnd.c
index 6d0d6ff..7f1b873 100644
--- a/app/widgets/gimptoolbox-dnd.c
+++ b/app/widgets/gimptoolbox-dnd.c
@@ -22,6 +22,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "widgets-types.h"
@@ -153,28 +154,26 @@ gimp_toolbox_drop_uri_list (GtkWidget *widget,
 
   for (list = uri_list; list; list = g_list_next (list))
     {
-      const gchar       *uri   = list->data;
+      GFile             *file = g_file_new_for_uri (list->data);
       GimpImage         *image;
       GimpPDBStatusType  status;
       GError            *error = NULL;
 
       image = file_open_with_display (context->gimp, context, NULL,
-                                      uri, FALSE,
+                                      file, FALSE,
                                       G_OBJECT (gtk_widget_get_screen (widget)),
                                       gimp_widget_get_monitor (widget),
                                       &status, &error);
 
       if (! image && status != GIMP_PDB_CANCEL)
         {
-          gchar *filename = file_utils_uri_display_name (uri);
-
           gimp_message (context->gimp, G_OBJECT (widget), GIMP_MESSAGE_ERROR,
                         _("Opening '%s' failed:\n\n%s"),
-                        filename, error->message);
-
+                        gimp_file_get_utf8_name (file), error->message);
           g_clear_error (&error);
-          g_free (filename);
         }
+
+      g_object_unref (file);
     }
 }
 
diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c
index 4f87b31..b0e4051 100644
--- a/app/widgets/gimptoolbox.c
+++ b/app/widgets/gimptoolbox.c
@@ -778,6 +778,7 @@ toolbox_paste_received (GtkClipboard *clipboard,
     {
       const gchar *newline = strchr (text, '\n');
       gchar       *copy;
+      GFile       *file = NULL;
 
       if (newline)
         copy = g_strndup (text, newline - text);
@@ -787,6 +788,11 @@ toolbox_paste_received (GtkClipboard *clipboard,
       g_strstrip (copy);
 
       if (strlen (copy))
+        file = g_file_new_for_commandline_arg (copy);
+
+      g_free (copy);
+
+      if (file)
         {
           GtkWidget         *widget = GTK_WIDGET (toolbox);
           GimpImage         *image;
@@ -794,25 +800,21 @@ toolbox_paste_received (GtkClipboard *clipboard,
           GError            *error = NULL;
 
           image = file_open_with_display (context->gimp, context, NULL,
-                                          copy, FALSE,
+                                          file, FALSE,
                                           G_OBJECT (gtk_widget_get_screen (widget)),
                                           gimp_widget_get_monitor (widget),
                                           &status, &error);
 
           if (! image && status != GIMP_PDB_CANCEL)
             {
-              gchar *filename = file_utils_uri_display_name (copy);
-
               gimp_message (context->gimp, NULL, GIMP_MESSAGE_ERROR,
                             _("Opening '%s' failed:\n\n%s"),
-                            filename, error->message);
-
+                            gimp_file_get_utf8_name (file), error->message);
               g_clear_error (&error);
-              g_free (filename);
             }
-        }
 
-      g_free (copy);
+          g_object_unref (file);
+        }
     }
 
   g_object_unref (context);
diff --git a/tools/pdbgen/pdb/fileops.pdb b/tools/pdbgen/pdb/fileops.pdb
index 64667f2..dbee7be 100644
--- a/tools/pdbgen/pdb/fileops.pdb
+++ b/tools/pdbgen/pdb/fileops.pdb
@@ -55,6 +55,7 @@ HELP
   GimpPlugInProcedure *file_proc;
   GimpProcedure       *proc;
   gchar               *uri;
+  GFile               *file;
   gint                 i;
 
   uri = file_utils_filename_to_uri (gimp,
@@ -65,10 +66,13 @@ HELP
     return gimp_procedure_get_return_values (procedure, FALSE,
                                              error ? *error : NULL);
 
+  file = g_file_new_for_uri (uri);
+  g_free (uri);
+
   file_proc =
-    file_procedure_find (gimp->plug_in_manager->load_procs, uri, error);
+    file_procedure_find (gimp->plug_in_manager->load_procs, file, error);
 
-  g_free (uri);
+  g_object_unref (file);
 
   if (! file_proc)
     return gimp_procedure_get_return_values (procedure, FALSE,
@@ -146,12 +150,18 @@ HELP
 
   if (uri)
     {
+      GFile             *file;
       GList             *layers;
       GimpPDBStatusType  status;
 
+      file = g_file_new_for_uri (uri);
+      g_free (uri);
+
       layers = file_open_layers (gimp, context, progress,
                                  image, FALSE,
-                                 uri, run_mode, NULL, &status, error);
+                                 file, run_mode, NULL, &status, error);
+
+      g_object_unref (file);
 
       if (layers)
         {
@@ -203,12 +213,18 @@ HELP
 
   if (uri)
     {
+      GFile             *file;
       GList             *layers;
       GimpPDBStatusType  status;
 
+      file = g_file_new_for_uri (uri);
+      g_free (uri);
+
       layers = file_open_layers (gimp, context, progress,
                                  image, FALSE,
-                                 uri, run_mode, NULL, &status, error);
+                                 file, run_mode, NULL, &status, error);
+
+      g_object_unref (file);
 
       if (layers)
         {
@@ -273,6 +289,7 @@ HELP
   GimpPlugInProcedure *file_proc;
   GimpProcedure       *proc;
   gchar               *uri;
+  GFile               *file;
   gint                 i;
 
   uri = file_utils_filename_to_uri (gimp,
@@ -283,13 +300,17 @@ HELP
     return gimp_procedure_get_return_values (procedure, FALSE,
                                              error ? *error : NULL);
 
+  file = g_file_new_for_uri (uri);
+  g_free (uri);
+
   file_proc =
-    file_procedure_find (gimp->plug_in_manager->save_procs, uri, NULL);
+    file_procedure_find (gimp->plug_in_manager->save_procs, file, NULL);
 
   if (! file_proc)
-    file_proc = file_procedure_find (gimp->plug_in_manager->export_procs, uri, error);
+    file_proc = file_procedure_find (gimp->plug_in_manager->export_procs, file,
+                                     error);
 
-  g_free (uri);
+  g_object_unref (file);
 
   if (! file_proc)
     return gimp_procedure_get_return_values (procedure, FALSE,


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