private void AddNodeForChildren(FileSystemEntry entry, NodeViewModel oldParent, NodeViewModel newParent) { Invariants.Assert(entry != null); Invariants.Assert(newParent != null); Invariants.Assert(newParent.Children.Count == 0); // Create children nodes var directoryEntry = entry as DirectoryEntry; if (directoryEntry != null) { foreach (var childEntry in directoryEntry.Entries.ToForeachEnum()) { var child = CreateNodeViewModel(childEntry, newParent); newParent.AddChild(child); } } // Note: It is correct to compare the "Name" property only for computing // diffs, as we are guaranteed that both nodes have the same parent, hence // are located in the same directory. We also use the // System.Reflection.Type to handle the fact a directory can be deleted // and then a name with the same name can be added. We need to consider // that as a pair of "delete/add" instead of a "no-op". var diffs = ArrayUtilities.BuildArrayDiffs( oldParent == null ? ArrayUtilities.EmptyList <NodeViewModel> .Instance : oldParent.Children, newParent.Children, NodeTypeAndNameComparer.Instance); foreach (var item in diffs.LeftOnlyItems.ToForeachEnum()) { _changes.DeletedItems.Add(item.ItemId); } foreach (var newChild in diffs.RightOnlyItems.ToForeachEnum()) { newChild.ItemId = _newNodeNextItemId; _newNodeNextItemId++; newChild.IsExpanded = newParent.IsRoot; _newNodes.AddNode(newChild); if (oldParent != null) { _changes.AddedItems.Add(newChild.ItemId); } } foreach (var pair in diffs.CommonItems.ToForeachEnum()) { pair.RigthtItem.ItemId = pair.LeftItem.ItemId; pair.RigthtItem.IsExpanded = pair.LeftItem.IsExpanded; _newNodes.AddNode(pair.RigthtItem); } // Call recursively on all children if (directoryEntry != null) { Invariants.Assert(directoryEntry.Entries.Count == newParent.Children.Count); for (var i = 0; i < newParent.Children.Count; i++) { var childEntry = directoryEntry.Entries[i]; var newChildNode = newParent.Children[i]; var oldChildNode = GetCommonOldNode(newParent, i, diffs, newChildNode); AddNodeForChildren(childEntry, oldChildNode, newChildNode); } } }
private void AddNodeForChildren(IDictionary <RelativePath, DirectoryEntry> previouslyLoadedChildren, NodeViewModel oldParent, NodeViewModel newParent) { Invariants.Assert(oldParent != null); Invariants.Assert(newParent != null); Invariants.Assert(newParent.Children.Count == 0); var oldParentDirectory = oldParent as DirectoryNodeViewModel; if (oldParentDirectory == null) { return; } var newParentDirectory = newParent as DirectoryNodeViewModel; if (newParentDirectory == null) { return; } var oldParentChildrenList = oldParentDirectory.CopyChildren(); // Note: The "IsRoot" test is to ensure we always load children of the root node // so that the returned hierarchy is not empty. if (oldParentChildrenList.Count == 0 && !oldParent.IsRoot) { return; } // Create children nodes var directoryEntry = LoadNewNodeChildren(previouslyLoadedChildren, newParentDirectory); if (directoryEntry != null) { foreach (var childEntry in directoryEntry.Entries.ToForeachEnum()) { var child = CreateNodeViewModel(childEntry, newParent); newParent.AddChild(child); } } // Note: It is correct to compare the "Name" property only for computing // diffs, as we are guaranteed that both nodes have the same parent, hence // are located in the same directory. We also use the // System.Reflection.Type to handle the fact a directory can be deleted // and then a name with the same name can be added. We need to consider // that as a pair of "delete/add" instead of a "no-op". var diffs = ArrayUtilities.BuildArrayDiffs(oldParentChildrenList, newParent.Children, NodeTypeAndNameComparer.Instance); // Mark deleted items foreach (var item in diffs.LeftOnlyItems.ToForeachEnum()) { _changes.DeletedItems.Add(item.ItemId); } // Mark added items foreach (var newChild in diffs.RightOnlyItems.ToForeachEnum()) { newChild.ItemId = _newNodeNextItemId; _newNodeNextItemId++; newChild.IsExpanded = newParent.IsRoot; _newNodes.AddNode(newChild); _changes.AddedItems.Add(newChild.ItemId); } // Commons items don't need updating, just adding to the new parent foreach (var pair in diffs.CommonItems.ToForeachEnum()) { pair.RigthtItem.ItemId = pair.LeftItem.ItemId; pair.RigthtItem.IsExpanded = pair.LeftItem.IsExpanded; _newNodes.AddNode(pair.RigthtItem); } // Call recursively on all children if (directoryEntry != null) { Invariants.Assert(directoryEntry.Entries.Count == newParent.Children.Count); for (var i = 0; i < newParent.Children.Count; i++) { var newChildNode = newParent.Children[i]; var oldChildNode = GetCommonOldNode(newParent, i, diffs, newChildNode); if (oldChildNode != null) { AddNodeForChildren(previouslyLoadedChildren, oldChildNode, newChildNode); } } } }