/// <summary>
        /// Occurs when a drag-and-drop operation is completed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DragDropHandler(object sender, DragEventArgs e)
        {
            if (lastDragDropTarget != null)
            {
                lastDragDropTarget.BackColor = lastDragDropTargetBackColor;
                lastDragDropTarget           = null;
            }

            var sourceNode = GetDragDropSourceNode(e);

            if (sourceNode == null)
            {
                MessageBox.Show(@"Drag & Drop Canceled: Unknown Source");

                return;
            }

            var targetNode = GetDragDropTargetNode(e);

            switch (e.Effect)
            {
            case DragDropEffects.Copy:
                DoDragDropCopy((dynamic)sourceNode, (dynamic)targetNode);
                break;

            case DragDropEffects.Move:
                DoDragDropMove((dynamic)sourceNode, (dynamic)targetNode);
                break;
            }
        }
 // ReSharper disable once UnusedParameter.Local
 private void AfterSelectImplementation(JTokenTreeNode node, TreeViewEventArgs e)
 {
     AfterSelect?.Invoke(this, new AfterSelectEventArgs(
                             $"{node.JTokenTag.Type}",
                             $"{node.JTokenTag.Type}",
                             () => $"{node.JTokenTag}"));
 }
예제 #3
0
 /// <summary>
 /// Implementation of "paste and replace" action.
 /// </summary>
 /// <param name="node"></param>
 public static void ClipboardPasteReplace(this JTokenTreeNode node)
 {
     node.ClipboardPaste(
         jt => node.JTokenTag.Replace(jt),
         n => node.InsertInParent(n, true)
         );
 }
예제 #4
0
        /// <summary>
        /// Implementation of "paste" action using 2 delegates for the concrete action on JToken tree and TreeView.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="pasteJTokenImplementation">Implementation of paste action in the JToken tree.</param>
        /// <param name="pasteTreeNodeImplementation">Implementation of paste action in the treeView.</param>
        private static void ClipboardPaste(this JTokenTreeNode node, Action <JToken> pasteJTokenImplementation, Action <TreeNode> pasteTreeNodeImplementation)
        {
            var sourceJTokenTreeNode = EditorClipboard <JTokenTreeNode> .Get();

            var jTokenSource = sourceJTokenTreeNode.JTokenTag.DeepClone();

            try
            {
                pasteJTokenImplementation(jTokenSource);
            }
            catch (Exception exception)
            {
                // If cut was asked, the clipboard is now empty and source should be inserted again in clipboard
                if (EditorClipboard <JTokenTreeNode> .IsEmpty())
                {
                    EditorClipboard <JTokenTreeNode> .Set(sourceJTokenTreeNode, false);
                }

                throw new JTokenTreeNodePasteException(exception);
            }

            var treeView = node.TreeView;

            treeView.BeginUpdate();

            pasteTreeNodeImplementation(JsonTreeNodeFactory.Create(jTokenSource));

            treeView.EndUpdate();

            // If cut was asked, the clipboard is now empty and source should be removed from treeview
            if (EditorClipboard <JTokenTreeNode> .IsEmpty())
            {
                sourceJTokenTreeNode.EditDelete();
            }
        }
예제 #5
0
 /// <summary>
 /// Implementation of "paste into" action.
 /// </summary>
 /// <param name="node"></param>
 public static void ClipboardPasteInto(this JTokenTreeNode node)
 {
     node.ClipboardPaste(
         jt => ((JContainer)node.JTokenTag).AddFirst(jt),
         n => node.InsertInCurrent(n)
         );
 }
예제 #6
0
 /// <summary>
 /// Implementation of "paste before" action.
 /// </summary>
 /// <param name="node"></param>
 public static void ClipboardPasteBefore(this JTokenTreeNode node)
 {
     node.ClipboardPaste(
         jt => node.JTokenTag.AddBeforeSelf(jt),
         n => node.InsertInParent(n, true)
         );
 }
예제 #7
0
 /// <summary>
 /// Implementation of "paste after" action.
 /// </summary>
 /// <param name="node">Reference node for the paste.</param>
 public static void ClipboardPasteAfter(this JTokenTreeNode node)
 {
     node.ClipboardPaste(
         jt => node.JTokenTag.AddAfterSelf(jt),
         n => node.InsertInParent(n, false)
         );
 }
        private bool IsDragDropValid(JTokenTreeNode sourceNode, JTokenTreeNode targetNode, DragDropEffects effect)
        {
            if (sourceNode == null || targetNode == null)
            {
                return(false);
            }

            if (sourceNode.JTokenTag is JProperty)
            {
                return(targetNode.JTokenTag is JObject);
            }

            if (sourceNode.JTokenTag is JObject)
            {
                switch (effect)
                {
                case DragDropEffects.Copy:
                    return(targetNode.JTokenTag is JArray);

                case DragDropEffects.Move:
                    return(!(targetNode.JTokenTag.Parent is JProperty) &&
                           targetNode.JTokenTag is JArray);
                }
            }

            if (sourceNode.JTokenTag is JArray)
            {
                switch (effect)
                {
                case DragDropEffects.Copy:
                    return(targetNode.JTokenTag is JArray);

                case DragDropEffects.Move:
                    return(!(targetNode.JTokenTag.Parent is JProperty) &&
                           targetNode.JTokenTag is JArray);
                }
            }

            if (sourceNode.JTokenTag is JValue)
            {
                switch (effect)
                {
                case DragDropEffects.Copy:
                    return(targetNode.JTokenTag is JArray);

                case DragDropEffects.Move:
                    return(!(targetNode.JTokenTag.Parent is JProperty) &&
                           targetNode.JTokenTag is JArray);
                }
            }

            return(false);
        }
예제 #9
0
        /// <summary>
        /// Implementation of "delete" action.
        /// </summary>
        /// <param name="node"></param>
        public static void EditDelete(this JTokenTreeNode node)
        {
            if (node == null)
            {
                return;
            }

            try
            {
                node.JTokenTag.Remove();
            }
            catch (Exception exception)
            {
                throw new JTokenTreeNodeDeleteException(exception);
            }

            var treeView = node.TreeView;

            treeView.BeginUpdate();

            node.CleanParentTreeNode();

            treeView.EndUpdate();
        }
        /// <summary>
        /// Occurs when an object is dragged over the control's bounds.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DragOverHandler(object sender, DragEventArgs e)
        {
            var targetNode = GetDragDropTargetNode(e);

            if (targetNode == null)
            {
                e.Effect = DragDropEffects.None;

                if (lastDragDropTarget != null)
                {
                    lastDragDropTarget.BackColor = lastDragDropTargetBackColor;
                }

                lastDragDropTarget = null;

                return;
            }

            var keyState = (KeyStates)e.KeyState;

            if (keyState.HasFlag(KeyStates.Control | KeyStates.Shift))
            {
                e.Effect = DragDropEffects.None;
            }
            else if (keyState.HasFlag(KeyStates.Control))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else if (keyState.HasFlag(KeyStates.Shift))
            {
                e.Effect = DragDropEffects.Move;
            }
            else
            {
                e.Effect = DragDropEffects.Move;
            }

            var sourceNode = GetDragDropSourceNode(e);

            if (targetNode == lastDragDropTarget)
            {
                if (!targetNode.IsExpanded && DateTime.Now - lastDragOverDateTime >= dragDropExpandDelay)
                {
                    targetNode.Expand();
                }

                if (IsDragDropValid(sourceNode, targetNode, e.Effect))
                {
                    lastDragDropTargetBackColor = targetNode.BackColor;
                    targetNode.BackColor        = Color.BlueViolet;
                }
                else
                {
                    targetNode.BackColor = lastDragDropTargetBackColor;
                    e.Effect             = DragDropEffects.None;
                }
            }
            else
            {
                lastDragDropTarget   = targetNode;
                lastDragOverDateTime = DateTime.Now;

                if (IsDragDropValid(sourceNode, targetNode, e.Effect))
                {
                    lastDragDropTargetBackColor = targetNode.BackColor;
                    targetNode.BackColor        = Color.BlueViolet;
                }
                else
                {
                    targetNode.BackColor = lastDragDropTargetBackColor;
                    e.Effect             = DragDropEffects.None;
                }
            }

            if (lastDragDropTarget != null)
            {
                lastDragDropTarget.BackColor = lastDragDropTargetBackColor;
            }
        }
 private void DoDragDropMove(JTokenTreeNode sourceNode, JTokenTreeNode targetNode)
 {
     // TODO: Move sourceNode to target
     MessageBox.Show(@"Drag & Drop: Unmanaged Move");
 }
 /// <summary>
 /// Catches all unmanaged copies.
 /// </summary>
 /// <param name="sourceNode"></param>
 /// <param name="targetNode"></param>
 private void DoDragDropCopy(JTokenTreeNode sourceNode, JTokenTreeNode targetNode)
 {
     MessageBox.Show(@"Drag & Drop: Unmanaged Copy");
 }
예제 #13
0
        /// <summary>
        /// Implementation of "cut" action
        /// </summary>
        /// <param name="node"></param>
        public static JTokenTreeNode ClipboardCut(this JTokenTreeNode node)
        {
            EditorClipboard <JTokenTreeNode> .Set(node, false);

            return(node);
        }