[gthumb] edit metadata: use a task to load and save the metadata



commit f9c78be0288b26aaec61672852f57881a75705cc
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Jul 17 12:03:17 2011 +0200

    edit metadata: use a task to load and save the metadata
    
    This way a progress dialog is shown and the user can cancel the operation.
    Related to bug #638371.

 extensions/edit_metadata/dlg-edit-metadata.c |   51 ++++---
 gthumb/Makefile.am                           |    2 +
 gthumb/gth-load-file-data-task.c             |    8 -
 gthumb/gth-save-file-data-task.c             |  201 ++++++++++++++++++++++++++
 gthumb/gth-save-file-data-task.h             |   57 ++++++++
 5 files changed, 288 insertions(+), 31 deletions(-)
---
diff --git a/extensions/edit_metadata/dlg-edit-metadata.c b/extensions/edit_metadata/dlg-edit-metadata.c
index 362e5f7..b3e7210 100644
--- a/extensions/edit_metadata/dlg-edit-metadata.c
+++ b/extensions/edit_metadata/dlg-edit-metadata.c
@@ -45,17 +45,16 @@ destroy_cb (GtkWidget  *widget,
 
 
 static void
-write_metadata_ready_cb (GObject      *source_object,
-			 GAsyncResult *result,
-			 gpointer      user_data)
+save_file_data_task_completed_cb (GthTask  *task,
+				  GError   *error,
+				  gpointer  user_data)
 {
 	DialogData *data = user_data;
 	GthMonitor *monitor;
 	GList      *scan;
-	GError     *error = NULL;
 
-	if (! _g_write_metadata_finish (result, &error)) {
-		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not save the file metadata"), &error);
+	if (error != NULL) {
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not save the file metadata"), &error);
 		return;
 	}
 
@@ -84,6 +83,7 @@ edit_metadata_dialog__response_cb (GtkDialog *dialog,
 				   gpointer   user_data)
 {
 	DialogData *data = user_data;
+	GthTask    *task;
 
 	if (response != GTK_RESPONSE_OK) {
 		gtk_widget_destroy (GTK_WIDGET (data->dialog));
@@ -91,19 +91,23 @@ edit_metadata_dialog__response_cb (GtkDialog *dialog,
 	}
 
 	gth_edit_metadata_dialog_update_info (GTH_EDIT_METADATA_DIALOG (data->dialog), data->file_list);
-	_g_write_metadata_async (data->file_list,
-				 GTH_METADATA_WRITE_DEFAULT,
-				 "*",
-				 NULL,
-				 write_metadata_ready_cb,
-				 data);
+
+	task = gth_save_file_data_task_new (data->file_list, "*");
+	g_signal_connect (task,
+			  "completed",
+			  G_CALLBACK (save_file_data_task_completed_cb),
+			  data);
+	gth_browser_exec_task (data->browser, task, FALSE);
+
+	g_object_unref (task);
+
 }
 
 
 static void
-info_ready_cb (GList    *files,
-	       GError   *error,
-	       gpointer  user_data)
+load_file_data_task_completed_cb (GthTask  *task,
+				  GError   *error,
+				  gpointer  user_data)
 {
 	DialogData *data = user_data;
 
@@ -113,7 +117,7 @@ info_ready_cb (GList    *files,
 		return;
 	}
 
-	data->file_list = _g_object_list_ref (files);
+	data->file_list = _g_object_list_ref (gth_load_file_data_task_get_result (GTH_LOAD_FILE_DATA_TASK (task)));
 	gth_edit_metadata_dialog_set_file_list (GTH_EDIT_METADATA_DIALOG (data->dialog), data->file_list);
 
 	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
@@ -127,6 +131,7 @@ dlg_edit_metadata (GthBrowser *browser,
 		   GList      *files)
 {
 	DialogData *data;
+	GthTask    *task;
 
 	data = g_new0 (DialogData, 1);
 	data->browser = browser;
@@ -142,12 +147,12 @@ dlg_edit_metadata (GthBrowser *browser,
 			  G_CALLBACK (edit_metadata_dialog__response_cb),
 			  data);
 
-	/* FIXME: progress dialog ? */
+	task = gth_load_file_data_task_new (data->files, "*");
+	g_signal_connect (task,
+			  "completed",
+			  G_CALLBACK (load_file_data_task_completed_cb),
+			  data);
+	gth_browser_exec_task (browser, task, FALSE);
 
-	_g_query_all_metadata_async (data->files,
-				     GTH_LIST_DEFAULT,
-				     "*",
-				     NULL,
-				     info_ready_cb,
-				     data);
+	g_object_unref (task);
 }
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 90569f2..4739efc 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -91,6 +91,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-preferences.h				\
 	gth-progress-dialog.h				\
 	gth-request-dialog.h				\
+	gth-save-file-data-task.h			\
 	gth-screensaver.h				\
 	gth-sidebar.h					\
 	gth-statusbar.h					\
@@ -218,6 +219,7 @@ gthumb_SOURCES = 					\
 	gth-preferences.c				\
 	gth-progress-dialog.c				\
 	gth-request-dialog.c				\
+	gth-save-file-data-task.c			\
 	gth-screensaver.c				\
 	gth-sidebar.c					\
 	gth-source-tree.c				\
diff --git a/gthumb/gth-load-file-data-task.c b/gthumb/gth-load-file-data-task.c
index 6ab3301..e93a40a 100644
--- a/gthumb/gth-load-file-data-task.c
+++ b/gthumb/gth-load-file-data-task.c
@@ -137,13 +137,6 @@ gth_load_file_data_task_exec (GthTask *task)
 
 
 static void
-gth_load_file_data_task_cancelled (GthTask *task)
-{
-	/* FIXME */
-}
-
-
-static void
 gth_load_file_data_task_class_init (GthLoadFileDataTaskClass *klass)
 {
 	GObjectClass *object_class;
@@ -157,7 +150,6 @@ gth_load_file_data_task_class_init (GthLoadFileDataTaskClass *klass)
 
 	task_class = GTH_TASK_CLASS (klass);
 	task_class->exec = gth_load_file_data_task_exec;
-	task_class->cancelled = gth_load_file_data_task_cancelled;
 }
 
 
diff --git a/gthumb/gth-save-file-data-task.c b/gthumb/gth-save-file-data-task.c
new file mode 100644
index 0000000..1723eef
--- /dev/null
+++ b/gthumb/gth-save-file-data-task.c
@@ -0,0 +1,201 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 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 <config.h>
+#include <glib/gi18n.h>
+#include "glib-utils.h"
+#include "gth-save-file-data-task.h"
+#include "gth-metadata-provider.h"
+
+
+struct _GthSaveFileDataTaskPrivate {
+	GList *file_data_list;
+	char  *attributes;
+	int    n_files;
+	GList *current;
+	int    n_current;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_save_file_data_task_finalize (GObject *object)
+{
+	GthSaveFileDataTask *self;
+
+	self = GTH_SAVE_FILE_DATA_TASK (object);
+
+	_g_object_list_unref (self->priv->file_data_list);
+	g_free (self->priv->attributes);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void save_current_file (GthSaveFileDataTask *self);
+
+
+static void
+save_next_file (GthSaveFileDataTask *self)
+{
+	self->priv->current = self->priv->current->next;
+	self->priv->n_current++;
+	save_current_file (self);
+}
+
+
+static void
+write_metadata_ready_cb (GObject      *source_object,
+			 GAsyncResult *result,
+			 gpointer      user_data)
+{
+	GthSaveFileDataTask *self = user_data;
+	GError              *error = NULL;
+
+	if (! _g_write_metadata_finish (result, &error)) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	save_next_file (self);
+}
+
+
+static void
+save_current_file (GthSaveFileDataTask *self)
+{
+	GFile *file;
+	int    n_remaining;
+	char  *details;
+	GList *files;
+
+	if (self->priv->current == NULL) {
+		gth_task_completed (GTH_TASK (self), NULL);
+		return;
+	}
+
+	file = self->priv->current->data;
+
+	n_remaining = self->priv->n_files - self->priv->n_current;
+	details = g_strdup_printf (g_dngettext (NULL, "%d file remaining", "%d files remaining", n_remaining), n_remaining);
+	gth_task_progress (GTH_TASK (self),
+			   _("Saving file information"),
+			   details,
+			   FALSE,
+			   ((double) self->priv->n_current + 0.5) / self->priv->n_files);
+
+	files = g_list_prepend (NULL, file);
+	_g_write_metadata_async (files,
+				 GTH_METADATA_WRITE_DEFAULT,
+				 self->priv->attributes,
+				 gth_task_get_cancellable (GTH_TASK (self)),
+				 write_metadata_ready_cb,
+				 self);
+
+	g_list_free (files);
+	g_free (details);
+}
+
+
+static void
+gth_save_file_data_task_exec (GthTask *task)
+{
+	GthSaveFileDataTask *self;
+
+	g_return_if_fail (GTH_IS_SAVE_FILE_DATA_TASK (task));
+
+	self = GTH_SAVE_FILE_DATA_TASK (task);
+
+	save_current_file (self);
+}
+
+
+static void
+gth_save_file_data_task_class_init (GthSaveFileDataTaskClass *klass)
+{
+	GObjectClass *object_class;
+	GthTaskClass *task_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthSaveFileDataTaskPrivate));
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = gth_save_file_data_task_finalize;
+
+	task_class = GTH_TASK_CLASS (klass);
+	task_class->exec = gth_save_file_data_task_exec;
+}
+
+
+static void
+gth_save_file_data_task_init (GthSaveFileDataTask *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_SAVE_FILE_DATA_TASK, GthSaveFileDataTaskPrivate);
+	self->priv->file_data_list = NULL;
+	self->priv->attributes = NULL;
+}
+
+
+GType
+gth_save_file_data_task_get_type (void)
+{
+	static GType type = 0;
+
+	if (! type) {
+		GTypeInfo type_info = {
+			sizeof (GthSaveFileDataTaskClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_save_file_data_task_class_init,
+			NULL,
+			NULL,
+			sizeof (GthSaveFileDataTask),
+			0,
+			(GInstanceInitFunc) gth_save_file_data_task_init
+		};
+
+		type = g_type_register_static (GTH_TYPE_TASK,
+					       "GthSaveFileDataTask",
+					       &type_info,
+					       0);
+	}
+
+	return type;
+}
+
+
+GthTask *
+gth_save_file_data_task_new (GList      *file_list,
+			     const char *attributes)
+{
+	GthSaveFileDataTask *self;
+
+	self = (GthSaveFileDataTask *) g_object_new (GTH_TYPE_SAVE_FILE_DATA_TASK, NULL);
+	self->priv->file_data_list = gth_file_data_list_dup (file_list);
+	self->priv->attributes = g_strdup (attributes);
+	self->priv->n_files = g_list_length (self->priv->file_data_list);;
+	self->priv->current = self->priv->file_data_list;
+	self->priv->n_current = 0;
+
+	return (GthTask *) self;
+}
diff --git a/gthumb/gth-save-file-data-task.h b/gthumb/gth-save-file-data-task.h
new file mode 100644
index 0000000..80f132b
--- /dev/null
+++ b/gthumb/gth-save-file-data-task.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 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_SAVE_FILE_DATA_TASK_H
+#define GTH_SAVE_FILE_DATA_TASK_H
+
+#include <glib.h>
+#include "gth-file-data.h"
+#include "gth-task.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_SAVE_FILE_DATA_TASK            (gth_save_file_data_task_get_type ())
+#define GTH_SAVE_FILE_DATA_TASK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_SAVE_FILE_DATA_TASK, GthSaveFileDataTask))
+#define GTH_SAVE_FILE_DATA_TASK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_SAVE_FILE_DATA_TASK, GthSaveFileDataTaskClass))
+#define GTH_IS_SAVE_FILE_DATA_TASK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_SAVE_FILE_DATA_TASK))
+#define GTH_IS_SAVE_FILE_DATA_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_SAVE_FILE_DATA_TASK))
+#define GTH_SAVE_FILE_DATA_TASK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_SAVE_FILE_DATA_TASK, GthSaveFileDataTaskClass))
+
+typedef struct _GthSaveFileDataTask        GthSaveFileDataTask;
+typedef struct _GthSaveFileDataTaskClass   GthSaveFileDataTaskClass;
+typedef struct _GthSaveFileDataTaskPrivate GthSaveFileDataTaskPrivate;
+
+struct _GthSaveFileDataTask {
+	GthTask __parent;
+	GthSaveFileDataTaskPrivate *priv;
+};
+
+struct _GthSaveFileDataTaskClass {
+	GthTaskClass __parent;
+};
+
+GType       gth_save_file_data_task_get_type   (void);
+GthTask *   gth_save_file_data_task_new        (GList      *file_list, /* GthFileData list */
+		     	     	     	        const char *attributes);
+
+G_END_DECLS
+
+#endif /* GTH_SAVE_FILE_DATA_TASK_H */



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