/// <summary> /// Retrieves an item at the given path. If the item doesn't exist, /// then a NotFoundException. /// </summary> /// <param name="path"></param> /// <returns></returns> public TValue Get(HierarchicalPath path) { // If we are at the top-level path, return ourselves. if (path.Count == 0) { // If we have the item, then return it. If we don't have the // item, then throw an exception. if (HasItem) { // We have the item, so return it. return(Item); } // Throw a not found exception since we can't find it. throw new KeyNotFoundException("Cannot retrieve value at path " + path); } // Get the top-level element for a child and make sure we have it. string topLevel = path.First; if (!nodes.ContainsKey(topLevel)) { throw new KeyNotFoundException("Cannot retrieve value at path " + path); } // Pass the request into the child level. HierarchicalPath childPath = path.Splice(1); HierarchicalPathTreeCollection <TValue> child = nodes[topLevel]; return(child.Get(childPath)); }
/// <summary> /// Adds an item at the specified path. /// </summary> /// <param name="path">The path.</param> /// <param name="item">The item.</param> public void Add( HierarchicalPath path, TValue item) { // If are the top-level path, set the item. if (path.Count == 0) { Item = item; HasItem = true; return; } // We have at least one more level. Figure out the top-level string // and see if we have to create the child tree node for it. string topLevel = path.First; if (!nodes.ContainsKey(topLevel)) { nodes[topLevel] = CreateChild(topLevel); } // Pull out the child tree so we can add it. HierarchicalPathTreeCollection <TValue> child = nodes[topLevel]; HierarchicalPath childPath = path.Splice(1); child.Add(childPath, item); }
public void TestSplice3() { // Setup var path = new HierarchicalPath("/a/b/c/d/e"); // Operation HierarchicalPath results = path.Splice(3, 2); // Verification Assert.AreEqual("./d/e", results.ToString()); }
/// <summary> /// Determines whether the collection contains a collection at that path. /// </summary> /// <param name="path">The path.</param> /// <returns> /// <c>true</c> if [contains] [the specified path]; otherwise, <c>false</c>. /// </returns> public bool Contains(HierarchicalPath path) { // If we have no levels, then we found it. if (path.Count == 0) { return(HasItem); } // Check to see if this tree contains the next level in the path. if (nodes.ContainsKey(path.First)) { return(nodes[path.First].Contains(path.Splice(1))); } // Otherwise, we don't have the child so there is no chance // we can contain the item. return(false); }
/// <summary> /// Retrieves the child-level tree collection for a given path. /// </summary> /// <param name="path"></param> /// <returns></returns> public HierarchicalPathTreeCollection <TValue> GetChild(HierarchicalPath path) { // If we are at the top-level path, return ourselves. if (path.Count == 0) { return(this); } // Get the top-level element for a child and make sure we have it. string topLevel = path.First; if (!nodes.ContainsKey(topLevel)) { throw new KeyNotFoundException("Cannot retrieve value at path " + path); } // Pass the request to the child. HierarchicalPathTreeCollection <TValue> child = nodes[topLevel]; return(child.GetChild(path.Splice(1))); }
/// <summary> /// Converts the given list of path containers into a Gtk.TreeStore. /// The resulting store will have three fields: the part of the path /// that represents the item, the full path, and the item. If the level /// doesn't exist (such as the created "/a" when "/a/b" is the only item), /// then the third column will be the default value. /// </summary> /// <typeparam name="TItem">The type of the item.</typeparam> /// <param name="list">The list.</param> /// <param name="reorderInPlace">if set to <c>true</c> [reorder in place].</param> /// <returns></returns> public static TreeStore ToTreeStore <TItem>( this IList <TItem> list, bool reorderInPlace) where TItem : IHierarchicalPathContainer { // Create a new tree store to populate. var store = new TreeStore( typeof(string), typeof(HierarchicalPath), typeof(TItem)); // If we are not reordering the list in place, then create a new one // that we can reorder. if (!reorderInPlace) { var newList = new List <TItem>(list); list = newList; } // Order the list so everything is grouped together. list.OrderByHierarchicalPath(); // Go through the ordered list and append all the tree elements. // Because of the ordering, we can do this as a single pass through // the list. HierarchicalPath lastPath = null; var iterPath = new List <TreeIter>(); foreach (TItem item in list) { // Pull out the path we'll be appending. HierarchicalPath path = item.HierarchicalPath; // Roll up the list to a common root. while (lastPath != null && lastPath.Count > 0 && !path.StartsWith(lastPath)) { // We don't have a common root, so move up a level. iterPath.RemoveLast(); lastPath = lastPath.Parent; } // Add any parent items to the list that we don't already // have. We do this by adding placeholders up to the current // TreeIter list until we get to the parent. TreeIter treeIter; while (iterPath.Count < path.Count - 1) { // Pull out the path we'll be inserting. string parentName = path[iterPath.Count]; lastPath = path.Splice(iterPath.Count, 1); // We have to add a placeholder item for this inserted // parent item. if (iterPath.Count == 0) { // We are at the top, so insert it there. treeIter = store.AppendValues(parentName, lastPath, default(TItem)); } else { // Append it to the parent item above it. treeIter = store.AppendValues( iterPath[iterPath.Count - 2], parentName, lastPath, default(TItem)); } // Append the newly inserted iterator into the list. iterPath.Add(treeIter); } // Once we get through this, we insert the current item. lastPath = item.HierarchicalPath; string name = lastPath.Last; if (iterPath.Count == 0) { // We are at the top, so insert it there. treeIter = store.AppendValues(name, lastPath, item); } else { // Append it to the parent item above it. treeIter = store.AppendValues( iterPath[iterPath.Count - 1], name, lastPath, item); } // Append the newly inserted iterator into the list. iterPath.Add(treeIter); } // Return the resulting store. return(store); }