[gthumb] [importer] do not overwrite files with the same name



commit 23f7209fd2d816053a884dea178fd24c145091b1
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Jul 25 16:37:25 2010 +0200

    [importer] do not overwrite files with the same name
    
    [bug #624932]

 extensions/file_manager/gth-duplicate-task.c |   64 +++++-------------
 extensions/importer/gth-import-task.c        |   15 ++++
 gthumb/gio-utils.c                           |    2 +-
 gthumb/glib-utils.c                          |   90 ++++++++++++++++++-------
 gthumb/glib-utils.h                          |    1 +
 5 files changed, 100 insertions(+), 72 deletions(-)
---
diff --git a/extensions/file_manager/gth-duplicate-task.c b/extensions/file_manager/gth-duplicate-task.c
index 1d13c82..0b98595 100644
--- a/extensions/file_manager/gth-duplicate-task.c
+++ b/extensions/file_manager/gth-duplicate-task.c
@@ -25,10 +25,9 @@
 
 
 struct _GthDuplicateTaskPrivate {
-	GList                *file_list;
-	GList                *current;
-	int                   attempt;
-	GthOverwriteResponse  default_response;
+	GList *file_list;
+	GList *current;
+	GFile *destination;
 };
 
 
@@ -43,38 +42,12 @@ gth_duplicate_task_finalize (GObject *object)
 	self = GTH_DUPLICATE_TASK (object);
 
 	_g_object_list_unref (self->priv->file_list);
+	_g_object_unref (self->priv->destination);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 
-static GFile *
-get_destination (GthFileData *file_data,
-	         int          n)
-{
-	char       *uri;
-	char       *uri_no_ext;
-	const char *ext;
-	char       *new_uri;
-	GFile      *new_file;
-
-	uri = g_file_get_uri (file_data->file);
-	uri_no_ext = _g_uri_remove_extension (uri);
-	ext = _g_uri_get_file_extension (uri);
-	new_uri = g_strdup_printf ("%s%%20(%d)%s",
-				   uri_no_ext,
-				   n + 1,
-				   (ext == NULL) ? "" : ext);
-	new_file = g_file_new_for_uri (new_uri);
-
-	g_free (new_uri);
-	g_free (uri_no_ext);
-	g_free (uri);
-
-	return new_file;
-}
-
-
 static void
 copy_progress_cb (GObject    *object,
 		  const char *description,
@@ -112,19 +85,15 @@ copy_ready_cb (GthOverwriteResponse  response,
 	if (error != NULL) {
 		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
 			g_clear_error (&error);
-
-			self->priv->attempt++;
 			duplicate_current_file (self);
-			return;
 		}
-
-		gth_task_completed (GTH_TASK (self), error);
+		else
+			gth_task_completed (GTH_TASK (self), error);
 		return;
 	}
 
-	self->priv->default_response = response;
 	self->priv->current = self->priv->current->next;
-	self->priv->attempt = 1;
+	_g_clear_object (&self->priv->destination);
 	duplicate_current_file (self);
 }
 
@@ -133,7 +102,6 @@ static void
 duplicate_current_file (GthDuplicateTask *self)
 {
 	GthFileData *file_data;
-	GFile       *destination;
 
 	if (self->priv->current == NULL) {
 		gth_task_completed (GTH_TASK (self), NULL);
@@ -141,13 +109,20 @@ duplicate_current_file (GthDuplicateTask *self)
 	}
 
 	file_data = self->priv->current->data;
-	destination = get_destination (file_data, self->priv->attempt);
+	if (self->priv->destination == NULL) {
+		self->priv->destination = _g_file_get_duplicated (file_data->file);
+	}
+	else {
+		GFile *tmp = self->priv->destination;
+		self->priv->destination = _g_file_get_duplicated (tmp);
+		g_object_unref (tmp);
+	}
 
 	_g_copy_file_async (file_data,
-			    destination,
+			    self->priv->destination,
 			    FALSE,
 			    G_FILE_COPY_ALL_METADATA,
-			    self->priv->default_response,
+			    GTH_OVERWRITE_RESPONSE_ALWAYS_NO,
 			    G_PRIORITY_DEFAULT,
 			    gth_task_get_cancellable (GTH_TASK (self)),
 			    copy_progress_cb,
@@ -156,8 +131,6 @@ duplicate_current_file (GthDuplicateTask *self)
 			    self,
 			    copy_ready_cb,
 			    self);
-
-	g_object_unref (destination);
 }
 
 
@@ -171,7 +144,6 @@ gth_duplicate_task_exec (GthTask *task)
 	self = GTH_DUPLICATE_TASK (task);
 
 	self->priv->current = self->priv->file_list;
-	self->priv->attempt = 1;
 	duplicate_current_file (self);
 }
 
@@ -197,7 +169,7 @@ static void
 gth_duplicate_task_init (GthDuplicateTask *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_DUPLICATE_TASK, GthDuplicateTaskPrivate);
-	self->priv->default_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
+	self->priv->destination = NULL;
 }
 
 
diff --git a/extensions/importer/gth-import-task.c b/extensions/importer/gth-import-task.c
index 5775c92..3871988 100644
--- a/extensions/importer/gth-import-task.c
+++ b/extensions/importer/gth-import-task.c
@@ -36,6 +36,7 @@ struct _GthImportTaskPrivate {
 	GthBrowser          *browser;
 	GList               *files;
 	GFile               *destination;
+	GHashTable          *destinations;
 	GthSubfolderType     subfolder_type;
 	GthSubfolderFormat   subfolder_format;
 	gboolean             single_subfolder;
@@ -72,6 +73,7 @@ gth_import_task_finalize (GObject *object)
 	if (ImportPhotos)
 		gtk_window_present (GTK_WINDOW (self->priv->browser));
 
+	g_object_unref (self->priv->destinations);
 	_g_object_list_unref (self->priv->files);
 	g_object_unref (self->priv->destination);
 	_g_object_unref (self->priv->destination_file);
@@ -317,6 +319,15 @@ file_buffer_ready_cb (void     **buffer,
 	}
 
 	destination_file = _g_file_get_destination (file_data->file, NULL, destination);
+
+	/* avoid to overwrite an already imported file */
+	while (g_hash_table_lookup (self->priv->destinations, destination_file) != NULL) {
+		GFile *tmp = destination_file;
+		destination_file = _g_file_get_duplicated (tmp);
+		g_object_unref (tmp);
+	}
+	g_hash_table_insert (self->priv->destinations, g_object_ref (destination_file), GINT_TO_POINTER (1));
+
 	if (self->priv->overwrite_files || ! g_file_query_exists (destination_file, NULL)) {
 		_g_object_unref (self->priv->destination_file);
 		self->priv->destination_file = gth_file_data_new (destination_file, file_data->info);
@@ -493,6 +504,10 @@ gth_import_task_init (GthImportTask *self)
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMPORT_TASK, GthImportTaskPrivate);
 	self->priv->catalogs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 	self->priv->delete_not_supported = FALSE;
+	self->priv->destinations = g_hash_table_new_full (g_file_hash,
+							  (GEqualFunc) g_file_equal,
+							  g_object_unref,
+							  NULL);
 }
 
 
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 1536665..5c4afd0 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -1298,7 +1298,7 @@ copy_file_ready_cb (GObject      *source_object,
 				gtk_widget_show (dialog);
 			}
 			else {
-				copy_file_data->ready_callback (copy_file_data->default_response, NULL, copy_file_data->user_data);
+				copy_file_data->ready_callback (copy_file_data->default_response, error, copy_file_data->user_data);
 				copy_file_data_free (copy_file_data);
 			}
 			return;
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index 18a0689..11ad124 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -1618,25 +1618,26 @@ _g_uri_get_basename (const char *uri)
 const char *
 _g_uri_get_file_extension (const char *uri)
 {
-	int         len;
-	int         p;
-	const char *ptr = uri;
+	char *p;
 
 	if (uri == NULL)
 		return NULL;
 
-	len = strlen (uri);
-	if (len <= 1)
+	p = strrchr (uri, '.');
+	if (p == NULL)
 		return NULL;
 
-	p = len - 1;
-	while ((p >= 0) && (ptr[p] != '.'))
-		p--;
+	if (p != uri) {
+		char *p2;
 
-	if (p < 0)
-		return NULL;
+		p2 = p - 1;
+		while ((*p2 != '.') && (p2 != uri))
+			p2--;
+		if (strncmp (p2, ".tar.", 5) == 0)
+			p = p2;
+	}
 
-	return uri + p;
+	return p;
 }
 
 
@@ -1744,25 +1745,16 @@ _g_uri_get_parent (const char *uri)
 char *
 _g_uri_remove_extension (const char *uri)
 {
-	int   len;
-	int   p;
-	char *new_path;
+	const char *ext;
 
 	if (uri == NULL)
 		return NULL;
 
-	len = strlen (uri);
-	if (len == 1)
+	ext = _g_uri_get_file_extension (uri);
+	if (ext == NULL)
 		return g_strdup (uri);
-
-	p = len - 1;
-	while ((p > 0) && (uri[p] != '.'))
-		p--;
-	if (p == 0)
-		p = len;
-	new_path = g_strndup (uri, (guint) p);
-
-	return new_path;
+	else
+		return g_strndup (uri, strlen (uri) - strlen (ext));
 }
 
 
@@ -2045,6 +2037,54 @@ _g_file_get_destination (GFile *source,
 
 
 GFile *
+_g_file_get_duplicated (GFile *file)
+{
+	GString    *new_uri;
+	char       *uri;
+	char       *uri_noext;
+	GRegex     *regex;
+	GMatchInfo *match_info;
+	GFile      *duplicated;
+
+	new_uri = g_string_new ("");
+	uri = g_file_get_uri (file);
+	uri_noext = _g_uri_remove_extension (uri);
+
+	regex = g_regex_new ("^(.*)%20\\(([0-9]+)\\)$", 0, 0, NULL);
+	g_regex_match (regex, uri_noext, 0, &match_info);
+	if (g_match_info_matches (match_info)) {
+		char    *word;
+		guint64  n;
+
+		word = g_match_info_fetch (match_info, 1);
+		g_string_append (new_uri, word);
+		g_free (word);
+
+		word = g_match_info_fetch (match_info, 2);
+		n = g_ascii_strtoull (word, NULL, 10);
+		g_string_append_printf (new_uri, "%%20(%" G_GUINT64_FORMAT ")", n + 1);
+
+		g_free (word);
+	}
+	else {
+		g_string_append (new_uri, uri_noext);
+		g_string_append (new_uri, "%20(2)");
+	}
+
+	g_string_append (new_uri, _g_uri_get_file_extension (uri));
+	duplicated = g_file_new_for_uri (new_uri->str);
+
+	g_match_info_free (match_info);
+	g_regex_unref (regex);
+	g_free (uri_noext);
+	g_free (uri);
+	g_string_free (new_uri, TRUE);
+
+	return duplicated;
+}
+
+
+GFile *
 _g_file_get_child (GFile *file,
 		   ...)
 {
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 680525f..e86ff1a 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -244,6 +244,7 @@ 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_duplicated           (GFile      *file);
 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]