[gthumb] selections: fixed reordering of files
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] selections: fixed reordering of files
- Date: Mon, 26 Mar 2012 17:10:45 +0000 (UTC)
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]