[gthumb/ext] [photo importer] added code to copy the files to the destination



commit a0166724f7df92954fdc116161656a0b09863750
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Thu Aug 13 17:49:16 2009 +0200

    [photo importer] added code to copy the files to the destination

 extensions/photo_importer/dlg-photo-importer.c |   79 +++++----
 extensions/photo_importer/gth-import-task.c    |  211 +++++++++++++++++++++++-
 extensions/photo_importer/gth-import-task.h    |   18 ++-
 gthumb/gio-utils.c                             |   37 +----
 gthumb/glib-utils.c                            |   35 ++++
 gthumb/glib-utils.h                            |    3 +
 6 files changed, 300 insertions(+), 83 deletions(-)
---
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 9ec4e1c..58d17d7 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -93,14 +93,23 @@ destroy_dialog (gpointer user_data)
 	eel_gconf_set_boolean (PREF_PHOTO_IMPORT_DELETE, delete_imported);
 
 	if (data->import) {
-		GthTask *task;
-
-		task = gth_import_task_new (destination,
+		GthFileStore *file_store;
+		GList        *files;
+		GthTask      *task;
+
+		file_store = (GthFileStore *) gth_file_view_get_model (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (data->file_list))));
+		files = gth_file_store_get_checked (file_store);
+		task = gth_import_task_new (data->browser,
+					    files,
+					    destination,
 					    subfolder_type,
 					    single_subfolder,
 					    gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("tags_entry"))),
 					    delete_imported);
 		gth_browser_exec_task (data->browser, task, FALSE);
+
+		g_object_unref (task);
+		_g_object_list_unref (files);
 	}
 
 	_g_object_unref (destination);
@@ -460,15 +469,39 @@ select_none_button_clicked_cb (GtkButton  *button,
 }
 
 
+static GthFileData *
+create_example_file_data (void)
+{
+	GFile       *file;
+	GFileInfo   *info;
+	GthFileData *file_data;
+	GthMetadata *metadata;
+
+	file = g_file_new_for_uri ("file://home/user/document.txt");
+	info = g_file_info_new ();
+	file_data = gth_file_data_new (file, info);
+
+	metadata = g_object_new (GTH_TYPE_METADATA,
+				 "raw", "2005:03:09 13:23:51",
+				 "formatted", "2005:03:09 13:23:51",
+				 NULL);
+	g_file_info_set_attribute_object (info, "Embedded::Image::DateTime", G_OBJECT (metadata));
+
+	g_object_unref (metadata);
+	g_object_unref (info);
+	g_object_unref (file);
+
+	return file_data;
+}
+
+
 static void
 update_destination (DialogData *data)
 {
 	GFile             *destination;
-	GTimeVal           timeval;
 	GthSubfolderType   subfolder_type;
-	GDate             *date;
-	char             **parts = NULL;
-	char              *child;
+	gboolean           single_subfolder;
+	GthFileData       *example_data;
 	GFile             *destination_example;
 	char              *uri;
 	char              *example;
@@ -478,34 +511,11 @@ update_destination (DialogData *data)
 		return;
 
 	subfolder_type = gtk_combo_box_get_active (GTK_COMBO_BOX (data->subfolder_type_list));
-	if (subfolder_type == GTH_SUBFOLDER_TYPE_CURRENT_DATE)
-		g_get_current_time (&timeval);
-	else
-		_g_time_val_from_exif_date ("2005:04:03 11:34:18", &timeval);
-
-	date = g_date_new ();
-	g_date_set_time_val (date, &timeval);
-
-	switch (subfolder_type) {
-	case GTH_SUBFOLDER_TYPE_NONE:
-		break;
-	case GTH_SUBFOLDER_TYPE_FILE_DATE:
-	case GTH_SUBFOLDER_TYPE_CURRENT_DATE:
-		parts = g_new0 (char *, 4);
-		parts[0] = g_strdup_printf ("%04d", g_date_get_year (date));
-		parts[1] = g_strdup_printf ("%02d", g_date_get_month (date));
-		parts[2] = g_strdup_printf ("%02d", g_date_get_day (date));
-		break;
-	}
+	single_subfolder = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("single_subfolder_checkbutton")));
 
-	if (parts == NULL)
-		child = NULL;
-	else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("single_subfolder_checkbutton"))))
-		child = g_strjoinv ("-", parts);
-	else
-		child = g_strjoinv ("/", parts);
+	example_data = create_example_file_data ();
+	destination_example = gth_import_task_get_file_destination (example_data, destination, subfolder_type, single_subfolder);
 
-	destination_example = _g_file_append_path (destination, child);
 	uri = g_file_get_uri (destination_example);
 	example = g_strdup_printf (_("example: %s"), uri);
 	gtk_label_set_text (GTK_LABEL (GET_WIDGET ("example_label")), example);
@@ -515,8 +525,7 @@ update_destination (DialogData *data)
 	g_free (example);
 	g_free (uri);
 	g_object_unref (destination_example);
-	g_strfreev (parts);
-	g_date_free (date);
+	g_object_unref (example_data);
 	g_object_unref (destination);
 }
 
diff --git a/extensions/photo_importer/gth-import-task.c b/extensions/photo_importer/gth-import-task.c
index 6758477..7ab0fd0 100644
--- a/extensions/photo_importer/gth-import-task.c
+++ b/extensions/photo_importer/gth-import-task.c
@@ -25,7 +25,19 @@
 
 
 struct _GthImportTaskPrivate {
-	GCancellable *cancellable;
+	GthBrowser       *browser;
+	GList            *files;
+	GFile            *destination;
+	GthSubfolderType  subfolder_type;
+	gboolean          single_subfolder;
+	char             *tags;
+	gboolean          delete_imported;
+	GCancellable     *cancellable;
+
+	gsize             tot_size;
+	gsize             copied_size;
+	gsize             current_file_size;
+	GList            *current;
 };
 
 
@@ -39,23 +51,142 @@ gth_import_task_finalize (GObject *object)
 
 	self = GTH_IMPORT_TASK (object);
 
+	_g_object_list_unref (self->priv->files);
+	g_object_unref (self->priv->destination);
+	g_free (self->priv->tags);
 	g_object_unref (self->priv->cancellable);
+	g_object_unref (self->priv->browser);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 
+static void import_current_file (GthImportTask *self);
+
+
 static void
-gth_import_task_exec (GthTask *task)
+copy_ready_cb (GError   *error,
+	       gpointer  user_data)
 {
-	/* FIXME */
+	GthImportTask *self = user_data;
+	GthFileData   *file_data;
+
+	if (error != NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	/*
+	 * adjust orientation
+	 * add tags
+	 */
+
+	file_data = self->priv->current->data;
+	self->priv->copied_size += self->priv->current_file_size;
+	self->priv->current = self->priv->current->next;
+	import_current_file (self);
 }
 
 
 static void
-gth_import_task_cancel (GthTask *task)
+copy_progress_cb (GObject    *object,
+		  const char *description,
+		  const char *details,
+		  gboolean    pulse,
+		  double      fraction,
+		  gpointer    user_data)
 {
-	g_cancellable_cancel (GTH_IMPORT_TASK (task)->priv->cancellable);
+	GthImportTask *self = user_data;
+
+	fraction = (((double) self->priv->current_file_size * fraction) + self->priv->copied_size) / self->priv->tot_size;
+	gth_task_progress (GTH_TASK (self), description, details, pulse, fraction);
+}
+
+
+static void
+file_info_ready_cb (GList    *files,
+		    GError   *error,
+		    gpointer  user_data)
+{
+	GthImportTask *self = user_data;
+	GthFileData   *file_data;
+	GFile         *destination;
+	GFile         *destination_file;
+
+	if (error != NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	file_data = self->priv->current->data;
+	self->priv->current_file_size = g_file_info_get_size (file_data->info);
+
+	destination = gth_import_task_get_file_destination (file_data,
+							    self->priv->destination,
+							    self->priv->subfolder_type,
+							    self->priv->single_subfolder);
+	if (! g_file_make_directory_with_parents (destination, self->priv->cancellable, &error)) {
+		if (! g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+			gth_task_completed (GTH_TASK (self), error);
+			return;
+		}
+	}
+
+	destination_file = _g_file_get_destination (file_data->file, NULL, destination);
+	_g_copy_file_async (file_data,
+			    destination_file,
+			    FALSE /*self->priv->delete_imported*/,
+			    G_FILE_COPY_ALL_METADATA | G_FILE_COPY_TARGET_DEFAULT_PERMS,
+			    G_PRIORITY_DEFAULT,
+			    self->priv->cancellable,
+			    copy_progress_cb,
+			    self,
+			    copy_ready_cb,
+			    self);
+
+	g_object_unref (destination_file);
+	g_object_unref (destination);
+}
+
+
+static void
+import_current_file (GthImportTask *self)
+{
+	GthFileData *file_data;
+	GList       *list;
+
+	if (self->priv->current == NULL) {
+		gth_browser_go_to (self->priv->browser, self->priv->destination);
+		gth_task_completed (GTH_TASK (self), NULL);
+		return;
+	}
+
+	file_data = self->priv->current->data;
+	list = g_list_prepend (NULL, file_data);
+	_g_query_metadata_async (list,
+				 "Exif::Image::DateTime",
+				 self->priv->cancellable,
+				 file_info_ready_cb,
+				 self);
+
+	g_list_free (list);
+}
+
+
+static void
+gth_import_task_exec (GthTask *base)
+{
+	GthImportTask *self = (GthImportTask *) base;
+
+	self->priv->current = self->priv->files;
+	import_current_file (self);
+}
+
+
+static void
+gth_import_task_cancel (GthTask *base)
+{
+	g_cancellable_cancel (GTH_IMPORT_TASK (base)->priv->cancellable);
 }
 
 
@@ -114,7 +245,9 @@ gth_import_task_get_type (void)
 
 
 GthTask *
-gth_import_task_new (GFile            *destination,
+gth_import_task_new (GthBrowser       *browser,
+		     GList            *files,
+		     GFile            *destination,
 		     GthSubfolderType  subfolder_type,
 		     gboolean          single_subfolder,
 		     const char       *tags,
@@ -123,6 +256,72 @@ gth_import_task_new (GFile            *destination,
 	GthImportTask *self;
 
 	self = GTH_IMPORT_TASK (g_object_new (GTH_TYPE_IMPORT_TASK, NULL));
+	self->priv->browser = g_object_ref (browser);
+	self->priv->files = _g_object_list_ref (files);
+	self->priv->destination = g_file_dup (destination);
+	self->priv->subfolder_type = subfolder_type;
+	self->priv->single_subfolder = single_subfolder;
+	self->priv->tags = g_strdup (tags);
+	self->priv->delete_imported = delete_imported;
 
 	return (GthTask *) self;
 }
+
+
+GFile *
+gth_import_task_get_file_destination (GthFileData      *file_data,
+				      GFile            *destination,
+				      GthSubfolderType  subfolder_type,
+				      gboolean          single_subfolder)
+{
+	GFile     *file_destination;
+	GTimeVal   timeval;
+	GDate     *date;
+	char     **parts = NULL;
+	char      *child;
+
+	if (subfolder_type == GTH_SUBFOLDER_TYPE_CURRENT_DATE) {
+		g_get_current_time (&timeval);
+	}
+	else if (subfolder_type == GTH_SUBFOLDER_TYPE_FILE_DATE) {
+		GthMetadata *metadata;
+
+		metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "Embedded::Image::DateTime");
+		if (metadata != NULL)
+			_g_time_val_from_exif_date (gth_metadata_get_raw (metadata), &timeval);
+		else
+			subfolder_type = GTH_SUBFOLDER_TYPE_NONE;
+	}
+
+	date = g_date_new ();
+
+	switch (subfolder_type) {
+	case GTH_SUBFOLDER_TYPE_FILE_DATE:
+	case GTH_SUBFOLDER_TYPE_CURRENT_DATE:
+		g_date_set_time_val (date, &timeval);
+
+		parts = g_new0 (char *, 4);
+		parts[0] = g_strdup_printf ("%04d", g_date_get_year (date));
+		parts[1] = g_strdup_printf ("%02d", g_date_get_month (date));
+		parts[2] = g_strdup_printf ("%02d", g_date_get_day (date));
+		break;
+
+	case GTH_SUBFOLDER_TYPE_NONE:
+		break;
+	}
+
+	if (parts == NULL)
+		child = NULL;
+	else if (single_subfolder)
+		child = g_strjoinv ("-", parts);
+	else
+		child = g_strjoinv ("/", parts);
+
+	file_destination = _g_file_append_path (destination, child);
+
+	g_free (child);
+	g_strfreev (parts);
+	g_date_free (date);
+
+	return file_destination;
+}
diff --git a/extensions/photo_importer/gth-import-task.h b/extensions/photo_importer/gth-import-task.h
index 66b49d8..4318cb8 100644
--- a/extensions/photo_importer/gth-import-task.h
+++ b/extensions/photo_importer/gth-import-task.h
@@ -49,12 +49,18 @@ struct _GthImportTaskClass {
 	GthTaskClass __parent;
 };
 
-GType         gth_import_task_get_type     (void);
-GthTask *     gth_import_task_new          (GFile            *destination,
-					    GthSubfolderType  subfolder_type,
-					    gboolean          single_subfolder,
-					    const char       *tags,
-					    gboolean          delete_imported);
+GType       gth_import_task_get_type               (void);
+GthTask *   gth_import_task_new                    (GthBrowser       *browser,
+						    GList            *files, /* GthFileData list */
+						    GFile            *destination,
+						    GthSubfolderType  subfolder_type,
+						    gboolean          single_subfolder,
+						    const char       *tags,
+						    gboolean          delete_imported);
+GFile *     gth_import_task_get_file_destination   (GthFileData      *file_data,
+					            GFile            *destination,
+					            GthSubfolderType  subfolder_type,
+					            gboolean          single_subfolder);
 
 G_END_DECLS
 
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 1485e17..f940f4f 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -1461,41 +1461,6 @@ copy_data__copy_current_file_ready_cb (GError   *error,
 }
 
 
-static GFile *
-get_destination_file (GFile *source,
-		      GFile *source_base,
-		      GFile *destination_folder)
-{
-	char       *source_uri;
-	const char *source_suffix;
-	char       *destination_folder_uri;
-	char       *destination_uri;
-	GFile      *destination;
-
-	source_uri = g_file_get_uri (source);
-	if (source_base != NULL) {
-		char *source_base_uri;
-
-		source_base_uri = g_file_get_uri (source_base);
-		source_suffix = source_uri + strlen (source_base_uri);
-
-		g_free (source_base_uri);
-	}
-	else
-		source_suffix = _g_uri_get_basename (source_uri);
-
-	destination_folder_uri = g_file_get_uri (destination_folder);
-	destination_uri = g_strconcat (destination_folder_uri, "/", source_suffix, NULL);
-	destination = g_file_new_for_uri (destination_uri);
-
-	g_free (destination_uri);
-	g_free (destination_folder_uri);
-	g_free (source_uri);
-
-	return destination;
-}
-
-
 static void
 copy_data__copy_current_file (CopyData *copy_data)
 {
@@ -1513,7 +1478,7 @@ copy_data__copy_current_file (CopyData *copy_data)
 		_g_object_unref (copy_data->source_base);
 		copy_data->source_base = g_file_get_parent (source->file);
 	}
-	destination = get_destination_file (source->file, copy_data->source_base, copy_data->destination);
+	destination = _g_file_get_destination (source->file, copy_data->source_base, copy_data->destination);
 
 	flags = copy_data->flags;
 	if ((flags & G_FILE_COPY_ALL_METADATA) && (g_hash_table_lookup (copy_data->source_hash, source->file) == NULL))
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index fcdd88e..236c2a1 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -1617,6 +1617,41 @@ _g_file_get_standard_type (GFile *file)
 
 
 GFile *
+_g_file_get_destination (GFile *source,
+		         GFile *source_base,
+		         GFile *destination_folder)
+{
+	char       *source_uri;
+	const char *source_suffix;
+	char       *destination_folder_uri;
+	char       *destination_uri;
+	GFile      *destination;
+
+	source_uri = g_file_get_uri (source);
+	if (source_base != NULL) {
+		char *source_base_uri;
+
+		source_base_uri = g_file_get_uri (source_base);
+		source_suffix = source_uri + strlen (source_base_uri);
+
+		g_free (source_base_uri);
+	}
+	else
+		source_suffix = _g_uri_get_basename (source_uri);
+
+	destination_folder_uri = g_file_get_uri (destination_folder);
+	destination_uri = g_strconcat (destination_folder_uri, "/", source_suffix, NULL);
+	destination = g_file_new_for_uri (destination_uri);
+
+	g_free (destination_uri);
+	g_free (destination_folder_uri);
+	g_free (source_uri);
+
+	return destination;
+}
+
+
+GFile *
 _g_file_get_child (GFile *file,
 		   ...)
 {
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 30cb271..d5caccd 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -216,6 +216,9 @@ gboolean        _g_file_equal                    (GFile      *file1,
 						  GFile      *file2);
 char *          _g_file_get_display_name         (GFile      *file);
 GFileType 	_g_file_get_standard_type        (GFile      *file);
+GFile *         _g_file_get_destination          (GFile      *source,
+						  GFile      *source_base,
+						  GFile      *destination_folder);
 GFile *         _g_file_get_child                (GFile      *file,
 						  ...);
 GIcon *         _g_file_get_icon                 (GFile      *file);



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