[gthumb/ext] [import dialog] fixed file loading cancellation



commit b1986ff7a4416f3c13a5952a03aeb560e91a99e1
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Aug 10 23:20:48 2009 +0200

    [import dialog] fixed file loading cancellation

 extensions/photo_importer/dlg-photo-importer.c |   40 +++++++++++++++---------
 extensions/search/gth-search-task.c            |    2 +-
 gthumb/glib-utils.c                            |   25 +++++++++++++++
 gthumb/glib-utils.h                            |    3 ++
 gthumb/gth-metadata-provider.c                 |   36 +++++++++++++++++++--
 gthumb/gth-task.c                              |    2 +-
 6 files changed, 88 insertions(+), 20 deletions(-)
---
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 209d59e..e2deb6c 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -42,6 +42,7 @@ typedef struct {
 	GtkWidget     *dialog;
 	GtkBuilder    *builder;
 	GFile         *source;
+	GFile         *last_source;
 	GtkListStore  *source_store;
 	GtkWidget     *source_list;
 	GtkWidget     *subfolder_type_list;
@@ -81,6 +82,7 @@ destroy_dialog (gpointer user_data)
 	_g_object_unref (data->source);
 	_g_object_unref (data->cancellable);
 	_g_object_list_unref (data->files);
+	_g_object_unref (data->last_source);
 	g_free (data);
 }
 
@@ -100,11 +102,10 @@ static void
 cancel (DialogData *data,
 	DoneFunc    done_func)
 {
-	data->done_func = done_func;
-
 	if (data->cancelling)
 		return;
 
+	data->done_func = done_func;
 	data->cancelling = TRUE;
 	if (data->loading_list)
 		g_cancellable_cancel (data->cancellable);
@@ -150,18 +151,18 @@ list_ready_cb (GList    *files,
 	data->loading_list = FALSE;
 
 	if (data->cancelling) {
-		g_print ("...CANCELED\n");
 		gth_file_list_cancel (GTH_FILE_LIST (data->file_list), cancel_done, data);
 		return;
 	}
 
-	g_print ("...DONE\n");
-
 	if (error != NULL) {
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not load the folder"), &error);
 		return;
 	}
 
+	_g_object_unref (data->last_source);
+	data->last_source = g_file_dup (data->source);
+
 	data->files = _g_object_list_ref (files);
 	gth_file_list_set_files (GTH_FILE_LIST (data->file_list), data->files);
 }
@@ -173,11 +174,15 @@ list_source_files (gpointer user_data)
 	DialogData *data = user_data;
 	GList      *list;
 
-	g_print ("LOADING...\n");
-
+	_g_object_clear (&data->last_source);
 	_g_object_list_unref (data->files);
 	data->files = NULL;
 
+	if (data->source == NULL) {
+		gth_file_list_clear (GTH_FILE_LIST (data->file_list), _("(Empty)"));
+		return;
+	}
+
 	gth_file_list_clear (GTH_FILE_LIST (data->file_list), _("Getting folder listing..."));
 
 	data->loading_list = TRUE;
@@ -197,6 +202,8 @@ list_source_files (gpointer user_data)
 static void
 load_file_list (DialogData *data)
 {
+	if (_g_file_equal (data->source, data->last_source))
+		return;
 	cancel (data, list_source_files);
 }
 
@@ -210,6 +217,8 @@ source_list_changed_cb (GtkWidget  *widget,
 	GMount      *mount;
 
 	if (! gtk_combo_box_get_active_iter (GTK_COMBO_BOX (data->source_list), &iter)) {
+		_g_object_clear (&data->source);
+		_g_object_clear (&data->last_source);
 		gth_file_list_clear (GTH_FILE_LIST (data->file_list), _("(Empty)"));
 		return;
 	}
@@ -219,6 +228,8 @@ source_list_changed_cb (GtkWidget  *widget,
 			    -1);
 
 	if (volume == NULL) {
+		_g_object_clear (&data->source);
+		_g_object_clear (&data->last_source);
 		gth_file_list_clear (GTH_FILE_LIST (data->file_list), _("Empty"));
 		return;
 	}
@@ -251,9 +262,9 @@ filter_checkbutton_toggled_cb (GtkToggleButton *togglebutton,
 static void
 update_source_list (DialogData *data)
 {
-	gboolean  source_available = FALSE;
-	GList    *mounts;
-	GList    *scan;
+	gboolean    source_available = FALSE;
+	GList       *mounts;
+	GList       *scan;
 
 	gtk_list_store_clear (data->source_store);
 
@@ -288,8 +299,8 @@ update_source_list (DialogData *data)
 						    -1);
 
 				if (g_file_equal (data->source, root)) {
-					gtk_combo_box_set_active_iter (GTK_COMBO_BOX (data->source_list), &iter);
 					source_available = TRUE;
+					gtk_combo_box_set_active_iter (GTK_COMBO_BOX (data->source_list), &iter);
 				}
 
 				g_free (name);
@@ -304,7 +315,7 @@ update_source_list (DialogData *data)
 	if (! source_available) {
 		_g_object_unref (data->source);
 		data->source = NULL;
-		source_list_changed_cb (NULL, data);
+		load_file_list (data);
 	}
 
 	_g_object_list_unref (mounts);
@@ -370,8 +381,6 @@ dlg_photo_importer (GthBrowser *browser,
 					"text", SOURCE_LIST_COLUMN_NAME,
 					NULL);
 
-	update_source_list (data);
-
 	data->subfolder_type_list = _gtk_combo_box_new_with_texts (_("No subfolder"),
 								   _("Day photo taken"),
 								   _("Month photo taken"),
@@ -437,5 +446,6 @@ dlg_photo_importer (GthBrowser *browser,
 	gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
 	gtk_widget_show (data->dialog);
 
-	load_file_list (data);
+	update_source_list (data);
+	/*load_file_list (data);*/
 }
diff --git a/extensions/search/gth-search-task.c b/extensions/search/gth-search-task.c
index 94277d3..a2f14f1 100644
--- a/extensions/search/gth-search-task.c
+++ b/extensions/search/gth-search-task.c
@@ -365,7 +365,7 @@ gth_search_task_cancel (GthTask *task)
 	if (GTH_SEARCH_TASK (task)->priv->io_operation)
 		g_cancellable_cancel (GTH_SEARCH_TASK (task)->priv->cancellable);
 	else
-		gth_task_completed (task, g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, NULL));
+		gth_task_completed (task, g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, ""));
 }
 
 
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index ae83f03..5dee212 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -53,6 +53,18 @@ _g_object_unref (gpointer object)
 }
 
 
+void
+_g_object_clear (gpointer  object)
+{
+	gpointer *object_p = (gpointer *) object;
+
+	if ((object_p != NULL) && (*object_p != NULL)) {
+		g_object_unref (*object_p);
+		*object_p = NULL;
+	}
+}
+
+
 GList *
 _g_object_list_ref (GList *list)
 {
@@ -1549,6 +1561,19 @@ _g_build_uri (const char *base, ...)
 /* GIO utils */
 
 
+gboolean
+_g_file_equal (GFile *file1,
+	       GFile *file2)
+{
+	if ((file1 == NULL) && (file2 == NULL))
+		return TRUE;
+	if ((file1 == NULL) || (file2 == NULL))
+		return FALSE;
+
+	return g_file_equal (file1, file2);
+}
+
+
 char *
 _g_file_get_display_name (GFile *file)
 {
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index fb4e29d..30cb271 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -77,6 +77,7 @@ G_BEGIN_DECLS
 
 gpointer      _g_object_ref                  (gpointer     object);
 void          _g_object_unref                (gpointer     object);
+void          _g_object_clear                (gpointer     object);
 GList *       _g_object_list_ref             (GList       *list);
 void          _g_object_list_unref           (GList       *list);
 GType         g_object_list_get_type         (void);
@@ -211,6 +212,8 @@ char *          _g_build_uri                     (const char *base,
 
 /* GIO utils */
 
+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_child                (GFile      *file,
diff --git a/gthumb/gth-metadata-provider.c b/gthumb/gth-metadata-provider.c
index d5c6873..f572d48 100644
--- a/gthumb/gth-metadata-provider.c
+++ b/gthumb/gth-metadata-provider.c
@@ -293,6 +293,7 @@ typedef struct {
 
 typedef struct {
 	GCancellable            *cancellable;
+	gulong                   cancel_signal;
 	InfoReadyCallback        ready_func;
 	gpointer                 user_data;
 	guint                    check_id;
@@ -314,6 +315,9 @@ query_metadata_done (QueryMetadataData *rmd)
 	g_free (rmtd->attributes);
 	_g_object_list_unref (rmtd->files);
 	g_free (rmtd);
+	if (rmd->cancel_signal != 0)
+		g_signal_handler_disconnect (rmd->cancellable, rmd->cancel_signal);
+	_g_object_unref (rmd->cancellable);
 	g_free (rmd);
 }
 
@@ -323,8 +327,9 @@ read_metadata_thread (gpointer data)
 {
 	QueryMetadataThreadData *rmtd = data;
 	GList                   *scan;
+	gboolean                 cancelled = FALSE;
 
-	for (scan = gth_main_get_all_metadata_providers (); scan; scan = scan->next) {
+	for (scan = gth_main_get_all_metadata_providers (); ! cancelled && scan; scan = scan->next) {
 		GthMetadataProvider *metadata_provider;
 
 		metadata_provider = g_object_new (G_OBJECT_TYPE (scan->data), NULL);
@@ -334,6 +339,14 @@ read_metadata_thread (gpointer data)
 
 			for (scan_files = rmtd->files; scan_files; scan_files = scan_files->next) {
 				GthFileData *file_data = scan_files->data;
+
+				g_mutex_lock (rmtd->mutex);
+				cancelled = rmtd->thread_done;
+				g_mutex_unlock (rmtd->mutex);
+
+				if (cancelled)
+					break;
+
 				gth_metadata_provider_read (metadata_provider, file_data, rmtd->attributes);
 			}
 		}
@@ -354,7 +367,7 @@ check_read_metadata_thread (gpointer data)
 {
 	QueryMetadataData       *rmd = data;
 	QueryMetadataThreadData *rmtd = rmd->rmtd;
-	gboolean                thread_done;
+	gboolean                 thread_done;
 
 	g_source_remove (rmd->check_id);
 	rmd->check_id = 0;
@@ -372,6 +385,20 @@ check_read_metadata_thread (gpointer data)
 }
 
 
+static void
+query_metadata_cancelled_cb (GCancellable *cancellable,
+                             gpointer      user_data)
+{
+	QueryMetadataData       *rmd = user_data;
+	QueryMetadataThreadData *rmtd = rmd->rmtd;
+
+	g_mutex_lock (rmtd->mutex);
+	rmtd->thread_done = TRUE;
+	rmtd->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
+	g_mutex_unlock (rmtd->mutex);
+}
+
+
 void
 _g_query_metadata_async (GList             *files,       /* GthFileData * list */
 			 const char        *attributes,
@@ -389,7 +416,10 @@ _g_query_metadata_async (GList             *files,       /* GthFileData * list *
 	rmtd->mutex = g_mutex_new ();
 
 	rmd = g_new0 (QueryMetadataData, 1);
-	rmd->cancellable = cancellable;
+	rmd->cancellable = _g_object_ref (cancellable);
+	if (rmd->cancellable != NULL)
+		rmd->cancel_signal = g_signal_connect (rmd->cancellable, "cancelled", G_CALLBACK (query_metadata_cancelled_cb), rmd);
+
 	rmd->ready_func = ready_func;
 	rmd->user_data = user_data;
 	rmd->rmtd = rmtd;
diff --git a/gthumb/gth-task.c b/gthumb/gth-task.c
index 1cd96ad..c3be98b 100644
--- a/gthumb/gth-task.c
+++ b/gthumb/gth-task.c
@@ -76,7 +76,7 @@ base_exec (GthTask *task)
 static void
 base_cancel (GthTask *task)
 {
-	gth_task_completed (task, g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, NULL));
+	gth_task_completed (task, g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, ""));
 }
 
 



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