コード例 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ReadOnlyBlockListInner{IIndex}"/> class.
 /// </summary>
 /// <param name="owner">Parent containing the inner.</param>
 /// <param name="propertyName">Property name of the inner in <paramref name="owner"/>.</param>
 public ReadOnlyBlockListInner(IReadOnlyNodeState owner, string propertyName)
     : base(owner, propertyName)
 {
     BlockType       = NodeTreeHelperBlockList.BlockListBlockType(Owner.Node, PropertyName);
     _BlockStateList = CreateBlockStateList();
     BlockStateList  = _BlockStateList.ToReadOnly();
 }
コード例 #2
0
        /// <summary>
        /// Gets the frame that creates cells associated to states in the inner.
        /// </summary>
        /// <param name="inner">The inner.</param>
        public virtual IFrameFrame InnerToFrame(IFrameInner <IFrameBrowsingChildIndex> inner)
        {
            // Call overloads of this method if they exist.
            ControllerTools.AssertNoOverride(this, Type.FromTypeof <FrameTemplateSet>());

            IFrameNodeState Owner     = inner.Owner;
            Type            OwnerType = Type.FromGetType(Owner.Node);

            //Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(OwnerType);
            //IFrameNodeTemplate Template = NodeTypeToTemplate(InterfaceType);
            IFrameNodeTemplate Template = NodeTypeToTemplate(OwnerType);

            IFrameFrame Frame = Template.PropertyToFrame(inner.PropertyName);

            if (Frame is IFrameBlockListFrame AsBlockListFrame)
            {
                IFrameBlockListInner <IFrameBrowsingBlockNodeIndex> BlockListInner = inner as IFrameBlockListInner <IFrameBrowsingBlockNodeIndex>;
                Debug.Assert(BlockListInner != null);

                Type BlockType = NodeTreeHelperBlockList.BlockListBlockType(Owner.Node, BlockListInner.PropertyName);
                IFrameBlockTemplate BlockTemplate = BlockTypeToTemplate(BlockType);

                Frame = BlockTemplate.GetPlaceholderFrame();
            }

            return(Frame);
        }
コード例 #3
0
        private protected virtual bool IsNodeTreeValid(Node node)
        {
            Type           ChildNodeType;
            IList <string> PropertyNames = NodeTreeHelper.EnumChildNodeProperties(node);
            bool           IsValid       = true;

            foreach (string PropertyName in PropertyNames)
            {
                if (NodeTreeHelperChild.IsChildNodeProperty(node, PropertyName, out ChildNodeType))
                {
                    IsValid &= InvariantFailed(IsNodeTreeChildNodeValid(node, PropertyName));
                }
                else if (NodeTreeHelperOptional.IsOptionalChildNodeProperty(node, PropertyName, out ChildNodeType))
                {
                    IsValid &= InvariantFailed(IsNodeTreeOptionalNodeValid(node, PropertyName));
                }
                else if (NodeTreeHelperList.IsNodeListProperty(node, PropertyName, out ChildNodeType))
                {
                    IsValid &= InvariantFailed(IsNodeTreeListValid(node, PropertyName));
                }
                else if (NodeTreeHelperBlockList.IsBlockListProperty(node, PropertyName, /*out Type ChildInterfaceType,*/ out ChildNodeType))
                {
                    IsValid &= InvariantFailed(IsNodeTreeBlockListValid(node, PropertyName));
                }
            }

            return(IsValid);
        }
コード例 #4
0
        /// <summary>
        /// Replaces a node.
        /// </summary>
        /// <param name="operation">Details of the operation performed.</param>
        public virtual void Replace(IWriteableReplaceOperation operation)
        {
            int BlockIndex = operation.BlockIndex;

            Debug.Assert(BlockIndex >= 0 && BlockIndex < BlockStateList.Count);

            IWriteableBlockState BlockState = (IWriteableBlockState)BlockStateList[BlockIndex];

            int Index = operation.Index;

            Debug.Assert(Index >= 0 && Index < BlockState.StateList.Count);

            IBlock ChildBlock = BlockState.ChildBlock;
            Node   ParentNode = Owner.Node;

            IWriteableNodeState OldChildState = (IWriteableNodeState)BlockState.StateList[Index];
            Node OldNode = OldChildState.Node;
            IWriteableBrowsingBlockNodeIndex OldBrowsingIndex = (IWriteableBrowsingBlockNodeIndex)OldChildState.ParentIndex;

            BlockState.Remove(OldBrowsingIndex, Index);

            NodeTreeHelperBlockList.ReplaceInBlock(ChildBlock, Index, operation.NewNode);

            IWriteableBrowsingExistingBlockNodeIndex NewBrowsingIndex = CreateBrowsingNodeIndex(operation.NewNode, BlockIndex, Index);
            IWriteablePlaceholderNodeState           NewChildState    = (IWriteablePlaceholderNodeState)CreateNodeState(NewBrowsingIndex);

            BlockState.Insert(NewBrowsingIndex, Index, NewChildState);

            operation.Update(OldBrowsingIndex, NewBrowsingIndex, OldNode, NewChildState);
        }
コード例 #5
0
        private protected virtual bool IsNodeTreeBlockListValid(Node node, string propertyName)
        {
            NodeTreeHelperBlockList.GetChildBlockList(node, propertyName, out IList <NodeTreeBlock> ChildBlockList);
            Debug.Assert(ChildBlockList != null);

            bool IsValid = true;

            if (ChildBlockList.Count == 0)
            {
                IsValid &= InvariantFailed(IsEmptyBlockListValid(node, propertyName));
            }

            for (int BlockIndex = 0; BlockIndex < ChildBlockList.Count; BlockIndex++)
            {
                NodeTreeBlock Block = ChildBlockList[BlockIndex];
                Debug.Assert(Block.NodeList.Count > 0);

                for (int Index = 0; Index < Block.NodeList.Count; Index++)
                {
                    Node ChildNode = Block.NodeList[Index];
                    Debug.Assert(ChildNode != null);

                    IsValid &= InvariantFailed(IsNodeTreeValid(ChildNode));
                }
            }

            return(IsValid);
        }
コード例 #6
0
        private protected virtual void UpdateInterfaceType(Type nodeType)
        {
            if (InterfaceType == Type.Missing)
            {
                string[] Split    = CollectionName.Split('.');
                Type     BaseType = nodeType;

                for (int i = 0; i < Split.Length; i++)
                {
                    string PropertyName = Split[i];
                    Type   ChildNodeType;

                    if (i + 1 < Split.Length)
                    {
                        bool IsValidProperty = NodeTreeHelperChild.IsChildNodeProperty(BaseType, PropertyName, out ChildNodeType) || NodeTreeHelperOptional.IsOptionalChildNodeProperty(BaseType, PropertyName, out ChildNodeType);
                        Debug.Assert(IsValidProperty);

                        BaseType = ChildNodeType;
                    }
                    else
                    {
                        Type ChildInterfaceType;
                        bool IsValidProperty = NodeTreeHelperBlockList.IsBlockListProperty(BaseType, PropertyName, /*out ChildInterfaceType,*/ out /*ChildNodeType*/ ChildInterfaceType) || NodeTreeHelperList.IsNodeListProperty(BaseType, PropertyName, out ChildInterfaceType);
                        Debug.Assert(IsValidProperty);

                        BaseType = ChildInterfaceType;
                    }
                }

                InterfaceType = BaseType;
            }
        }
コード例 #7
0
        /// <summary>
        /// Modifies the index to address the next position in a block list.
        /// </summary>
        public virtual void MoveBlockUp()
        {
            NodeTreeHelperBlockList.GetLastBlockIndex(ParentNode, PropertyName, out int LastBlockIndex);
            Debug.Assert(BlockIndex + 1 < LastBlockIndex);

            BlockIndex++;
        }
コード例 #8
0
        /// <summary>
        /// Modifies the index to address the next position in a list.
        /// </summary>
        public virtual void MoveUp()
        {
            NodeTreeHelperBlockList.GetLastBlockChildIndex(ParentNode, PropertyName, BlockIndex, out int LastIndex);
            Debug.Assert(Index + 1 < LastIndex);

            Index++;
        }
コード例 #9
0
        /// <summary>
        /// Expands the block list.
        /// * Only expand block list of arguments
        /// * Only expand if the list is empty. In that case, add a single default argument.
        /// </summary>
        private protected virtual void ExpandBlockList(IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> blockListInner, WriteableOperationList operationList)
        {
            if (!blockListInner.IsEmpty)
            {
                return;
            }

            if (!NodeHelper.IsCollectionWithExpand(blockListInner.Owner.Node, blockListInner.PropertyName))
            {
                return;
            }

            Node       NewItem    = NodeHelper.CreateDefaultFromType(blockListInner.InterfaceType);
            Pattern    NewPattern = NodeHelper.CreateEmptyPattern();
            Identifier NewSource  = NodeHelper.CreateEmptyIdentifier();
            IBlock     NewBlock   = NodeTreeHelperBlockList.CreateBlock(blockListInner.Owner.Node, blockListInner.PropertyName, ReplicationStatus.Normal, NewPattern, NewSource);

            Action <IWriteableOperation>     HandlerRedo = (IWriteableOperation operation) => RedoExpandBlockList(operation);
            Action <IWriteableOperation>     HandlerUndo = (IWriteableOperation operation) => UndoExpandBlockList(operation);
            WriteableExpandArgumentOperation Operation   = CreateExpandArgumentOperation(blockListInner.Owner.Node, blockListInner.PropertyName, NewBlock, NewItem, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();

            operationList.Add(Operation);
        }
コード例 #10
0
        /// <summary>
        /// Moves a block around in a block list.
        /// </summary>
        /// <param name="operation">Details of the operation performed.</param>
        public virtual void MoveBlock(WriteableMoveBlockOperation operation)
        {
            int BlockIndex = operation.BlockIndex;
            int Direction  = operation.Direction;

            Debug.Assert(BlockIndex >= 0 && BlockIndex < BlockStateList.Count);
            Debug.Assert(BlockIndex + Direction >= 0 && BlockIndex + Direction < BlockStateList.Count);

            int MoveIndex = BlockIndex;
            IWriteableBlockState BlockState = (IWriteableBlockState)BlockStateList[MoveIndex];

            MoveInBlockStateList(MoveIndex, Direction);
            NodeTreeHelperBlockList.MoveBlock(Owner.Node, PropertyName, MoveIndex, Direction);

            if (Direction > 0)
            {
                for (int i = MoveIndex; i < MoveIndex + Direction; i++)
                {
                    for (int j = 0; j < BlockStateList[i].StateList.Count; j++)
                    {
                        IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = BlockStateList[i].StateList[j].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                        Debug.Assert(ChildNodeIndex != null);

                        ChildNodeIndex.MoveBlockDown();
                    }

                    for (int j = 0; j < BlockState.StateList.Count; j++)
                    {
                        IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = BlockState.StateList[j].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                        Debug.Assert(ChildNodeIndex != null);

                        ChildNodeIndex.MoveBlockUp();
                    }
                }
            }
            else if (Direction < 0)
            {
                for (int i = MoveIndex; i > MoveIndex + Direction; i--)
                {
                    for (int j = 0; j < BlockStateList[i].StateList.Count; j++)
                    {
                        IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = BlockStateList[i].StateList[j].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                        Debug.Assert(ChildNodeIndex != null);

                        ChildNodeIndex.MoveBlockUp();
                    }

                    for (int j = 0; j < BlockState.StateList.Count; j++)
                    {
                        IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = BlockState.StateList[j].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                        Debug.Assert(ChildNodeIndex != null);

                        ChildNodeIndex.MoveBlockDown();
                    }
                }
            }

            operation.Update(BlockState);
        }
コード例 #11
0
        /// <summary>
        /// Merges two blocks at the given index.
        /// </summary>
        /// <param name="operation">Details of the operation performed.</param>
        public virtual void MergeBlocks(IWriteableMergeBlocksOperation operation)
        {
            Debug.Assert(operation != null);

            int MergeBlockIndex = operation.BlockIndex;

            Debug.Assert(MergeBlockIndex > 0 && MergeBlockIndex < BlockStateList.Count);

            IWriteableBlockState FirstBlockState  = BlockStateList[MergeBlockIndex - 1];
            IWriteableBlockState SecondBlockState = BlockStateList[MergeBlockIndex];
            int MergeIndex = FirstBlockState.StateList.Count;

            Debug.Assert(MergeIndex > 0);

            NodeTreeHelperBlockList.MergeBlocks(Owner.Node, PropertyName, MergeBlockIndex, out IBlock mergedBlock);
            Debug.Assert(FirstBlockState.ChildBlock == mergedBlock);

            RemoveFromBlockStateList(MergeBlockIndex - 1);

            operation.Update(FirstBlockState, MergeIndex);

            int i;

            for (i = 0; i < MergeIndex; i++)
            {
                IWriteablePlaceholderNodeState           State          = FirstBlockState.StateList[0];
                IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = State.ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                Debug.Assert(ChildNodeIndex != null);

                FirstBlockState.Remove(ChildNodeIndex, 0);
                SecondBlockState.Insert(ChildNodeIndex, i, State);
            }

            for (; i < SecondBlockState.StateList.Count; i++)
            {
                IWriteablePlaceholderNodeState           State          = SecondBlockState.StateList[i];
                IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = State.ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                Debug.Assert(ChildNodeIndex != null);

                ChildNodeIndex.MoveBlockDown();

                for (int j = 0; j < MergeIndex; j++)
                {
                    ChildNodeIndex.MoveUp();
                }
            }

            for (i = MergeBlockIndex; i < BlockStateList.Count; i++)
            {
                foreach (IWriteablePlaceholderNodeState State in BlockStateList[i].StateList)
                {
                    IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = State.ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                    Debug.Assert(ChildNodeIndex != null);

                    ChildNodeIndex.MoveBlockDown();
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ReadOnlyBrowsingNewBlockNodeIndex"/> class.
        /// </summary>
        /// <param name="parentNode">Node containing the block list.</param>
        /// <param name="node">First node in the block.</param>
        /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the block list.</param>
        /// <param name="blockIndex">Position of the block in the block list.</param>
        public ReadOnlyBrowsingNewBlockNodeIndex(Node parentNode, Node node, string propertyName, int blockIndex)
            : base(node, propertyName, blockIndex)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName));
            Debug.Assert(blockIndex >= 0);
            Debug.Assert(NodeTreeHelperBlockList.IsBlockChildNode(parentNode, propertyName, blockIndex, 0, node));

            ParentNode = parentNode;
        }
コード例 #13
0
        /// <summary>
        /// Checks that a frame is correctly constructed.
        /// </summary>
        /// <param name="nodeType">Type of the node this frame can describe.</param>
        /// <param name="nodeTemplateTable">Table of templates with all frames.</param>
        /// <param name="commentFrameCount">Number of comment frames found so far.</param>
        public override bool IsValid(Type nodeType, FrameTemplateReadOnlyDictionary nodeTemplateTable, ref int commentFrameCount)
        {
            bool IsValid = true;

            IsValid &= base.IsValid(nodeType, nodeTemplateTable, ref commentFrameCount);
            IsValid &= NodeTreeHelperBlockList.IsBlockListProperty(nodeType, PropertyName, /*out Type ChildInterfaceType,*/ out Type ChildNodeType);

            Debug.Assert(IsValid);
            return(IsValid);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="WriteableInsertionExistingBlockNodeIndex"/> class.
        /// </summary>
        /// <param name="parentNode">Node containing the block list.</param>
        /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the block list..</param>
        /// <param name="node">Inserted node.</param>
        /// <param name="blockIndex">Position of the block in the block list.</param>
        /// <param name="index">Position where to insert <paramref name="node"/> in the block.</param>
        public WriteableInsertionExistingBlockNodeIndex(INode parentNode, string propertyName, INode node, int blockIndex, int index)
            : base(parentNode, propertyName, node)
        {
            Debug.Assert(blockIndex >= 0);
            Debug.Assert(index >= 0); // You can insert at position 0, contrary to a browsing index that only supports positions other than 0.
            Debug.Assert(NodeTreeHelperBlockList.GetLastBlockChildIndex(parentNode, propertyName, blockIndex, out int LastIndex) && index <= LastIndex);

            BlockIndex = blockIndex;
            Index      = index;
        }
コード例 #15
0
        private protected virtual void CloneChildren(INode parentNode, IBlock parentBlock)
        {
            for (int i = 0; i < StateList.Count; i++)
            {
                IReadOnlyPlaceholderNodeState ChildState = StateList[i];

                INode ChildNodeClone = ChildState.CloneNode();
                Debug.Assert(ChildNodeClone != null);

                NodeTreeHelperBlockList.InsertIntoBlock(parentBlock, i, ChildNodeClone);
            }
        }
コード例 #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WriteableInsertionNewBlockNodeIndex"/> class.
        /// </summary>
        /// <param name="parentNode">Node containing the block list.</param>
        /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the block list.</param>
        /// <param name="node">First node in the block.</param>
        /// <param name="blockIndex">Position of the block in the block list.</param>
        /// <param name="patternNode">Replication pattern in the block.</param>
        /// <param name="sourceNode">Source identifier in the block.</param>
        public WriteableInsertionNewBlockNodeIndex(INode parentNode, string propertyName, INode node, int blockIndex, IPattern patternNode, IIdentifier sourceNode)
            : base(parentNode, propertyName, node)
        {
            Debug.Assert(blockIndex >= 0);
            Debug.Assert(NodeTreeHelperBlockList.GetLastBlockIndex(parentNode, propertyName, out int LastBlockIndex) && blockIndex <= LastBlockIndex);
            Debug.Assert(patternNode != null);
            Debug.Assert(sourceNode != null);

            BlockIndex  = blockIndex;
            PatternNode = patternNode;
            SourceNode  = sourceNode;
        }
コード例 #17
0
        /// <summary>
        /// Moves a node around in a list or block list. In a block list, the node stays in same block.
        /// </summary>
        /// <param name="operation">Details of the operation performed.</param>
        public virtual void Move(IWriteableMoveNodeOperation operation)
        {
            Debug.Assert(operation != null);

            int BlockIndex = operation.BlockIndex;

            Debug.Assert(BlockIndex >= 0 && BlockIndex < BlockStateList.Count);

            IWriteableBlockState BlockState = BlockStateList[BlockIndex];
            IWriteablePlaceholderNodeStateReadOnlyList StateList = BlockState.StateList;

            int MoveIndex = operation.Index;
            int Direction = operation.Direction;

            Debug.Assert(MoveIndex >= 0 && MoveIndex < StateList.Count);
            Debug.Assert(MoveIndex + Direction >= 0 && MoveIndex + Direction < StateList.Count);

            IWriteableBrowsingExistingBlockNodeIndex ExistingBlockNodeIndex = StateList[MoveIndex].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;

            Debug.Assert(ExistingBlockNodeIndex != null);

            BlockState.Move(ExistingBlockNodeIndex, MoveIndex, Direction);

            IBlock ChildBlock = BlockState.ChildBlock;

            NodeTreeHelperBlockList.MoveNode(ChildBlock, MoveIndex, Direction);

            operation.Update(StateList[MoveIndex + Direction]);

            if (Direction > 0)
            {
                for (int i = MoveIndex; i < MoveIndex + Direction; i++)
                {
                    IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = StateList[i].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                    Debug.Assert(ChildNodeIndex != null);

                    ChildNodeIndex.MoveDown();
                    ExistingBlockNodeIndex.MoveUp();
                }
            }
            else if (Direction < 0)
            {
                for (int i = MoveIndex; i > MoveIndex + Direction; i--)
                {
                    IWriteableBrowsingExistingBlockNodeIndex ChildNodeIndex = StateList[i].ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                    Debug.Assert(ChildNodeIndex != null);

                    ChildNodeIndex.MoveUp();
                    ExistingBlockNodeIndex.MoveDown();
                }
            }
        }
コード例 #18
0
        /// <summary>
        /// Changes the replication state of a block.
        /// </summary>
        /// <param name="operation">Details of the operation performed.</param>
        public virtual void ChangeReplication(WriteableChangeBlockOperation operation)
        {
            ReplicationStatus Replication = operation.Replication;
            int BlockIndex = operation.BlockIndex;

            Debug.Assert(BlockIndex >= 0 && BlockIndex < BlockStateList.Count);

            IWriteableBlockState BlockState = (IWriteableBlockState)BlockStateList[BlockIndex];

            NodeTreeHelperBlockList.SetReplication(BlockState.ChildBlock, Replication);

            operation.Update(BlockState);
        }
コード例 #19
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ReadOnlyBrowsingExistingBlockNodeIndex"/> class.
        /// </summary>
        /// <param name="parentNode">Node containing the block list.</param>
        /// <param name="node">Indexed node in the block.</param>
        /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the block list.</param>
        /// <param name="blockIndex">Position of the block in the block list.</param>
        /// <param name="index">Position of the node in the block.</param>
        public ReadOnlyBrowsingExistingBlockNodeIndex(INode parentNode, INode node, string propertyName, int blockIndex, int index)
            : base(node, propertyName, blockIndex)
        {
            Debug.Assert(parentNode != null);
            Debug.Assert(node != null);
            Debug.Assert(!string.IsNullOrEmpty(propertyName));
            Debug.Assert(blockIndex >= 0);
            Debug.Assert(index >= 0);
            Debug.Assert(NodeTreeHelperBlockList.IsBlockChildNode(parentNode, propertyName, blockIndex, index, node));

            ParentNode = parentNode;
            Index      = index;
        }
コード例 #20
0
        private protected virtual void SetNodeTypeToDefault(IFrameTemplateDictionary dictionary, Type nodeType)
        {
            Debug.Assert(dictionary.ContainsKey(nodeType));
            Debug.Assert(dictionary[nodeType] == null);

            FrameHorizontalPanelFrame RootFrame    = (FrameHorizontalPanelFrame)CreateHorizontalPanelFrame();
            FrameNodeTemplate         RootTemplate = (FrameNodeTemplate)CreateNodeTemplate();

            RootTemplate.NodeType = nodeType;
            RootTemplate.Root     = RootFrame;

            // Set the template, even if empty, in case the node recursively refers to itself (ex: expressions).
            dictionary[nodeType] = RootTemplate;

            RootFrame.Items.Add(CreateCommentFrame());

            Type           ChildNodeType;
            IList <string> Properties = NodeTreeHelper.EnumChildNodeProperties(nodeType);

            foreach (string PropertyName in Properties)
            {
                bool IsHandled = false;

                if (NodeTreeHelperChild.IsChildNodeProperty(nodeType, PropertyName, out ChildNodeType))
                {
                    FramePlaceholderFrame NewFrame = (FramePlaceholderFrame)CreatePlaceholderFrame();
                    NewFrame.PropertyName = PropertyName;
                    RootFrame.Items.Add(NewFrame);
                    IsHandled = true;
                }
                else if (NodeTreeHelperOptional.IsOptionalChildNodeProperty(nodeType, PropertyName, out ChildNodeType))
                {
                    FrameOptionalFrame NewFrame = (FrameOptionalFrame)CreateOptionalFrame();
                    NewFrame.PropertyName = PropertyName;
                    RootFrame.Items.Add(NewFrame);
                    IsHandled = true;
                }
                else if (NodeTreeHelperList.IsNodeListProperty(nodeType, PropertyName, out Type ListNodeType))
                {
                    FrameHorizontalListFrame NewFrame = (FrameHorizontalListFrame)CreateHorizontalListFrame();
                    NewFrame.PropertyName = PropertyName;
                    RootFrame.Items.Add(NewFrame);
                    IsHandled = true;
                }
                else if (NodeTreeHelperBlockList.IsBlockListProperty(nodeType, PropertyName, out Type ChildInterfaceType, out Type ChildItemType))
                {
                    FrameHorizontalBlockListFrame NewFrame = (FrameHorizontalBlockListFrame)CreateHorizontalBlockListFrame();
                    NewFrame.PropertyName = PropertyName;
                    RootFrame.Items.Add(NewFrame);
                    IsHandled = true;
                }
        /// <summary>
        /// Initializes a new instance of the <see cref="ReadOnlyBrowsingExistingBlockNodeIndex"/> class.
        /// </summary>
        /// <param name="parentNode">Node containing the block list.</param>
        /// <param name="node">Indexed node in the block.</param>
        /// <param name="propertyName">Property in <paramref name="parentNode"/> corresponding to the block list.</param>
        /// <param name="blockIndex">Position of the block in the block list.</param>
        /// <param name="index">Position of the node in the block.</param>
        public ReadOnlyBrowsingExistingBlockNodeIndex(Node parentNode, Node node, string propertyName, int blockIndex, int index)
            : base(node, propertyName, blockIndex)
        {
            Contract.RequireNotNull(parentNode, out Node ParentNode);
            Contract.RequireNotNull(node, out Node Node);
            Contract.RequireNotNull(propertyName, out string PropertyName);
            Debug.Assert(PropertyName.Length > 0);
            Debug.Assert(blockIndex >= 0);
            Debug.Assert(index >= 0);
            Debug.Assert(NodeTreeHelperBlockList.IsBlockChildNode(ParentNode, PropertyName, blockIndex, index, Node));

            this.ParentNode = ParentNode;
            Index           = index;
        }
コード例 #22
0
        private protected virtual void InsertNewBlock(IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> blockListInner, IWriteableInsertionNewBlockNodeIndex newBlockIndex, out IWriteableBrowsingCollectionNodeIndex nodeIndex)
        {
            IBlock NewBlock = NodeTreeHelperBlockList.CreateBlock(blockListInner.Owner.Node, blockListInner.PropertyName, ReplicationStatus.Normal, newBlockIndex.PatternNode, newBlockIndex.SourceNode);

            Action <IWriteableOperation>   HandlerRedo = (IWriteableOperation operation) => RedoInsertNewBlock(operation);
            Action <IWriteableOperation>   HandlerUndo = (IWriteableOperation operation) => UndoInsertNewBlock(operation);
            IWriteableInsertBlockOperation Operation   = CreateInsertBlockOperation(blockListInner.Owner.Node, blockListInner.PropertyName, newBlockIndex.BlockIndex, NewBlock, newBlockIndex.Node, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();
            SetLastOperation(Operation);
            CheckInvariant();

            nodeIndex = Operation.BrowsingIndex;
        }
コード例 #23
0
        /// <summary>
        /// Inserts a new block with one node in a block list.
        /// </summary>
        /// <param name="operation">Details of the operation performed.</param>
        public virtual void InsertNewBlock(IWriteableInsertBlockOperation operation)
        {
            Debug.Assert(operation != null);

            int BlockIndex = operation.BlockIndex;

            Debug.Assert(BlockIndex >= 0 && BlockIndex <= BlockStateList.Count);

            IBlock NewBlock = operation.Block;

            Debug.Assert(NewBlock != null);

            INode NewNode = operation.Node;

            Debug.Assert(NewBlock != null);

            INode ParentNode = Owner.Node;

            NodeTreeHelperBlockList.InsertIntoBlockList(ParentNode, PropertyName, BlockIndex, NewBlock);
            NodeTreeHelperBlockList.InsertIntoBlock(NewBlock, 0, NewNode);

            IWriteableBrowsingNewBlockNodeIndex      BrowsingNewBlockIndex      = CreateNewBlockNodeIndex(NewNode, BlockIndex);
            IWriteableBrowsingExistingBlockNodeIndex BrowsingExistingBlockIndex = (IWriteableBrowsingExistingBlockNodeIndex)BrowsingNewBlockIndex.ToExistingBlockIndex();

            IWriteableBlockState BlockState = (IWriteableBlockState)CreateBlockState(BrowsingNewBlockIndex, NewBlock);

            InsertInBlockStateList(BlockIndex, BlockState);

            IWriteablePlaceholderNodeState ChildState = (IWriteablePlaceholderNodeState)CreateNodeState(BrowsingExistingBlockIndex);

            BlockState.Insert(BrowsingExistingBlockIndex, 0, ChildState);

            operation.Update(BrowsingExistingBlockIndex, BlockState, ChildState);

            while (++BlockIndex < BlockStateList.Count)
            {
                IWriteableBlockState NextBlockState = BlockStateList[BlockIndex];

                foreach (IWriteablePlaceholderNodeState State in NextBlockState.StateList)
                {
                    IWriteableBrowsingExistingBlockNodeIndex NodeIndex = State.ParentIndex as IWriteableBrowsingExistingBlockNodeIndex;
                    Debug.Assert(NodeIndex != null);
                    Debug.Assert(NodeIndex.BlockIndex == BlockIndex - 1);

                    NodeIndex.MoveBlockUp();
                }
            }
        }
コード例 #24
0
        /// <summary>
        /// Creates and initializes a new block state in the inner.
        /// </summary>
        /// <param name="newBlockIndex">Index of the new block state to create.</param>
        /// <returns>The created block state.</returns>
        public virtual IReadOnlyBlockState InitNewBlock(IReadOnlyBrowsingNewBlockNodeIndex newBlockIndex)
        {
            Debug.Assert(newBlockIndex.PropertyName == PropertyName);

            int BlockIndex = newBlockIndex.BlockIndex;

            Debug.Assert(BlockIndex == BlockStateList.Count);

            NodeTreeHelperBlockList.GetChildBlock(Owner.Node, PropertyName, BlockIndex, out IBlock ChildBlock);

            IReadOnlyBlockState BlockState = CreateBlockState(newBlockIndex, ChildBlock);

            InsertInBlockStateList(BlockIndex, BlockState);

            return(BlockState);
        }
コード例 #25
0
        /// <inheritdoc/>
        public override void CloneChildren(Node parentNode)
        {
            NodeTreeHelperBlockList.ClearChildBlockList(parentNode, PropertyName);

            // Clone and insert all blocks. This will clone all children recursively.
            for (int BlockIndex = 0; BlockIndex < BlockStateList.Count; BlockIndex++)
            {
                IReadOnlyBlockState BlockState = BlockStateList[BlockIndex];
                ((IReadOnlyBlockState <IReadOnlyInner <IReadOnlyBrowsingChildIndex> >)BlockState).CloneBlock(parentNode, BlockIndex);
            }

            // Copy comments.
            IBlockList BlockList    = NodeTreeHelperBlockList.GetBlockList(Owner.Node, PropertyName);
            IBlockList NewBlockList = NodeTreeHelperBlockList.GetBlockList(parentNode, PropertyName);

            NodeTreeHelper.CopyDocumentation(BlockList, NewBlockList, cloneCommentGuid: true);
        }
コード例 #26
0
        private protected virtual void AddBlockNodeTypes(FrameTemplateDictionary dictionary, Type nodeType)
        {
            IList <string> Properties = NodeTreeHelper.EnumChildNodeProperties(nodeType);

            foreach (string PropertyName in Properties)
            {
                if (NodeTreeHelperBlockList.IsBlockListProperty(nodeType, PropertyName, /*out Type ChildInterfaceType,*/ out Type ChildItemType))
                {
                    Type BlockListType = NodeTreeHelperBlockList.BlockListBlockType(nodeType, PropertyName);

                    if (!dictionary.ContainsKey(BlockListType))
                    {
                        dictionary.Add(BlockListType, null);
                    }
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Creates a clone of the block and assigns it in the provided parent.
        /// </summary>
        /// <param name="parentNode">The node that will contains a reference to the cloned block upon return.</param>
        /// <param name="blockIndex">Position where to insert the block in <paramref name="parentNode"/>.</param>
        public virtual void CloneBlock(Node parentNode, int blockIndex)
        {
            Pattern PatternClone = ClonePattern();

            Debug.Assert(PatternClone != null);

            Identifier SourceClone = CloneSource();

            Debug.Assert(SourceClone != null);

            IBlock NewBlock = NodeTreeHelperBlockList.CreateBlock(parentNode, ParentInner.PropertyName, ChildBlock.Replication, PatternClone, SourceClone);

            NodeTreeHelperBlockList.InsertIntoBlockList(parentNode, ParentInner.PropertyName, blockIndex, NewBlock);
            NodeTreeHelper.CopyDocumentation(ChildBlock, NewBlock, cloneCommentGuid: true);

            // Clone children recursively.
            CloneChildren(parentNode, NewBlock);
        }
コード例 #28
0
        /// <summary>
        /// Checks that a frame selector is correctly constructed.
        /// </summary>
        /// <param name="nodeType">Type of the node this frame selector can describe.</param>
        /// <param name="nodeTemplateTable">Table of templates with all frames.</param>
        /// <param name="propertyName">The property for which frames can be selected.</param>
        public virtual bool IsValid(Type nodeType, IFocusTemplateReadOnlyDictionary nodeTemplateTable, string propertyName)
        {
            bool IsValid = true;

            IsValid &= SelectorType != null;
            IsValid &= !string.IsNullOrEmpty(SelectorName);

            Type ChildInterfaceType, ChildNodeType;

            IsValid &= NodeTreeHelperChild.IsChildNodeProperty(nodeType, propertyName, out ChildInterfaceType) ||
                       NodeTreeHelperOptional.IsOptionalChildNodeProperty(nodeType, propertyName, out ChildInterfaceType) ||
                       NodeTreeHelperList.IsNodeListProperty(nodeType, propertyName, out ChildInterfaceType) ||
                       NodeTreeHelperBlockList.IsBlockListProperty(nodeType, propertyName, out ChildInterfaceType, out ChildNodeType) ||
                       (NodeTreeHelper.IsBlockType(nodeType) && propertyName == nameof(BaseNode.IBlock.NodeList));

            IsValid &= nodeTemplateTable.ContainsKey(SelectorType);

            IFocusNodeTemplate Template = nodeTemplateTable[SelectorType] as IFocusNodeTemplate;

            Debug.Assert(Template != null);

            IFocusSelectionFrame AsSelectionFrame = Template.Root as IFocusSelectionFrame;

            IsValid &= AsSelectionFrame != null;

            if (IsValid)
            {
                IFocusSelectableFrame SelectedItem = null;
                foreach (IFocusSelectableFrame Item in AsSelectionFrame.Items)
                {
                    if (Item.Name == SelectorName)
                    {
                        SelectedItem = Item;
                        break;
                    }
                }

                IsValid &= SelectedItem != null;
            }

            Debug.Assert(IsValid);
            return(IsValid);
        }
コード例 #29
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FocusBlockListSelection"/> class.
        /// </summary>
        /// <param name="stateView">The state view that encompasses the selection.</param>
        /// <param name="propertyName">The property name.</param>
        /// <param name="startIndex">Index of the first selected block.</param>
        /// <param name="endIndex">Index following the last selected block.</param>
        public FocusBlockListSelection(IFocusNodeStateView stateView, string propertyName, int startIndex, int endIndex)
            : base(stateView)
        {
            Node Node = stateView.State.Node;

            Debug.Assert(NodeTreeHelperBlockList.IsBlockListProperty(Node, propertyName, /*out Type childInterfaceType,*/ out Type childNodeType));

            PropertyName = propertyName;

            if (startIndex <= endIndex)
            {
                StartIndex = startIndex;
                EndIndex   = endIndex;
            }
            else
            {
                StartIndex = endIndex;
                EndIndex   = startIndex;
            }
        }
コード例 #30
0
        /// <summary>
        /// Splits a block in two at the given index.
        /// </summary>
        /// <param name="inner">The inner where the block is split.</param>
        /// <param name="nodeIndex">Index of the last node to stay in the old block.</param>
        public virtual void SplitBlock(IWriteableBlockListInner inner, IWriteableBrowsingExistingBlockNodeIndex nodeIndex)
        {
            Contract.RequireNotNull(inner, out IWriteableBlockListInner Inner);
            Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingExistingBlockNodeIndex NodeIndex);
            Debug.Assert(Inner.IsSplittable(NodeIndex));

            IWriteableBlockState BlockState  = (IWriteableBlockState)Inner.BlockStateList[NodeIndex.BlockIndex];
            ReplicationStatus    Replication = BlockState.ChildBlock.Replication;
            Pattern    NewPatternNode        = NodeHelper.CreateSimplePattern(BlockState.ChildBlock.ReplicationPattern.Text);
            Identifier NewSourceNode         = NodeHelper.CreateSimpleIdentifier(BlockState.ChildBlock.SourceIdentifier.Text);
            IBlock     NewBlock = NodeTreeHelperBlockList.CreateBlock(Inner.Owner.Node, Inner.PropertyName, Replication, NewPatternNode, NewSourceNode);

            Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoSplitBlock(operation);
            Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoSplitBlock(operation);
            WriteableSplitBlockOperation Operation   = CreateSplitBlockOperation(Inner.Owner.Node, Inner.PropertyName, NodeIndex.BlockIndex, NodeIndex.Index, NewBlock, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();
            SetLastOperation(Operation);
            CheckInvariant();
        }