changeset 801:9b676bb76a2e

various refresh and notification fixes
author nadvornik
date Sat, 07 Jun 2008 22:44:17 +0000
parents a25b228978a0
children 3cfc54c77b30
files src/filedata.c src/view_file_list.c
diffstat 2 files changed, 75 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Sat Jun 07 15:08:33 2008 +0000
+++ b/src/filedata.c	Sat Jun 07 22:44:17 2008 +0000
@@ -220,8 +220,9 @@
 	file_data_set_collate_keys(fd);
 }
 
-static void file_data_check_changed_files(FileData *fd, struct stat *st)
+static gboolean file_data_check_changed_files_recursive(FileData *fd, struct stat *st)
 {
+	gboolean ret = FALSE;
 	GList *work;
 	if (fd->size != st->st_size ||
 	    fd->date != st->st_mtime)
@@ -232,6 +233,7 @@
 		fd->pixbuf = NULL;
 		file_data_increment_version(fd);
 		file_data_send_notification(fd, NOTIFY_TYPE_REREAD);
+		ret = TRUE;
 		}
 
 	work = fd->sidecar_files;
@@ -239,15 +241,50 @@
 		{
 		FileData *sfd = work->data;
 		struct stat st;
+		work = work->next;
 
 		if (!stat_utf8(sfd->path, &st))
 			{
+			fd->size = 0;
+			fd->date = 0;
 			file_data_disconnect_sidecar_file(fd, sfd);
+			ret = TRUE;
+			continue;
 			}
 
-		file_data_check_changed_files(sfd, &st);
-		work = work->next;
+		ret |= file_data_check_changed_files_recursive(sfd, &st);
 		}
+	return ret;
+}
+
+
+static gboolean file_data_check_changed_files(FileData *fd)
+{
+	gboolean ret = FALSE;
+	struct stat st;
+	if (fd->parent) fd = fd->parent;
+
+	if (!stat_utf8(fd->path, &st))
+		{
+		/* parent is missing, we have to rebuild whole group */
+		ret = TRUE;
+		fd->size = 0;
+		fd->date = 0;
+		GList *work = fd->sidecar_files;
+		FileData *sfd = NULL;
+		while (work)
+			{
+			sfd = work->data;
+			work = work->next;
+		
+			file_data_disconnect_sidecar_file(fd, sfd);
+			}
+		if (sfd) file_data_check_sidecars(sfd); /* this will group the sidecars back together */
+		file_data_send_notification(fd, NOTIFY_TYPE_REREAD);
+		}
+	else 
+		ret |= file_data_check_changed_files_recursive(fd, &st);
+	return ret;
 }
 
 static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean check_sidecars)
@@ -262,8 +299,14 @@
 	fd = g_hash_table_lookup(file_data_pool, path_utf8);
 	if (fd)
 		{
-		file_data_check_changed_files(fd, st);
-		DEBUG_2("file_data_pool hit: '%s'", fd->path);
+		gboolean changed;
+		if (fd->parent)
+			changed = file_data_check_changed_files(fd);
+		else
+			changed = file_data_check_changed_files_recursive(fd, st);
+		if (changed && check_sidecars && sidecar_file_priority(fd->extension))
+			file_data_check_sidecars(fd);
+		DEBUG_2("file_data_pool hit: '%s' %s", fd->path, changed ? "(changed)" : "");
 		return file_data_ref(fd);
 		}
 
@@ -361,6 +404,7 @@
 	sfd->parent = target;
 	if(!g_list_find(target->sidecar_files, sfd))
 		target->sidecar_files = g_list_prepend(target->sidecar_files, sfd);
+	file_data_increment_version(sfd); /* increments both sfd and target */
 	return target;
 }
 
@@ -467,6 +511,8 @@
 {
 	sfd->parent = target;
 	g_assert(g_list_find(target->sidecar_files, sfd));
+	
+	file_data_increment_version(sfd); /* increments both sfd and target */
 
 	target->sidecar_files = g_list_remove(target->sidecar_files, sfd);
 	sfd->parent = NULL;
@@ -1541,12 +1587,8 @@
 static void realtime_monitor_check_cb(gpointer key, gpointer value, gpointer data)
 {
 	FileData *fd = key;
-	struct stat st;
 
-	if (stat_utf8(fd->path, &st))
-		file_data_check_changed_files(fd, &st);
-	else 
-		file_data_send_notification(fd, NOTIFY_TYPE_REREAD);
+	file_data_check_changed_files(fd);
 	
 	DEBUG_1("monitor %s", fd->path);
 }
--- a/src/view_file_list.c	Sat Jun 07 15:08:33 2008 +0000
+++ b/src/view_file_list.c	Sat Jun 07 22:44:17 2008 +0000
@@ -142,6 +142,21 @@
 	return i;
 }
 
+static gboolean vflist_store_clear_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+{
+	FileData *fd;
+	gtk_tree_model_get(model, iter, FILE_COLUMN_POINTER, &fd, -1);
+	file_data_unref(fd);
+	return FALSE;
+}
+
+static void vflist_store_clear(ViewFile *vf)
+{
+	GtkTreeModel *store;
+	store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
+	gtk_tree_model_foreach(store, vflist_store_clear_cb, NULL);
+	gtk_tree_store_clear(GTK_TREE_STORE(store));
+}
 
 void vflist_color_set(ViewFile *vf, FileData *fd, gint color_set)
 {
@@ -793,7 +808,7 @@
 					gtk_tree_store_append(store, &new, parent_iter);
 					}
 
-				vflist_setup_iter(vf, store, &new, fd);
+				vflist_setup_iter(vf, store, &new, file_data_ref(fd));
 				vflist_setup_iter_recursive(vf, store, &new, fd->sidecar_files, selected);
 				
 				if (g_list_find(selected, fd))
@@ -808,6 +823,7 @@
 				}
 			else if (match > 0)
 				{
+				file_data_unref(old_fd);
 				valid = gtk_tree_store_remove(store, &iter);
 				}
 			else
@@ -828,6 +844,10 @@
 
 	while (valid)
 		{
+		FileData *old_fd;
+		gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &old_fd, -1);
+		file_data_unref(old_fd);
+
 		valid = gtk_tree_store_remove(store, &iter);
 		}
 }
@@ -1514,7 +1534,7 @@
 
 	if (!vf->list)
 		{
-		gtk_tree_store_clear(store);
+		vflist_store_clear(vf);
 		vf_send_update(vf);
 		return;
 		}
@@ -1748,8 +1768,6 @@
 
 gint vflist_set_fd(ViewFile *vf, FileData *dir_fd)
 {
-	GtkTreeStore *store;
-
 	if (!dir_fd) return FALSE;
 	if (vf->dir_fd == dir_fd) return TRUE;
 
@@ -1757,8 +1775,7 @@
 	vf->dir_fd = file_data_ref(dir_fd);
 
 	/* force complete reload */
-	store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)));
-	gtk_tree_store_clear(store);
+	vflist_store_clear(vf);
 
 	filelist_free(vf->list);
 	vf->list = NULL;