[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: Fri, 23 Sep 2022 04:45:45 +0000 (UTC)
commit 8d854cd7096af97deccebccf8be1eaca4df37e7c
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 | 108 +++++++++++++++++++++++++++++++++++++++++
src/nautilus-file-operations.h | 7 +++
src/nautilus-files-view.c | 12 ++++-
3 files changed, 126 insertions(+), 1 deletion(-)
---
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index aa8bd29f3..4a29bff7c 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -8026,6 +8026,114 @@ 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)
+{
+ CreateJob *job = user_data;
+
+ gdk_pixbuf_save_to_stream_finish (res, NULL);
+ nautilus_progress_info_set_progress (job->common.progress, 1, 1);
+ finalize_common ((CommonJob *) job);
+ g_object_unref (source_object);
+}
+
+static void
+paste_image_stream_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CreateJob *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->length);
+ 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);
+ }
+ else
+ {
+ 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;
+ CreateJob *job = user_data;
+
+ clipboard = GDK_CLIPBOARD (source_object);
+
+ if (job_aborted ((CommonJob *) job))
+ {
+ return;
+ }
+
+ value = gdk_clipboard_read_value_finish (clipboard, res, NULL);
+
+ 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
+ {
+ 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;
+ CreateJob *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 (CreateJob, 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);
+
+ if (!nautilus_file_undo_manager_is_operating ())
+ {
+ g_autoptr (GFile) target_dir = g_file_new_for_uri (parent_dir_uri);
+
+ /* job->common.undo_info = nautilus_file_undo_info_ext_new (NAUTILUS_FILE_UNDO_OP_COPY, */
+ /* 1, */
+ /* NULL, target_dir); */
+ }
+}
+
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]