private string ArgsToText(
     TVNMA_ActionArgs Args, 
     bool bBefore)
 {
     // Deleted node?
     if (!bBefore && Args.Action == TVNMA_Actions.Delete)
     {
         if (Args.DestNode != null)
         {
             return string.Format("Action={0}, OldPath=[{1}] CurSelPath=[{2}]",
                 Args.Action.ToString(),
                 Args.Tag as string,
                 Args.DestNode.FullPath);
         }
         else
         {
             return "Empty!";
         }
     }
     else
     {
         return string.Format("@{0},Action={1},OldPath=[{2}] NewPath[{3}]",
             Args.SrcNode.Index,
             Args.Action.ToString(),
             Args.Tag as string,
             Args.SrcNode.FullPath);
     }
 }
        private bool BeforeTVNMA(TVNMA_ActionArgs Args)
        {
            switch (Args.Action)
            {
                case TVNMA_Actions.Add_Above:
                    Args.TextNew = "New node above - " + Args.TextOld;
                    break;

                case TVNMA_Actions.Add_Below:
                    Args.TextNew = "New node below - " + Args.TextOld;
                    break;
                case TVNMA_Actions.Rename:
                    Args.TextNew = Args.TextOld + "*";
                    break;
            }

            Text = ArgsToText(Args, true);
            Args.Tag = Args.SrcNode.FullPath;
            return true;
        }
示例#3
0
 private bool DoOnBeforeAction(TVNMA_ActionArgs Args)
 {
     return OnBeforeAction == null ? true : OnBeforeAction(Args);
 }
示例#4
0
        private bool CarryTVNodeAction(
            TVNMA_ActionArgs Args)
        {
            // SrcNode should always be not null
            if (Args.SrcNode == null)
                return false;

            // Capture old title before calling the callback
            Args.TextOld = Args.SrcNode.Text;

            // Internal flag allows us to call this function recursively if needed.
            bool bInternal = Args.Action.HasFlag(TVNMA_Actions.Internal);
            if (!bInternal && !DoOnBeforeAction(Args))
                return false;

            var tv = Args.SrcNode.TreeView;

            TreeNode PrevParent = Args.SrcNode.Parent == null ? tv.TopNode : Args.SrcNode.Parent;

            // Clear the internal flag
            Args.Action &= ~TVNMA_Actions.Internal;
            switch (Args.Action)
            {
                case TVNMA_Actions.Rename:
                    Args.SrcNode.Text = Args.TextNew;
                    break;

                case TVNMA_Actions.Add_Both:
                {
                    // Create new node with the desired title.
                    // (No need to insert the node into the tree since it will be moved.)
                    Args.DestNode = new TreeNode(Args.TextNew);

                    // Move the node above
                    Args.DestNode.MoveAboveOrBelow(
                        Args.SrcNode,
                        bAbove: Args.Action == TVNMA_Actions.Add_Above);
                    break;
                }

                case TVNMA_Actions.Add_Above:
                case TVNMA_Actions.Add_Below:
                    goto case TVNMA_Actions.Add_Both;

                case TVNMA_Actions.Move_Above:
                    Args.SrcNode.MoveAboveOrBelow(
                        Args.DestNode,
                        bAbove: true);
                    break;

                case TVNMA_Actions.Move_Below:
                    Args.SrcNode.MoveAboveOrBelow(
                        Args.DestNode,
                        bAbove: false);
                    break;

                case TVNMA_Actions.Move_Into_Top:
                    Args.SrcNode.MakeChildOf(
                        Args.DestNode,
                        bAppend: false);
                    break;

                case TVNMA_Actions.Move_Into_Bottom:
                    Args.SrcNode.MakeChildOf(
                        Args.DestNode,
                        bAppend: true);
                    break;

                case TVNMA_Actions.Indent:
                    Args.SrcNode.Indent();
                    break;

                case TVNMA_Actions.UnIndent:
                    Args.SrcNode.UnIndent();
                    break;

                case TVNMA_Actions.Delete:
                {
                    // Elect the new selected node after deleltion
                    
                    // NextNode?
                    Args.DestNode = Args.SrcNode.NextNode;
                    
                    // PrevNode?
                    if (Args.DestNode == null)
                        Args.DestNode = Args.SrcNode.PrevNode;

                    // Parent?
                    if (Args.DestNode == null)
                        Args.DestNode = Args.SrcNode.Parent;

                    // Delete the node
                    Args.SrcNode.Remove();

                    // Also clear the node reference so the caller knows
                    Args.SrcNode = null;

                    break;
                }

                default:
                    return false;
            }

            TreeNode VisSrcNode = (Args.Action == TVNMA_Actions.Delete) ? Args.DestNode : Args.SrcNode;

            if (VisSrcNode != null)
            {
                tv.SelectedNode = VisSrcNode;

                // Set new parent
                if (VisSrcNode.Parent == null && tv.TopNode != null)
                    tv.TopNode.SetAutoImageIndex();
                else
                    VisSrcNode.Parent.SetAutoImageIndex();
            }

            if (PrevParent != null)
                PrevParent.SetAutoImageIndex();

            return bInternal ? true : DoOnAfterAction(Args);
        }
示例#5
0
        private void CreateMenuItems()
        {
            m_AllActions = TVNMA_Actions.None;
            if (WantedActions == null)
                return;

            // Create all menu items
            var _acts = new Dictionary<TVNMA_Actions, TVNMA_ActionOptions>();
            foreach (var act in WantedActions)
            {
                if (bWantMenu)
                {
                    _acts[act.Action] = act;
                    act.MenuItem = new ToolStripMenuItem()
                    {
                        ShortcutKeys = act.Shortcut,
                        Text = act.MenuText
                    };
                }
                m_AllActions |= act.Action;
            }

            if (!bWantMenu)
                return;

            if (Menu == null)
                Menu = new ContextMenuStrip();

            m_AllMenuItems = new List<ToolStripItem>();
            var AddSep = new Action(() =>
            {
                m_AllMenuItems.Add(new ToolStripSeparator());
            });

            //
            // Assign Ident menu item actions
            //
            TVNMA_ActionOptions Opts;
            if (_acts.TryGetValue(TVNMA_Actions.Indent, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    CarryTVNodeAction(new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Indent,
                        SrcNode = tv.SelectedNode
                    });
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (_acts.TryGetValue(TVNMA_Actions.UnIndent, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    CarryTVNodeAction(new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.UnIndent,
                        SrcNode = tv.SelectedNode
                    });
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (m_AllActions.HasFlag(TVNMA_Actions.Indent_Both))
                AddSep();

            //
            // Assign Add menu item actions
            //
            if (_acts.TryGetValue(TVNMA_Actions.Add_Above, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    CarryTVNodeAction(new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Add_Above,
                        SrcNode = tv.SelectedNode
                    });
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (_acts.TryGetValue(TVNMA_Actions.Add_Below, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    CarryTVNodeAction(new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Add_Below,
                        SrcNode = tv.SelectedNode
                    });
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (m_AllActions.HasFlag(TVNMA_Actions.Add_Both))
                AddSep();

            //
            // Assign Move menu item actions
            //
            if (_acts.TryGetValue(TVNMA_Actions.Move_Above, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    var Args = new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Move_Above,
                        SrcNode = tv.SelectedNode,
                        DestNode = tv.SelectedNode.PrevNode
                    };
                    if (Args.DestNode != null)
                        CarryTVNodeAction(Args);
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (_acts.TryGetValue(TVNMA_Actions.Move_Below, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    var Args = new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Move_Below,
                        SrcNode = tv.SelectedNode,
                        DestNode = tv.SelectedNode.NextNode
                    };
                    if (Args.DestNode != null)
                        CarryTVNodeAction(Args);
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (m_AllActions.HasFlag(TVNMA_Actions.Move_Both))
                AddSep();

            //
            // Add Rename/Delete
            //
            if (_acts.TryGetValue(TVNMA_Actions.Rename, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    CarryTVNodeAction(new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Rename,
                        SrcNode = tv.SelectedNode
                    });
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (_acts.TryGetValue(TVNMA_Actions.Delete, out Opts))
            {
                Opts.MenuItem.Click += new EventHandler(delegate (object o, EventArgs ev)
                {
                    CarryTVNodeAction(new TVNMA_ActionArgs()
                    {
                        Action = TVNMA_Actions.Delete,
                        SrcNode = tv.SelectedNode
                    });
                });
                m_AllMenuItems.Add(Opts.MenuItem);
            }

            if (m_AllActions.HasFlag(TVNMA_Actions.RenOrDel))
                AddSep();

            //
            // Add all the menu items
            //
            if (m_AllMenuItems[m_AllMenuItems.Count - 1] is ToolStripSeparator)
                m_AllMenuItems.RemoveAt(m_AllMenuItems.Count - 1);

            foreach (var mi in m_AllMenuItems)
                Menu.Items.Add(mi);

            tv.ContextMenuStrip = Menu;
        }
示例#6
0
        private void SetupDragDropHandlers()
        {
            if (!bWantDragDrop)
                return;

            tv.AllowDrop = true;
            //
            // ItemDrag
            //
            tv.ItemDrag += new ItemDragEventHandler(delegate (object sender, ItemDragEventArgs e)
            {
                tv.DoDragDrop(
                    e.Item,
                    DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link);
            });

            //
            // DragEnter
            //
            tv.DragEnter += new DragEventHandler(delegate (object sender, DragEventArgs e)
            {
                if (e.Data.GetDataPresent(TV_NODE))
                {
                    e.Effect = GetDragEffectFromKeyState(e.KeyState);
                }
                else
                {
                    e.Effect = DragDropEffects.None;
                }
            });

            //
            // DragOver
            //
            tv.DragOver += new DragEventHandler(delegate (object sender, DragEventArgs e)
            {
                if (!e.Data.GetDataPresent(TV_NODE))
                    return;

                var treeView = sender as System.Windows.Forms.TreeView;
                Point pt = treeView.PointToClient(new Point(e.X, e.Y));

                TreeNode DestTreeNode = treeView.GetNodeAt(pt);

                if (DestTreeNode == null)
                    return;

                TreeNode SrcTreeNode = e.Data.GetData(TV_NODE) as TreeNode;

                // Select the destination node
                treeView.SelectedNode = DestTreeNode;

                // Make sure we are not going to drop the src node into any of its parent nodes
                var parent = DestTreeNode;
                while (parent != null)
                {
                    if (parent == SrcTreeNode)
                    {
                        e.Effect = DragDropEffects.None;
                        return;
                    }

                    // Walk up the tree to figure out that the destination node is not inside its parent
                    parent = parent.Parent;
                }

                if (nAutoExpandMS > 0)
                {
                    // If the destination node has changed, then reset the stopwatch
                    if (m_LastDragOverDestTreeNode != DestTreeNode)
                    {
                        m_DragOverAutoExpandStopWatch.Restart();
                    }
                    else
                    {
                        // Enough time elapsed? User's intent to open this node
                        if (m_DragOverAutoExpandStopWatch.ElapsedMilliseconds > nAutoExpandMS)
                            DestTreeNode.Expand();
                    }

                    // Remember the last node
                    m_LastDragOverDestTreeNode = DestTreeNode;
                }
                e.Effect = GetDragEffectFromKeyState(e.KeyState);
            });

            //
            // DragDrop
            //
            tv.DragDrop += new DragEventHandler(delegate (object sender, DragEventArgs e)
            {
                if (!e.Data.GetDataPresent(TV_NODE))
                {
                    e.Effect = DragDropEffects.None;
                    return;
                }

                var tv = sender as System.Windows.Forms.TreeView;
                Point pt = tv.PointToClient(new Point(e.X, e.Y));

                TreeNode DestTreeNode = tv.GetNodeAt(pt);
                TreeNode SrcTreeNode = e.Data.GetData(TV_NODE) as TreeNode;

                // Remember the source node's parent (before the action takes place).
                // We need this so we can properly update its image indexes.
                // For example, if we move out its last child, then it becomes a regular node.
                var SrcParent = SrcTreeNode.Parent;

                // Create a TreeNode Action
                var Args = new TVNMA_ActionArgs()
                {
                    SrcNode = SrcTreeNode,
                    DestNode = DestTreeNode
                };

                // Convert KeyStates into an elaborate action
                if (m_bDragInto && m_bDragAbove)
                {
                    Args.Action = TVNMA_Actions.Move_Into_Top;
                }
                else if (m_bDragInto && !m_bDragAbove)
                {
                    Args.Action = TVNMA_Actions.Move_Into_Bottom;
                }
                else if (m_bDragAbove)
                {
                    Args.Action = TVNMA_Actions.Move_Above;
                }
                else if (m_bDragInto)
                {
                    Args.Action = TVNMA_Actions.Move_Into_Bottom;
                }

                // No action intended yet, let's try to guess user's intent
                if (Args.Action == TVNMA_Actions.None)
                {
                    // Must be moving to a parent node
                    if (DestTreeNode.IsExpanded)
                    {
                        Args.Action = TVNMA_Actions.Move_Into_Bottom;
                    }
                    // Just a regular node, let's just move above
                    else
                    {
                        Args.Action = TVNMA_Actions.Move_Above;
                    }
                }
                CarryTVNodeAction(Args);

                DestTreeNode.SetAutoImageIndex();
                if (SrcParent != null)
                    SrcParent.SetAutoImageIndex();
            });

            //
            // BeforeCollapse
            //
            tv.BeforeCollapse += new TreeViewCancelEventHandler(delegate (object sender, TreeViewCancelEventArgs e)
            {
                e.Node.SetAllImageIndex(TVNMA_NodeIconIndex.Closed);
            });

            //
            // BeforeExpand
            //
            tv.BeforeExpand += new TreeViewCancelEventHandler(delegate (object sender, TreeViewCancelEventArgs e)
            {
                e.Node.SetAllImageIndex(TVNMA_NodeIconIndex.Opened);
            });
        }
 private bool AfterTVNMA(TVNMA_ActionArgs Args)
 {
     Text = ArgsToText(Args, false);
     return true;
 }