[gthumb] load the original image when copying to the clipboard and saving
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] load the original image when copying to the clipboard and saving
- Date: Sat, 9 Nov 2013 20:01:17 +0000 (UTC)
commit 05ec784908c00b861706df2dbc6438c10a93bf06
Author: Paolo Bacchilega <paobac src gnome org>
Date: Thu Oct 10 17:44:28 2013 +0200
load the original image when copying to the clipboard and saving
extensions/image_viewer/gth-image-viewer-page.c | 90 +++++-----
gthumb/Makefile.am | 2 +
gthumb/gth-image-task-chain.c | 209 +++++++++++++++++++++++
gthumb/gth-image-task-chain.h | 57 ++++++
gthumb/gth-image-task.c | 4 -
gthumb/gth-save-image-task.c | 15 +-
gthumb/gth-save-image-task.h | 6 +-
7 files changed, 325 insertions(+), 58 deletions(-)
---
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 3b0c72c..6602bac 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -1248,7 +1248,6 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
GthImageViewerPage *self;
SaveData *data;
GthFileData *current_file;
- GthImage *image;
GthTask *task;
self = (GthImageViewerPage *) base;
@@ -1288,8 +1287,10 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
* wants to save (see load_file_delayed_cb in gth-browser.c). */
g_file_info_set_attribute_boolean (data->file_to_save->info, "gth::file::is-modified", FALSE);
- image = gth_image_new_for_surface (gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER
(self->priv->viewer)));
- task = gth_save_image_task_new (image, mime_type, data->file_to_save, GTH_OVERWRITE_RESPONSE_YES);
+ task = gth_image_task_chain_new (_("Saving"),
+ gth_original_image_task_new (self),
+ gth_save_image_task_new (NULL, mime_type, data->file_to_save,
GTH_OVERWRITE_RESPONSE_YES),
+ NULL);
g_signal_connect (task,
"completed",
G_CALLBACK (save_image_task_completed_cb),
@@ -1297,7 +1298,6 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
gth_browser_exec_task (GTH_BROWSER (self->priv->browser), task, FALSE);
_g_object_unref (task);
- _g_object_unref (image);
}
@@ -1698,22 +1698,45 @@ gth_image_viewer_page_get_is_modified (GthImageViewerPage *self)
}
-void
-gth_image_viewer_page_copy_image (GthImageViewerPage *self)
+/* -- gth_image_viewer_page_copy_image -- */
+
+
+static void
+copy_image_original_image_ready_cb (GthTask *task,
+ GError *error,
+ gpointer user_data)
{
- cairo_surface_t *image;
- GtkClipboard *clipboard;
- GdkPixbuf *pixbuf;
+ GthImageViewerPage *self = user_data;
+ cairo_surface_t *image;
- image = gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER (self->priv->viewer));
- if (image == NULL)
- return;
+ image = gth_original_image_task_get_image (task);
+ if (image != NULL) {
+ GtkClipboard *clipboard;
+ GdkPixbuf *pixbuf;
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (self->priv->viewer),
GDK_SELECTION_CLIPBOARD);
- pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
- gtk_clipboard_set_image (clipboard, pixbuf);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (self->priv->viewer),
GDK_SELECTION_CLIPBOARD);
+ pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
+ gtk_clipboard_set_image (clipboard, pixbuf);
- g_object_unref (pixbuf);
+ g_object_unref (pixbuf);
+ }
+
+ cairo_surface_destroy (image);
+ g_object_unref (task);
+}
+
+
+void
+gth_image_viewer_page_copy_image (GthImageViewerPage *self)
+{
+ GthTask *task;
+
+ task = gth_original_image_task_new (self);
+ g_signal_connect (task,
+ "completed",
+ G_CALLBACK (copy_image_original_image_ready_cb),
+ self);
+ gth_browser_exec_task (self->priv->browser, task, FALSE);
}
@@ -1869,19 +1892,17 @@ typedef struct _GthOriginalImageTaskClass GthOriginalImageTaskClass;
struct _GthOriginalImageTask {
- GthTask __parent;
-
- GthImageViewerPage *viewer_page;
- cairo_surface_t *image;
+ GthImageTask __parent;
+ GthImageViewerPage *viewer_page;
};
struct _GthOriginalImageTaskClass {
- GthTaskClass __parent;
+ GthImageTaskClass __parent;
};
-G_DEFINE_TYPE (GthOriginalImageTask, gth_original_image_task, GTH_TYPE_TASK)
+G_DEFINE_TYPE (GthOriginalImageTask, gth_original_image_task, GTH_TYPE_IMAGE_TASK)
static void
@@ -1890,14 +1911,17 @@ get_original_image_ready_cb (GObject *source_object,
gpointer user_data)
{
GthOriginalImageTask *self = user_data;
+ cairo_surface_t *image = NULL;
GError *error = NULL;
gth_image_viewer_page_get_original_finish (self->viewer_page,
result,
- &self->image,
+ &image,
&error);
+ gth_image_task_set_destination_surface (GTH_IMAGE_TASK (self), image);
gth_task_completed (GTH_TASK (self), error);
+ cairo_surface_destroy (image);
_g_error_free (error);
}
@@ -1916,26 +1940,10 @@ gth_original_image_task_exec (GthTask *base)
static void
-gth_original_image_task_finalize (GObject *object)
-{
- GthOriginalImageTask *self;
-
- self = GTH_ORIGINAL_IMAGE_TASK (object);
- cairo_surface_destroy (self->image);
-
- G_OBJECT_CLASS (gth_original_image_task_parent_class)->finalize (object);
-}
-
-
-static void
gth_original_image_task_class_init (GthOriginalImageTaskClass *class)
{
- GObjectClass *object_class;
GthTaskClass *task_class;
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = gth_original_image_task_finalize;
-
task_class = GTH_TASK_CLASS (class);
task_class->exec = gth_original_image_task_exec;
}
@@ -1945,7 +1953,6 @@ static void
gth_original_image_task_init (GthOriginalImageTask *self)
{
self->viewer_page = NULL;
- self->image = NULL;
}
@@ -1964,6 +1971,5 @@ gth_original_image_task_new (GthImageViewerPage *self)
cairo_surface_t *
gth_original_image_task_get_image (GthTask *task)
{
- GthOriginalImageTask *image_task = GTH_ORIGINAL_IMAGE_TASK (task);
- return (image_task->image != NULL) ? cairo_surface_reference (image_task->image) : NULL;
+ return gth_image_task_get_destination_surface (GTH_IMAGE_TASK (task));
}
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 172514b..7c810e7 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -74,6 +74,7 @@ PUBLIC_HEADER_FILES = \
gth-image-saver.h \
gth-image-selector.h \
gth-image-task.h \
+ gth-image-task-chain.h \
gth-image-utils.h \
gth-image-viewer.h \
gth-image-viewer-tool.h \
@@ -210,6 +211,7 @@ gthumb_SOURCES = \
gth-image-saver.c \
gth-image-selector.c \
gth-image-task.c \
+ gth-image-task-chain.c \
gth-image-utils.c \
gth-image-viewer.c \
gth-image-viewer-tool.c \
diff --git a/gthumb/gth-image-task-chain.c b/gthumb/gth-image-task-chain.c
new file mode 100644
index 0000000..3c08565
--- /dev/null
+++ b/gthumb/gth-image-task-chain.c
@@ -0,0 +1,209 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include "glib-utils.h"
+#include "gth-image-task.h"
+#include "gth-image-task-chain.h"
+
+
+struct _GthImageTaskChainPrivate {
+ GList *tasks;
+ GList *current;
+ gulong task_completed;
+ gulong task_progress;
+ gulong task_dialog;
+
+};
+
+
+G_DEFINE_TYPE (GthImageTaskChain, gth_image_task_chain, GTH_TYPE_TASK)
+
+
+static void
+gth_image_task_chain_finalize (GObject *object)
+{
+ GthImageTaskChain *self;
+
+ g_return_if_fail (GTH_IS_IMAGE_TASK_CHAIN (object));
+
+ self = GTH_IMAGE_TASK_CHAIN (object);
+ _g_object_list_unref (self->priv->tasks);
+
+ G_OBJECT_CLASS (gth_image_task_chain_parent_class)->finalize (object);
+}
+
+
+static void _gth_image_task_chain_exec_current_task (GthImageTaskChain *self);
+
+
+static void
+image_task_completed_cb (GthTask *task,
+ GError *error,
+ gpointer user_data)
+{
+ GthImageTaskChain *self = user_data;
+
+ g_signal_handler_disconnect (task, self->priv->task_completed);
+ g_signal_handler_disconnect (task, self->priv->task_progress);
+ g_signal_handler_disconnect (task, self->priv->task_dialog);
+
+ if (error != NULL) {
+ gth_task_completed (GTH_TASK (self), error);
+ return;
+ }
+
+ self->priv->current = self->priv->current->next;
+ _gth_image_task_chain_exec_current_task (self);
+}
+
+
+static void
+image_task_progress_cb (GthTask *task,
+ const char *description,
+ const char *details,
+ gboolean pulse,
+ double fraction,
+ gpointer user_data)
+{
+ GthImageTaskChain *self = user_data;
+
+ gth_task_progress (GTH_TASK (self),
+ NULL,
+ description,
+ pulse,
+ fraction);
+}
+
+
+static void
+image_task_dialog_cb (GthTask *task,
+ gboolean opened,
+ GtkWidget *dialog,
+ gpointer user_data)
+{
+ gth_task_dialog (GTH_TASK (user_data), opened, dialog);
+}
+
+
+static void
+_gth_image_task_chain_exec_current_task (GthImageTaskChain *self)
+{
+ GthTask *task;
+
+ if (self->priv->current == NULL) {
+ gth_task_completed (GTH_TASK (self), NULL);
+ return;
+ }
+
+ task = (GthTask *) self->priv->current->data;
+ self->priv->task_completed =
+ g_signal_connect (task,
+ "completed",
+ G_CALLBACK (image_task_completed_cb),
+ self);
+ self->priv->task_progress =
+ g_signal_connect (task,
+ "progress",
+ G_CALLBACK (image_task_progress_cb),
+ self);
+ self->priv->task_dialog =
+ g_signal_connect (task,
+ "dialog",
+ G_CALLBACK (image_task_dialog_cb),
+ self);
+
+ if (self->priv->current != self->priv->tasks) {
+ GthTask *previous_task;
+ GthImage *image;
+
+ previous_task = (GthTask *) self->priv->current->prev->data;
+ image = gth_image_task_get_destination (GTH_IMAGE_TASK (previous_task));
+ gth_image_task_set_source (GTH_IMAGE_TASK (task), image);
+ }
+
+ gth_task_exec (task, gth_task_get_cancellable (GTH_TASK (self)));
+}
+
+
+static void
+gth_image_task_chain_exec (GthTask *task)
+{
+ GthImageTaskChain *self;
+
+ g_return_if_fail (GTH_IS_IMAGE_TASK_CHAIN (task));
+
+ self = GTH_IMAGE_TASK_CHAIN (task);
+
+ self->priv->current = self->priv->tasks;
+ _gth_image_task_chain_exec_current_task (self);
+}
+
+
+static void
+gth_image_task_chain_class_init (GthImageTaskChainClass *klass)
+{
+ GObjectClass *object_class;
+ GthTaskClass *task_class;
+
+ g_type_class_add_private (klass, sizeof (GthImageTaskChainPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_image_task_chain_finalize;
+
+ task_class = GTH_TASK_CLASS (klass);
+ task_class->exec = gth_image_task_chain_exec;
+}
+
+
+static void
+gth_image_task_chain_init (GthImageTaskChain *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_TASK_CHAIN, GthImageTaskChainPrivate);
+ self->priv->tasks = NULL;
+ self->priv->task_completed = 0;
+ self->priv->task_dialog = 0;
+ self->priv->task_progress = 0;
+}
+
+
+GthTask *
+gth_image_task_chain_new (const char *description,
+ GthTask *task,
+ ...)
+{
+ GthImageTaskChain *self;
+ va_list args;
+
+ self = (GthImageTaskChain *) g_object_new (GTH_TYPE_IMAGE_TASK_CHAIN,
+ "description", description,
+ NULL);
+
+ va_start (args, task);
+ while (task != NULL) {
+ self->priv->tasks = g_list_prepend (self->priv->tasks, task);
+ task = va_arg (args, GthTask *);
+ }
+ va_end (args);
+ self->priv->tasks = g_list_reverse (self->priv->tasks);
+
+ return (GthTask *) self;
+}
diff --git a/gthumb/gth-image-task-chain.h b/gthumb/gth-image-task-chain.h
new file mode 100644
index 0000000..d789141
--- /dev/null
+++ b/gthumb/gth-image-task-chain.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2013 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_IMAGE_TASK_CHAIN_H
+#define GTH_IMAGE_TASK_CHAIN_H
+
+#include <glib.h>
+#include "gth-task.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_IMAGE_TASK_CHAIN (gth_image_task_chain_get_type ())
+#define GTH_IMAGE_TASK_CHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_IMAGE_TASK_CHAIN,
GthImageTaskChain))
+#define GTH_IMAGE_TASK_CHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_IMAGE_TASK_CHAIN,
GthImageTaskChainClass))
+#define GTH_IS_IMAGE_TASK_CHAIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_IMAGE_TASK_CHAIN))
+#define GTH_IS_IMAGE_TASK_CHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_IMAGE_TASK_CHAIN))
+#define GTH_IMAGE_TASK_CHAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_IMAGE_TASK_CHAIN,
GthImageTaskChainClass))
+
+typedef struct _GthImageTaskChain GthImageTaskChain;
+typedef struct _GthImageTaskChainClass GthImageTaskChainClass;
+typedef struct _GthImageTaskChainPrivate GthImageTaskChainPrivate;
+
+struct _GthImageTaskChain {
+ GthTask __parent;
+ GthImageTaskChainPrivate *priv;
+};
+
+struct _GthImageTaskChainClass {
+ GthTaskClass __parent;
+};
+
+GType gth_image_task_chain_get_type (void);
+GthTask * gth_image_task_chain_new (const char *description,
+ GthTask *task,
+ ...) G_GNUC_NULL_TERMINATED;
+
+G_END_DECLS
+
+#endif /* GTH_IMAGE_TASK_CHAIN_H */
diff --git a/gthumb/gth-image-task.c b/gthumb/gth-image-task.c
index 922d347..880c009 100644
--- a/gthumb/gth-image-task.c
+++ b/gthumb/gth-image-task.c
@@ -96,8 +96,6 @@ void
gth_image_task_set_source (GthImageTask *self,
GthImage *source)
{
- g_return_if_fail (GTH_IS_IMAGE (source));
-
_g_object_ref (source);
_g_object_unref (self->priv->source);
self->priv->source = source;
@@ -135,8 +133,6 @@ void
gth_image_task_set_destination (GthImageTask *self,
GthImage *destination)
{
- g_return_if_fail (GTH_IS_IMAGE (destination));
-
_g_object_ref (destination);
_g_object_unref (self->priv->destination);
self->priv->destination = destination;
diff --git a/gthumb/gth-save-image-task.c b/gthumb/gth-save-image-task.c
index 6edffc7..4e5c54c 100644
--- a/gthumb/gth-save-image-task.c
+++ b/gthumb/gth-save-image-task.c
@@ -3,7 +3,7 @@
/*
* GThumb
*
- * Copyright (C) 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2012, 2013 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,14 +27,13 @@
struct _GthSaveImageTaskPrivate {
- GthImage *image;
char *mime_type;
GthFileData *file_data;
GthOverwriteResponse overwrite_mode;
};
-G_DEFINE_TYPE (GthSaveImageTask, gth_save_image_task, GTH_TYPE_TASK)
+G_DEFINE_TYPE (GthSaveImageTask, gth_save_image_task, GTH_TYPE_IMAGE_TASK)
static void
@@ -44,7 +43,6 @@ gth_save_image_task_finalize (GObject *object)
self = GTH_SAVE_IMAGE_TASK (object);
- _g_object_unref (self->priv->image);
g_free (self->priv->mime_type);
_g_object_unref (self->priv->file_data);
@@ -127,7 +125,7 @@ save_to_file_ready_cb (GthFileData *file_data,
GtkWidget *d;
d = gth_overwrite_dialog_new (NULL,
- self->priv->image,
+ gth_image_task_get_source (GTH_IMAGE_TASK (self)),
self->priv->file_data->file,
self->priv->overwrite_mode,
TRUE);
@@ -160,7 +158,7 @@ save_image (GthSaveImageTask *self)
description = g_strdup_printf (_("Saving '%s'"), filename);
gth_task_progress (GTH_TASK (self), description, NULL, TRUE, 0.0);
- gth_image_save_to_file (self->priv->image,
+ gth_image_save_to_file (gth_image_task_get_source (GTH_IMAGE_TASK (self)),
self->priv->mime_type,
self->priv->file_data,
((self->priv->overwrite_mode == GTH_OVERWRITE_RESPONSE_YES)
@@ -177,6 +175,7 @@ save_image (GthSaveImageTask *self)
static void
gth_save_image_task_exec (GthTask *task)
{
+ gth_image_task_set_destination (GTH_IMAGE_TASK (task), gth_image_task_get_source (GTH_IMAGE_TASK
(task)));
save_image (GTH_SAVE_IMAGE_TASK (task));
}
@@ -201,7 +200,6 @@ static void
gth_save_image_task_init (GthSaveImageTask *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_SAVE_IMAGE_TASK, GthSaveImageTaskPrivate);
- self->priv->image = NULL;
self->priv->mime_type = NULL;
self->priv->file_data = NULL;
}
@@ -215,14 +213,13 @@ gth_save_image_task_new (GthImage *image,
{
GthSaveImageTask *self;
- g_return_val_if_fail (image != NULL, NULL);
g_return_val_if_fail (file_data != NULL, NULL);
self = (GthSaveImageTask *) g_object_new (GTH_TYPE_SAVE_IMAGE_TASK, NULL);
- self->priv->image = g_object_ref (image);
self->priv->mime_type = g_strdup (mime_type);
self->priv->file_data = gth_file_data_dup (file_data);
self->priv->overwrite_mode = overwrite_mode;
+ gth_image_task_set_source (GTH_IMAGE_TASK (self), image);
return (GthTask *) self;
}
diff --git a/gthumb/gth-save-image-task.h b/gthumb/gth-save-image-task.h
index ca3caa2..02a6f57 100644
--- a/gthumb/gth-save-image-task.h
+++ b/gthumb/gth-save-image-task.h
@@ -24,8 +24,8 @@
#include <glib.h>
#include "gth-image.h"
+#include "gth-image-task.h"
#include "gth-overwrite-dialog.h"
-#include "gth-task.h"
G_BEGIN_DECLS
@@ -41,12 +41,12 @@ typedef struct _GthSaveImageTaskClass GthSaveImageTaskClass;
typedef struct _GthSaveImageTaskPrivate GthSaveImageTaskPrivate;
struct _GthSaveImageTask {
- GthTask __parent;
+ GthImageTask __parent;
GthSaveImageTaskPrivate *priv;
};
struct _GthSaveImageTaskClass {
- GthTaskClass __parent;
+ GthImageTaskClass __parent;
};
GType gth_save_image_task_get_type (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]