[gthumb] rename_series: speed-up dialog appearance



commit aa6f0e18977f5310a3e9fe8be282174b6e31efe9
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Apr 2 16:59:12 2011 +0200

    rename_series: speed-up dialog appearance
    
    Load only the metadata required to rename and sort
    the files.
    
    [bug #645515]

 extensions/rename_series/actions.c           |   26 +---
 extensions/rename_series/dlg-rename-series.c |  138 +++++++++++++++-
 extensions/rename_series/dlg-rename-series.h |    2 +-
 gthumb/Makefile.am                           |    2 +
 gthumb/gth-file-data.c                       |   31 ++--
 gthumb/gth-file-data.h                       |    2 +
 gthumb/gth-load-file-data-task.c             |  220 ++++++++++++++++++++++++++
 gthumb/gth-load-file-data-task.h             |   58 +++++++
 gthumb/gth-main.c                            |    3 +
 9 files changed, 432 insertions(+), 50 deletions(-)
---
diff --git a/extensions/rename_series/actions.c b/extensions/rename_series/actions.c
index db11991..7a88bb6 100644
--- a/extensions/rename_series/actions.c
+++ b/extensions/rename_series/actions.c
@@ -26,24 +26,6 @@
 #include "dlg-rename-series.h"
 
 
-static void
-file_list_ready_cb (GList    *file_list,
-		    GError   *error,
-		    gpointer  user_data)
-{
-	GthBrowser *browser = user_data;
-
-	if (error != NULL) {
-		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Cannot read file information"), &error);
-		return;
-	}
-
-	dlg_rename_series (browser, file_list);
-
-	g_object_unref (browser);
-}
-
-
 void
 gth_browser_activate_action_edit_rename (GtkAction  *action,
 					 GthBrowser *browser)
@@ -55,13 +37,7 @@ gth_browser_activate_action_edit_rename (GtkAction  *action,
 	items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
 	file_data_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
 	file_list = gth_file_data_list_to_file_list (file_data_list);
-	g_object_ref (browser);
-	_g_query_all_metadata_async (file_list,
-				     GTH_LIST_DEFAULT,
-				     "*",
-				     NULL,
-				     file_list_ready_cb,
-				     browser);
+	dlg_rename_series (browser, file_list);
 
 	_g_object_list_unref (file_list);
 	_g_object_list_unref (file_data_list);
diff --git a/extensions/rename_series/dlg-rename-series.c b/extensions/rename_series/dlg-rename-series.c
index 6628197..57d4b78 100644
--- a/extensions/rename_series/dlg-rename-series.c
+++ b/extensions/rename_series/dlg-rename-series.c
@@ -58,9 +58,11 @@ enum {
 typedef struct {
 	GthBrowser    *browser;
 	GList         *file_list;
+	GList         *file_data_list;
 	GList         *new_file_list;
 	GList         *new_names_list;
 	gboolean       single_file;
+	gboolean       first_update;
 	GtkBuilder    *builder;
 	GtkWidget     *dialog;
 	GtkWidget     *list_view;
@@ -69,6 +71,7 @@ typedef struct {
 	GtkListStore  *list_store;
 	GtkListStore  *sort_model;
 	gboolean       help_visible;
+	char          *required_attributes;
 } DialogData;
 
 
@@ -78,7 +81,9 @@ destroy_cb (GtkWidget  *widget,
 {
 	gth_browser_set_dialog (data->browser, "rename_series", NULL);
 
+	g_free (data->required_attributes);
 	g_object_unref (data->builder);
+	_g_object_list_unref (data->file_data_list);
 	_g_object_list_unref (data->file_list);
 	_g_string_list_free (data->new_names_list);
 	g_list_free (data->new_file_list);
@@ -304,9 +309,101 @@ template_eval_cb (const GMatchInfo *info,
 }
 
 
+static char *
+get_required_attributes (DialogData *data)
+{
+	GtkTreeIter  iter;
+	GString     *required_attributes;
+	const char  *template;
+
+	required_attributes = g_string_new (GFILE_STANDARD_ATTRIBUTES);
+
+	/* attributes required for sorting */
+
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (data->sort_combobox), &iter)) {
+		GthFileDataSort *sort_type;
+
+		gtk_tree_model_get (GTK_TREE_MODEL (data->sort_model),
+				    &iter,
+				    SORT_DATA_COLUMN, &sort_type,
+				    -1);
+
+		g_string_append (required_attributes, ",");
+		g_string_append (required_attributes, sort_type->required_attributes);
+	}
+
+	/* attributes required for renaming */
+
+	template = gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("template_entry")));
+
+	if (g_strstr_len (template, -1, "%A") != NULL) {
+		GRegex  *re;
+		char   **a;
+		int      i;
+
+		re = g_regex_new ("%A\\{([^}]+)\\}", 0, 0, NULL);
+		a = g_regex_split (re, template, 0);
+		for (i = 1; i < g_strv_length (a); i += 2) {
+			g_string_append (required_attributes, ",");
+			g_string_append (required_attributes, a[i]);
+		}
+
+		g_strfreev (a);
+		g_regex_unref (re);
+	}
+
+	if (g_strstr_len (template, -1, "%D") != NULL) {
+		int i;
+
+		for (i = 0; FileDataDigitalizationTags[i] != NULL; i++) {
+			g_string_append (required_attributes, ",");
+			g_string_append (required_attributes, FileDataDigitalizationTags[i]);
+		}
+	}
+
+	if (g_strstr_len (template, -1, "%M") != NULL) {
+		g_string_append (required_attributes, ",");
+		g_string_append (required_attributes, G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
+	}
+
+
+	return g_string_free (required_attributes, FALSE);
+}
+
+
+static void dlg_rename_series_update_preview (DialogData *data);
+
+
+static void
+load_file_data_task_completed_cb (GthTask  *task,
+				  GError   *error,
+				  gpointer  user_data)
+{
+	DialogData *data = user_data;
+
+	if (error != NULL) {
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Cannot read file information"), &error);
+		gtk_widget_destroy (data->dialog);
+		return;
+	}
+
+	_g_object_list_unref (data->file_data_list);
+	data->file_data_list = _g_object_list_ref (gth_load_file_data_task_get_result (GTH_LOAD_FILE_DATA_TASK (task)));
+
+	gtk_widget_set_sensitive (data->dialog, TRUE);
+	gtk_window_present (GTK_WINDOW (data->dialog));
+	gtk_widget_grab_focus (GET_WIDGET ("template_entry"));
+	dlg_rename_series_update_preview (data);
+
+	g_object_unref (task);
+}
+
+
 static void
 dlg_rename_series_update_preview (DialogData *data)
 {
+	char         *required_attributes;
+	gboolean      reload_required;
 	GtkTreeIter   iter;
 	int           change_case;
 	TemplateData *template_data;
@@ -315,6 +412,32 @@ dlg_rename_series_update_preview (DialogData *data)
 	GError       *error = NULL;
 	GList        *scan1, *scan2;
 
+	required_attributes = get_required_attributes (data);
+	reload_required = attribute_list_reload_required (data->required_attributes, required_attributes);
+	g_free (data->required_attributes);
+	data->required_attributes = required_attributes;
+
+	if (reload_required) {
+		GthTask *task;
+
+		gtk_widget_set_sensitive (data->dialog, FALSE);
+
+		task = gth_load_file_data_task_new (data->file_list, data->required_attributes);
+		g_signal_connect (task,
+				  "completed",
+				  G_CALLBACK (load_file_data_task_completed_cb),
+				  data);
+		gth_browser_exec_task (data->browser, task, FALSE);
+
+		return;
+	}
+
+	if ((data->first_update) && (data->file_data_list->next == NULL)) {
+		GthFileData *file_data = data->file_data_list->data;
+		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("template_entry")), g_file_info_get_attribute_string (file_data->info, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME));
+		data->first_update = FALSE;
+	}
+
 	if (data->new_names_list != NULL) {
 		_g_string_list_free (data->new_names_list);
 		data->new_names_list = NULL;
@@ -325,7 +448,7 @@ dlg_rename_series_update_preview (DialogData *data)
 		data->new_file_list = NULL;
 	}
 
-	data->new_file_list = g_list_copy (data->file_list);
+	data->new_file_list = g_list_copy (data->file_data_list);
 	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (data->sort_combobox), &iter)) {
 		GthFileDataSort *sort_type;
 
@@ -449,7 +572,8 @@ dlg_rename_series (GthBrowser *browser,
 	data = g_new0 (DialogData, 1);
 	data->browser = browser;
 	data->builder = _gtk_builder_new_from_file ("rename-series.ui", "rename_series");
-	data->file_list = gth_file_data_list_dup (file_list);
+	data->file_list = _g_file_list_dup (file_list);
+	data->first_update = TRUE;
 
 	/* Get the widgets. */
 
@@ -486,11 +610,7 @@ dlg_rename_series (GthBrowser *browser,
 
 	gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("preview_label")), data->list_view);
 
-	if (data->file_list->next == NULL) {
-		GthFileData *file_data = data->file_list->data;
-		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("template_entry")), g_file_info_get_attribute_string (file_data->info, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME));
-	}
-	else
+	if (data->file_list->next != NULL)
 		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("template_entry")), eel_gconf_get_string (PREF_RENAME_SERIES_TEMPLATE, DEFAULT_TEMPLATE));
 
 	start_at = eel_gconf_get_integer (PREF_RENAME_SERIES_START_AT, DEFAULT_START_AT);
@@ -538,7 +658,7 @@ dlg_rename_series (GthBrowser *browser,
 		gtk_combo_box_set_active (GTK_COMBO_BOX (data->sort_combobox), 0);
 
 	gtk_widget_show (data->sort_combobox);
-	gtk_container_add (GTK_CONTAINER (GET_WIDGET ("sort_by_box")), data->sort_combobox);
+	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("sort_by_box")), data->sort_combobox, FALSE, FALSE, 0);
 	gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("sort_by_label")), data->sort_combobox);
 
 	/* reverse order */
@@ -557,7 +677,7 @@ dlg_rename_series (GthBrowser *browser,
 								    NULL);
 	gtk_combo_box_set_active (GTK_COMBO_BOX (data->change_case_combobox), change_case);
 	gtk_widget_show (data->change_case_combobox);
-	gtk_container_add (GTK_CONTAINER (GET_WIDGET ("change_case_box")), data->change_case_combobox);
+	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("change_case_box")), data->change_case_combobox, FALSE, FALSE, 0);
 	gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("change_case_label")), data->change_case_combobox);
 
 	dlg_rename_series_update_preview (data);
diff --git a/extensions/rename_series/dlg-rename-series.h b/extensions/rename_series/dlg-rename-series.h
index 7e339c9..d48ca9f 100644
--- a/extensions/rename_series/dlg-rename-series.h
+++ b/extensions/rename_series/dlg-rename-series.h
@@ -25,6 +25,6 @@
 #include <gthumb.h>
 
 void dlg_rename_series (GthBrowser *browser,
-		        GList      *file_list  /* GthFileData list */);
+		        GList      *file_list  /* GFile list */);
 
 #endif /* DLG_RENAME_SERIES_H */
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 3f00e47..b24c9c6 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -74,6 +74,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-image-viewer-tool.h				\
 	gth-info-bar.h					\
 	gth-list-view.h					\
+	gth-load-file-data-task.h			\
 	gth-location-chooser.h				\
 	gth-main.h					\
 	gth-menu-button.h				\
@@ -191,6 +192,7 @@ gthumb_SOURCES = 					\
 	gth-image-viewer-tool.c				\
 	gth-info-bar.c					\
 	gth-list-view.c					\
+	gth-load-file-data-task.c			\
 	gth-location-chooser.c				\
 	gth-main.c					\
 	gth-main-default-hooks.c			\
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index 8a43ed3..d48bc69 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -30,6 +30,20 @@
 
 #define GTH_FILE_DATA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTH_TYPE_FILE_DATA, GthFileDataPrivate))
 
+
+const char *FileDataDigitalizationTags[] = {
+	"Exif::Photo::DateTimeOriginal",
+	"Xmp::exif::DateTimeOriginal",
+	"Exif::Photo::DateTimeDigitized",
+	"Xmp::exif::DateTimeDigitized",
+	"Xmp::xmp::CreateDate",
+	"Xmp::photoshop::DateCreated",
+	"Xmp::xmp::ModifyDate",
+	"Xmp::xmp::MetadataDate",
+	NULL
+};
+
+
 struct _GthFileDataPrivate {
 	GTimeVal  ctime;   /* creation time */
 	GTimeVal  mtime;   /* modification time */
@@ -275,19 +289,6 @@ gth_file_data_get_creation_time (GthFileData *self)
 }
 
 
-static const char *try_digitalization_tag[] = {
-	"Exif::Photo::DateTimeOriginal",
-	"Xmp::exif::DateTimeOriginal",
-	"Exif::Photo::DateTimeDigitized",
-	"Xmp::exif::DateTimeDigitized",
-	"Xmp::xmp::CreateDate",
-	"Xmp::photoshop::DateCreated",
-	"Xmp::xmp::ModifyDate",
-	"Xmp::xmp::MetadataDate",
-	NULL
-};
-
-
 gboolean
 gth_file_data_get_digitalization_time (GthFileData *self,
 				       GTimeVal    *_time)
@@ -299,10 +300,10 @@ gth_file_data_get_digitalization_time (GthFileData *self,
 		return TRUE;
 	}
 
-	for (i = 0; try_digitalization_tag[i] != NULL; i++) {
+	for (i = 0; FileDataDigitalizationTags[i] != NULL; i++) {
 		GthMetadata *m;
 
-		m = (GthMetadata *) g_file_info_get_attribute_object (self->info, try_digitalization_tag[i]);
+		m = (GthMetadata *) g_file_info_get_attribute_object (self->info, FileDataDigitalizationTags[i]);
 		if (m == NULL)
 			continue;
 
diff --git a/gthumb/gth-file-data.h b/gthumb/gth-file-data.h
index 8b23006..aad7ed8 100644
--- a/gthumb/gth-file-data.h
+++ b/gthumb/gth-file-data.h
@@ -29,6 +29,8 @@
 
 G_BEGIN_DECLS
 
+extern const char *FileDataDigitalizationTags[];
+
 #define GTH_TYPE_FILE_DATA (gth_file_data_get_type ())
 #define GTH_FILE_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_DATA, GthFileData))
 #define GTH_FILE_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_DATA, GthFileDataClass))
diff --git a/gthumb/gth-load-file-data-task.c b/gthumb/gth-load-file-data-task.c
new file mode 100644
index 0000000..912709f
--- /dev/null
+++ b/gthumb/gth-load-file-data-task.c
@@ -0,0 +1,220 @@
+/* -*- 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-load-file-data-task.h"
+#include "gth-metadata-provider.h"
+
+
+struct _GthLoadFileDataTaskPrivate {
+	GList *file_list;
+	int    n_files;
+	GList *current;
+	int    n_current;
+	char  *attributes;
+	GList *file_data_list;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_load_file_data_task_finalize (GObject *object)
+{
+	GthLoadFileDataTask *self;
+
+	self = GTH_LOAD_FILE_DATA_TASK (object);
+
+	_g_object_list_unref (self->priv->file_list);
+	_g_object_list_unref (self->priv->file_data_list);
+	g_free (self->priv->attributes);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void load_current_file (GthLoadFileDataTask *self);
+
+
+static void
+load_next_file (GthLoadFileDataTask *self)
+{
+	self->priv->current = self->priv->current->next;
+	self->priv->n_current++;
+	load_current_file (self);
+}
+
+
+static void
+metadata_ready_cb (GList    *files,
+		   GError   *error,
+		   gpointer  user_data)
+{
+	GthLoadFileDataTask *self = user_data;
+	GthFileData         *file_data;
+
+	if (error != NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	file_data = files->data;
+	self->priv->file_data_list = g_list_prepend (self->priv->file_data_list, g_object_ref (file_data));
+
+	load_next_file (self);
+}
+
+
+static void
+load_current_file (GthLoadFileDataTask *self)
+{
+	GFile *file;
+	char  *details;
+	GList *files;
+
+	if (self->priv->current == NULL) {
+		self->priv->file_data_list = g_list_reverse (self->priv->file_data_list);
+		gth_task_completed (GTH_TASK (self), NULL);
+		return;
+	}
+
+	file = self->priv->current->data;
+
+	/* translators: %s is a filename */
+	details = g_strdup_printf (_("Loading \"%s\""), g_file_get_parse_name (file));
+	gth_task_progress (GTH_TASK (self),
+			   _("Reading file information"),
+			   details,
+			   FALSE,
+			   ((double) self->priv->n_current + 0.5) / self->priv->n_files);
+
+	files = g_list_prepend (NULL, file);
+	_g_query_all_metadata_async (files,
+				     GTH_LIST_DEFAULT,
+				     self->priv->attributes,
+				     gth_task_get_cancellable (GTH_TASK (self)),
+				     metadata_ready_cb,
+				     self);
+
+	g_list_free (files);
+	g_free (details);
+}
+
+
+static void
+gth_load_file_data_task_exec (GthTask *task)
+{
+	GthLoadFileDataTask *self;
+
+	g_return_if_fail (GTH_IS_LOAD_FILE_DATA_TASK (task));
+
+	self = GTH_LOAD_FILE_DATA_TASK (task);
+
+	load_current_file (self);
+}
+
+
+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;
+	GthTaskClass *task_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthLoadFileDataTaskPrivate));
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = gth_load_file_data_task_finalize;
+
+	task_class = GTH_TASK_CLASS (klass);
+	task_class->exec = gth_load_file_data_task_exec;
+	task_class->cancelled = gth_load_file_data_task_cancelled;
+}
+
+
+static void
+gth_load_file_data_task_init (GthLoadFileDataTask *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_LOAD_FILE_DATA_TASK, GthLoadFileDataTaskPrivate);
+	self->priv->file_data_list = NULL;
+}
+
+
+GType
+gth_load_file_data_task_get_type (void)
+{
+	static GType type = 0;
+
+	if (! type) {
+		GTypeInfo type_info = {
+			sizeof (GthLoadFileDataTaskClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_load_file_data_task_class_init,
+			NULL,
+			NULL,
+			sizeof (GthLoadFileDataTask),
+			0,
+			(GInstanceInitFunc) gth_load_file_data_task_init
+		};
+
+		type = g_type_register_static (GTH_TYPE_TASK,
+					       "GthLoadFileDataTask",
+					       &type_info,
+					       0);
+	}
+
+	return type;
+}
+
+
+GthTask *
+gth_load_file_data_task_new (GList      *file_list,
+			     const char *attributes)
+{
+	GthLoadFileDataTask *self;
+
+	self = (GthLoadFileDataTask *) g_object_new (GTH_TYPE_LOAD_FILE_DATA_TASK, NULL);
+	self->priv->file_list = _g_file_list_dup (file_list);
+	self->priv->n_files = g_list_length (file_list);;
+	self->priv->attributes = g_strdup (attributes);
+	self->priv->current = self->priv->file_list;
+	self->priv->n_current = 0;
+
+	return (GthTask *) self;
+}
+
+
+GList *
+gth_load_file_data_task_get_result (GthLoadFileDataTask *self)
+{
+	return self->priv->file_data_list;
+}
diff --git a/gthumb/gth-load-file-data-task.h b/gthumb/gth-load-file-data-task.h
new file mode 100644
index 0000000..ef428ec
--- /dev/null
+++ b/gthumb/gth-load-file-data-task.h
@@ -0,0 +1,58 @@
+/* -*- 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_LOAD_FILE_DATA_TASK_H
+#define GTH_LOAD_FILE_DATA_TASK_H
+
+#include <glib.h>
+#include "gth-file-data.h"
+#include "gth-task.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_LOAD_FILE_DATA_TASK            (gth_load_file_data_task_get_type ())
+#define GTH_LOAD_FILE_DATA_TASK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_LOAD_FILE_DATA_TASK, GthLoadFileDataTask))
+#define GTH_LOAD_FILE_DATA_TASK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_LOAD_FILE_DATA_TASK, GthLoadFileDataTaskClass))
+#define GTH_IS_LOAD_FILE_DATA_TASK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_LOAD_FILE_DATA_TASK))
+#define GTH_IS_LOAD_FILE_DATA_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_LOAD_FILE_DATA_TASK))
+#define GTH_LOAD_FILE_DATA_TASK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_LOAD_FILE_DATA_TASK, GthLoadFileDataTaskClass))
+
+typedef struct _GthLoadFileDataTask        GthLoadFileDataTask;
+typedef struct _GthLoadFileDataTaskClass   GthLoadFileDataTaskClass;
+typedef struct _GthLoadFileDataTaskPrivate GthLoadFileDataTaskPrivate;
+
+struct _GthLoadFileDataTask {
+	GthTask __parent;
+	GthLoadFileDataTaskPrivate *priv;
+};
+
+struct _GthLoadFileDataTaskClass {
+	GthTaskClass __parent;
+};
+
+GType       gth_load_file_data_task_get_type   (void);
+GthTask *   gth_load_file_data_task_new        (GList               *file_list, /* GFile list */
+					        const char          *attributes);
+GList *     gth_load_file_data_task_get_result (GthLoadFileDataTask *self);
+
+G_END_DECLS
+
+#endif /* GTH_LOAD_FILE_DATA_TASK_H */
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index e7d6ac9..1d1363d 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -1339,6 +1339,9 @@ attribute_list_reload_required (const char *old_attributes,
 	int        i;
 	gboolean   reload_required;
 
+	if (old_attributes == NULL)
+		return TRUE;
+
 	old_attributes_v = g_strsplit (old_attributes, ",", -1);
 	new_attributes_v = g_strsplit (new_attributes, ",", -1);
 	new_attributes_len = g_strv_length (new_attributes_v);



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