Example #1
0
        /// <summary>
        /// It is assumed that the node oldFlattenedTree[oldIndex] and newFlattenedTree[newIndex] coorespond
        /// to one another (have the same path to root)
        /// Copies the expandedness of the node 'oldFlattenedTree[oldIndex]' to the new node at
        /// newFlattenedTree[newIndex], as well as all the state for child node.
        /// </summary>
        internal static void CopyExpandedStateForNode(List <CallTreeViewNode> newFlattenedTree, int newIndex,
                                                      ObservableCollectionEx <CallTreeViewNode> oldFlattenedTree, int oldIndex)
        {
            Debug.Assert(newIndex == newFlattenedTree.Count - 1);
            CallTreeViewNode oldNode = oldFlattenedTree[oldIndex];

            if (oldNode.m_isExpanded)
            {
                CallTreeViewNode newNode = newFlattenedTree[newIndex];
                Debug.Assert(newNode.Data.DisplayName == oldNode.Data.DisplayName);
                newNode.m_isExpanded = true;
                if (newNode.HasChildren)
                {
                    var children = newNode.MakeChildren();
                    for (int i = 0; i < children.Count; i++)
                    {
                        var newChild = children[i];
                        newFlattenedTree.Add(newChild);

                        // This is N squared so can take a long time if there are many children
                        // We can simply give up in that case.
                        if (i < 50)
                        {
                            int oldChildIndex = FindChild(oldFlattenedTree, oldNode, oldIndex, newChild.Data.DisplayName);
                            if (oldChildIndex >= 0)
                            {
                                CopyExpandedStateForNode(newFlattenedTree, newFlattenedTree.Count - 1, oldFlattenedTree, oldChildIndex);
                            }
                        }
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// I did not make this a property because it is too profound an operation (heavy)
        /// This sets the root of the tree.  This is how you change the display to a new tree.
        /// </summary>
        public void SetRoot(CallTreeNode root)
        {
            List <CallTreeViewNode> newFlattenedTree = new List <CallTreeViewNode>();

            newFlattenedTree.Add(new CallTreeViewNode(this, root, 0));

            // Copy over the nodes to the new flattened tree (as best we can)
            if (m_flattenedTree.Count > 0 && m_flattenedTree[0].Data.DisplayName == root.DisplayName)
            {
                CallTreeViewNode.CopyExpandedStateForNode(newFlattenedTree, 0, m_flattenedTree, 0);
            }

            // Destroy old nodes (to save memory because GUI keeps references to them)
            foreach (var node in m_flattenedTree)
            {
                node.Dispose();
            }

            // Update the whole tree with the new tree.
            m_flattenedTree.ReplaceRange(0, m_flattenedTree.Count, newFlattenedTree);
            Validate();
            m_root        = root;
            m_curPosition = null;
            m_endPosition = null;

            // Expand the root element
            var rootView = InsureVisible(m_root);

            rootView.IsExpanded = true;
        }
Example #3
0
        /// <summary>
        /// An Unexpanded CallTreeViewNode does not have any children even if the Data (CallTreeNode) does
        /// This routine will make the necessary children (it is part of expanding the node).
        /// </summary>
        private List <CallTreeViewNode> MakeChildren()
        {
            var callees = m_treeView.DisplayCallees(Data);

            Debug.Assert(callees != null);
            var ret = new List <CallTreeViewNode>();

            for (int i = 0; i < callees.Count; i++)
            {
                CallTreeNode elem    = callees[i];
                var          newNode = new CallTreeViewNode(m_treeView, elem, m_depth + 1);

                if (IsSecondaryChild || elem.IsGraphNode)
                {
                    newNode.IsSecondaryChild = true;
                }
                ret.Add(newNode);
            }
            return(ret);
        }
Example #4
0
        /// <summary>
        /// Given a CallTreeNode, find a CallTreeViewNode for it (ensure that it is displayed)
        /// </summary>
        private CallTreeViewNode InsureVisible(CallTreeNode treeNode)
        {
            if (treeNode.Caller == null)
            {
                return(m_flattenedTree[0]);
            }

            CallTreeViewNode caller = InsureVisible(treeNode.Caller);

            if (caller == null)         // should never happen, but we can fall back to giving up.
            {
                return(null);
            }

            caller.IsExpanded = true;
            caller.ValidateTree();

            int callerPos = caller.MyIndex + 1;

            while (callerPos < m_flattenedTree.Count)
            {
                var child = m_flattenedTree[callerPos];
                if (child.m_depth <= caller.m_depth)
                {
                    break;
                }

                if (child.Data == treeNode)
                {
                    return(child);
                }

                callerPos++;
            }
            Debug.Assert(false, "Should have found call node");
            return(null);
        }
Example #5
0
        /// <summary>
        /// Given a node == flattenedTree[sampleIndex] find the sampleIndex in flattenedTree of a child with Data.NameBase == 'nameBame'
        /// </summary>
        private static int FindChild(ObservableCollectionEx <CallTreeViewNode> flattenedTree, CallTreeViewNode node, int index, string nameBase)
        {
            Debug.Assert(flattenedTree[index] == node);
            int childDepth = node.m_depth + 1;
            int childIndex = index;

            for (; ;)
            {
                childIndex++;
                if (childIndex >= flattenedTree.Count)
                {
                    break;
                }

                var child = flattenedTree[childIndex];
                if (child.m_depth < childDepth)
                {
                    break;
                }

                if (child.m_depth == childDepth && child.Data.DisplayName == nameBase)
                {
                    return(childIndex);
                }
            }
            return(-1);
        }