Example #1
0
        private void LoadDirectoryNodeChildren(DirectoryNodeViewModel directoryNode)
        {
            if (directoryNode.ChildrenLoaded)
            {
                return;
            }

            var directoryEntry = _nodeViewModelLoader.LoadChildren(directoryNode);

            if (directoryEntry == null)
            {
                return;
            }

            var children = directoryEntry.Entries
                           .Select(childEntry => {
                var node = IncrementalHierarchyBuilder.CreateNodeViewModel(_nodeTemplateFactory, childEntry, directoryNode);

                // Initialize template icon if needed
                if (node is FileNodeViewModel)
                {
                    if (node.Template.Icon == null)
                    {
                        var extension = PathHelpers.GetExtension(childEntry.Name);
                        Invariants.Assert(extension != null);
                        node.Template.Icon = _imageSourceFactory.GetFileExtensionIcon(extension);
                    }
                }

                return(node);
            })
                           .ToList();

            foreach (var child in children)
            {
                child.ItemId = _nodes.MaxItemId + 1;
                _nodes.AddNode(child);
            }

            directoryNode.SetChildren(children);
        }
Example #2
0
        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);
                }
            }
        }
Example #3
0
        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);
                    }
                }
            }
        }