changeset 2029:d11d79da26cf

fixed file_data_check_sidecars use more clear algorithm: if the group has changed disconnect everything create new group
author Vladimir Nadvornik <nadvornik@suse.cz>
date Thu, 09 Aug 2012 17:32:36 +0200
parents bd17e7855808
children fb287a0612fe
files src/filedata.c
diffstat 1 files changed, 112 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Thu Aug 09 17:30:12 2012 +0200
+++ b/src/filedata.c	Thu Aug 09 17:32:36 2012 +0200
@@ -29,7 +29,7 @@
 
 static gint sidecar_file_priority(const gchar *extension);
 static void file_data_check_sidecars(const GList *basename_list);
-static FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd);
+static void file_data_disconnect_sidecar_file(FileData *target, FileData *sfd);
 
 
 
@@ -570,86 +570,134 @@
 	return 0;
 }
 
-static FileData *file_data_add_sidecar_file(FileData *target, FileData *sfd)
+static void file_data_check_sidecars(const GList *basename_list)
 {
-	sfd->parent = target;
-	if (!g_list_find(target->sidecar_files, sfd))
-		target->sidecar_files = g_list_insert_sorted(target->sidecar_files, sfd, file_data_sort_by_ext);
-	file_data_increment_version(sfd); /* increments both sfd and target */
-	return target;
-}
-
-
-static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source)
-{
-	GList *work;
+	/* basename_list contains the new group - first is the parent, then sorted sidecars */
+	/* all files in the list have ref count > 0 */ 
+
+	const GList *work;
+	GList *s_work, *new_sidecars;
+	FileData *parent_fd;
+
+	if (!basename_list) return;
+
+
+	DEBUG_2("basename start");
+	work = basename_list;
+	while (work)
+		{
+		FileData *fd = work->data;
+		work = work->next;
+		g_assert(fd->magick == 0x12345678);
+		DEBUG_2("basename: %p %s", fd, fd->name);
+		if (fd->parent) 
+			{
+			g_assert(fd->parent->magick == 0x12345678);
+			DEBUG_2("                  parent: %p", fd->parent);
+			}
+		s_work = fd->sidecar_files;
+		while (s_work)
+			{
+			FileData *sfd = s_work->data;
+			s_work = s_work->next;
+			g_assert(sfd->magick == 0x12345678);
+			DEBUG_2("                  sidecar: %p %s", sfd, sfd->name);
+			}
+		
+		g_assert(fd->parent == NULL || fd->sidecar_files == NULL);
+		}
+
+	parent_fd = basename_list->data;
+
+	/* check if the second and next entries of basename_list are already connected
+	   as sidecars of the first entry (parent_fd) */
+	work = basename_list->next;
+	s_work = parent_fd->sidecar_files;
 	
-	file_data_add_sidecar_file(target, source);
-
-	work = source->sidecar_files;
+	while (work && s_work)
+		{
+		if (work->data != s_work->data) break;
+		work = work->next;
+		s_work = s_work->next;
+		}
+		
+	if (!work && !s_work) 
+		{
+		DEBUG_2("basename no change");
+		return; /* no change in grouping */
+		}
+	
+	/* we have to regroup it */
+	
+	/* first, disconnect everything and send notification*/
+
+	work = basename_list;
+	while (work)
+		{
+		FileData *fd = work->data;
+		work = work->next;
+		g_assert(fd->parent == NULL || fd->sidecar_files == NULL);
+		
+		if (fd->parent)
+			{
+			FileData *old_parent = fd->parent;
+			g_assert(old_parent->parent == NULL || old_parent->sidecar_files == NULL);
+			file_data_ref(old_parent);
+			file_data_disconnect_sidecar_file(old_parent, fd);
+			file_data_send_notification(old_parent, NOTIFY_REREAD);
+			file_data_unref(old_parent);
+			}
+		
+		while (fd->sidecar_files)
+			{
+			FileData *sfd = fd->sidecar_files->data;
+			g_assert(sfd->parent == NULL || sfd->sidecar_files == NULL);
+			file_data_ref(sfd);
+			file_data_disconnect_sidecar_file(fd, sfd);
+			file_data_send_notification(sfd, NOTIFY_REREAD);
+			file_data_unref(sfd);
+			}
+		file_data_send_notification(fd, NOTIFY_GROUPING);
+		
+		g_assert(fd->parent == NULL && fd->sidecar_files == NULL);
+		}
+
+	/* now we can form the new group */
+	work = basename_list->next;
+	new_sidecars = NULL;
 	while (work)
 		{
 		FileData *sfd = work->data;
-		file_data_add_sidecar_file(target, sfd);
+		g_assert(sfd->magick == 0x12345678);
+		g_assert(sfd->parent == NULL && sfd->sidecar_files == NULL);
+		sfd->parent = parent_fd;
+		new_sidecars = g_list_prepend(new_sidecars, sfd);
 		work = work->next;
 		}
-
-	g_list_free(source->sidecar_files);
-	source->sidecar_files = NULL;
-
-	return target;
+	g_assert(parent_fd->sidecar_files == NULL);
+	parent_fd->sidecar_files = g_list_reverse(new_sidecars);
+	DEBUG_1("basename group changed for %s", parent_fd->path);
 }
 
-static void file_data_check_sidecars(const GList *basename_list)
+
+static void file_data_disconnect_sidecar_file(FileData *target, FileData *sfd)
 {
-	GList *work;
-	FileData *parent_fd;
-	if (!basename_list) return;
-	/* process the group list - the first one is the parent file, others are sidecars */
-	parent_fd = basename_list->data;
-	work = basename_list->next;
-	while (work)
-		{
-		FileData *sfd = work->data;
-		work = work->next;
-
-		file_data_merge_sidecar_files(parent_fd, sfd);
-		}
-		
-	/* there may be some sidecars that are already deleted - disconnect them */
-	work = parent_fd->sidecar_files;
-	while (work)
-		{
-		FileData *sfd = work->data;
-		work = work->next;
-		
-		if (!g_list_find((GList *)basename_list, sfd)) 
-			{
-			printf("removing unknown %s: %s \n", parent_fd->path, sfd->path);
-			file_data_disconnect_sidecar_file(parent_fd, sfd);
-			file_data_send_notification(sfd, NOTIFY_REREAD);
-			file_data_send_notification(parent_fd, NOTIFY_REREAD);
-			}
-		}
-}
-
-static FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd)
-{
-	sfd->parent = target;
+	g_assert(target->magick == 0x12345678);
+	g_assert(sfd->magick == 0x12345678);
 	g_assert(g_list_find(target->sidecar_files, sfd));
+
+	file_data_ref(target);
+	file_data_ref(sfd);
+
+	g_assert(sfd->parent == target);
 	
 	file_data_increment_version(sfd); /* increments both sfd and target */
 
 	target->sidecar_files = g_list_remove(target->sidecar_files, sfd);
 	sfd->parent = NULL;
 
-	if (sfd->ref == 0)
-		{
-		file_data_free(sfd);
-		return NULL;
-		}
-
-	return sfd;
+	file_data_unref(target);
+	file_data_unref(sfd);
 }
 
 /* disables / enables grouping for particular file, sends UPDATE notification */