private void GenerateChildItems() { if (graphItems == null) { cachedItems = emptyList; return; } var rootChildren = new List <IncludeTreeViewItem>(); cachedItems = rootChildren; // Create first layer of folder and leaf items var leafItems = new List <FolderIncludeTreeViewItem_Leaf>(); foreach (IncludeGraph.GraphItem item in graphItems) { if (item == includingFile) { continue; } leafItems.Add(new FolderIncludeTreeViewItem_Leaf(item)); } // Group by folder. if (leafItems.Count > 0) { leafItems.Sort((x, y) => x.ParentFolder.CompareTo(y.ParentFolder)); var root = new FolderIncludeTreeViewItem_Folder("", 0); GroupIncludeRecursively(root, leafItems, 0, leafItems.Count, 0); rootChildren.AddRange(root.ChildrenList); } }
private void GroupIncludeRecursively(FolderIncludeTreeViewItem_Folder parentFolder, List <FolderIncludeTreeViewItem_Leaf> allLeafItems, int begin, int end, int commonPrefixLength) { System.Diagnostics.Debug.Assert(begin < end); System.Diagnostics.Debug.Assert(allLeafItems.Count >= end); // Look through the sorted subsection of folders and find ranges where the prefix changes. while (begin < end) { // New subgroup to look at! string currentPrefix = GetNextPathPrefix(allLeafItems[begin].ParentFolder, commonPrefixLength + 1); // Find end of the rest of the group and expand recurively. for (int i = begin; i <= end; ++i) { if (i == end || !allLeafItems[i].ParentFolder.StartsWith(currentPrefix)) { // Find maximal prefix of this group. string largestPrefix = LargestCommonFolderPrefixInRange(allLeafItems, begin, i, currentPrefix); var newGroup = new FolderIncludeTreeViewItem_Folder(largestPrefix, commonPrefixLength); parentFolder.ChildrenList.Add(newGroup); // If there are any direct children, they will be first due to sorting. Add them to the new group and ignore this part of the range. while (allLeafItems[begin].ParentFolder.Length == largestPrefix.Length) { newGroup.ChildrenList.Add(allLeafItems[begin]); ++begin; if (begin == i) { break; } } // What's left is non-direct children (== folders!) that we need to handle recursively. int numFoldersInGroup = i - begin; if (numFoldersInGroup > 0) { GroupIncludeRecursively(newGroup, allLeafItems, begin, i, largestPrefix.Length); } // Next group starts at this element. begin = i; break; } } } }