[nautilus/wip/corey/rework-clipboard] files-view: Allow pasting GDK_TYPE_PIXBUF
- From: Corey Berla <coreyberla src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/corey/rework-clipboard] files-view: Allow pasting GDK_TYPE_PIXBUF
- Date: Tue, 27 Sep 2022 22:54:26 +0000 (UTC)
commit 962ca8379cc96ccb451153209a9e883748b97e96
Author: Corey Berla <corey berla me>
Date: Tue Sep 20 15:18:13 2022 -0700
files-view: Allow pasting GDK_TYPE_PIXBUF
In my testing, copying images was captured as GDK_TYPE_PIXBUF.
Allow pasting those files into Nautilus. Since we don't have
any information regarding filename, popup a dialog that asks for a
filename and allows choosing a supported filetype.
src/nautilus-file-operations.c | 138 +++++++++++++++++++++++++++++++++++++++++
src/nautilus-file-operations.h | 7 +++
src/nautilus-files-view.c | 12 +++-
3 files changed, 156 insertions(+), 1 deletion(-)
---
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index aa8bd29f3..97f8c0184 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -236,6 +236,17 @@ typedef struct
gpointer done_callback_data;
} CompressJob;
+typedef struct
+{
+ CommonJob common;
+ GFile *dest_file;
+ GFile *dest_dir;
+ int suffix;
+ GdkPixbuf *pixbuf;
+ NautilusCreateCallback done_callback;
+ gpointer done_callback_data;
+} PasteImageJob;
+
static void
source_info_clear (SourceInfo *source_info)
{
@@ -8026,6 +8037,133 @@ nautilus_file_operations_new_folder (GtkWidget *parent_view
g_task_run_in_thread (task, create_task_thread_func);
}
+static void
+paste_image_save_callback (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PasteImageJob *job = user_data;
+ g_autoptr (GError) error = NULL;
+
+ gdk_pixbuf_save_to_stream_finish (res, &error);
+
+ if (job_aborted ((CommonJob *) job) || error != NULL)
+ {
+ g_file_delete (job->dest_file, NULL, NULL);
+ return;
+ }
+
+ nautilus_progress_info_set_progress (job->common.progress, 1, 1);
+ nautilus_progress_info_set_status (job->common.progress, _("Pasted clipboard data"));
+ finalize_common ((CommonJob *) job);
+ g_object_unref (source_object);
+ g_object_unref (job->dest_file);
+}
+
+static void
+paste_image_stream_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PasteImageJob *job = user_data;
+ g_autoptr (GError) error = NULL;
+
+ g_autoptr (GFileOutputStream) stream = g_file_create_finish (G_FILE (source_object), res, &error);
+
+ if (error != NULL && IS_IO_ERROR (error, EXISTS))
+ {
+ /* Translators: This is an auto-generated name when there's a duplicate. i.e. "Pasted image 1.png" */
+ g_autofree gchar *filename = g_strdup_printf (_("Pasted image %d.png"), ++job->suffix);
+ g_autoptr (GFile) location = g_file_get_child (job->dest_dir, filename);
+ g_file_create_async (location, 0, 0, job->common.cancellable, paste_image_stream_ready, job);
+ g_warning ("getting suffix %d", job->suffix);
+ }
+ else if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ }
+ else
+ {
+ nautilus_progress_info_set_progress (job->common.progress, .75, 1);
+ nautilus_progress_info_set_details (job->common.progress, _("Saving clipboard data to disk"));
+ job->dest_file = g_object_ref (G_FILE (source_object));
+ gdk_pixbuf_save_to_stream_async (job->done_callback_data,
+ G_OUTPUT_STREAM (stream),
+ "png",
+ job->common.cancellable,
+ paste_image_save_callback, job, NULL);
+ }
+}
+
+static void
+paste_image_received_callback (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GdkClipboard *clipboard;
+ const GValue *value;
+ PasteImageJob *job = user_data;
+ g_autoptr (GError) error = NULL;
+
+ clipboard = GDK_CLIPBOARD (source_object);
+
+ if (job_aborted ((CommonJob *) job))
+ {
+ return;
+ }
+
+ value = gdk_clipboard_read_value_finish (clipboard, res, &error);
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ nautilus_progress_info_set_status (job->common.progress, _("Failed to paste image"));
+ finalize_common ((CommonJob *) job);
+ return;
+ }
+
+ nautilus_progress_info_set_progress (job->common.progress, .5, 1);
+
+ if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF))
+ {
+ GdkPixbuf *pixbuf = g_value_get_object (value);
+ g_autoptr (GFile) location = g_file_get_child (job->dest_dir, _("Pasted image.png"));
+
+ job->done_callback_data = gdk_pixbuf_copy (pixbuf);
+ g_file_create_async (location, 0, 0, job->common.cancellable, paste_image_stream_ready, job);
+ }
+ else
+ {
+ nautilus_progress_info_set_status (job->common.progress, _("Failed to paste image"));
+ finalize_common ((CommonJob *) job);
+ }
+}
+
+void
+nautilus_file_operations_paste_image_from_clipboard (GtkWidget *parent_view,
+ NautilusFileOperationsDBusData *dbus_data,
+ const char *parent_dir_uri,
+ NautilusCreateCallback done_callback,
+ gpointer done_callback_data)
+{
+ g_autoptr (GTask) task = NULL;
+ PasteImageJob *job;
+ GtkWindow *parent_window;
+ GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (parent_view));
+
+
+ if (parent_view)
+ {
+ parent_window = (GtkWindow *) gtk_widget_get_ancestor (parent_view, GTK_TYPE_WINDOW);
+ }
+
+ job = op_job_new (PasteImageJob, parent_window, dbus_data);
+ job->dest_dir = g_file_new_for_uri (parent_dir_uri);
+
+ nautilus_progress_info_start (job->common.progress);
+ nautilus_progress_info_set_details (job->common.progress, _("Retrieving clipboard data"));
+ gdk_clipboard_read_value_async (clipboard, GDK_TYPE_PIXBUF, 0, job->common.cancellable,
paste_image_received_callback, job);
+}
+
void
nautilus_file_operations_new_file_from_template (GtkWidget *parent_view,
const char *parent_dir,
diff --git a/src/nautilus-file-operations.h b/src/nautilus-file-operations.h
index 14d664f80..37f6ab4ac 100644
--- a/src/nautilus-file-operations.h
+++ b/src/nautilus-file-operations.h
@@ -164,3 +164,10 @@ void nautilus_file_operations_compress (GList *files,
NautilusFileOperationsDBusData *dbus_data,
NautilusCreateCallback done_callback,
gpointer done_callback_data);
+
+void
+nautilus_file_operations_paste_image_from_clipboard (GtkWidget *parent_view,
+ NautilusFileOperationsDBusData *dbus_data,
+ const char *parent_dir_uri,
+ NautilusCreateCallback done_callback,
+ gpointer done_callback_data);
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index c78523f3a..89841ff6f 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -2795,6 +2795,15 @@ paste_files (NautilusFilesView *view,
{
gdk_clipboard_read_value_async (clipboard, G_TYPE_FILE, 0, priv->clipboard_cancellable,
paste_value_received_callback, data);
}
+ else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_PIXBUF))
+ {
+ nautilus_file_operations_paste_image_from_clipboard (GTK_WIDGET (view),
+ NULL,
+ data->dest_uri,
+ NULL,
+ NULL);
+ paste_callback_data_free (data);
+ }
}
static void
@@ -7211,7 +7220,8 @@ update_actions_state_for_clipboard_targets (NautilusFilesView *view)
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view));
formats = gdk_clipboard_get_formats (clipboard);
is_data_copied = gdk_content_formats_contain_gtype (formats, NAUTILUS_TYPE_CLIPBOARD) ||
- gdk_content_formats_contain_gtype (formats, G_TYPE_FILE);
+ gdk_content_formats_contain_gtype (formats, G_TYPE_FILE) ||
+ gdk_content_formats_contain_gtype (formats, GDK_TYPE_PIXBUF);
action = g_action_map_lookup_action (G_ACTION_MAP (priv->view_action_group),
"paste");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]