brasero r786 - in trunk: . src



Author: philippr
Date: Thu May  1 18:16:22 2008
New Revision: 786
URL: http://svn.gnome.org/viewvc/brasero?rev=786&view=rev

Log:
	Fix #530521 â Disable Empty project button if no files are in project
	Also fixes two crashes:
	- when moving a node so that it replaces a parent node with the same name
	- crashes after suppressing some files

	* src/brasero-data-disc.c (brasero_data_disc_contents_removed_cb):
	* src/brasero-data-project.c (brasero_data_project_joliet_set_key),
	(brasero_data_project_joliet_add_node),
	(brasero_data_project_joliet_remove_node),
	(brasero_data_project_joliet_remove_children_node_cb),
	(brasero_data_project_uri_is_graft_needed),
	(brasero_data_project_remove_real),
	(brasero_data_project_destroy_node),
	(brasero_data_project_move_node), (brasero_data_project_clear),
	(brasero_data_project_reset), (brasero_data_project_file_moved):
	* src/brasero-data-project.h:
	* src/brasero-data-tree-model.c (brasero_data_tree_model_clear),
	(brasero_data_tree_model_reset),
	(brasero_data_tree_model_node_removed):
	* src/brasero-data-vfs.c (brasero_data_vfs_load_node),
	(brasero_data_vfs_reset):
	* src/brasero-file-node.c
	(brasero_file_node_check_imported_sibling),
	(brasero_file_node_unlink), (brasero_file_node_move_from),
	(brasero_file_node_move_to),
	(brasero_file_node_destroy_with_children),
	(brasero_file_node_destroy), (brasero_file_node_save_imported):
	* src/brasero-file-node.h:

Modified:
   trunk/ChangeLog
   trunk/src/brasero-data-disc.c
   trunk/src/brasero-data-project.c
   trunk/src/brasero-data-project.h
   trunk/src/brasero-data-tree-model.c
   trunk/src/brasero-data-vfs.c
   trunk/src/brasero-file-node.c
   trunk/src/brasero-file-node.h

Modified: trunk/src/brasero-data-disc.c
==============================================================================
--- trunk/src/brasero-data-disc.c	(original)
+++ trunk/src/brasero-data-disc.c	Thu May  1 18:16:22 2008
@@ -2009,7 +2009,7 @@
 	priv = BRASERO_DATA_DISC_PRIVATE (self);
 
 	root = brasero_data_project_get_root (priv->project);
-	brasero_disc_contents_changed (BRASERO_DISC (self), (BRASERO_FILE_NODE_CHILDREN (root) != NULL));
+	brasero_disc_contents_changed (BRASERO_DISC (self), (root && BRASERO_FILE_NODE_CHILDREN (root) != NULL));
 }
 
 /**

Modified: trunk/src/brasero-data-project.c
==============================================================================
--- trunk/src/brasero-data-project.c	(original)
+++ trunk/src/brasero-data-project.c	Thu May  1 18:16:22 2008
@@ -288,6 +288,8 @@
 		sprintf (key->name,
 			 "%.64s",
 			 BRASERO_FILE_NODE_NAME (node));
+
+	key->parent = node->parent;
 }
 
 static void
@@ -298,6 +300,9 @@
 	BraseroJolietKey key;
 	GSList *list;
 
+	if (!node->parent)
+		return;
+
 	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
 
 	if (!priv->joliet)
@@ -334,6 +339,9 @@
 	gboolean success;
 	gpointer list;
 
+	if (!node->parent)
+		return FALSE;
+
 	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
 
 	brasero_data_project_joliet_set_key (&key, node);
@@ -372,7 +380,7 @@
 	BraseroJolietKey *key = data_key;
 	GSList *nodes = data;
 
-	if (brasero_file_node_is_ancestor (parent, key->parent)) {
+	if (brasero_file_node_is_ancestor (parent, key->parent) || parent == key->parent) {
 		g_slist_free (nodes);
 		return TRUE;
 	}
@@ -736,11 +744,17 @@
 		gchar *parent_uri;
 
 		node = iter->data;
-		if (node->parent == priv->root)
+		if (node->parent == priv->root) {
+			g_free (parent);
+			g_free (name);
 			return TRUE;
+		}
 
-		if (node->parent->is_fake)
+		if (node->parent->is_fake) {
+			g_free (parent);
+			g_free (name);
 			return TRUE;
+		}
 
 		/* make sure the node has the right name. */
 		if (strcmp (BRASERO_FILE_NODE_NAME (node), name)) {
@@ -1066,17 +1080,35 @@
 {
 	BraseroDataProjectPrivate *priv;
 	BraseroDataProjectClass *klass;
+	BraseroFileNode *former_parent;
+	guint former_position;
 
 	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
 
 	brasero_data_project_node_removed (self, node);
 
-	/* unlink the node and signal the removal */
+	/* save parent, unparent it, signal the removal */
+	former_parent = node->parent;
+	former_position = brasero_file_node_get_pos_as_child (node);
+
+	brasero_file_node_unlink (node);
+
 	klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
 	if (klass->node_removed)
-		klass->node_removed (self, node);
+		klass->node_removed (self, former_parent, former_position, node);
+
+	/* save imported nodes in their parent structure or destroy it */
+	if (!node->is_imported) {
+		BraseroFileTreeStats *stats;
+
+		stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+		brasero_file_node_destroy (node, stats);
+	}
+	else
+		brasero_file_node_save_imported (node,
+						 former_parent,
+						 priv->sort_func);
 
-	brasero_file_node_remove (node, priv->sort_func);
 	g_signal_emit (self,
 		       brasero_data_project_signals [SIZE_CHANGED_SIGNAL],
 		       0);
@@ -1151,17 +1183,26 @@
 {
 	BraseroDataProjectPrivate *priv;
 	BraseroDataProjectClass *klass;
+	BraseroFileNode *former_parent;
+	BraseroFileTreeStats *stats;
+	guint former_position;
 
 	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
 
 	brasero_data_project_node_removed (self, node);
 
 	/* unlink the node and signal the removal */
+	former_parent = node->parent;
+	former_position = brasero_file_node_get_pos_as_child (node);
+
+	brasero_file_node_unlink (node);
+
 	klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
 	if (klass->node_removed)
-		klass->node_removed (self, node);
+		klass->node_removed (self, former_parent, former_position, node);
 
-	brasero_file_node_destroy (node);
+	stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+	brasero_file_node_destroy (node, stats);
 
 	g_signal_emit (self,
 		       brasero_data_project_signals [SIZE_CHANGED_SIGNAL],
@@ -1172,41 +1213,19 @@
 	 * used to remove imported nodes. */
 }
 
-static void
-brasero_data_project_move_node_real (BraseroDataProject *self,
-				     BraseroFileNode *node,
-				     BraseroFileNode *parent)
-{
-	BraseroDataProjectPrivate *priv;
-	BraseroDataProjectClass *klass;
-
-	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
-
-	/* really reparent it; signal:
-	 * - old location removal
-	 * - new location addition */
-	klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
-	if (klass->node_removed)
-		klass->node_removed (self, node);
-
-	brasero_file_node_move (node, parent, priv->sort_func);
-
-	if (klass->node_added)
-		klass->node_added (self, node, NULL);
-
-	/* Check joliet name compatibility; this must be done after move as it
-	 * depends on the parent. */
-	if (strlen (BRASERO_FILE_NODE_NAME (node)) > 64)
-		brasero_data_project_joliet_add_node (self, node);
-}
-
 gboolean
 brasero_data_project_move_node (BraseroDataProject *self,
 				BraseroFileNode *node,
 				BraseroFileNode *parent)
 {
+	BraseroFileNode *imported_sibling;
+	BraseroFileNode *target_sibling;
 	BraseroDataProjectPrivate *priv;
-	BraseroFileNode *sibling;
+	BraseroDataProjectClass *klass;
+	BraseroFileNode *former_parent;
+	BraseroFileTreeStats *stats;
+	guint former_position;
+	gboolean check_graft;
 
 	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
 
@@ -1230,22 +1249,21 @@
 
 	/* One case could make us fail: if there is the same name in
 	 * the directory: in that case return FALSE; check now. */
-	sibling = brasero_file_node_check_name_existence (parent, BRASERO_FILE_NODE_NAME (node));
-	if (sibling) {
-		if (brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, BRASERO_FILE_NODE_NAME (node)))
-			return FALSE;
-
-		/* The node existed and the user wants the existing to 
-		 * be replaced, so we delete that node (since the new
-		 * one would have the old one's children otherwise). */
-		brasero_data_project_remove_real (self, sibling);
-	}
+	target_sibling = brasero_file_node_check_name_existence (parent, BRASERO_FILE_NODE_NAME (node));
+	if (target_sibling
+	&&  brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, BRASERO_FILE_NODE_NAME (node)))
+		return FALSE;
 
 	/* If node was in the joliet incompatible table, remove it */
 	brasero_data_project_joliet_remove_node (self, node);
 
-	/* see if it replaced an imported file */
-	sibling = brasero_file_node_check_imported_sibling (node);
+	/* check if this file was hiding an imported file. One exception is if
+	 * there is a sibling in the target directory which is the parent of our
+	 * node. */
+	if (!target_sibling || !brasero_file_node_is_ancestor (target_sibling, node))
+		imported_sibling = brasero_file_node_check_imported_sibling (node);
+	else
+		imported_sibling = NULL;
 
 	if (!node->is_grafted) {
 		gchar *uri;
@@ -1253,14 +1271,43 @@
 		/* Get the URI and all the nodes with the same URI and 
 		 * add the list to the hash => add a graft.
 		 * See note underneath: if it wasn't grafted before the
-		 * move it has to be a graft now. */
+		 * move it should probably be a graft now.
+		 * NOTE: we need to do it now before it gets unparented. */
 		uri = brasero_data_project_node_to_uri (self, node);
 		brasero_data_project_uri_graft_nodes (self, uri);
 		g_free (uri);
 
-		brasero_data_project_move_node_real (self, node, parent);
+		check_graft = FALSE;
 	}
-	else {
+	else
+		check_graft = TRUE;
+
+	/* really reparent it; signal:
+	 * - old location removal
+	 * - new location addition */
+
+	/* unparent node now in case its target sibling is a parent */
+	former_parent = node->parent;
+	former_position = brasero_file_node_get_pos_as_child (node);
+	brasero_file_node_move_from (node, stats);
+
+	klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
+	if (former_parent && klass->node_removed)
+		klass->node_removed (self, former_parent, former_position, node);
+
+	if (target_sibling) {
+		/* The node existed and the user wants the existing to 
+		 * be replaced, so we delete that node (since the new
+		 * one would have the old one's children otherwise). */
+		brasero_data_project_remove_real (self, target_sibling);
+	}
+
+	brasero_file_node_move_to (node, parent, priv->sort_func);
+
+	if (klass->node_added)
+		klass->node_added (self, node, NULL);
+
+	if (check_graft) {
 		BraseroGraft *graft;
 		BraseroURINode *uri_node;
 
@@ -1268,18 +1315,22 @@
 		uri_node = graft->node;
 
 		/* check if still need a graft point after the location change. */
-		brasero_data_project_move_node_real (self, node, parent);
 		if (!brasero_data_project_uri_is_graft_needed (self, uri_node->uri))
 			brasero_data_project_uri_remove_graft (self, uri_node->uri);
 	}
 
-	if (sibling) {
+	/* Check joliet name compatibility; this must be done after move as it
+	 * depends on the parent. */
+	if (strlen (BRASERO_FILE_NODE_NAME (node)) > 64)
+		brasero_data_project_joliet_add_node (self, node);
+
+	if (imported_sibling) {
 		BraseroDataProjectClass *klass;
 
 		klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
-		brasero_file_node_add (sibling->parent, sibling, priv->sort_func);
+		brasero_file_node_add (imported_sibling->parent, imported_sibling, priv->sort_func);
 		if (klass->node_added)
-			brasero_data_project_add_node_and_children (self, sibling, klass->node_added);
+			brasero_data_project_add_node_and_children (self, imported_sibling, klass->node_added);
 	}
 
 	/* NOTE: if it has come back to its original location on the 
@@ -2824,7 +2875,8 @@
 	g_hash_table_destroy (priv->reference);
 	priv->reference = g_hash_table_new (g_direct_hash, g_direct_equal);
 
-	brasero_file_node_destroy (priv->root);
+	/* no need to give a stats since we're destroying it */
+	brasero_file_node_destroy (priv->root, NULL);
 	priv->root = NULL;
 
 #ifdef BUILD_INOTIFY
@@ -2839,15 +2891,17 @@
 {
 	BraseroDataProjectPrivate *priv;
 	BraseroDataProjectClass *klass;
+	guint num_nodes;
 
 	priv = BRASERO_DATA_PROJECT_PRIVATE (self);
 
 	/* Do it now */
+	num_nodes = brasero_file_node_get_n_children (priv->root);
+	brasero_data_project_clear (self);
+
 	klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
 	if (klass->reset)
-		klass->reset (self);
-
-	brasero_data_project_clear (self);
+		klass->reset (self, num_nodes);
 
 	priv->loading = 0;
 	priv->root = brasero_file_node_root_new ();
@@ -3149,7 +3203,10 @@
 		g_free (parent_uri);
 	}
 	else {
+		guint former_position;
 		BraseroFileNode *sibling;
+		BraseroFileTreeStats *stats;
+		BraseroFileNode *former_parent;
 		BraseroDataProjectClass *klass;
 		BraseroDataProjectPrivate *priv;
 
@@ -3180,10 +3237,16 @@
 		sibling = brasero_file_node_check_imported_sibling (node);
 
 		/* move it */
-		if (klass->node_removed)
-			klass->node_removed (BRASERO_DATA_PROJECT (monitor), node);
+		former_parent = node->parent;
+		former_position = brasero_file_node_get_pos_as_child (node);
 
-		brasero_file_node_move (node, parent, priv->sort_func);
+		stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+		brasero_file_node_move_from (node, stats);
+		if (klass->node_removed)
+			klass->node_removed (BRASERO_DATA_PROJECT (monitor),
+					     former_parent,
+					     former_position,
+					     node);
 
 		if (name_dest && strcmp (name_dest, name_src)) {
 			/* the name has been changed so update it */
@@ -3195,6 +3258,8 @@
 		if (strlen (name_dest) > 64)
 			brasero_data_project_joliet_add_node (BRASERO_DATA_PROJECT (monitor), node);
 
+		brasero_file_node_move_to (node, parent, priv->sort_func);
+
 		if (klass->node_added)
 			klass->node_added (BRASERO_DATA_PROJECT (monitor), node, NULL);
 

Modified: trunk/src/brasero-data-project.h
==============================================================================
--- trunk/src/brasero-data-project.h	(original)
+++ trunk/src/brasero-data-project.h	Thu May  1 18:16:22 2008
@@ -63,7 +63,12 @@
 
 	/* virtual functions */
 
-	void		(*reset)		(BraseroDataProject *project);
+	/**
+	 * num_nodes is the number of nodes that were at the root of the 
+	 * project.
+	 */
+	void		(*reset)		(BraseroDataProject *project,
+						 guint num_nodes);
 
 	/* NOTE: node_added is also called when there is a moved node;
 	 * in this case a node_removed is first called and then the
@@ -75,8 +80,15 @@
 	gboolean	(*node_added)		(BraseroDataProject *project,
 						 BraseroFileNode *node,
 						 const gchar *uri);
+
+	/* This is more an unparent signal. It shouldn't be assumed that the
+	 * node was destroyed or not destroyed. Like the above function, it is
+	 * also called when a node is moved. */
 	void		(*node_removed)		(BraseroDataProject *project,
+						 BraseroFileNode *former_parent,
+						 guint former_position,
 						 BraseroFileNode *node);
+
 	void		(*node_changed)		(BraseroDataProject *project,
 						 BraseroFileNode *node);
 	void		(*node_reordered)	(BraseroDataProject *project,
@@ -165,7 +177,7 @@
 				    const gchar *uri,
 				    GFileInfo *info);
 void
-brasero_data_project_directory_node_loaded (BraseroDataProject *self,
+brasero_data_project_directory_node_loaded (BraseroDataProject *project,
 					    BraseroFileNode *parent);
 
 gboolean
@@ -203,9 +215,10 @@
 				  BraseroFileNode *node);
 
 void
-brasero_data_project_set_sort_function (BraseroDataProject *self,
+brasero_data_project_set_sort_function (BraseroDataProject *project,
 					GtkSortType sort_type,
 					GCompareFunc sort_func);
+
 G_END_DECLS
 
 #endif /* _BRASERO_DATA_PROJECT_H_ */

Modified: trunk/src/brasero-data-tree-model.c
==============================================================================
--- trunk/src/brasero-data-tree-model.c	(original)
+++ trunk/src/brasero-data-tree-model.c	Thu May  1 18:16:22 2008
@@ -1129,28 +1129,11 @@
 }
 
 static void
-brasero_data_tree_model_clear_children (BraseroDataTreeModel *self,
-					BraseroFileNode *parent)
+brasero_data_tree_model_clear (BraseroDataTreeModel *self, 
+			       guint num_nodes)
 {
-	BraseroFileNode *node;
+	guint i;
 	GtkTreePath *treepath;
-
-	node = BRASERO_FILE_NODE_CHILDREN (parent);
-	if (!node)
-		return;
-
-	treepath = brasero_data_tree_model_node_to_path (self, node);
-
-	for (; node; node = node->next)
-		gtk_tree_model_row_deleted (GTK_TREE_MODEL (self), treepath);
-
-	gtk_tree_path_free (treepath);
-}
-
-static void
-brasero_data_tree_model_clear (BraseroDataTreeModel *self)
-{
-	BraseroFileNode *root;
 	BraseroDataTreeModelPrivate *priv;
 
 	priv = BRASERO_DATA_TREE_MODEL_PRIVATE (self);
@@ -1159,18 +1142,23 @@
 		priv->shown = NULL;
 	}
 
-	root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (self));
-	brasero_data_tree_model_clear_children (self, root);
+	/* NOTE: no need to move to the next row since previous one was deleted */
+	treepath = gtk_tree_path_new_first ();
+	for (i = 0; i < num_nodes; i ++)
+		gtk_tree_model_row_deleted (GTK_TREE_MODEL (self), treepath);
+
+	gtk_tree_path_free (treepath);
 }
 
 static void
-brasero_data_tree_model_reset (BraseroDataProject *project)
+brasero_data_tree_model_reset (BraseroDataProject *project,
+			       guint num_nodes)
 {
-	brasero_data_tree_model_clear (BRASERO_DATA_TREE_MODEL (project));
+	brasero_data_tree_model_clear (BRASERO_DATA_TREE_MODEL (project), num_nodes);
 
 	/* chain up this function except if we invalidated the node */
 	if (BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->reset)
-		BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->reset (project);
+		BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->reset (project, num_nodes);
 }
 
 static gboolean
@@ -1270,37 +1258,46 @@
 
 static void
 brasero_data_tree_model_node_removed (BraseroDataProject *project,
+				      BraseroFileNode *former_parent,
+				      guint former_position,
 				      BraseroFileNode *node)
 {
 	BraseroDataTreeModelPrivate *priv;
-	BraseroFileNode *parent;
+	GSList *iter, *next;
 	GtkTreePath *path;
 
 	/* see if we really need to tell the treeview we changed */
 	if (!node->is_visible
-	&&   node->parent
-	&&  !node->parent->is_root
-	&&  !node->parent->is_visible)
+	&&   former_parent
+	&&  !former_parent->is_root
+	&&  !former_parent->is_visible)
 		goto end;
 
 	priv = BRASERO_DATA_TREE_MODEL_PRIVATE (project);
 
-	/* remove it from the shown list */
+	/* remove it from the shown list and all its children as well */
 	priv->shown = g_slist_remove (priv->shown, node);
+	for (iter = priv->shown; iter; iter = next) {
+		BraseroFileNode *tmp;
+
+		tmp = iter->data;
+		next = iter->next;
+		if (brasero_file_node_is_ancestor (node, tmp))
+			priv->shown = g_slist_remove (priv->shown, tmp);
+	}
 
 	/* See if the parent of this node still has children. If not we need to
 	 * add a bogus row. If it hasn't got children then it only remains our
 	 * node in the list.
 	 * NOTE: parent has to be a directory. */
-	parent = node->parent;
-	if (!parent->is_root && BRASERO_FILE_NODE_CHILDREN (parent) == node && !node->next) {
+	if (!former_parent->is_root && !BRASERO_FILE_NODE_CHILDREN (former_parent)) {
 		GtkTreeIter iter;
 
 		iter.stamp = priv->stamp;
-		iter.user_data = parent;
+		iter.user_data = former_parent;
 		iter.user_data2 = GINT_TO_POINTER (BRASERO_ROW_BOGUS);
 
-		path = brasero_data_tree_model_node_to_path (BRASERO_DATA_TREE_MODEL (project), parent);
+		path = brasero_data_tree_model_node_to_path (BRASERO_DATA_TREE_MODEL (project), former_parent);
 		gtk_tree_path_append_index (path, 1);
 
 		gtk_tree_model_row_inserted (GTK_TREE_MODEL (project), path, &iter);
@@ -1309,14 +1306,19 @@
 
 	/* remove the node. Do it after adding a possible BOGUS row.
 	 * NOTE since BOGUS row has been added move row. */
-	path = brasero_data_tree_model_node_to_path (BRASERO_DATA_TREE_MODEL (project), node);
+	path = brasero_data_tree_model_node_to_path (BRASERO_DATA_TREE_MODEL (project), former_parent);
+	gtk_tree_path_append_index (path, former_position);
+
 	gtk_tree_model_row_deleted (GTK_TREE_MODEL (project), path);
 	gtk_tree_path_free (path);
 
 end:
 	/* chain up this function */
 	if (BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->node_removed)
-		BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->node_removed (project, node);
+		BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->node_removed (project,
+												 former_parent,
+												 former_position,
+												 node);
 }
 
 static void

Modified: trunk/src/brasero-data-vfs.c
==============================================================================
--- trunk/src/brasero-data-vfs.c	(original)
+++ trunk/src/brasero-data-vfs.c	Thu May  1 18:16:22 2008
@@ -679,7 +679,6 @@
 {
 	BraseroDataVFSPrivate *priv;
 	gchar *registered;
-	gboolean result;
 
 	priv = BRASERO_DATA_VFS_PRIVATE (self);
 
@@ -709,7 +708,7 @@
 			       0,
 			       TRUE);
 
-	return result;
+	return TRUE;
 }
 
 static gboolean
@@ -1055,13 +1054,14 @@
 }
 
 static void
-brasero_data_vfs_reset (BraseroDataProject *project)
+brasero_data_vfs_reset (BraseroDataProject *project,
+			guint num_nodes)
 {
 	brasero_data_vfs_clear (BRASERO_DATA_VFS (project));
 
 	/* chain up this function except if we invalidated the node */
 	if (BRASERO_DATA_PROJECT_CLASS (brasero_data_vfs_parent_class)->reset)
-		BRASERO_DATA_PROJECT_CLASS (brasero_data_vfs_parent_class)->reset (project);
+		BRASERO_DATA_PROJECT_CLASS (brasero_data_vfs_parent_class)->reset (project, num_nodes);
 }
 
 static void

Modified: trunk/src/brasero-file-node.c
==============================================================================
--- trunk/src/brasero-file-node.c	(original)
+++ trunk/src/brasero-file-node.c	Thu May  1 18:16:22 2008
@@ -531,6 +531,11 @@
 
 	parent = node->parent;
 
+	/* That could happen if a node is moved to a location where another node
+	 * (to be removed) has the same name and is a parent of this node */
+	if (!parent)
+		return NULL;
+
 	/* See if among the imported children of the parent one of them
 	 * has the same name as the node being removed. If so, restore
 	 * it with all its imported children (provided that's a
@@ -878,7 +883,7 @@
 	return node;
 }
 
-static void
+void
 brasero_file_node_unlink (BraseroFileNode *node)
 {
 	BraseroFileNode *iter;
@@ -889,6 +894,20 @@
 
 	iter = BRASERO_FILE_NODE_CHILDREN (node->parent);
 
+	/* handle the size change for previous parent */
+	if (!node->is_grafted && !node->is_imported) {
+		BraseroFileNode *parent;
+
+		/* handle the size change if it wasn't grafted */
+		for (parent = node->parent; parent && !parent->is_root; parent = parent->parent) {
+			parent->union3.sectors -= BRASERO_FILE_NODE_SECTORS (node);
+			if (parent->is_grafted)
+				break;
+		}
+	}
+
+	node->is_deep = FALSE;
+
 	if (iter == node) {
 		node->parent->union2.children = node->next;
 		node->parent = NULL;
@@ -929,37 +948,36 @@
 			return;
 		}
 	}
-
-	/* don't handle size change for parents */
 }
 
 void
-brasero_file_node_move (BraseroFileNode *node,
-			BraseroFileNode *parent,
-			GCompareFunc sort_func)
+brasero_file_node_move_from (BraseroFileNode *node,
+			     BraseroFileTreeStats *stats)
 {
-	BraseroFileTreeStats *stats;
 	gboolean was_deep;
-	guint depth;
 
 	/* NOTE: for the time being no backend supports moving imported files */
 	if (node->is_imported)
 		return;
 
 	was_deep = (brasero_file_node_get_depth (node) > 6);
+	if (was_deep)
+		stats->num_deep --;
 
-	/* handle the size change for previous parent */
-	if (!node->is_grafted) {
-		BraseroFileNode *parent;
-
-		/* handle the size change if it wasn't grafted */
-		for (parent = node->parent; parent && !parent->is_root; parent = parent->parent) {
-			parent->union3.sectors -= BRASERO_FILE_NODE_SECTORS (node);
-			if (parent->is_grafted)
-				break;
-		}
-	}
 	brasero_file_node_unlink (node);
+}
+
+void
+brasero_file_node_move_to (BraseroFileNode *node,
+			   BraseroFileNode *parent,
+			   GCompareFunc sort_func)
+{
+	BraseroFileTreeStats *stats;
+	guint depth;
+
+	/* NOTE: for the time being no backend supports moving imported files */
+	if (node->is_imported)
+		return;
 
 	/* reinsert it now at the new location */
 	parent->union2.children = brasero_file_node_insert (BRASERO_FILE_NODE_CHILDREN (parent),
@@ -982,11 +1000,7 @@
 	/* NOTE: here stats about the tree can change if the parent has a depth
 	 * > 6 and if previous didn't. Other stats remains unmodified. */
 	stats = brasero_file_node_get_tree_stats (parent, &depth);
-	if (was_deep && depth <= 6) {
-		stats->num_deep --;
-		node->is_deep = FALSE;
-	}
-	else if (!was_deep && depth > 6) {
+	if (!depth > 6) {
 		stats->num_deep ++;
 		node->is_deep = TRUE;
 	}
@@ -1055,41 +1069,34 @@
 		brasero_utils_unregister_string (BRASERO_FILE_NODE_MIME (node));
 
 	if (node->is_root)
-		g_free (stats);
+		g_free (BRASERO_FILE_NODE_STATS (node));
 
 	g_free (node);
 }
 
 /**
- * returns the number of files destroyed
+ * Destroy a node and its children updating the tree stats.
+ * If it isn't unlinked yet, it does it.
  */
 void
-brasero_file_node_destroy (BraseroFileNode *node)
+brasero_file_node_destroy (BraseroFileNode *node,
+			   BraseroFileTreeStats *stats)
 {
-	BraseroFileTreeStats *stats;
-
-	if (!node->is_grafted) {
-		BraseroFileNode *parent;
-
-		/* handle the size change if it wasn't grafted */
-		for (parent = node->parent; parent && !parent->is_root; parent = parent->parent) {
-			parent->union3.sectors -= BRASERO_FILE_NODE_SECTORS (node);
-			if (parent->is_grafted)
-				break;
-		}
-	}
-
-	/* try to get the statistics structure */
-	stats = brasero_file_node_get_tree_stats (node, NULL);
-
-	/* remove from the parent children list */
+	/* remove from the parent children list or more probably from the 
+	 * import list. */
 	if (node->parent)
 		brasero_file_node_unlink (node);
 
-	/* traverse the whole tree and free children */
+	/* traverse the whole tree and free children updating tree stats */
 	brasero_file_node_destroy_with_children (node, stats);
 }
 
+/**
+ * Pre-remove function that unparent a node (before a possible destruction).
+ * If node is imported, it saves it in its parent, destroys all child nodes
+ * that are not imported and restore children that were imported.
+ * NOTE: tree stats are only updated if the node is imported.
+ */
 
 static void
 brasero_file_node_save_imported_children (BraseroFileNode *node,
@@ -1123,26 +1130,24 @@
 }
 
 void
-brasero_file_node_remove (BraseroFileNode *node,
-			  GCompareFunc sort_func)
+brasero_file_node_save_imported (BraseroFileNode *node,
+				 BraseroFileNode *parent,
+				 GCompareFunc sort_func)
 {
 	BraseroFileTreeStats *stats;
-	BraseroFileNode *parent;
 	BraseroImport *import;
 
-	/* if it isn't imported just destroy it */
+	/* if it isn't imported return */
 	if (!node->is_imported)
-		return brasero_file_node_destroy (node);
+		return;
 
 	/* Remove all the children that are not imported. Also restore
 	 * all children that were replaced so as to restore the original
 	 * order of files. */
 
-	parent = node->parent;
-
-	/* that shouldn't happen */
+	/* that shouldn't happen since root itself is considered imported */
 	if (!parent || !parent->is_imported)
-		return brasero_file_node_destroy (node);
+		return;
 
 	/* save the node in its parent import structure */
 	import = BRASERO_FILE_NODE_IMPORT (parent);
@@ -1161,6 +1166,9 @@
 	import->replaced = node;
 	node->parent = parent;
 
-	/* Explore children and remove not imported ones and restore */
-	return brasero_file_node_save_imported_children (node, stats, sort_func);
+	/* Explore children and remove not imported ones and restore.
+	 * Update the tree stats at the same time.
+	 * NOTE: here the tree stats are only used for the grafted children that
+	 * are not imported in the tree. */
+	brasero_file_node_save_imported_children (node, stats, sort_func);
 }

Modified: trunk/src/brasero-file-node.h
==============================================================================
--- trunk/src/brasero-file-node.h	(original)
+++ trunk/src/brasero-file-node.h	Thu May  1 18:16:22 2008
@@ -251,16 +251,24 @@
 brasero_file_node_ungraft (BraseroFileNode *node);
 
 void
-brasero_file_node_move (BraseroFileNode *node,
-			BraseroFileNode *parent,
-			GCompareFunc sort_func);
+brasero_file_node_move_from (BraseroFileNode *node,
+			     BraseroFileTreeStats *stats);
+void
+brasero_file_node_move_to (BraseroFileNode *node,
+			   BraseroFileNode *parent,
+			   GCompareFunc sort_func);
+
+void
+brasero_file_node_unlink (BraseroFileNode *node);
 
 void
-brasero_file_node_destroy (BraseroFileNode *node);
+brasero_file_node_destroy (BraseroFileNode *node,
+			   BraseroFileTreeStats *stats);
 
 void
-brasero_file_node_remove (BraseroFileNode *node,
-			  GCompareFunc sort_func);
+brasero_file_node_save_imported (BraseroFileNode *node,
+				 BraseroFileNode *parent,
+				 GCompareFunc sort_func);
 
 gchar *
 brasero_file_node_get_uri_name (const gchar *uri);



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