예제 #1
0
        public void StartsWith4()
        {
            var nr = new HierarchicalPath("/this/is");
            var sr = new HierarchicalPath("/this");

            Assert.AreEqual(true, nr.StartsWith(sr));
        }
예제 #2
0
        public void StartsWith2()
        {
            var nr = new HierarchicalPath("/this/is");
            var sr = new HierarchicalPath("/not/in/is/a/path");

            Assert.AreEqual(false, nr.StartsWith(sr));
        }
        /// <summary>
        /// Shuffles the contents of the list so that each HierarchicalPath is
        /// followed directly by the items underneath it, but still retain the
        /// relative order elements that aren't in the hierarchicy.
        ///
        /// For example, given "/z/a", "/z", and "/b", it would sort them into
        /// "/z", "/z/a", "/b".
        /// </summary>
        /// <typeparam name="TItem">The type of the item.</typeparam>
        /// <param name="list">The list.</param>
        public static void OrderByHierarchicalPath <TItem>(this IList <TItem> list)
            where TItem : IHierarchicalPathContainer
        {
            // If the list is empty or has a single time, we don't have to do
            // anything.
            int count = list.Count;

            if (count <= 1)
            {
                return;
            }

            // For the first path, go through the list and perform a bubble
            // sort to reorder the elements so that parent elements will be
            // before the child ones.
            for (int startIndex = 0;
                 startIndex < count - 1;
                 startIndex++)
            {
                // Pull out the path at this index.
                HierarchicalPath startPath = list[startIndex].HierarchicalPath;
                bool             startOver = false;

                // Go through all the items after the start index.
                for (int testIndex = startIndex + 1;
                     testIndex < count;
                     testIndex++)
                {
                    // Pull out the test path for comparison.
                    HierarchicalPath testPath = list[testIndex].HierarchicalPath;

                    // Check for equal levels since we don't swap equal-level
                    // elements.
                    if (startPath.Count == testPath.Count)
                    {
                        continue;
                    }

                    // Check to see which one has the least number of elements
                    // since that will be "higher" on the list.
                    if (startPath.StartsWith(testPath))
                    {
                        // We have to insert the parent before the current start
                        // index, then start processing again.
                        TItem item = list[testIndex];
                        list.RemoveAt(testIndex);
                        list.Insert(startIndex, item);

                        // Decrement the start index to start again.
                        startOver = true;
                        break;
                    }
                }

                // If we are starting over, we shift the index back slight and
                // start the outer loop again.
                if (startOver)
                {
                    startIndex--;
                    break;
                }
            }

            // The second pass involves grouping the related items together.
            // This is a 2-loop process. The first loop is the item we are
            // comparing against. The second looks for items that are underneath
            // the test path and brings them before items that are not.
            for (int startIndex = 0;
                 startIndex < count - 1;
                 startIndex++)
            {
                // Pull out the path at this index.
                HierarchicalPath startPath = list[startIndex].HierarchicalPath;

                // Go through all the items after the start index.
                int  lastChildIndex = startIndex;
                bool foundNonChild  = false;

                for (int testIndex = startIndex + 1;
                     testIndex < count;
                     testIndex++)
                {
                    // Pull out the test path for comparison.
                    HierarchicalPath testPath = list[testIndex].HierarchicalPath;

                    // Check to see if testPath is underneath the startPath.
                    if (testPath.StartsWith(startPath))
                    {
                        // Check to see if we have a non-child between the last
                        // child path and this one.
                        if (foundNonChild)
                        {
                            // Increment the last child index since we'll be
                            // inserting this new item there.
                            lastChildIndex++;

                            // Remove the item from the test position and insert
                            // it into the updated child index.
                            TItem item = list[testIndex];
                            list.RemoveAt(testIndex);
                            list.Insert(lastChildIndex, item);

                            // Move the index back to it (and a bit more to
                            // handle the for() loop incrementer.
                            testIndex = lastChildIndex - 1;

                            // Clear out the non child flag.
                            foundNonChild = false;
                        }
                        else
                        {
                            // This is a child item, just mark it and continue.
                            lastChildIndex = testIndex;
                        }
                    }
                    else
                    {
                        // This isn't a child path
                        foundNonChild = true;
                    }
                }
            }
        }
 public void StartsWith4()
 {
     var nr = new HierarchicalPath("/this/is");
     var sr = new HierarchicalPath("/this");
     Assert.AreEqual(true, nr.StartsWith(sr));
 }
 public void StartsWith2()
 {
     var nr = new HierarchicalPath("/this/is");
     var sr = new HierarchicalPath("/not/in/is/a/path");
     Assert.AreEqual(false, nr.StartsWith(sr));
 }
        /// <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);
        }