[gthumb/ext] do not reload a catalog after a reorder operation



commit 1739a22bbde8f4bd2d9e6f6cce04f298c43d03cb
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Thu Aug 27 14:41:35 2009 +0200

    do not reload a catalog after a reorder operation

 extensions/catalogs/gth-file-source-catalogs.c |   39 +++++++++-----
 gthumb/gth-browser.c                           |   25 +++++++++
 gthumb/gth-file-store.c                        |   66 ++++++++++++++++++++----
 gthumb/gth-file-store.h                        |    2 +
 gthumb/gth-marshal.list                        |    5 +-
 gthumb/gth-monitor.c                           |   27 ++++++++++
 gthumb/gth-monitor.h                           |    6 ++
 7 files changed, 144 insertions(+), 26 deletions(-)
---
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index f875a52..5f713a0 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -719,6 +719,7 @@ typedef struct {
 	int            dest_pos;
 	ReadyCallback  callback;
 	gpointer       data;
+	int           *new_order;
 } ReorderData;
 
 
@@ -729,6 +730,7 @@ reorder_data_free (ReorderData *reorder_data)
 	_g_object_list_unref (reorder_data->file_list);
 	_g_object_unref (reorder_data->destination);
 	_g_object_unref (reorder_data->file_source);
+	g_free (reorder_data->new_order);
 	g_free (reorder_data);
 }
 
@@ -740,32 +742,32 @@ reorder_buffer_ready_cb (void     *buffer,
 		         gpointer  user_data)
 {
 	ReorderData *reorder_data = user_data;
-	GFile       *parent;
-	GList       *files;
 
 	g_free (buffer);
 
-	parent = g_file_get_parent (reorder_data->destination->file);
-	files = g_list_append (NULL, reorder_data->destination->file);
-	gth_monitor_folder_changed (gth_main_get_default_monitor (),
-				    parent,
-				    files,
-				    GTH_MONITOR_EVENT_CHANGED);
-
+	gth_monitor_order_changed (gth_main_get_default_monitor (),
+				   reorder_data->destination->file,
+				   reorder_data->new_order);
 	reorder_data->callback (G_OBJECT (reorder_data->file_source), error, reorder_data->data);
 
-	g_list_free (files);
-	g_object_unref (parent);
 	reorder_data_free (reorder_data);
 }
 
 
-static void
+static int *
 reorder_catalog_list (GthCatalog *catalog,
 		      GList      *file_list,
 		      int         dest_pos)
 {
-	GList *scan;
+	GHashTable *positions;
+	int        *new_order;
+	GList      *scan;
+	int         pos;
+	GList      *all_files;
+
+	positions = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, (GDestroyNotify) g_object_unref, NULL);
+	for (scan = gth_catalog_get_file_list (catalog), pos = 0; scan; scan = scan->next, pos++)
+		g_hash_table_insert (positions, g_object_ref ((GFile *) scan->data), GINT_TO_POINTER (pos));
 
 	for (scan = file_list; scan; scan = scan->next) {
 		int file_pos = gth_catalog_remove_file (catalog, (GFile *) scan->data);
@@ -776,6 +778,15 @@ reorder_catalog_list (GthCatalog *catalog,
 	for (scan = file_list; scan; scan = scan->next)
 		if (gth_catalog_insert_file (catalog, dest_pos, (GFile *) scan->data))
 			dest_pos++;
+
+	all_files = gth_catalog_get_file_list (catalog);
+	new_order = g_new0 (int, g_list_length (all_files));
+	for (scan = all_files, pos = 0; scan; scan = scan->next, pos++)
+		new_order[pos] = GPOINTER_TO_INT (g_hash_table_lookup (positions, (GFile *) scan->data));
+
+	g_hash_table_destroy (positions);
+
+	return new_order;
 }
 
 
@@ -797,7 +808,7 @@ reorder_catalog_ready_cb (GObject  *object,
 	}
 
 	catalog = (GthCatalog *) object;
-	reorder_catalog_list (catalog, reorder_data->file_list, reorder_data->dest_pos);
+	reorder_data->new_order = reorder_catalog_list (catalog, reorder_data->file_list, reorder_data->dest_pos);
 	gth_catalog_set_order (catalog, "general::unsorted", FALSE);
 
 	buffer = gth_catalog_to_data (catalog, &buffer_size);
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 6d4478b..f94846b 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -131,6 +131,7 @@ struct _GthBrowserPrivateData {
 	gulong             file_renamed_id;
 	gulong             metadata_changed_id;
 	gulong             entry_points_changed_id;
+	gulong             order_changed_id;
 	GthFileData       *location;
 	GthFileData       *current_file;
 	GthFileSource     *location_source;
@@ -1840,6 +1841,8 @@ _gth_browser_real_close (GthBrowser *browser)
 				     browser->priv->metadata_changed_id);
 	g_signal_handler_disconnect (gth_main_get_default_monitor (),
 				     browser->priv->entry_points_changed_id);
+	g_signal_handler_disconnect (gth_main_get_default_monitor (),
+				     browser->priv->order_changed_id);
 
 	/* cancel async operations */
 
@@ -2358,6 +2361,9 @@ folder_changed_cb (GthMonitor      *monitor,
 	gboolean     update_folder_tree;
 	gboolean     update_file_list;
 
+	if (browser->priv->location == NULL)
+			return;
+
 	if ((event == GTH_MONITOR_EVENT_DELETED) && (_g_file_list_find_file_or_ancestor (list, browser->priv->location->file) != NULL)) {
 		_gth_browser_load (browser, parent, GTH_ACTION_GO_TO, TRUE);
 		return;
@@ -2619,6 +2625,20 @@ entry_points_changed_cb (GthMonitor *monitor,
 
 
 static void
+order_changed_cb (GthMonitor      *monitor,
+		  GFile           *file,
+		  int             *new_order,
+		   GthBrowser     *browser)
+{
+	if (browser->priv->location == NULL)
+		return;
+
+	if (g_file_equal (file, browser->priv->location->file))
+		gth_file_store_reorder (gth_browser_get_file_store (browser), new_order);
+}
+
+
+static void
 pref_general_filter_changed (GConfClient *client,
 			     guint        cnxn_id,
 			     GConfEntry  *entry,
@@ -3318,6 +3338,11 @@ _gth_browser_construct (GthBrowser *browser)
 				  "entry-points-changed",
 				  G_CALLBACK (entry_points_changed_cb),
 				  browser);
+	browser->priv->order_changed_id =
+		g_signal_connect (gth_main_get_default_monitor (),
+				  "order-changed",
+				  G_CALLBACK (order_changed_cb),
+				  browser);
 
 	/* init browser data */
 
diff --git a/gthumb/gth-file-store.c b/gthumb/gth-file-store.c
index 62922d6..753ad6b 100644
--- a/gthumb/gth-file-store.c
+++ b/gthumb/gth-file-store.c
@@ -1590,19 +1590,65 @@ gth_file_store_clear (GthFileStore *file_store)
 {
 	int i;
 
-	for (i = file_store->priv->tot_rows - 1; i >= 0; i--) {
-		GthFileRow *row = file_store->priv->all_rows[i];
-
-		if (row->visible) {
-			GtkTreePath *path;
+	for (i = file_store->priv->num_rows - 1; i >= 0; i--) {
+		GthFileRow  *row = file_store->priv->rows[i];
+		GtkTreePath *path;
 
-			path = gtk_tree_path_new ();
-			gtk_tree_path_append_index (path, row->pos);
-			gtk_tree_model_row_deleted (GTK_TREE_MODEL (file_store), path);
-			gtk_tree_path_free (path);
-		}
+		path = gtk_tree_path_new ();
+		gtk_tree_path_append_index (path, row->pos);
+		gtk_tree_model_row_deleted (GTK_TREE_MODEL (file_store), path);
+		gtk_tree_path_free (path);
 	}
 
 	_gth_file_store_free_rows (file_store);
 	_gth_file_store_increment_stamp (file_store);
 }
+
+
+static int
+reorder_sort_func (gconstpointer a,
+		   gconstpointer b,
+		   gpointer      user_data)
+{
+	GHashTable *new_positions = user_data;
+	int         apos = GPOINTER_TO_INT (g_hash_table_lookup (new_positions, * (GthFileRow **) a));
+	int         bpos = GPOINTER_TO_INT (g_hash_table_lookup (new_positions, * (GthFileRow **) b));
+
+	if (apos < bpos)
+		return -1;
+	if (apos > bpos)
+		return 1;
+	return 0;
+}
+
+
+void
+gth_file_store_reorder (GthFileStore *file_store,
+			int          *new_order)
+{
+	int         *order;
+	GHashTable  *new_positions;
+	int          i;
+
+	order = g_new (int, file_store->priv->num_rows);
+	for (i = 0; i < file_store->priv->num_rows; i++)
+		order[new_order[i]] = i;
+
+	new_positions = g_hash_table_new (g_direct_hash, g_direct_equal);
+	for (i = 0; i < file_store->priv->num_rows; i++)
+		g_hash_table_insert (new_positions, file_store->priv->rows[i], GINT_TO_POINTER (order[i]));
+
+	g_qsort_with_data (file_store->priv->rows,
+			   file_store->priv->num_rows,
+			   (gsize) sizeof (GthFileRow *),
+			   reorder_sort_func,
+			   new_positions);
+
+	for (i = 0; i < file_store->priv->num_rows; i++)
+		file_store->priv->rows[i]->pos = i;
+
+	gtk_tree_model_rows_reordered (GTK_TREE_MODEL (file_store), NULL, NULL, new_order);
+
+	g_hash_table_destroy (new_positions);
+	g_free (order);
+}
diff --git a/gthumb/gth-file-store.h b/gthumb/gth-file-store.h
index 0e7c8f9..9aa5157 100644
--- a/gthumb/gth-file-store.h
+++ b/gthumb/gth-file-store.h
@@ -127,6 +127,8 @@ void            gth_file_store_queue_remove      (GthFileStore         *file_sto
 					          GtkTreeIter          *iter);
 void            gth_file_store_exec_remove       (GthFileStore         *file_store);
 void            gth_file_store_clear             (GthFileStore         *file_store);
+void            gth_file_store_reorder           (GthFileStore         *file_store,
+						  int                  *new_order);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-marshal.list b/gthumb/gth-marshal.list
index edd97c8..2569f8e 100644
--- a/gthumb/gth-marshal.list
+++ b/gthumb/gth-marshal.list
@@ -1,9 +1,10 @@
 VOID:ENUM, ENUM
 VOID:INT, INT
+VOID:OBJECT, BOOLEAN
 VOID:OBJECT, BOXED, ENUM
 VOID:OBJECT, OBJECT
-VOID:OBJECT, BOOLEAN
-VOID:OBJECT, UINT
+VOID:OBJECT, POINTER
 VOID:OBJECT, STRING
+VOID:OBJECT, UINT
 VOID:POINTER, POINTER
 VOID:STRING, STRING, BOOLEAN, DOUBLE
diff --git a/gthumb/gth-monitor.c b/gthumb/gth-monitor.c
index 043b083..c4205a6 100644
--- a/gthumb/gth-monitor.c
+++ b/gthumb/gth-monitor.c
@@ -40,6 +40,7 @@ enum {
 	FILE_RENAMED,
 	METADATA_CHANGED,
 	ENTRY_POINTS_CHANGED,
+	ORDER_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -162,6 +163,17 @@ gth_monitor_class_init (GthMonitorClass *class)
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE,
 			      0);
+	monitor_signals[ORDER_CHANGED] =
+		g_signal_new ("order-changed",
+			      G_TYPE_FROM_CLASS (class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GthMonitorClass, order_changed),
+			      NULL, NULL,
+			      gth_marshal_VOID__OBJECT_POINTER,
+			      G_TYPE_NONE,
+			      2,
+			      G_TYPE_OBJECT,
+			      G_TYPE_POINTER);
 }
 
 
@@ -312,3 +324,18 @@ gth_monitor_file_entry_points_changed (GthMonitor *monitor)
 		       monitor_signals[ENTRY_POINTS_CHANGED],
 		       0);
 }
+
+
+void
+gth_monitor_order_changed (GthMonitor *monitor,
+			   GFile      *file,
+			   int        *new_order)
+{
+	g_return_if_fail (GTH_IS_MONITOR (monitor));
+
+	g_signal_emit (G_OBJECT (monitor),
+		       monitor_signals[ORDER_CHANGED],
+		       0,
+		       file,
+		       new_order);
+}
diff --git a/gthumb/gth-monitor.h b/gthumb/gth-monitor.h
index 1fb562d..de5de93 100644
--- a/gthumb/gth-monitor.h
+++ b/gthumb/gth-monitor.h
@@ -73,6 +73,9 @@ struct _GthMonitorClass
 	void   (*metadata_changed)        (GthMonitor      *monitor,
 					   GthFileData     *file_data);
 	void   (*entry_points_changed)    (GthMonitor      *monitor);
+	void   (*order_changed)           (GthMonitor      *monitor,
+					   GFile           *file,
+					   int             *new_order);
 };
 
 GType         gth_monitor_get_type                   (void);
@@ -93,6 +96,9 @@ void          gth_monitor_file_renamed               (GthMonitor      *monitor,
 void          gth_monitor_metadata_changed           (GthMonitor      *monitor,
 						      GthFileData     *file_data);
 void          gth_monitor_file_entry_points_changed  (GthMonitor      *monitor);
+void          gth_monitor_order_changed              (GthMonitor      *monitor,
+						      GFile           *file,
+						      int             *new_order);
 
 G_END_DECLS
 



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