[gthumb] selections: fixed reordering of files



commit dae19e5a2edf0ddcc7f2b29f71c1ecccd72e848f
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Mar 26 19:10:09 2012 +0200

    selections: fixed reordering of files

 extensions/catalogs/gth-file-source-catalogs.c     |   84 ++---------------
 extensions/selections/gth-file-source-selections.c |    5 +
 extensions/selections/gth-selections-manager.c     |   89 +++++++++++++++++-
 extensions/selections/gth-selections-manager.h     |    3 +
 gthumb/gio-utils.c                                 |    2 +-
 gthumb/glib-utils.c                                |   97 ++++++++++++++++++++
 gthumb/glib-utils.h                                |    6 +
 7 files changed, 205 insertions(+), 81 deletions(-)
---
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index 82e3a3e..bbd9612 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -1206,90 +1206,24 @@ reorder_buffer_ready_cb (void     **buffer,
 }
 
 
-static int
-remove_from_file_list_and_get_position (GList **file_list,
-					GFile  *file)
-{
-	GList *scan;
-	int    i = 0;
-
-	for (scan = *file_list; scan; scan = scan->next, i++)
-		if (g_file_equal ((GFile *) scan->data, file))
-			break;
-
-	if (scan == NULL)
-		return -1;
-
-	*file_list = g_list_remove_link (*file_list, scan);
-
-	return i;
-}
-
-
 static int *
 reorder_catalog_list (GthCatalog *catalog,
 		      GList      *visible_files,
 		      GList      *files_to_move,
 		      int         dest_pos)
 {
-	GHashTable *positions;
-	GList      *new_visible_files;
-	GList      *scan;
-	int        *new_order;
-	int         pos;
-	GList      *new_file_list;
-	GHashTable *visibles;
-
-	/* save the original positions */
-
-	positions = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, (GDestroyNotify) g_object_unref, NULL);
-	for (scan = visible_files, pos = 0; scan; scan = scan->next, pos++)
-		g_hash_table_insert (positions, g_object_ref ((GFile *) scan->data), GINT_TO_POINTER (pos));
-
-	/* create the new visible list */
-
-	new_visible_files = g_list_copy (visible_files);
-
-	for (scan = files_to_move; scan; scan = scan->next) {
-		int file_pos = remove_from_file_list_and_get_position (&new_visible_files, (GFile *) scan->data);
-		if (file_pos < dest_pos)
-			dest_pos--;
-	}
-
-	for (scan = files_to_move; scan; scan = scan->next) {
-		new_visible_files = g_list_insert (new_visible_files, (GFile *) scan->data, dest_pos);
-		dest_pos++;
-	}
-
-	/* compute the new order */
-
-	new_order = g_new0 (int, g_list_length (new_visible_files));
-	for (scan = new_visible_files, pos = 0; scan; scan = scan->next, pos++)
-		new_order[pos] = GPOINTER_TO_INT (g_hash_table_lookup (positions, (GFile *) scan->data));
-
-	/* save the new order in the catalog, appending the hidden files at
-	 * the end. */
-
-	new_file_list = _g_object_list_ref (new_visible_files);
-
-	visibles = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, (GDestroyNotify) g_object_unref, NULL);
-	for (scan = new_visible_files; scan; scan = scan->next)
-		g_hash_table_insert (visibles, g_object_ref ((GFile *) scan->data), GINT_TO_POINTER (1));
-
-	new_file_list = g_list_reverse (new_file_list);
-	for (scan = gth_catalog_get_file_list (catalog); scan; scan = scan->next) {
-		GFile *file = scan->data;
-
-		if (g_hash_table_lookup (visibles, file) == NULL)
-			new_file_list = g_list_prepend (new_file_list, g_object_ref (file));
-	}
-	new_file_list = g_list_reverse (new_file_list);
+	int   *new_order;
+	GList *new_file_list;
+
+	_g_list_reorder (gth_catalog_get_file_list (catalog),
+			 visible_files,
+			 files_to_move,
+			 dest_pos,
+			 &new_order,
+			 &new_file_list);
 	gth_catalog_set_file_list (catalog, new_file_list);
 
 	_g_object_list_unref (new_file_list);
-	g_hash_table_destroy (visibles);
-	g_list_free (new_visible_files);
-	g_hash_table_destroy (positions);
 
 	return new_order;
 }
diff --git a/extensions/selections/gth-file-source-selections.c b/extensions/selections/gth-file-source-selections.c
index 35a2236..ce28c07 100644
--- a/extensions/selections/gth-file-source-selections.c
+++ b/extensions/selections/gth-file-source-selections.c
@@ -118,6 +118,11 @@ gth_file_source_selections_write_metadata (GthFileSource *file_source,
 					   ReadyCallback  callback,
 					   gpointer       user_data)
 {
+	if (_g_file_attributes_matches_any (attributes, "sort::*"))
+		gth_selections_manager_set_sort_type (file_data->file,
+						      g_file_info_get_attribute_string (file_data->info, "sort::type"),
+						      g_file_info_get_attribute_boolean (file_data->info, "sort::inverse"));
+
 	object_ready_with_error (file_source, callback, user_data, NULL);
 }
 
diff --git a/extensions/selections/gth-selections-manager.c b/extensions/selections/gth-selections-manager.c
index c7cc14a..5ba4c2b 100644
--- a/extensions/selections/gth-selections-manager.c
+++ b/extensions/selections/gth-selections-manager.c
@@ -31,8 +31,10 @@
 
 
 struct _GthSelectionsManagerPrivate {
-	GList  *files[N_SELECTIONS];
-	GMutex *mutex;
+	GList    *files[N_SELECTIONS];
+	char     *order[N_SELECTIONS];
+	gboolean  order_inverse[N_SELECTIONS];
+	GMutex   *mutex;
 };
 
 
@@ -70,8 +72,10 @@ gth_selections_manager_finalize (GObject *object)
 
 	self = GTH_SELECTIONS_MANAGER (object);
 
-	for (i = 0; i < N_SELECTIONS; i++)
+	for (i = 0; i < N_SELECTIONS; i++) {
 		_g_object_list_unref (self->priv->files[i]);
+		g_free (self->priv->order[i]);
+	}
 	g_mutex_free (self->priv->mutex);
 
 	G_OBJECT_CLASS (gth_selections_manager_parent_class)->finalize (object);
@@ -97,8 +101,11 @@ gth_selections_manager_init (GthSelectionsManager *self)
 
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_SELECTIONS_MANAGER, GthSelectionsManagerPrivate);
 	self->priv->mutex = g_mutex_new ();
-	for (i = 0; i < N_SELECTIONS; i++)
+	for (i = 0; i < N_SELECTIONS; i++) {
 		self->priv->files[i] = NULL;
+		self->priv->order[i] = NULL;
+		self->priv->order_inverse[i] = FALSE;
+	}
 }
 
 
@@ -201,6 +208,8 @@ gth_selections_manager_update_file_info (GFile     *file,
 
 	g_file_info_set_sort_order (info, n_selection);
 	g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+	if (n_selection > 0)
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
 	g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
 	g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE);
 	g_file_info_set_attribute_int32 (info, "gthumb::n-selection", n_selection);
@@ -245,6 +254,23 @@ gth_selections_manager_update_file_info (GFile     *file,
 	g_file_info_set_name (info, name);
 
 	g_free (name);
+
+	/* sort order */
+
+	if (n_selection > 0) {
+		GthSelectionsManager *self;
+
+		self = gth_selections_manager_get_default ();
+
+		if (self->priv->order[n_selection] != NULL) {
+			g_file_info_set_attribute_string (info, "sort::type", self->priv->order[n_selection - 1]);
+			g_file_info_set_attribute_boolean (info, "sort::inverse", self->priv->order_inverse[n_selection - 1]);
+		}
+		else {
+			g_file_info_remove_attribute (info, "sort::type");
+			g_file_info_remove_attribute (info, "sort::inverse");
+		}
+	}
 }
 
 
@@ -423,7 +449,60 @@ gth_selections_manager_reorder (GFile *folder,
 				GList *files_to_move, /* GFile list */
 				int    dest_pos)
 {
-	/* FIXME */
+	GthSelectionsManager *self;
+	int                   n_selection;
+	int                  *new_order;
+	GList                *new_file_list;
+
+	n_selection = _g_file_get_n_selection (folder);
+	if (n_selection <= 0)
+		return;
+
+	self = gth_selections_manager_get_default ();
+
+	/* reorder the file list */
+
+	g_mutex_lock (self->priv->mutex);
+	_g_list_reorder (self->priv->files[n_selection - 1],
+			 visible_files,
+			 files_to_move,
+			 dest_pos,
+			 &new_order,
+			 &new_file_list);
+	_g_object_list_unref (self->priv->files[n_selection - 1]);
+	self->priv->files[n_selection - 1] = new_file_list;
+	g_mutex_unlock (self->priv->mutex);
+
+	gth_selections_manager_set_sort_type (folder, "general::unsorted", FALSE);
+
+	gth_monitor_order_changed (gth_main_get_default_monitor (),
+				   folder,
+				   new_order);
+
+	g_free (new_order);
+}
+
+
+void
+gth_selections_manager_set_sort_type (GFile      *folder,
+				      const char *sort_type,
+				      gboolean    sort_inverse)
+{
+	GthSelectionsManager *self;
+	int                   n_selection;
+
+	n_selection = _g_file_get_n_selection (folder);
+	if (n_selection <= 0)
+		return;
+
+	self = gth_selections_manager_get_default ();
+	g_mutex_lock (self->priv->mutex);
+
+	g_free (self->priv->order[n_selection - 1]);
+	self->priv->order[n_selection - 1] = g_strdup (sort_type);
+	self->priv->order_inverse[n_selection - 1] = sort_inverse;
+
+	g_mutex_unlock (self->priv->mutex);
 }
 
 
diff --git a/extensions/selections/gth-selections-manager.h b/extensions/selections/gth-selections-manager.h
index 08ac363..f6294a1 100644
--- a/extensions/selections/gth-selections-manager.h
+++ b/extensions/selections/gth-selections-manager.h
@@ -65,6 +65,9 @@ void     gth_selections_manager_reorder          (GFile                *folder,
 						  GList                *visible_files, /* GFile list */
 						  GList                *files_to_move, /* GFile list */
 						  int                   dest_pos);
+void     gth_selections_manager_set_sort_type    (GFile                *folder,
+						  const char           *sort_type,
+						  gboolean              sort_inverse);
 void     gth_selections_manager_update_file_info (GFile                *file,
 						  GFileInfo            *info);
 
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 68f8ba3..3fedbf8 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -183,7 +183,7 @@ typedef struct {
 	ChildData            *current;
 	GHashTable           *already_visited;
 	GList                *to_visit;
-	const char           *attributes;
+	char                 *attributes;
 	GCancellable         *cancellable;
 	GFileEnumerator      *enumerator;
 	GError               *error;
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index 2a1b6ce..80214a9 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -1028,6 +1028,103 @@ _g_utf8_remove_extension (const char *str)
 }
 
 
+static int
+remove_from_file_list_and_get_position (GList **file_list,
+					GFile  *file)
+{
+	GList *scan;
+	int    i = 0;
+
+	for (scan = *file_list; scan; scan = scan->next, i++)
+		if (g_file_equal ((GFile *) scan->data, file))
+			break;
+
+	if (scan == NULL)
+		return -1;
+
+	*file_list = g_list_remove_link (*file_list, scan);
+
+	return i;
+}
+
+
+void
+_g_list_reorder (GList  *all_files,
+		 GList  *visible_files,
+		 GList  *files_to_move,
+		 int     dest_pos,
+		 int   **new_order_p,
+		 GList **new_file_list_p)
+{
+	GHashTable *positions;
+	GList      *new_visible_files;
+	GList      *scan;
+	int        *new_order;
+	int         pos;
+	GList      *new_file_list;
+	GHashTable *visibles;
+
+	/* save the original positions */
+
+	positions = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, (GDestroyNotify) g_object_unref, NULL);
+	for (scan = visible_files, pos = 0; scan; scan = scan->next, pos++)
+		g_hash_table_insert (positions, g_object_ref ((GFile *) scan->data), GINT_TO_POINTER (pos));
+
+	/* create the new visible list */
+
+	new_visible_files = g_list_copy (visible_files);
+
+	for (scan = files_to_move; scan; scan = scan->next) {
+		int file_pos = remove_from_file_list_and_get_position (&new_visible_files, (GFile *) scan->data);
+		if (file_pos < dest_pos)
+			dest_pos--;
+	}
+
+	for (scan = files_to_move; scan; scan = scan->next) {
+		new_visible_files = g_list_insert (new_visible_files, (GFile *) scan->data, dest_pos);
+		dest_pos++;
+	}
+
+	/* compute the new order */
+
+	new_order = g_new0 (int, g_list_length (new_visible_files));
+	for (scan = new_visible_files, pos = 0; scan; scan = scan->next, pos++)
+		new_order[pos] = GPOINTER_TO_INT (g_hash_table_lookup (positions, (GFile *) scan->data));
+
+	/* save the new order in the catalog, appending the hidden files at
+	 * the end. */
+
+	new_file_list = _g_object_list_ref (new_visible_files);
+
+	visibles = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, (GDestroyNotify) g_object_unref, NULL);
+	for (scan = new_visible_files; scan; scan = scan->next)
+		g_hash_table_insert (visibles, g_object_ref ((GFile *) scan->data), GINT_TO_POINTER (1));
+
+	new_file_list = g_list_reverse (new_file_list);
+	for (scan = all_files; scan; scan = scan->next) {
+		GFile *file = scan->data;
+
+		if (g_hash_table_lookup (visibles, file) == NULL)
+			new_file_list = g_list_prepend (new_file_list, g_object_ref (file));
+	}
+	new_file_list = g_list_reverse (new_file_list);
+
+	if (new_order_p != NULL)
+		*new_order_p = new_order;
+	else
+		g_free (new_order);
+
+	if (new_file_list_p != NULL)
+		*new_file_list_p = new_file_list;
+	else
+		_g_object_list_unref (new_file_list);
+
+	g_hash_table_destroy (visibles);
+	g_list_free (new_visible_files);
+	g_hash_table_destroy (positions);
+}
+
+
 GList *
 _g_list_insert_list_before (GList *list1,
 			    GList *sibling,
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 799a339..28fd1d8 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -184,6 +184,12 @@ char *          _g_utf8_remove_extension         (const char  *str);
 GList *         _g_list_insert_list_before       (GList       *list1,
 						  GList       *sibling,
 						  GList       *list2);
+void            _g_list_reorder                  (GList       *all_files,
+						  GList       *visible_files,
+						  GList       *files_to_move,
+						  int          dest_pos,
+						  int        **new_order_p,
+						  GList      **new_file_list_p);
 const char *    get_static_string                (const char  *s);
 char *          _g_rand_string                   (int          len);
 int             _g_strv_find                     (char       **v,



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