2008-03-12 00:22:39 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2008-03-29 00:09:44 +08:00
|
|
|
* URI plug-in, GIO/GVfs backend
|
2008-03-12 05:34:00 +08:00
|
|
|
* Copyright (C) 2008 Sven Neumann <sven@gimp.org>
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2008-03-12 00:22:39 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2008-03-12 00:22:39 +08:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2009-01-18 06:28:01 +08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2008-03-12 00:22:39 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2008-03-13 00:06:15 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
#include <gio/gio.h>
|
|
|
|
|
|
|
|
#include <libgimp/gimp.h>
|
|
|
|
#include <libgimp/gimpui.h>
|
|
|
|
|
|
|
|
#include "uri-backend.h"
|
|
|
|
|
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
|
|
|
|
2008-03-12 02:45:54 +08:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
DOWNLOAD,
|
|
|
|
UPLOAD
|
|
|
|
} Mode;
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
|
2009-04-21 23:48:17 +08:00
|
|
|
static gchar * get_protocols (void);
|
|
|
|
static gboolean copy_uri (const gchar *src_uri,
|
|
|
|
const gchar *dest_uri,
|
|
|
|
Mode mode,
|
|
|
|
GimpRunMode run_mode,
|
|
|
|
GError **error);
|
|
|
|
static gboolean mount_enclosing_volume (GFile *file,
|
|
|
|
GError **error);
|
2008-03-12 00:22:39 +08:00
|
|
|
|
|
|
|
static gchar *supported_protocols = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
uri_backend_init (const gchar *plugin_name,
|
|
|
|
gboolean run,
|
|
|
|
GimpRunMode run_mode,
|
|
|
|
GError **error)
|
|
|
|
{
|
2008-03-12 02:45:54 +08:00
|
|
|
if (run_mode == GIMP_RUN_INTERACTIVE)
|
|
|
|
{
|
|
|
|
gimp_ui_init (plugin_name, FALSE);
|
|
|
|
}
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
uri_backend_shutdown (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
uri_backend_get_load_help (void)
|
|
|
|
{
|
|
|
|
return "Loads a file using the GIO Virtual File System";
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
uri_backend_get_save_help (void)
|
|
|
|
{
|
|
|
|
return "Saves a file using the GIO Virtual File System";
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
uri_backend_get_load_protocols (void)
|
|
|
|
{
|
|
|
|
if (! supported_protocols)
|
|
|
|
supported_protocols = get_protocols ();
|
|
|
|
|
|
|
|
return supported_protocols;
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
uri_backend_get_save_protocols (void)
|
|
|
|
{
|
|
|
|
if (! supported_protocols)
|
|
|
|
supported_protocols = get_protocols ();
|
|
|
|
|
|
|
|
return supported_protocols;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
uri_backend_load_image (const gchar *uri,
|
|
|
|
const gchar *tmpname,
|
|
|
|
GimpRunMode run_mode,
|
|
|
|
GError **error)
|
|
|
|
{
|
2008-03-12 05:34:00 +08:00
|
|
|
gchar *dest_uri = g_filename_to_uri (tmpname, NULL, error);
|
2008-03-12 00:22:39 +08:00
|
|
|
|
2008-03-12 05:34:00 +08:00
|
|
|
if (dest_uri)
|
|
|
|
{
|
2008-03-12 21:55:27 +08:00
|
|
|
gboolean success = copy_uri (uri, dest_uri, DOWNLOAD, run_mode, error);
|
2008-03-12 00:22:39 +08:00
|
|
|
|
2008-03-12 05:34:00 +08:00
|
|
|
g_free (dest_uri);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
2008-03-12 00:22:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
uri_backend_save_image (const gchar *uri,
|
|
|
|
const gchar *tmpname,
|
|
|
|
GimpRunMode run_mode,
|
|
|
|
GError **error)
|
|
|
|
{
|
2008-03-12 05:34:00 +08:00
|
|
|
gchar *src_uri = g_filename_to_uri (tmpname, NULL, error);
|
2008-03-12 00:22:39 +08:00
|
|
|
|
2008-03-12 05:34:00 +08:00
|
|
|
if (src_uri)
|
|
|
|
{
|
2008-03-12 21:55:27 +08:00
|
|
|
gboolean success = copy_uri (src_uri, uri, UPLOAD, run_mode, error);
|
2008-03-12 00:22:39 +08:00
|
|
|
|
2008-03-12 05:34:00 +08:00
|
|
|
g_free (src_uri);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
2008-03-12 00:22:39 +08:00
|
|
|
}
|
|
|
|
|
2009-04-21 23:48:17 +08:00
|
|
|
gchar *
|
|
|
|
uri_backend_map_image (const gchar *uri,
|
|
|
|
GimpRunMode run_mode)
|
|
|
|
{
|
|
|
|
GFile *file = g_file_new_for_uri (uri);
|
|
|
|
gchar *path = NULL;
|
|
|
|
gboolean success = TRUE;
|
|
|
|
|
|
|
|
if (! file)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (run_mode == GIMP_RUN_INTERACTIVE)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (! mount_enclosing_volume (file, &error))
|
|
|
|
{
|
|
|
|
|
|
|
|
if (error->domain == G_IO_ERROR &&
|
|
|
|
error->code == G_IO_ERROR_ALREADY_MOUNTED)
|
|
|
|
success = TRUE;
|
|
|
|
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
path = g_file_get_path (file);
|
|
|
|
|
|
|
|
g_object_unref (file);
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
|
|
|
static gchar *
|
|
|
|
get_protocols (void)
|
|
|
|
{
|
2008-03-12 21:55:27 +08:00
|
|
|
const gchar * const *schemes;
|
|
|
|
GString *string = g_string_new (NULL);
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
schemes = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
|
|
|
|
2008-03-20 20:03:40 +08:00
|
|
|
for (i = 0; schemes && schemes[i]; i++)
|
2008-03-12 00:22:39 +08:00
|
|
|
{
|
|
|
|
if (string->len > 0)
|
|
|
|
g_string_append_c (string, ',');
|
|
|
|
|
2008-03-12 21:55:27 +08:00
|
|
|
g_string_append (string, schemes[i]);
|
|
|
|
g_string_append_c (string, ':');
|
2008-03-12 00:22:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return g_string_free (string, FALSE);
|
|
|
|
}
|
|
|
|
|
2008-03-18 19:16:59 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
Mode mode;
|
|
|
|
GTimeVal last_time;
|
|
|
|
} UriProgress;
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
static void
|
|
|
|
uri_progress_callback (goffset current_num_bytes,
|
|
|
|
goffset total_num_bytes,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2008-03-18 19:16:59 +08:00
|
|
|
UriProgress *progress = user_data;
|
|
|
|
GTimeVal now;
|
|
|
|
|
|
|
|
/* update the progress only up to 10 times a second */
|
|
|
|
g_get_current_time (&now);
|
|
|
|
|
2008-03-19 00:33:01 +08:00
|
|
|
if (progress->last_time.tv_sec &&
|
|
|
|
((now.tv_sec - progress->last_time.tv_sec) * 1000 +
|
2008-03-18 19:16:59 +08:00
|
|
|
(now.tv_usec - progress->last_time.tv_usec) / 1000) < 100)
|
|
|
|
return;
|
|
|
|
|
|
|
|
progress->last_time = now;
|
2008-03-12 00:22:39 +08:00
|
|
|
|
2008-03-12 02:45:54 +08:00
|
|
|
if (total_num_bytes > 0)
|
|
|
|
{
|
|
|
|
const gchar *format;
|
2008-03-29 00:33:24 +08:00
|
|
|
gchar *done = g_format_size_for_display (current_num_bytes);
|
|
|
|
gchar *total = g_format_size_for_display (total_num_bytes);
|
2008-03-12 02:45:54 +08:00
|
|
|
|
2008-03-18 19:16:59 +08:00
|
|
|
switch (progress->mode)
|
2008-03-12 02:45:54 +08:00
|
|
|
{
|
|
|
|
case DOWNLOAD:
|
|
|
|
format = _("Downloading image (%s of %s)");
|
|
|
|
break;
|
2008-07-24 22:43:40 +08:00
|
|
|
|
2008-03-12 02:45:54 +08:00
|
|
|
case UPLOAD:
|
|
|
|
format = _("Uploading image (%s of %s)");
|
|
|
|
break;
|
2008-07-24 22:43:40 +08:00
|
|
|
|
2008-03-12 02:45:54 +08:00
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_progress_set_text_printf (format, done, total);
|
2008-06-28 23:29:01 +08:00
|
|
|
gimp_progress_update ((gdouble) current_num_bytes /
|
|
|
|
(gdouble) total_num_bytes);
|
2008-03-12 02:45:54 +08:00
|
|
|
|
|
|
|
g_free (total);
|
|
|
|
g_free (done);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const gchar *format;
|
2008-03-29 00:33:24 +08:00
|
|
|
gchar *done = g_format_size_for_display (current_num_bytes);
|
2008-03-12 02:45:54 +08:00
|
|
|
|
2008-03-18 19:16:59 +08:00
|
|
|
switch (progress->mode)
|
2008-03-12 02:45:54 +08:00
|
|
|
{
|
|
|
|
case DOWNLOAD:
|
|
|
|
format = _("Downloaded %s of image data");
|
|
|
|
break;
|
2008-07-24 22:43:40 +08:00
|
|
|
|
2008-03-12 02:45:54 +08:00
|
|
|
case UPLOAD:
|
|
|
|
format = _("Uploaded %s of image data");
|
|
|
|
break;
|
2008-07-24 22:43:40 +08:00
|
|
|
|
2008-03-12 02:45:54 +08:00
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_progress_set_text_printf (format, done);
|
|
|
|
gimp_progress_pulse ();
|
|
|
|
|
|
|
|
g_free (done);
|
|
|
|
}
|
2008-03-12 00:22:39 +08:00
|
|
|
}
|
|
|
|
|
2008-03-12 21:55:27 +08:00
|
|
|
static void
|
|
|
|
mount_volume_ready (GFile *file,
|
|
|
|
GAsyncResult *res,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
g_file_mount_enclosing_volume_finish (file, res, error);
|
|
|
|
|
|
|
|
gtk_main_quit ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
mount_enclosing_volume (GFile *file,
|
|
|
|
GError **error)
|
|
|
|
{
|
2009-03-06 03:44:15 +08:00
|
|
|
GMountOperation *operation = gtk_mount_operation_new (NULL);
|
2008-03-12 21:55:27 +08:00
|
|
|
|
|
|
|
g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
|
|
|
|
operation,
|
|
|
|
NULL,
|
|
|
|
(GAsyncReadyCallback) mount_volume_ready,
|
|
|
|
error);
|
|
|
|
gtk_main ();
|
|
|
|
|
|
|
|
g_object_unref (operation);
|
|
|
|
|
|
|
|
return (*error == NULL);
|
|
|
|
}
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
static gboolean
|
|
|
|
copy_uri (const gchar *src_uri,
|
|
|
|
const gchar *dest_uri,
|
2008-03-12 02:45:54 +08:00
|
|
|
Mode mode,
|
2008-03-12 21:55:27 +08:00
|
|
|
GimpRunMode run_mode,
|
2008-03-12 00:22:39 +08:00
|
|
|
GError **error)
|
|
|
|
{
|
2008-03-18 19:16:59 +08:00
|
|
|
GFile *src_file;
|
|
|
|
GFile *dest_file;
|
|
|
|
UriProgress progress = { 0, };
|
|
|
|
gboolean success;
|
2008-03-12 00:22:39 +08:00
|
|
|
|
|
|
|
gimp_progress_init (_("Connecting to server"));
|
|
|
|
|
2008-03-18 19:16:59 +08:00
|
|
|
progress.mode = mode;
|
|
|
|
|
2009-03-31 17:52:58 +08:00
|
|
|
src_file = g_file_new_for_uri (src_uri);
|
|
|
|
dest_file = g_file_new_for_uri (dest_uri);
|
|
|
|
|
2008-11-23 00:55:32 +08:00
|
|
|
success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, NULL,
|
2008-03-18 19:16:59 +08:00
|
|
|
uri_progress_callback, &progress,
|
2008-03-12 00:22:39 +08:00
|
|
|
error);
|
|
|
|
|
2008-03-12 21:55:27 +08:00
|
|
|
if (! success &&
|
|
|
|
run_mode == GIMP_RUN_INTERACTIVE &&
|
|
|
|
(*error)->domain == G_IO_ERROR &&
|
|
|
|
(*error)->code == G_IO_ERROR_NOT_MOUNTED)
|
|
|
|
{
|
2008-03-13 00:06:15 +08:00
|
|
|
g_clear_error (error);
|
|
|
|
|
2008-03-12 21:55:27 +08:00
|
|
|
if (mount_enclosing_volume (mode == DOWNLOAD ? src_file : dest_file,
|
|
|
|
error))
|
|
|
|
{
|
|
|
|
success = g_file_copy (src_file, dest_file, 0, NULL,
|
2008-03-19 19:04:14 +08:00
|
|
|
uri_progress_callback, &progress,
|
2008-03-12 21:55:27 +08:00
|
|
|
error);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-12 00:22:39 +08:00
|
|
|
g_object_unref (src_file);
|
|
|
|
g_object_unref (dest_file);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|