[gthumb/ext: 51/79] Added ability to change the file tags in the metadata dialog



commit 28cfcf4472f3769f0198006c68a40244cd9b5e26
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Fri Jul 17 12:56:40 2009 +0200

    Added ability to change the file tags in the metadata dialog

 extensions/catalogs/gth-file-source-catalogs.c     |  159 +++++---------------
 extensions/comments/data/ui/edit-comment-page.ui   |   30 ++++-
 extensions/comments/gth-edit-comment-page.c        |   45 +++++-
 .../comments/gth-metadata-provider-comment.c       |    1 +
 gthumb/gth-browser.c                               |   34 ++++-
 gthumb/gth-file-data.c                             |   16 +--
 gthumb/gth-file-source-vfs.c                       |  119 ++++-----------
 gthumb/gth-file-source.c                           |  124 ++++++++++++----
 gthumb/gth-file-source.h                           |   17 +-
 gthumb/gth-file-store.c                            |    5 +-
 gthumb/gth-metadata-provider.c                     |   80 ++++++++++
 gthumb/gth-metadata-provider.h                     |    9 +-
 gthumb/gth-string-list.c                           |   71 ++++++----
 gthumb/gth-string-list.h                           |    2 +
 14 files changed, 410 insertions(+), 302 deletions(-)
---
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index aed46e1..561a010 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -31,7 +31,6 @@
 
 struct _GthFileSourceCatalogsPrivate
 {
-	GCancellable *cancellable;
 	GList        *files;
 	GthCatalog   *catalog;
 	ListReady     ready_func;
@@ -137,34 +136,10 @@ gth_file_source_catalogs_get_file_info (GthFileSource *file_source,
 }
 
 
-static void
-list__done_func (GError   *error,
-		 gpointer  user_data)
-{
-	GthFileSourceCatalogs *catalogs = user_data;
-
-	if (G_IS_OBJECT (catalogs))
-		gth_file_source_set_active (GTH_FILE_SOURCE (catalogs), FALSE);
-
-	if (error != NULL) {
-		_g_object_list_unref (catalogs->priv->files);
-		catalogs->priv->files = NULL;
-		g_clear_error (&error);
-	}
-
-	g_object_ref (catalogs);
-	catalogs->priv->ready_func ((GthFileSource *) catalogs,
-				    catalogs->priv->files,
-				    error,
-				    catalogs->priv->ready_data);
-	g_object_unref (catalogs);
-}
-
-
 static GthFileData *
-create_file_data (GthFileSourceCatalogs *catalogs,
-		  GFile                 *file,
-		  GFileInfo             *info)
+gth_file_source_catalogs_get_file_data (GthFileSource *file_source,
+					GFile         *file,
+					GFileInfo     *info)
 {
 	GthFileData *file_data = NULL;
 	char        *uri;
@@ -183,7 +158,7 @@ create_file_data (GthFileSourceCatalogs *catalogs,
 		}
 
 		catalog_file = gth_catalog_file_from_gio_file (file, NULL);
-		update_file_info (GTH_FILE_SOURCE (catalogs), catalog_file, info);
+		update_file_info (file_source, catalog_file, info);
 		file_data = gth_file_data_new (catalog_file, info);
 
 		g_object_unref (catalog_file);
@@ -191,7 +166,7 @@ create_file_data (GthFileSourceCatalogs *catalogs,
 
 	case G_FILE_TYPE_DIRECTORY:
 		catalog_file = gth_catalog_file_from_gio_file (file, NULL);
-		update_file_info (GTH_FILE_SOURCE (catalogs), catalog_file, info);
+		update_file_info (file_source, catalog_file, info);
 		file_data = gth_file_data_new (catalog_file, info);
 
 		g_object_unref (catalog_file);
@@ -207,6 +182,31 @@ create_file_data (GthFileSourceCatalogs *catalogs,
 }
 
 
+
+static void
+list__done_func (GError   *error,
+		 gpointer  user_data)
+{
+	GthFileSourceCatalogs *catalogs = user_data;
+
+	if (G_IS_OBJECT (catalogs))
+		gth_file_source_set_active (GTH_FILE_SOURCE (catalogs), FALSE);
+
+	if (error != NULL) {
+		_g_object_list_unref (catalogs->priv->files);
+		catalogs->priv->files = NULL;
+		g_clear_error (&error);
+	}
+
+	g_object_ref (catalogs);
+	catalogs->priv->ready_func ((GthFileSource *) catalogs,
+				    catalogs->priv->files,
+				    error,
+				    catalogs->priv->ready_data);
+	g_object_unref (catalogs);
+}
+
+
 static void
 list__for_each_file_func (GFile     *file,
 			  GFileInfo *info,
@@ -215,7 +215,7 @@ list__for_each_file_func (GFile     *file,
 	GthFileSourceCatalogs *catalogs = user_data;
 	GthFileData           *file_data;
 
-	file_data = create_file_data (catalogs, file, info);
+	file_data = gth_file_source_get_file_data (GTH_FILE_SOURCE (catalogs), file, info);
 	if (file_data != NULL)
 		catalogs->priv->files = g_list_prepend (catalogs->priv->files, file_data);
 }
@@ -266,7 +266,7 @@ gth_file_source_catalogs_list (GthFileSource *file_source,
 	GFile                 *gio_file;
 
 	gth_file_source_set_active (GTH_FILE_SOURCE (catalogs), TRUE);
-	g_cancellable_reset (catalogs->priv->cancellable);
+	g_cancellable_reset (gth_file_source_get_cancellable (file_source));
 
 	_g_object_list_unref (catalogs->priv->files);
 	catalogs->priv->files = NULL;
@@ -284,7 +284,7 @@ gth_file_source_catalogs_list (GthFileSource *file_source,
 		gth_catalog_set_file (catalogs->priv->catalog, gio_file);
 		gth_catalog_list_async (catalogs->priv->catalog,
 					attributes,
-					catalogs->priv->cancellable,
+					gth_file_source_get_cancellable (file_source),
 					catalog_list_ready_cb,
 					file_source);
 	}
@@ -293,7 +293,7 @@ gth_file_source_catalogs_list (GthFileSource *file_source,
 					   FALSE,
 					   TRUE,
 					   attributes,
-					   catalogs->priv->cancellable,
+					   gth_file_source_get_cancellable (file_source),
 					   list__start_dir_func,
 					   list__for_each_file_func,
 					   list__done_func,
@@ -304,82 +304,6 @@ gth_file_source_catalogs_list (GthFileSource *file_source,
 }
 
 
-typedef struct {
-	GthFileSourceCatalogs *catalogs;
-	ListReady              ready_func;
-	gpointer               ready_data;
-} ReadAttributesData;
-
-
-static void
-read_attributes_data_free (ReadAttributesData *data)
-{
-	g_free (data);
-}
-
-
-static void
-info_ready_cb (GList    *files,
-	       GError   *error,
-	       gpointer  user_data)
-{
-	ReadAttributesData    *data = user_data;
-	GthFileSourceCatalogs *catalogs = data->catalogs;
-	GList                 *scan;
-	GList                 *result_files;
-
-	g_object_ref (catalogs);
-
-	result_files = NULL;
-	for (scan = files; scan; scan = scan->next) {
-		GthFileData *file_data = scan->data;
-		result_files = g_list_prepend (result_files, create_file_data (catalogs, file_data->file, file_data->info));
-	}
-	result_files = g_list_reverse (result_files);
-
-	data->ready_func ((GthFileSource *) catalogs,
-			  result_files,
-			  error,
-			  data->ready_data);
-
-	_g_object_list_unref (result_files);
-	read_attributes_data_free (data);
-	g_object_unref (catalogs);
-
-	if (G_IS_OBJECT (catalogs))
-		gth_file_source_set_active (GTH_FILE_SOURCE (catalogs), FALSE);
-}
-
-
-static void
-gth_file_source_catalogs_read_attributes (GthFileSource *file_source,
-					  GList         *files,
-					  const char    *attributes,
-					  ListReady      func,
-					  gpointer       user_data)
-{
-	GthFileSourceCatalogs *catalogs = (GthFileSourceCatalogs *) file_source;
-	ReadAttributesData    *data;
-	GList                 *gio_files;
-
-	gth_file_source_set_active (GTH_FILE_SOURCE (catalogs), TRUE);
-
-	data = g_new0 (ReadAttributesData, 1);
-	data->catalogs = catalogs;
-	data->ready_func = func;
-	data->ready_data = user_data;
-
-	gio_files = gth_file_source_to_gio_file_list (GTH_FILE_SOURCE (catalogs), files);
-	g_query_info_async (gio_files,
-			    GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE,
-			    catalogs->priv->cancellable,
-			    info_ready_cb,
-			    data);
-
-	_g_object_list_unref (gio_files);
-}
-
-
 /* -- gth_file_source_vfs_copy -- */
 
 
@@ -506,20 +430,11 @@ gth_file_source_catalogs_copy (GthFileSource *file_source,
 
 	g_query_info_async (cod->file_list,
 			    G_FILE_ATTRIBUTE_STANDARD_TYPE,
-			    GTH_FILE_SOURCE_CATALOGS (file_source)->priv->cancellable,
+			    gth_file_source_get_cancellable (file_source),
 			    copy__file_list_info_ready_cb,
 			    cod);
 }
 
-static void
-gth_file_source_catalogs_cancel (GthFileSource *file_source)
-{
-	GthFileSourceCatalogs *catalogs = (GthFileSourceCatalogs *) file_source;
-
-	if (gth_file_source_is_active (file_source))
-		g_cancellable_cancel (catalogs->priv->cancellable);
-}
-
 
 static void
 gth_file_source_catalogs_finalize (GObject *object)
@@ -553,10 +468,9 @@ gth_file_source_catalogs_class_init (GthFileSourceCatalogsClass *class)
 	file_source_class->get_entry_points = get_entry_points;
 	file_source_class->to_gio_file = gth_file_source_catalogs_to_gio_file;
 	file_source_class->get_file_info = gth_file_source_catalogs_get_file_info;
+	file_source_class->get_file_data = gth_file_source_catalogs_get_file_data;
 	file_source_class->list = gth_file_source_catalogs_list;
-	file_source_class->read_attributes = gth_file_source_catalogs_read_attributes;
 	file_source_class->copy = gth_file_source_catalogs_copy;
-	file_source_class->cancel = gth_file_source_catalogs_cancel;
 }
 
 
@@ -566,7 +480,6 @@ gth_file_source_catalogs_init (GthFileSourceCatalogs *catalogs)
 	gth_file_source_add_scheme (GTH_FILE_SOURCE (catalogs), "catalog://");
 
 	catalogs->priv = g_new0 (GthFileSourceCatalogsPrivate, 1);
-	catalogs->priv->cancellable = g_cancellable_new ();
 	catalogs->priv->catalog = gth_catalog_new ();
 }
 
diff --git a/extensions/comments/data/ui/edit-comment-page.ui b/extensions/comments/data/ui/edit-comment-page.ui
index 98f15e0..e1a2c72 100644
--- a/extensions/comments/data/ui/edit-comment-page.ui
+++ b/extensions/comments/data/ui/edit-comment-page.ui
@@ -4,7 +4,7 @@
   <!-- interface-naming-policy project-wide -->
   <object class="GtkTable" id="content">
     <property name="visible">True</property>
-    <property name="n_rows">4</property>
+    <property name="n_rows">5</property>
     <property name="n_columns">2</property>
     <property name="column_spacing">6</property>
     <property name="row_spacing">6</property>
@@ -53,7 +53,7 @@
     <child>
       <object class="GtkScrolledWindow" id="scrolledwindow3">
         <property name="width_request">250</property>
-        <property name="height_request">200</property>
+        <property name="height_request">150</property>
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="hscrollbar_policy">automatic</property>
@@ -121,5 +121,31 @@
     <child>
       <placeholder/>
     </child>
+    <child>
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">_Tags:</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">tags_entry</property>
+      </object>
+      <packing>
+        <property name="top_attach">4</property>
+        <property name="bottom_attach">5</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="tags_entry">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="invisible_char">&#x25CF;</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="right_attach">2</property>
+        <property name="top_attach">4</property>
+        <property name="bottom_attach">5</property>
+      </packing>
+    </child>
   </object>
 </interface>
diff --git a/extensions/comments/gth-edit-comment-page.c b/extensions/comments/gth-edit-comment-page.c
index 95c095d..5afa8d4 100644
--- a/extensions/comments/gth-edit-comment-page.c
+++ b/extensions/comments/gth-edit-comment-page.c
@@ -59,6 +59,7 @@ gth_edit_comment_page_real_set_file (GthEditMetadataPage *base,
 	GthEditCommentPage *self;
 	GtkTextBuffer      *buffer;
 	GthMetadata        *metadata;
+	GthStringList      *tags;
 
 	self = GTH_EDIT_COMMENT_PAGE (base);
 
@@ -95,6 +96,18 @@ gth_edit_comment_page_real_set_file (GthEditMetadataPage *base,
 		/*gtk_widget_set_sensitive (self->priv->date_datetime, FALSE);*/
 	}
 
+	tags = (GthStringList *) g_file_info_get_attribute_object (file_data->info, "Embedded::Image::Keywords");
+	if (tags != NULL) {
+		char *value;
+
+		value = gth_string_list_join (tags, ", ");
+		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("tags_entry")), value);
+
+		g_free (value);
+	}
+	else
+		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("tags_entry")), "");
+
 	gtk_widget_grab_focus (GET_WIDGET ("note_text"));
 }
 
@@ -103,11 +116,15 @@ void
 gth_edit_comment_page_real_update_info (GthEditMetadataPage *base,
 					GFileInfo           *info)
 {
-	GthEditCommentPage *self;
-	GtkTextBuffer      *buffer;
-	GtkTextIter         start;
-	GtkTextIter         end;
-	char               *text;
+	GthEditCommentPage  *self;
+	GtkTextBuffer       *buffer;
+	GtkTextIter          start;
+	GtkTextIter          end;
+	char                *text;
+	int                  i;
+	char               **tagv;
+	GList               *tags;
+	GthStringList       *string_list;
 
 	self = GTH_EDIT_COMMENT_PAGE (base);
 
@@ -119,6 +136,24 @@ gth_edit_comment_page_real_update_info (GthEditMetadataPage *base,
 
 	g_file_info_set_attribute_string (self->priv->file_data->info, "comment::place", gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("place_entry"))));
 	g_file_info_set_attribute_string (self->priv->file_data->info, "comment::time", gtk_entry_get_text (GTK_ENTRY (self->priv->date_datetime)));
+
+	tagv = g_strsplit (gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("tags_entry"))), ",", -1);
+	tags = NULL;
+	for (i = 0; tagv[i] != NULL; i++) {
+		char *tag;
+
+		tag = g_strstrip (tagv[i]);
+		if (tag[0] != '\0')
+			tags = g_list_prepend (tags, g_strdup (tag));
+	}
+	tags = g_list_reverse (tags);
+	string_list = gth_string_list_new (tags);
+	g_file_info_set_attribute_object (self->priv->file_data->info, "comment::categories", G_OBJECT (string_list));
+	g_file_info_set_attribute_object (self->priv->file_data->info, "Embedded::Image::Keywords", G_OBJECT (string_list));
+
+	g_object_unref (string_list);
+	g_strfreev (tagv);
+	_g_string_list_free (tags);
 }
 
 
diff --git a/extensions/comments/gth-metadata-provider-comment.c b/extensions/comments/gth-metadata-provider-comment.c
index 6d6876f..dbdc117 100644
--- a/extensions/comments/gth-metadata-provider-comment.c
+++ b/extensions/comments/gth-metadata-provider-comment.c
@@ -99,6 +99,7 @@ gth_metadata_provider_comment_read (GthMetadataProvider *self,
 
 			value = (GObject *) gth_string_list_new_from_ptr_array (categories);
 			g_file_info_set_attribute_object (file_data->info, "comment::categories", value);
+			g_file_info_set_attribute_object (file_data->info, "Embedded::Image::Keywords", value);
 			g_object_unref (value);
 		}
 	}
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index ce1a02b..630a1c8 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -146,6 +146,7 @@ struct _GthBrowserPrivateData {
 	gulong             task_progress;
 	GList             *load_data_queue;
 	guint              load_file_timeout;
+	char              *list_attributes;
 
 	/* fulscreen */
 
@@ -1187,6 +1188,32 @@ metadata_ready_cb (GList    *files,
 }
 
 
+static const char *
+_gth_browser_get_list_attributes (GthBrowser *browser)
+{
+	GString *attributes;
+
+	if (browser->priv->list_attributes != NULL)
+		return browser->priv->list_attributes;
+
+	attributes = g_string_new ("");
+	if (eel_gconf_get_boolean (PREF_FAST_FILE_TYPE, TRUE))
+		g_string_append (attributes, GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE);
+	else
+		g_string_append (attributes, GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE);
+
+	/* FIXME: make the attribute list based on the data required to
+	 * filter and view the file list. */
+
+	g_string_append (attributes, ",comment::*");
+	browser->priv->list_attributes = attributes->str;
+
+	g_string_free (attributes, FALSE);
+
+	return browser->priv->list_attributes;
+}
+
+
 static void
 load_data_ready (LoadData *data,
 		 GList    *files,
@@ -1197,10 +1224,8 @@ load_data_ready (LoadData *data,
 		load_data_free (data);
 	}
 	else if (g_file_equal ((GFile *) data->current->data, data->requested_folder))
-		/* FIXME: make the metadata attribute list automatic, based
-		 * on the data required to filter and view the file list. */
 		_g_query_metadata_async (files,
-					 "file::*,comment::*",
+					 _gth_browser_get_list_attributes (data->browser),
 					 data->cancellable,
 					 metadata_ready_cb,
 				 	 data);
@@ -1736,6 +1761,7 @@ gth_browser_finalize (GObject *object)
 		_g_object_list_unref (browser->priv->history);
 		gth_icon_cache_free (browser->priv->menu_icon_cache);
 		g_hash_table_unref (browser->priv->named_dialogs);
+		g_free (browser->priv->list_attributes);
 		g_free (browser->priv);
 		browser->priv = NULL;
 	}
@@ -2125,7 +2151,7 @@ folder_changed_cb (GthMonitor      *monitor,
 			monitor_data->update_folder_tree = update_folder_tree;
 			gth_file_source_read_attributes (monitor_data->file_source,
 						 	 list,
-						 	 eel_gconf_get_boolean (PREF_FAST_FILE_TYPE, TRUE) ? GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE : GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE,
+						 	 _gth_browser_get_list_attributes (browser),
 						 	 file_attributes_ready_cb,
 						 	 monitor_data);
 			break;
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index 1174634..497731b 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -452,20 +452,8 @@ gth_file_data_get_attribute_as_string (GthFileData *file_data,
 		obj = g_file_info_get_attribute_object (file_data->info, id);
 		if (GTH_IS_METADATA (obj))
 			g_object_get (obj, "formatted", &value, NULL);
-		else if (GTH_IS_STRING_LIST (obj)) {
-			GList   *list;
-			GList   *scan;
-			GString *str;
-
-			list = gth_string_list_get_list (GTH_STRING_LIST (obj));
-			str = g_string_new ("");
-			for (scan = list; scan; scan = scan->next) {
-				if (scan != list)
-					g_string_append (str, " ");
-				g_string_append (str, (char *) scan->data);
-			}
-			value = g_string_free (str, FALSE);
-		}
+		else if (GTH_IS_STRING_LIST (obj))
+			value = gth_string_list_join (GTH_STRING_LIST (obj), " ");
 		else
 			value = g_file_info_get_attribute_as_string (file_data->info, id);
 		break;
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index 4f71cf3..898968b 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -38,7 +38,6 @@
 
 struct _GthFileSourceVfsPrivate
 {
-	GCancellable      *cancellable;
 	GList             *files;
 	ListReady          ready_func;
 	gpointer           ready_data;
@@ -54,7 +53,7 @@ static guint mount_monitor_id = 0;
 
 
 static GList *
-get_entry_points (GthFileSource *file_source)
+gth_file_source_vfs_get_entry_points (GthFileSource *file_source)
 {
 	GList     *list;
 	GFile     *file;
@@ -118,8 +117,8 @@ get_entry_points (GthFileSource *file_source)
 
 
 static GFile *
-to_gio_file (GthFileSource *file_source,
-	     GFile         *file)
+gth_file_source_vfs_to_gio_file (GthFileSource *file_source,
+				 GFile         *file)
 {
 	char  *uri;
 	GFile *gio_file;
@@ -133,9 +132,9 @@ to_gio_file (GthFileSource *file_source,
 
 
 static GFileInfo *
-get_file_info (GthFileSource *file_source,
-	       GFile         *file,
-	       const char    *attributes)
+gth_file_source_vfs_get_file_info (GthFileSource *file_source,
+				   GFile         *file,
+				   const char    *attributes)
 {
 	GFile     *gio_file;
 	GFileInfo *file_info;
@@ -153,6 +152,9 @@ get_file_info (GthFileSource *file_source,
 }
 
 
+/* -- gth_file_source_vfs_list -- */
+
+
 static void
 list__done_func (GError   *error,
 		 gpointer  user_data)
@@ -199,17 +201,17 @@ list__start_dir_func (GFile       *directory,
 
 
 static void
-list (GthFileSource *file_source,
-      GFile         *folder,
-      const char    *attributes,
-      ListReady      func,
-      gpointer       user_data)
+gth_file_source_vfs_list (GthFileSource *file_source,
+			  GFile         *folder,
+			  const char    *attributes,
+			  ListReady      func,
+			  gpointer       user_data)
 {
 	GthFileSourceVfs *file_source_vfs = (GthFileSourceVfs *) file_source;
 	GFile            *gio_folder;
 
 	gth_file_source_set_active (file_source, TRUE);
-	g_cancellable_reset (file_source_vfs->priv->cancellable);
+	g_cancellable_reset (gth_file_source_get_cancellable (file_source));
 
 	_g_object_list_unref (file_source_vfs->priv->files);
 	file_source_vfs->priv->files = NULL;
@@ -223,7 +225,7 @@ list (GthFileSource *file_source,
 				   FALSE,
 				   TRUE,
 				   attributes,
-				   file_source_vfs->priv->cancellable,
+				   gth_file_source_get_cancellable (file_source),
 				   list__start_dir_func,
 				   list__for_each_file_func,
 				   list__done_func,
@@ -233,66 +235,6 @@ list (GthFileSource *file_source,
 }
 
 
-static void
-info_ready_cb (GList    *files,
-	       GError   *error,
-	       gpointer  user_data)
-{
-	GthFileSourceVfs *file_source_vfs = user_data;
-	GList            *scan;
-	GList            *result_files;
-
-	if (G_IS_OBJECT (file_source_vfs))
-		gth_file_source_set_active (GTH_FILE_SOURCE (file_source_vfs), FALSE);
-
-	result_files = NULL;
-	for (scan = files; scan; scan = scan->next)
-		result_files = g_list_prepend (result_files, g_object_ref ((GthFileData *) scan->data));
-	result_files = g_list_reverse (result_files);
-
-	file_source_vfs->priv->ready_func ((GthFileSource *) file_source_vfs,
-					   result_files,
-					   error,
-					   file_source_vfs->priv->ready_data);
-
-	_g_object_list_unref (result_files);
-	g_object_unref (file_source_vfs);
-}
-
-
-static void
-read_attributes (GthFileSource *file_source,
-		 GList         *files,
-		 const char    *attributes,
-		 ListReady      func,
-		 gpointer       user_data)
-{
-	GthFileSourceVfs *file_source_vfs = (GthFileSourceVfs *) file_source;
-
-	gth_file_source_set_active (file_source, TRUE);
-	g_cancellable_reset (file_source_vfs->priv->cancellable);
-
-	file_source_vfs->priv->ready_func = func;
-	file_source_vfs->priv->ready_data = user_data;
-
-	g_object_ref (file_source_vfs);
-	g_query_info_async (files,
-			    attributes,
-			    file_source_vfs->priv->cancellable,
-			    info_ready_cb,
-			    file_source_vfs);
-}
-
-
-static void
-cancel (GthFileSource *file_source)
-{
-	GthFileSourceVfs *file_source_vfs = (GthFileSourceVfs *) file_source;
-
-	g_cancellable_cancel (file_source_vfs->priv->cancellable);
-}
-
-
 /* -- gth_file_source_vfs_copy -- */
 
 
@@ -352,7 +294,7 @@ copy__copy_files (CopyOpData *cod)
 			     destinations,
 			     G_FILE_COPY_NONE,
 			     G_PRIORITY_DEFAULT,
-			     cod->file_source->priv->cancellable,
+			     gth_file_source_get_cancellable (GTH_FILE_SOURCE (cod->file_source)),
 			     NULL,
 			     NULL,
 			     copy__copy_files_done,
@@ -402,7 +344,7 @@ copy__copy_current_dir (CopyOpData *cod)
 				destination,
 				G_FILE_COPY_NONE,
 				G_PRIORITY_DEFAULT,
-				cod->file_source->priv->cancellable,
+				gth_file_source_get_cancellable (GTH_FILE_SOURCE (cod->file_source)),
 				NULL,
 				NULL,
 				copy__copy_current_dir_done,
@@ -462,7 +404,7 @@ gth_file_source_vfs_copy (GthFileSource *file_source,
 
 	g_query_info_async (cod->file_list,
 			    G_FILE_ATTRIBUTE_STANDARD_TYPE,
-			    cod->file_source->priv->cancellable,
+			    gth_file_source_get_cancellable (GTH_FILE_SOURCE (cod->file_source)),
 			    copy__file_list_info_ready_cb,
 			    cod);
 }
@@ -484,7 +426,7 @@ mount_monitor_mountpoints_changed_cb (GUnixMountMonitor *monitor,
 
 
 static void
-monitor_entry_points (GthFileSource *file_source)
+gth_file_source_vfs_monitor_entry_points (GthFileSource *file_source)
 {
 	GthFileSourceVfs *file_source_vfs = (GthFileSourceVfs *) file_source;
 
@@ -647,9 +589,9 @@ monitor_changed_cb (GFileMonitor      *file_monitor,
 
 
 static void
-monitor_directory (GthFileSource *file_source,
-		   GFile         *file,
-		   gboolean       activate)
+gth_file_source_vfs_monitor_directory (GthFileSource *file_source,
+				       GFile         *file,
+				       gboolean       activate)
 {
 	GthFileSourceVfs *file_source_vfs = (GthFileSourceVfs *) file_source;
 	GFileMonitor     *monitor;
@@ -711,16 +653,14 @@ gth_file_source_vfs_class_init (GthFileSourceVfsClass *class)
 	file_source_class = (GthFileSourceClass*) class;
 
 	object_class->finalize = gth_file_source_vfs_finalize;
-	file_source_class->get_entry_points = get_entry_points;
-	file_source_class->to_gio_file = to_gio_file;
-	file_source_class->get_file_info = get_file_info;
-	file_source_class->list = list;
-	file_source_class->read_attributes = read_attributes;
-	file_source_class->cancel = cancel;
+	file_source_class->get_entry_points = gth_file_source_vfs_get_entry_points;
+	file_source_class->to_gio_file = gth_file_source_vfs_to_gio_file;
+	file_source_class->get_file_info = gth_file_source_vfs_get_file_info;
+	file_source_class->list = gth_file_source_vfs_list;
 	file_source_class->copy = gth_file_source_vfs_copy;
 	file_source_class->can_cut = gth_file_source_vfs_can_cut;
-	file_source_class->monitor_entry_points = monitor_entry_points;
-	file_source_class->monitor_directory = monitor_directory;
+	file_source_class->monitor_entry_points = gth_file_source_vfs_monitor_entry_points;
+	file_source_class->monitor_directory = gth_file_source_vfs_monitor_directory;
 }
 
 
@@ -731,7 +671,6 @@ gth_file_source_vfs_init (GthFileSourceVfs *file_source)
 
 	file_source->priv = g_new0 (GthFileSourceVfsPrivate, 1);
 	gth_file_source_add_scheme (GTH_FILE_SOURCE (file_source), "vfs+");
-	file_source->priv->cancellable = g_cancellable_new ();
 	file_source->priv->monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, g_object_unref);
 	for (i = 0; i < GTH_MONITOR_N_EVENTS; i++)
 		file_source->priv->monitor_queue[i] = NULL;
diff --git a/gthumb/gth-file-source.c b/gthumb/gth-file-source.c
index 7ebd28a..79be24d 100644
--- a/gthumb/gth-file-source.c
+++ b/gthumb/gth-file-source.c
@@ -33,9 +33,10 @@
 
 struct _GthFileSourcePrivate
 {
-	GList    *schemes;
-	gboolean  active;
-	GList    *queue;
+	GList        *schemes;
+	gboolean      active;
+	GList        *queue;
+	GCancellable *cancellable;
 };
 
 
@@ -314,6 +315,15 @@ base_get_file_info (GthFileSource *file_source,
 }
 
 
+static GthFileData *
+base_get_file_data (GthFileSource  *file_source,
+		    GFile          *file,
+		    GFileInfo      *info)
+{
+	return gth_file_data_new (file, info);
+}
+
+
 static void
 base_list (GthFileSource *file_source,
 	   GFile         *folder,
@@ -326,24 +336,6 @@ base_list (GthFileSource *file_source,
 
 
 static void
-base_read_attributes (GthFileSource *file_source,
-		      GList         *files,
-		      const char    *attributes,
-		      ListReady      func,
-		      gpointer       data)
-{
-	/* void */
-}
-
-
-static void
-base_cancel (GthFileSource *file_source)
-{
-	/* void */
-}
-
-
-static void
 base_rename (GthFileSource *file_source,
 	     GFile         *file,
 	     GFile         *new_file,
@@ -401,6 +393,7 @@ gth_file_source_finalize (GObject *object)
 	if (file_source->priv != NULL) {
 		gth_file_source_clear_queue (file_source);
 		_g_string_list_free (file_source->priv->schemes);
+		g_object_unref (file_source->priv->cancellable);
 
 		g_free (file_source->priv);
 		file_source->priv = NULL;
@@ -423,9 +416,8 @@ gth_file_source_class_init (GthFileSourceClass *class)
 	class->get_current_list = base_get_current_list;
 	class->to_gio_file = base_to_gio_file;
 	class->get_file_info = base_get_file_info;
+	class->get_file_data = base_get_file_data;
 	class->list = base_list;
-	class->read_attributes = base_read_attributes;
-	class->cancel = base_cancel;
 	class->rename = base_rename;
 	class->can_cut = base_can_cut;
 	class->monitor_entry_points = base_monitor_entry_points;
@@ -437,6 +429,7 @@ static void
 gth_file_source_init (GthFileSource *file_source)
 {
 	file_source->priv = g_new0 (GthFileSourcePrivate, 1);
+	file_source->priv->cancellable = g_cancellable_new ();
 }
 
 
@@ -552,6 +545,15 @@ gth_file_source_get_file_info (GthFileSource *file_source,
 }
 
 
+GthFileData *
+gth_file_source_get_file_data (GthFileSource *file_source,
+			       GFile         *file,
+			       GFileInfo     *info)
+{
+	return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_file_data (file_source, file, info);
+}
+
+
 gboolean
 gth_file_source_is_active (GthFileSource *file_source)
 {
@@ -559,11 +561,18 @@ gth_file_source_is_active (GthFileSource *file_source)
 }
 
 
+GCancellable *
+gth_file_source_get_cancellable (GthFileSource *file_source)
+{
+	return file_source->priv->cancellable;
+}
+
+
 void
 gth_file_source_cancel (GthFileSource *file_source)
 {
 	gth_file_source_clear_queue (file_source);
-	GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->cancel (file_source);
+	g_cancellable_cancel (file_source->priv->cancellable);
 }
 
 
@@ -582,18 +591,81 @@ gth_file_source_list (GthFileSource *file_source,
 }
 
 
+/* -- gth_file_source_read_attributes -- */
+
+
+typedef struct {
+	GthFileSource *file_source;
+	ListReady      ready_func;
+	gpointer       ready_data;
+} ReadAttributesOpData;
+
+
+
+static void
+read_attributes_op_data_free (ReadAttributesOpData *data)
+{
+	g_object_unref (data->file_source);
+	g_free (data);
+}
+
+
+static void
+metadata_ready_cb (GList    *files,
+	           GError   *error,
+	           gpointer  user_data)
+{
+	ReadAttributesOpData *data = user_data;
+	GList                *scan;
+	GList                *result_files;
+
+	gth_file_source_set_active (data->file_source, FALSE);
+
+	result_files = NULL;
+	for (scan = files; scan; scan = scan->next) {
+		GthFileData *file_data = scan->data;
+		result_files = g_list_prepend (result_files, gth_file_source_get_file_data (data->file_source, file_data->file, file_data->info));
+	}
+	result_files = g_list_reverse (result_files);
+
+	data->ready_func (data->file_source,
+			  result_files,
+			  error,
+			  data->ready_data);
+
+	_g_object_list_unref (result_files);
+	read_attributes_op_data_free (data);
+}
+
+
 void
 gth_file_source_read_attributes (GthFileSource  *file_source,
 				 GList          *files,
 				 const char     *attributes,
 				 ListReady       func,
-				 gpointer        data)
+				 gpointer        user_data)
 {
+	ReadAttributesOpData *data;
+	GList                *gio_files;
+
 	if (gth_file_source_is_active (file_source)) {
 		gth_file_source_queue_read_attributes (file_source, files, attributes, func, data);
 		return;
 	}
-	GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->read_attributes (file_source, files, attributes, func, data);
+
+	data = g_new0 (ReadAttributesOpData, 1);
+	data->file_source = g_object_ref (file_source);
+	data->ready_func = func;
+	data->ready_data = user_data;
+
+	gio_files = gth_file_source_to_gio_file_list (file_source, files);
+	_g_query_all_metadata_async (gio_files,
+				     attributes,
+				     file_source->priv->cancellable,
+				     metadata_ready_cb,
+				     data);
+
+	_g_object_list_unref (gio_files);
 }
 
 
diff --git a/gthumb/gth-file-source.h b/gthumb/gth-file-source.h
index 40cf2cc..3a9d7b1 100644
--- a/gthumb/gth-file-source.h
+++ b/gthumb/gth-file-source.h
@@ -55,8 +55,8 @@ struct _GthFileSource
 
 	/*< protected >*/
 
-	GList *folders; /* list of GthFileData */
-	GList *files;   /* list of GthFileData */
+	GList        *folders; /* list of GthFileData */
+	GList        *files;   /* list of GthFileData */
 };
 
 struct _GthFileSourceClass
@@ -73,17 +73,14 @@ struct _GthFileSourceClass
 	GFileInfo *  (*get_file_info)         (GthFileSource  *file_source,
 					       GFile          *file,
 					       const char     *attributes);
+	GthFileData *(*get_file_data)         (GthFileSource  *file_source,
+					       GFile          *file,
+					       GFileInfo      *info);
 	void         (*list)                  (GthFileSource  *file_source,
 					       GFile          *folder,
 					       const char     *attributes,
 					       ListReady       func,
 					       gpointer        data);
-	void         (*read_attributes)       (GthFileSource  *file_source,
-					       GList          *files,
-					       const char     *attributes,
-					       ListReady       func,
-					       gpointer        data);
-	void         (*cancel)                (GthFileSource  *file_source);
 	void         (*rename)                (GthFileSource  *file_source,
 					       GFile          *file,
 					       GFile          *new_file,
@@ -124,7 +121,11 @@ GList *      gth_file_source_to_gio_file_list      (GthFileSource  *file_source,
 GFileInfo *  gth_file_source_get_file_info         (GthFileSource  *file_source,
 						    GFile          *file,
 						    const char     *attributes);
+GthFileData *gth_file_source_get_file_data         (GthFileSource  *file_source,
+					            GFile          *file,
+					            GFileInfo      *info);
 gboolean     gth_file_source_is_active             (GthFileSource  *file_source);
+GCancellable *gth_file_source_get_cancellable      (GthFileSource  *file_source);
 void         gth_file_source_cancel                (GthFileSource  *file_source);
 void         gth_file_source_list                  (GthFileSource  *file_source,
 						    GFile          *folder,
diff --git a/gthumb/gth-file-store.c b/gthumb/gth-file-store.c
index ea2bc43..4534d7f 100644
--- a/gthumb/gth-file-store.c
+++ b/gthumb/gth-file-store.c
@@ -156,7 +156,6 @@ _gth_file_store_clear_queue (GthFileStore *file_store)
 	g_list_free (file_store->priv->queue);
 	file_store->priv->queue = NULL;
 	file_store->priv->queue_size = 0;
-	file_store->priv->update_filter = FALSE;
 }
 
 
@@ -1312,8 +1311,10 @@ gth_file_store_exec_set (GthFileStore *file_store)
 {
 	_gth_file_store_list_changed (file_store);
 	_gth_file_store_clear_queue (file_store);
-	if (file_store->priv->update_filter)
+	if (file_store->priv->update_filter) {
 		_gth_file_store_update_visibility (file_store, NULL);
+		file_store->priv->update_filter = FALSE;
+	}
 }
 
 
diff --git a/gthumb/gth-metadata-provider.c b/gthumb/gth-metadata-provider.c
index 4f31f18..124a9f0 100644
--- a/gthumb/gth-metadata-provider.c
+++ b/gthumb/gth-metadata-provider.c
@@ -493,3 +493,83 @@ _g_write_metadata_async (GList         *files, /* GthFileData * list */
 	wmd->thread = g_thread_create (write_metadata_thread, wmtd, TRUE, NULL);
 	wmd->check_id = g_timeout_add (CHECK_THREAD_RATE, check_write_metadata_thread, wmd);
 }
+
+
+/* -- _g_query_all_metadata_async -- */
+
+
+typedef struct {
+	GList             *files;
+	char              *attributes;
+	GCancellable      *cancellable;
+	InfoReadyCallback  ready_func;
+	gpointer           user_data;
+} QueryAllMetadata;
+
+
+static void
+query_all_metadata_free (QueryAllMetadata *qam)
+{
+	_g_object_list_unref (qam->files);
+	g_free (qam->attributes);
+	_g_object_unref (qam->cancellable);
+	g_free (qam);
+}
+
+
+static void
+qam_metadata_ready_cb (GList    *files,
+		       GError   *error,
+		       gpointer  user_data)
+{
+	QueryAllMetadata *qam = user_data;
+
+	qam->ready_func (qam->files, error, qam->user_data);
+	query_all_metadata_free (qam);
+}
+
+
+static void
+qam_info_ready_cb (GList    *files,
+		   GError   *error,
+		   gpointer  user_data)
+{
+	QueryAllMetadata *qam = user_data;
+
+	if (error != NULL) {
+		qam->ready_func (NULL, error, qam->user_data);
+		query_all_metadata_free (qam);
+		return;
+	}
+
+	qam->files = _g_object_list_ref (files);
+	_g_query_metadata_async (qam->files,
+				 qam->attributes,
+				 qam->cancellable,
+				 qam_metadata_ready_cb,
+				 qam);
+}
+
+
+void
+_g_query_all_metadata_async (GList             *files, /* GFile * list */
+			     const char        *attributes,
+			     GCancellable      *cancellable,
+			     InfoReadyCallback  ready_func,
+			     gpointer           user_data)
+{
+	QueryAllMetadata *qam;
+
+	qam = g_new0 (QueryAllMetadata, 1);
+	qam->attributes = g_strdup (attributes);
+	if (cancellable != NULL)
+		qam->cancellable = g_object_ref (cancellable);
+	qam->ready_func = ready_func;
+	qam->user_data = user_data;
+
+	g_query_info_async (files,
+			    qam->attributes,
+			    qam->cancellable,
+			    qam_info_ready_cb,
+			    qam);
+}
diff --git a/gthumb/gth-metadata-provider.h b/gthumb/gth-metadata-provider.h
index e1d20d6..7e886a9 100644
--- a/gthumb/gth-metadata-provider.h
+++ b/gthumb/gth-metadata-provider.h
@@ -58,9 +58,9 @@ struct _GthMetadataProviderClass {
 
 GType                   gth_metadata_provider_get_type   (void);
 GthMetadataProvider *   gth_metadata_provider_new        (void);
-gboolean                gth_metadata_provider_can_read   (GthMetadataProvider  *self, 
+gboolean                gth_metadata_provider_can_read   (GthMetadataProvider  *self,
 						          char                **attribute_v);
-gboolean                gth_metadata_provider_can_write  (GthMetadataProvider  *self, 
+gboolean                gth_metadata_provider_can_write  (GthMetadataProvider  *self,
 						          char                **attribute_v);
 void                    gth_metadata_provider_read       (GthMetadataProvider  *self,
 							  GthFileData          *file_data,
@@ -78,6 +78,11 @@ void                    _g_write_metadata_async          (GList                *
 							  GCancellable         *cancellable,
 							  ReadyFunc             ready_func,
 							  gpointer              user_data);
+void                    _g_query_all_metadata_async      (GList                *files, /* GFile * list */
+							  const char           *attributes,
+							  GCancellable         *cancellable,
+							  InfoReadyCallback     ready_func,
+							  gpointer              user_data);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-string-list.c b/gthumb/gth-string-list.c
index f846c4f..7e4172e 100644
--- a/gthumb/gth-string-list.c
+++ b/gthumb/gth-string-list.c
@@ -32,25 +32,25 @@ struct _GthStringListPrivate {
 static gpointer gth_string_list_parent_class = NULL;
 
 
-static void 
-gth_string_list_finalize (GObject* obj) 
+static void
+gth_string_list_finalize (GObject* obj)
 {
 	GthStringList *self;
-	
+
 	self = GTH_STRING_LIST (obj);
-	
+
 	_g_string_list_free (self->priv->list);
-	
+
 	G_OBJECT_CLASS (gth_string_list_parent_class)->finalize (obj);
 }
 
 
-static void 
-gth_string_list_class_init (GthStringListClass * klass) 
+static void
+gth_string_list_class_init (GthStringListClass * klass)
 {
 	gth_string_list_parent_class = g_type_class_peek_parent (klass);
 	g_type_class_add_private (klass, sizeof (GthStringListPrivate));
-	
+
 	G_OBJECT_CLASS (klass)->finalize = gth_string_list_finalize;
 }
 
@@ -63,17 +63,17 @@ static void gth_string_list_instance_init (GthStringList * self) {
 GType gth_string_list_get_type (void) {
 	static GType gth_string_list_type_id = 0;
 	if (gth_string_list_type_id == 0) {
-		static const GTypeInfo g_define_type_info = { 
-			sizeof (GthStringListClass), 
-			(GBaseInitFunc) NULL, 
-			(GBaseFinalizeFunc) NULL, 
-			(GClassInitFunc) gth_string_list_class_init, 
-			(GClassFinalizeFunc) NULL, 
-			NULL, 
-			sizeof (GthStringList), 
-			0, 
-			(GInstanceInitFunc) gth_string_list_instance_init, 
-			NULL 
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthStringListClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gth_string_list_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (GthStringList),
+			0,
+			(GInstanceInitFunc) gth_string_list_instance_init,
+			NULL
 		};
 		gth_string_list_type_id = g_type_register_static (G_TYPE_OBJECT, "GthStringList", &g_define_type_info, 0);
 	}
@@ -81,15 +81,15 @@ GType gth_string_list_get_type (void) {
 }
 
 
-GthStringList * 
-gth_string_list_new (GList *list) 
+GthStringList *
+gth_string_list_new (GList *list)
 {
 	GthStringList *string_list;
-	
+
 	string_list = g_object_new (GTH_TYPE_STRING_LIST, NULL);
 	string_list->priv->list = _g_string_list_dup (list);
-	
-	return string_list; 
+
+	return string_list;
 }
 
 
@@ -98,7 +98,7 @@ gth_string_list_new_from_ptr_array (GPtrArray *array)
 {
 	GthStringList *string_list;
 	int            i;
-	
+
 	string_list = g_object_new (GTH_TYPE_STRING_LIST, NULL);
 	if (array != NULL) {
 		for (i = 0; i < array->len; i++)
@@ -107,7 +107,7 @@ gth_string_list_new_from_ptr_array (GPtrArray *array)
 	}
 	else
 		string_list->priv->list = NULL;
-	
+
 	return string_list;
 }
 
@@ -117,3 +117,22 @@ gth_string_list_get_list (GthStringList *list)
 {
 	return list->priv->list;
 }
+
+
+char *
+gth_string_list_join (GthStringList *list,
+		      const char    *separator)
+{
+	GString *str;
+	GList   *scan;
+
+	str = g_string_new ("");
+	for (scan = list->priv->list; scan; scan = scan->next) {
+		if (scan != list->priv->list)
+			g_string_append (str, separator);
+		g_string_append (str, (char *) scan->data);
+	}
+
+	return g_string_free (str, FALSE);
+}
+
diff --git a/gthumb/gth-string-list.h b/gthumb/gth-string-list.h
index cac473b..4bd9fa5 100644
--- a/gthumb/gth-string-list.h
+++ b/gthumb/gth-string-list.h
@@ -52,6 +52,8 @@ GType             gth_string_list_get_type            (void);
 GthStringList *   gth_string_list_new                 (GList         *list);
 GthStringList *   gth_string_list_new_from_ptr_array  (GPtrArray     *array);
 GList *           gth_string_list_get_list            (GthStringList *list);
+char *            gth_string_list_join                (GthStringList *list,
+						       const char    *separator);
 
 G_END_DECLS
 



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