[gthumb] importer: check if there is enough free space before importing the files



commit e8343e867b02edb374415ea960f4d94ae8bb3347
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Jul 5 18:31:42 2011 +0200

    importer: check if there is enough free space before importing the files

 extensions/importer/gth-import-task.c            |   69 +++++++++++++++++++++-
 extensions/importer/gth-import-task.h            |   29 +++++----
 extensions/photo_importer/dlg-photo-importer.c   |   53 +++++++++++++---
 extensions/picasaweb/dlg-import-from-picasaweb.c |   12 ++++
 4 files changed, 138 insertions(+), 25 deletions(-)
---
diff --git a/extensions/importer/gth-import-task.c b/extensions/importer/gth-import-task.c
index bcacf3c..174fd61 100644
--- a/extensions/importer/gth-import-task.c
+++ b/extensions/importer/gth-import-task.c
@@ -479,6 +479,8 @@ write_file_to_destination (GthImportTask *self,
 				   FALSE,
 				   (double) (self->priv->copied_size + ((double) self->priv->current_file_size / 3.0 * 2.0)) / self->priv->tot_size);
 
+		self->priv->buffer = NULL; /* the buffer will be deallocated in g_write_file_async */
+
 		g_write_file_async (self->priv->destination_file->file,
 				    buffer,
 				    count,
@@ -487,8 +489,6 @@ write_file_to_destination (GthImportTask *self,
 				    gth_task_get_cancellable (GTH_TASK (self)),
 				    write_buffer_ready_cb,
 				    self);
-
-		self->priv->buffer = NULL; /* the buffer will be deallocated in g_write_file_async */
 	}
 	else
 		g_file_copy_async (file_data->file,
@@ -820,3 +820,68 @@ gth_import_task_new (GthBrowser         *browser,
 
 	return (GthTask *) self;
 }
+
+
+gboolean
+gth_import_task_check_free_space (GFile   *destination,
+				  GList   *files, /* GthFileData list */
+				  GError **error)
+{
+	GFileInfo *info;
+	guint64    free_space;
+	goffset    total_file_size;
+	goffset    max_file_size;
+	goffset    min_free_space;
+	GList     *scan;
+
+	if (files == NULL) {
+		if (error != NULL)
+			*error = g_error_new (G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "%s", _("No file specified."));
+		return FALSE;
+	}
+
+	info = g_file_query_filesystem_info (destination, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, error);
+	if (info == NULL)
+		return FALSE;
+
+	free_space = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+
+	total_file_size = 0;
+	max_file_size = 0;
+	for (scan = files; scan; scan = scan->next) {
+		GthFileData *file_data = scan->data;
+		goffset      file_size = g_file_info_get_size (file_data->info);
+
+		total_file_size += file_size;
+		if (file_size > max_file_size)
+			max_file_size = file_size;
+	}
+
+	min_free_space = total_file_size +
+			 max_file_size +               /* image rotation can require a temporary file */
+			 (total_file_size * 5 / 100);  /* 5% of FS fragmentation */
+
+	if ((free_space < min_free_space) && (error != NULL)) {
+		char *destination_name;
+		char *min_free_space_s;
+		char *free_space_s;
+
+		destination_name = g_file_get_parse_name (destination);
+		min_free_space_s = g_format_size_for_display (min_free_space);
+		free_space_s = g_format_size_for_display (free_space);
+
+		*error = g_error_new (G_IO_ERROR,
+				      G_IO_ERROR_NO_SPACE,
+				      /* Translators: For example: Not enough free space in '/home/user/Images'.\n1.3 GB of space is required but only 300 MB is available. */
+				      _("Not enough free space in '%s'.\n%s of space is required but only %s is available."),
+				      destination_name,
+				      min_free_space_s,
+				      free_space_s);
+
+		g_free (free_space_s);
+		g_free (min_free_space_s);
+		g_free (destination_name);
+	}
+
+	return free_space >= min_free_space;
+}
diff --git a/extensions/importer/gth-import-task.h b/extensions/importer/gth-import-task.h
index 9b583af..feec59c 100644
--- a/extensions/importer/gth-import-task.h
+++ b/extensions/importer/gth-import-task.h
@@ -48,19 +48,22 @@ struct _GthImportTaskClass {
 	GthTaskClass __parent;
 };
 
-GType       gth_import_task_get_type   (void);
-GthTask *   gth_import_task_new        (GthBrowser         *browser,
-					GList              *files, /* GthFileData list */
-					GFile              *destination,
-					GthSubfolderType    subfolder_type,
-					GthSubfolderFormat  subfolder_format,
-					gboolean            single_subfolder,
-					const char         *custom_format,
-					const char         *event_name,
-					char              **tags,
-					gboolean            delete_imported,
-					gboolean            overwrite_files,
-					gboolean            adjust_orientation);
+GType       gth_import_task_get_type         (void);
+GthTask *   gth_import_task_new              (GthBrowser         *browser,
+					      GList              *files, /* GthFileData list */
+					      GFile              *destination,
+					      GthSubfolderType    subfolder_type,
+					      GthSubfolderFormat  subfolder_format,
+					      gboolean            single_subfolder,
+					      const char         *custom_format,
+					      const char         *event_name,
+					      char              **tags,
+					      gboolean            delete_imported,
+					      gboolean            overwrite_files,
+					      gboolean            adjust_orientation);
+gboolean    gth_import_task_check_free_space (GFile              *destination,
+					      GList              *files, /* GthFileData list */
+					      GError            **error);
 
 G_END_DECLS
 
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 01eeafe..c186a8b 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -61,6 +61,26 @@ typedef struct {
 } DialogData;
 
 
+static GList *
+get_selected_file_list (DialogData *data)
+{
+	GList     *file_list = NULL;
+	GtkWidget *file_view;
+	GList     *items;
+
+	file_view = gth_file_list_get_view (GTH_FILE_LIST (data->file_list));
+	items = gth_file_selection_get_selected (GTH_FILE_SELECTION (file_view));
+	if (items != NULL)
+		file_list = gth_file_list_get_files (GTH_FILE_LIST (data->file_list), items);
+	else
+		file_list = gth_file_store_get_visibles (GTH_FILE_STORE (gth_file_view_get_model (GTH_FILE_VIEW (file_view))));
+
+	_gtk_tree_path_list_free (items);
+
+	return file_list;
+}
+
+
 static void
 destroy_dialog (gpointer user_data)
 {
@@ -78,8 +98,6 @@ destroy_dialog (gpointer user_data)
 		GthSubfolderType    subfolder_type;
 		GthSubfolderFormat  subfolder_format;
 		char               *custom_format;
-		GtkWidget          *file_view;
-		GList              *items;
 		GList              *file_list;
 
 		destination = gth_import_preferences_get_destination ();
@@ -88,13 +106,7 @@ destroy_dialog (gpointer user_data)
 		subfolder_format = eel_gconf_get_enum (PREF_IMPORT_SUBFOLDER_FORMAT, GTH_TYPE_SUBFOLDER_FORMAT, GTH_SUBFOLDER_FORMAT_YYYYMMDD);
 		custom_format = eel_gconf_get_string (PREF_IMPORT_SUBFOLDER_CUSTOM_FORMAT, "");
 
-		file_view = gth_file_list_get_view (GTH_FILE_LIST (data->file_list));
-		items = gth_file_selection_get_selected (GTH_FILE_SELECTION (file_view));
-		if (items != NULL)
-			file_list = gth_file_list_get_files (GTH_FILE_LIST (data->file_list), items);
-		else
-			file_list = gth_file_store_get_visibles (GTH_FILE_STORE (gth_file_view_get_model (GTH_FILE_VIEW (file_view))));
-
+		file_list = get_selected_file_list (data);
 		if (file_list != NULL) {
 			char    **tags;
 			GthTask  *task;
@@ -119,7 +131,6 @@ destroy_dialog (gpointer user_data)
 		}
 
 		_g_object_list_unref (file_list);
-		_gtk_tree_path_list_free (items);
 		g_free (custom_format);
 		_g_object_unref (destination);
 	}
@@ -191,6 +202,28 @@ static void
 ok_clicked_cb (GtkWidget  *widget,
 	       DialogData *data)
 {
+	GList    *file_list;
+	GFile    *destination;
+	GError   *error = NULL;
+	gboolean  import;
+
+	file_list = get_selected_file_list (data);
+	destination = gth_import_preferences_get_destination ();
+	if (! gth_import_task_check_free_space (destination, file_list, &error)) {
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog),
+						    _("Could not import the files"),
+						    &error);
+		import = FALSE;
+	}
+	else
+		import = TRUE;
+
+	_g_object_unref (destination);
+	_g_object_list_unref (file_list);
+
+	if (! import)
+		return;
+
 	data->import = TRUE;
 	close_dialog (NULL, data);
 }
diff --git a/extensions/picasaweb/dlg-import-from-picasaweb.c b/extensions/picasaweb/dlg-import-from-picasaweb.c
index d9f94f8..410a37f 100644
--- a/extensions/picasaweb/dlg-import-from-picasaweb.c
+++ b/extensions/picasaweb/dlg-import-from-picasaweb.c
@@ -157,6 +157,7 @@ import_dialog_response_cb (GtkDialog *dialog,
 			file_list = get_files_to_download (data);
 			if (file_list != NULL) {
 				GFile               *destination;
+				GError              *error = NULL;
 				gboolean             single_subfolder;
 				GthSubfolderType     subfolder_type;
 				GthSubfolderFormat   subfolder_format;
@@ -166,6 +167,17 @@ import_dialog_response_cb (GtkDialog *dialog,
 				GthTask             *task;
 
 				destination = gth_import_preferences_get_destination ();
+
+				if (! gth_import_task_check_free_space (destination, file_list, &error)) {
+					_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog),
+									    _("Could not import the files"),
+									    &error);
+					_g_object_unref (destination);
+					_g_object_list_unref (file_list);
+					g_object_unref (album);
+					return;
+				}
+
 				subfolder_type = eel_gconf_get_enum (PREF_IMPORT_SUBFOLDER_TYPE, GTH_TYPE_SUBFOLDER_TYPE, GTH_SUBFOLDER_TYPE_FILE_DATE);
 				subfolder_format = eel_gconf_get_enum (PREF_IMPORT_SUBFOLDER_FORMAT, GTH_TYPE_SUBFOLDER_FORMAT, GTH_SUBFOLDER_FORMAT_YYYYMMDD);
 				single_subfolder = eel_gconf_get_boolean (PREF_IMPORT_SUBFOLDER_SINGLE, FALSE);



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