private void HandleDoubleClick()
        {
            MultiSourceTreeNode node = (MultiSourceTreeNode)GetNodeAt(lastClickX, lastClickY);

            if (node == null)
            {
                return;
            }

            foreach (NodeInfo info in node.InfoEntries)
            {
                foreach (NodeStateSubscriber subscriber in info.Subscriptions)
                {
                    foreach (MenuDefinition def in subscriber.State.MenuDefinitions.Keys)
                    {
                        bool match = false;
                        if (subscriber.State.MenuDefinitions[def]) // Will equal true if this is a default option.
                        {
                            match = true;
                            if (def.MenuItemTest != null)
                            {
                                match = def.MenuItemTest.Invoke(node, info);
                            }
                        }
                        if (match)
                        {
                            def.OnMenuClicked(node, info);
                            return;
                        }
                    }
                }
            }

            if (node.IsExpanded)
            {
                node.Collapse();
            }
            else
            {
                node.Expand();
            }
        }
 /// <summary>
 /// Recursively updates a node's child nodes after it has been renamed.
 /// </summary>
 void UpdateChildNodesAfterRename(MultiSourceTreeNode parentNode)
 {
     if (parentNode.ChildrenAdded)
     {
         foreach (MultiSourceTreeNode node in parentNode.Nodes)
         {
             foreach (NodeInfo info in node.InfoEntries)
             {
                 if (info.NodeType.SupportsRenaming)
                 {
                     info.NodeType.RenameChild(info, parentNode.InfoEntries[0]); // We're only using the first InfoEntry.
                 }
             }
             if (node.ChildrenAdded)
             {
                 UpdateChildNodesAfterRename(node);
             }
         }
     }
 }
        private void VerifyNode(MultiSourceTreeNode node)
        {
            if (node == null)
            {
                return;
            }
            List <NodeInfo> unmatchedEntries = new List <NodeInfo>();

            foreach (NodeInfo entry in node.InfoEntries)
            {
                if (!entry.NodeType.HasChildren(entry))
                {
                    unmatchedEntries.Add(entry);
                }
            }

            foreach (NodeInfo entry in unmatchedEntries)
            {
                //Output.Write(OutputTypes.Debug, " - Removing entry '" + entry.NodeType.GetType() + "' from node (has no children at this path)");
                RemoveNodeInfo(entry);
            }
        }
        void MultiSourceTreeView_MouseMove(object sender, MouseEventArgs e)
        {
            if (MousePosition == lastMousePosition)
            {
                return;
            }

            lastMousePosition = MousePosition;

            // Get the node that exists at the mouse position.
            MultiSourceTreeNode node = GetNodeAt(PointToClient(MousePosition)) as MultiSourceTreeNode;

            if (node != currentNode)
            {
                currentNode = node;

                UseInternalTooltips = true;
                tooltip.HideTooltip();

                ResetMouseIdleTimer();
            }
        }
        void MultiSourceTreeView_MouseDown(object sender, MouseEventArgs e)
        {
            ResetMouseIdleTimer();

            if (e.Button == MouseButtons.Left)
            {
                lastClickX = e.X;
                lastClickY = e.Y;
            }
            if (e.Button == MouseButtons.Right)
            {
                MultiSourceTreeNode node = GetNodeAt(e.X, e.Y) as MultiSourceTreeNode;
                if (node == null)
                {
                    return;
                }

                if (SelectedNode != node)
                {
                    if (SelectedNodes.Length < 2)
                    {
                        SelectedNode = node;
                    }
                }

                MultiSourceTreeNode[] selectedNodes = new MultiSourceTreeNode[SelectedNodes.Length];
                for (int x = 0; x < SelectedNodes.Length; x++)
                {
                    selectedNodes[x] = (MultiSourceTreeNode)SelectedNodes[x];
                }

                UpdateContextMenu(selectedNodes);
                if (popupMenu.SubItems.Count > 0)
                {
                    popupMenu.Popup(MousePosition);
                }
            }
        }
Exemple #6
0
 /// <summary>
 /// Adds a 'dummy node' to the specified MultiSourceTreeNode.
 /// </summary>
 /// <description>
 /// The purpose of a dummy node, is to allow a node to be expandable without
 /// having to actually populate it's child nodes first.  This allows us to
 /// load child nodes on the fly - thus greatly improving performance of the TreeView.
 /// </description>
 protected static void AddDummyNode(MultiSourceTreeNode node)
 {
     node.Nodes.Add("dummy");
 }
        private MultiSourceTreeNode UpdateNode(NodeInfo info)
        {
            if (InvokeRequired)
            {
                return((MultiSourceTreeNode)(Invoke((NodeMethodDelegate) delegate { return UpdateNode(info); })));
            }

            //Output.Write(OutputTypes.Debug, "Updating Node (" + info.NodeType.GetType() + "): " + info.Identifier);

            string treePath = info.NodeType.GetTreePath(info);

            if (treePath == "")
            {
                return(null);
            }
            MultiSourceTreeNode node = (MultiSourceTreeNode)GetNodeFromPath(treePath);

            if (node != null)
            {
                //Output.Write(OutputTypes.Debug, "Found node in the tree.");
                // Add Node Info to node.
                //Output.Write(OutputTypes.Debug, "Adding info entry.");
                if (!node.ContainsEntry(info))
                {
                    node.AddInfoEntry(info);
                }
                //else
                //Output.Write(OutputTypes.Debug, " - (Already contained)");
                info.ParentSource.UpdateNode(node);

                // Recursively update the parent nodes.
                NodeInfo parentInfo = info.NodeType.GetParentNodeInfo(info);
                if (parentInfo != null)
                {
                    if (parentInfo.Identifier != "")
                    {
                        //Output.Write(OutputTypes.Debug, "Updating parent node.");
                        UpdateNode(parentInfo);
                    }
                }

                return(node);
            }
            else
            {
                //Output.Write(OutputTypes.Debug, "The node does not exist in the tree.");
                NodeInfo            parentInfo = info.NodeType.GetParentNodeInfo(info);
                MultiSourceTreeNode parentNode;
                if (parentInfo.Identifier != "")
                {
                    //Output.Write(OutputTypes.Debug, "Updating parent node.");
                    parentNode = UpdateNode(parentInfo);
                }
                else
                {
                    // We've reached the root node, and the item does not exist.
                    string parentTreePath = parentInfo.NodeType.GetTreePath(parentInfo);
                    parentNode = (MultiSourceTreeNode)GetNodeFromPath(parentTreePath);
                }

                if (parentNode != null)
                {
                    if (parentNode.ChildrenAdded)
                    {
                        //Output.Write(OutputTypes.Debug, "Parent node exists and its children have been added.");
                        // Create the node.
                        string nodeName = info.NodeType.GetNodeName(info.Identifier);
                        node = info.ParentSource.CreateNode(nodeName, info, info.NodeType.HasChildren);
                        //Output.Write(OutputTypes.Debug, "Manually add the new node (" + node.Text + ") to " + parentNode.Text + ".");
                        AddChildNodes(parentNode, new MultiSourceTreeNode[] { node });
                        return(node);
                    }
                }
                return(parentNode);
            }
        }
        private void RemoveNodeInfo(NodeInfo info)
        {
            if (InvokeRequired)
            {
                Invoke(new MethodInvoker(delegate { RemoveNodeInfo(info); }));
                return;
            }

            // Retreive the node from the tree (if it exists).
            //Output.Write(OutputTypes.Debug, "Removing Node (" + info.NodeType.GetType() + "): " + info.Identifier);
            string treePath          = info.NodeType.GetTreePath(info);
            MultiSourceTreeNode node = (MultiSourceTreeNode)GetNodeFromPath(treePath);

            if (node != null)
            {
                // Store our parent, since this will change once we remove the node from it.
                TreeNode parentNode = node.Parent;

                //Output.Write(OutputTypes.Debug, "Node exists in the tree.");

                // Remove the entry if it exists.
                NodeInfo entry = node.FindInfoEntry(info.NodeType);
                if (entry != null)
                {
                    node.RemoveInfoEntry(entry);
                    //Output.Write(OutputTypes.Debug, "Removed matching InfoEntry from the node.");
                }
                //else
                //Output.Write(OutputTypes.Debug, "Matching InfoEntry was not found!");


                // Update the node if we still have entries.
                // DESIGN ISSUE:
                // -------------
                // When an entry is removed, child nodes will also need updating.
                // The problem is, there is no way to do this without recreating the child nodes.
                if (node.EntryCount > 0)
                {
                    info.ParentSource.UpdateNode(node);
                    //Output.Write(OutputTypes.Debug, "Node still contains entries - updating.");
                }
                else
                // Remove the node (if there is a parent to remove it from)
                if (parentNode != null)
                {
                    //Output.Write(OutputTypes.Debug, "Node contains no more entries - removing node.");
                    parentNode.Nodes.Remove(node);
                    if (parentNode.Nodes.Count == 0)
                    {
                        parentNode.Collapse();
                    }
                }

                // Verify the parent node.
                if (parentNode != null)
                {
                    if (parentNode is MultiSourceTreeNode)
                    {
                        //Output.Write(OutputTypes.Debug, "Verifying parent node: " + parentNode.Text);
                        VerifyNode(parentNode as MultiSourceTreeNode);
                    }
                }
            }
            else
            {
                //Output.Write(OutputTypes.Debug, "Node does not exist in the tree.");
                // The node doesn't exist in the tree, so we don't need to remove it.
                // We do, however, still need to update the node's parent to ensure that
                // it still contains child objects of this type.

                // Direct parent may not exist (which was causing issues previously)
                // Because of that, we will need to go all the way up the tree until we
                // either find a node, or hit the root node.
                MultiSourceTreeNode parentNode = GetFirstExistingParentNode(info);
                if (parentNode != null)
                {
                    //Output.Write(OutputTypes.Debug, "Located a parent node: " + parentNode.Text + " - Updating.");
                    VerifyNode(parentNode);
                }
                //else
                //Output.Write(OutputTypes.Debug, "No parent node was found - no updates required.");
            }
        }
        void MultiSourceTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            MultiSourceTreeNode node = (MultiSourceTreeNode)e.Node;

            LabelEdit = (node.InfoEntries[0].NodeType.SupportsRenaming);
        }
 /// <summary>
 /// Creates the child nodes of the specified node.
 /// </summary>
 protected void CreateChildren(MultiSourceTreeNode node)
 {
     CreateChildren(node, false);
 }