private UiContainerNode BuildExtensionNode(UiArchiveExtension key, ConcurrentBag<UiNode> entries)
        {
            string separator = Path.AltDirectorySeparatorChar.ToString();

            UiContainerNode extensionNode = new UiContainerNode(key.ToString().ToUpper(), UiNodeType.Group);
            Dictionary<string, UiContainerNode> dirs = new Dictionary<string, UiContainerNode>(entries.Count);
            foreach (UiNode leaf in entries)
            {
                UiNode parent = extensionNode;
                string[] path = leaf.Name.ToLowerInvariant().Split(Path.AltDirectorySeparatorChar);
                for (int i = 0; i < path.Length - 1; i++)
                {
                    UiContainerNode directory;
                    string directoryName = path[i];
                    string directoryPath = String.Join(separator, path, 0, i + 1);
                    if (!dirs.TryGetValue(directoryPath, out directory))
                    {
                        directory = new UiContainerNode(directoryName, UiNodeType.Directory) {Parent = parent};
                        dirs.Add(directoryPath, directory);
                    }
                    parent = directory;
                }
                leaf.Parent = parent;
                leaf.Name = path[path.Length - 1];
            }

            //foreach (IGrouping<UiNode, UiNode> leafs in entries.GroupBy(e => e.Parent))
            //    ((UiContainerNode)leafs.Key).SetChilds(leafs.ToArray());

            UiNode[] childs = null;
            foreach (IGrouping<UiNode, UiNode> leafs in dirs.Values.Union(entries).GroupBy(e => e.Parent))
            {
                if (leafs.Key == extensionNode)
                {
                    childs = leafs.ToArray();
                    continue;
                }

                ((UiContainerNode)leafs.Key).SetChilds(leafs.ToArray());
            }

            foreach (UiContainerNode node in dirs.Values)
                node.AbsorbSingleChildContainer();

            extensionNode.SetChilds(childs);
            return extensionNode;
        }
        public UiContainerNode TryBuild()
        {
            if (_nodes.Count == 0)
                return null;

            int counter = 0;
            UiContainerNode result = new UiContainerNode(Lang.Dockable.GameFileCommander.ArchivesNode, UiNodeType.Group);
            UiNode[] extensions = new UiNode[_nodes.Count];
            foreach (KeyValuePair<UiArchiveExtension, ConcurrentBag<UiNode>> pair in _nodes)
            {
                UiContainerNode extensionNode = BuildExtensionNode(pair.Key, pair.Value);
                extensionNode.Parent = result;
                extensions[counter++] = extensionNode;
            }
            result.SetChilds(extensions);
            return result;
        }
Esempio n. 3
0
        protected override UiNode[] ExpandChilds()
        {
            UiChildPackageBuilder childPackages = new UiChildPackageBuilder(InteractionService.GameLocation.Provide().AreasDirectory);

            _listing = ArchiveListingReaderV1.Read(_accessor, null, null);
            _listing.Parent = _parentListing;

            HashSet<string> set = new HashSet<string>();
            Dictionary<string, UiNode> dic = new Dictionary<string, UiNode>(_listing.Count * 2);

            foreach (ArchiveEntry entry in _listing)
            {
                UiNode parent = this;

                string name;
                string entryPath = entry.Name.ToLowerInvariant();
                int index = entryPath.LastIndexOf(Path.AltDirectorySeparatorChar);
                if (index > 0)
                {
                    name = entryPath.Substring(index + 1);
                    string directoryPath = entryPath.Substring(0, index);
                    set.Add(directoryPath);
                    if (!dic.TryGetValue(directoryPath, out parent))
                    {
                        string directoryName = directoryPath;
                        int nameIndex = directoryPath.LastIndexOf(Path.AltDirectorySeparatorChar);
                        if (nameIndex > 0)
                            directoryName = directoryPath.Substring(nameIndex + 1);

                        parent = new UiContainerNode(directoryName, UiNodeType.Directory);
                        dic.Add(directoryPath, parent);
                    }
                }
                else
                {
                    name = entryPath;
                }

                if (!dic.ContainsKey(entryPath))
                    dic.Add(entryPath, new UiArchiveLeaf(name, entry, _listing) {Parent = parent});

                childPackages.TryAdd(_listing, entry, entryPath, name);
            }

            UiContainerNode packagesNode = childPackages.TryBuild();
            if (packagesNode != null)
            {
                packagesNode.Parent = this;
                dic.Add(packagesNode.Name, packagesNode);
            }

            string separator = Path.AltDirectorySeparatorChar.ToString();
            foreach (string dir in set)
            {
                UiNode parent = this;

                string[] parts = dir.Split(Path.AltDirectorySeparatorChar);
                for (int i = 0; i < parts.Length; i++)
                {
                    UiNode node;
                    string name = parts[i];
                    string path = String.Join(separator, parts, 0, i + 1);
                    if (!dic.TryGetValue(path, out node))
                    {
                        node = new UiContainerNode(name, UiNodeType.Directory);
                        dic.Add(path, node);
                    }
                    node.Parent = parent;
                    parent = node;
                }
            }

            UiNode[] result = null;
            foreach (IGrouping<UiNode, UiNode> group in dic.Values.GroupBy(n => n.Parent))
            {
                if (group.Key == this)
                {
                    result = group.ToArray();
                    continue;
                }

                UiContainerNode dir = ((UiContainerNode)group.Key);
                dir.SetChilds(group.ToArray());
            }

            foreach (UiNode node in dic.Values)
            {
                if (node.Type != UiNodeType.Directory)
                    continue;

                UiContainerNode container = (UiContainerNode)node;
                container.AbsorbSingleChildContainer();
            }

            return result;
        }