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; }
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; }