Ejemplo n.º 1
0
        /// <summary>
        /// Reduces all expanded nodes, and clear all unassigned optional nodes.
        /// </summary>
        /// <param name="isChanged">True upon return if the node was changed. False if the node was already canonic.</param>
        public virtual void Canonicalize(out bool isChanged)
        {
            WriteableOperationList OperationList = CreateOperationList();

            Canonicalize(RootState, OperationList);

            if (OperationList.Count > 0)
            {
                Action <IWriteableOperation>     HandlerRedo      = (IWriteableOperation operation) => RedoRefresh(operation);
                Action <IWriteableOperation>     HandlerUndo      = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation RefreshOperation = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);

                RefreshOperation.Redo();

                WriteableOperationReadOnlyList OperationReadOnlyList = OperationList.ToReadOnly();
                WriteableOperationGroup        OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                SetLastOperation(OperationGroup);
                CheckInvariant();

                isChanged = true;
            }
            else
            {
                isChanged = false;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Expands an existing node. In the node:
        /// * All optional children are assigned if they aren't
        /// * If the node is a feature call, with no arguments, an empty argument is inserted.
        /// </summary>
        /// <param name="expandedIndex">Index of the expanded node.</param>
        /// <param name="isChanged">True upon return if the node was changed. False if the node was already expanded.</param>
        public virtual void Expand(IWriteableNodeIndex expandedIndex, out bool isChanged)
        {
            Contract.RequireNotNull(expandedIndex, out IWriteableNodeIndex ExpandedIndex);
            Debug.Assert(StateTable.ContainsKey(ExpandedIndex));
            Debug.Assert(StateTable[ExpandedIndex] is IWriteablePlaceholderNodeState);

            WriteableOperationList OperationList = CreateOperationList();

            DebugObjects.AddReference(OperationList);

            Expand(ExpandedIndex, OperationList);

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList OperationReadOnlyList = OperationList.ToReadOnly();
                WriteableOperationGroup        OperationGroup        = CreateOperationGroup(OperationReadOnlyList, null);

                SetLastOperation(OperationGroup);
                CheckInvariant();

                isChanged = true;
            }
            else
            {
                isChanged = false;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reduces an existing node. Opposite of Expand.
        /// </summary>
        /// <param name="reducedIndex">Index of the reduced node.</param>
        /// <param name="isChanged">True upon return if the node was changed. False if the node was already reduced.</param>
        public virtual void Reduce(IWriteableNodeIndex reducedIndex, out bool isChanged)
        {
            Contract.RequireNotNull(reducedIndex, out IWriteableNodeIndex ReducedIndex);
            Debug.Assert(StateTable.ContainsKey(ReducedIndex));
            Debug.Assert(StateTable[ReducedIndex] is IWriteablePlaceholderNodeState);

            WriteableOperationList OperationList = CreateOperationList();

            Reduce(ReducedIndex, OperationList, isNested: false);

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList OperationReadOnlyList = OperationList.ToReadOnly();
                WriteableOperationGroup        OperationGroup        = CreateOperationGroup(OperationReadOnlyList, null);

                SetLastOperation(OperationGroup);
                CheckInvariant();

                isChanged = true;
            }
            else
            {
                isChanged = false;
            }
        }
        /// <summary></summary>
        public virtual void RemoveNodeRange(IWriteableListInner inner, int firstNodeIndex, int lastNodeIndex)
        {
            Contract.RequireNotNull(inner, out IWriteableListInner Inner);
            Debug.Assert(firstNodeIndex >= 0 && firstNodeIndex < Inner.StateList.Count);
            Debug.Assert(lastNodeIndex >= 0 && lastNodeIndex <= Inner.StateList.Count);
            Debug.Assert(firstNodeIndex <= lastNodeIndex);

            System.Action <IWriteableOperation> HandlerRedoNode = (IWriteableOperation operation) => RedoRemoveNode(operation);
            System.Action <IWriteableOperation> HandlerUndoNode = (IWriteableOperation operation) => UndoRemoveNode(operation);

            WriteableOperationList OperationList = CreateOperationList();

            for (int i = firstNodeIndex; i < lastNodeIndex; i++)
            {
                WriteableRemoveNodeOperation OperationNode = CreateRemoveNodeOperation(Inner.Owner.Node, Inner.PropertyName, -1, firstNodeIndex, HandlerRedoNode, HandlerUndoNode, isNested: true);
                OperationList.Add(OperationNode);
            }

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList      OperationReadOnlyList = OperationList.ToReadOnly();
                System.Action <IWriteableOperation> HandlerRedo           = (IWriteableOperation operation) => RedoRefresh(operation);
                System.Action <IWriteableOperation> HandlerUndo           = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation    RefreshOperation      = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);
                WriteableOperationGroup             OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                OperationGroup.Redo();
                SetLastOperation(OperationGroup);
                CheckInvariant();
            }
        }
Ejemplo n.º 5
0
        /// <summary></summary>
        public virtual void InsertNodeRange(IWriteableBlockListInner inner, int blockIndex, int insertedIndex, IList <IWriteableInsertionCollectionNodeIndex> indexList)
        {
            Contract.RequireNotNull(inner, out IWriteableBlockListInner Inner);
            Debug.Assert(blockIndex >= 0 && blockIndex < Inner.BlockStateList.Count);

            IWriteableBlockState BlockState = (IWriteableBlockState)Inner.BlockStateList[blockIndex];

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

            int BlockNodeIndex = insertedIndex;

            foreach (IWriteableInsertionCollectionNodeIndex NodeIndex in indexList)
            {
                bool IsHandled = false;

                if (NodeIndex is IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex)
                {
                    Debug.Assert(AsExistingBlockNodeIndex.BlockIndex == blockIndex);
                    Debug.Assert(AsExistingBlockNodeIndex.Index == BlockNodeIndex);

                    BlockNodeIndex++;
                    IsHandled = true;
                }

                Debug.Assert(IsHandled);
            }

            int FinalNodeIndex = BlockNodeIndex;

            Action <IWriteableOperation> HandlerRedoInsertNode = (IWriteableOperation operation) => RedoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerUndoInsertNode = (IWriteableOperation operation) => UndoInsertNewNode(operation);

            WriteableOperationList OperationList = CreateOperationList();

            foreach (IWriteableInsertionCollectionNodeIndex NodeIndex in indexList)
            {
                if (NodeIndex is IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex)
                {
                    IndexToPositionAndNode(AsExistingBlockNodeIndex, out blockIndex, out int Index, out _, out Node Node);
                    WriteableInsertNodeOperation OperationInsertNode = CreateInsertNodeOperation(Inner.Owner.Node, Inner.PropertyName, blockIndex, Index, Node, HandlerRedoInsertNode, HandlerUndoInsertNode, isNested: true);
                    OperationList.Add(OperationInsertNode);
                }
            }

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList   OperationReadOnlyList = OperationList.ToReadOnly();
                Action <IWriteableOperation>     HandlerRedo           = (IWriteableOperation operation) => RedoRefresh(operation);
                Action <IWriteableOperation>     HandlerUndo           = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation RefreshOperation      = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);
                WriteableOperationGroup          OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                OperationGroup.Redo();
                SetLastOperation(OperationGroup);
                CheckInvariant();
            }
        }
Ejemplo n.º 6
0
        private protected virtual void Canonicalize(IWriteableNodeState state, WriteableOperationList operationList)
        {
            IWriteableNodeIndex NodeIndex = state.ParentIndex as IWriteableNodeIndex;

            Debug.Assert(NodeIndex != null);

            CanonicalizeChildren(state, operationList);

            Reduce(NodeIndex, operationList, isNested: state != RootState);
        }
Ejemplo n.º 7
0
        private protected virtual void SetLastOperation(IWriteableOperation operation)
        {
            WriteableOperationList OperationList = CreateOperationList();

            OperationList.Add(operation);
            WriteableOperationReadOnlyList OperationReadOnlyList = OperationList.ToReadOnly();
            WriteableOperationGroup        OperationGroup        = CreateOperationGroup(OperationReadOnlyList, null);

            SetLastOperation(OperationGroup);
        }
        /// <summary>
        /// Split an identifier with replace and insert indexes.
        /// </summary>
        /// <param name="inner">The inner where the node is replaced.</param>
        /// <param name="replaceIndex">Index for the replace operation.</param>
        /// <param name="insertIndex">Index for the insert operation.</param>
        /// <param name="firstIndex">Index of the replacing node upon return.</param>
        /// <param name="secondIndex">Index of the inserted node upon return.</param>
        public virtual void SplitIdentifier(IWriteableListInner inner, IWriteableInsertionListNodeIndex replaceIndex, IWriteableInsertionListNodeIndex insertIndex, out IWriteableBrowsingListNodeIndex firstIndex, out IWriteableBrowsingListNodeIndex secondIndex)
        {
            Contract.RequireNotNull(inner, out IWriteableListInner Inner);
            Contract.RequireNotNull(replaceIndex, out IWriteableInsertionListNodeIndex ReplaceIndex);
            Contract.RequireNotNull(insertIndex, out IWriteableInsertionListNodeIndex InsertIndex);
            IWriteableNodeState Owner       = Inner.Owner;
            IWriteableIndex     ParentIndex = Owner.ParentIndex;

            Debug.Assert(Contains(ParentIndex));
            Debug.Assert(IndexToState(ParentIndex) == Owner);
            WriteableInnerReadOnlyDictionary <string> InnerTable = Owner.InnerTable;

            Debug.Assert(InnerTable.ContainsKey(Inner.PropertyName));
            Debug.Assert(InnerTable[Inner.PropertyName] == Inner);

            int Index = ReplaceIndex.Index;

            Debug.Assert(InsertIndex.Index == Index + 1);
            Node ReplacingNode = ReplaceIndex.Node;
            Node InsertedNode  = InsertIndex.Node;

            Action <IWriteableOperation> HandlerRedoReplace = (IWriteableOperation operation) => RedoReplace(operation);
            Action <IWriteableOperation> HandlerUndoReplace = (IWriteableOperation operation) => UndoReplace(operation);
            IWriteableReplaceOperation   ReplaceOperation   = CreateReplaceOperation(Inner.Owner.Node, Inner.PropertyName, -1, Index, clearNode: false, ReplacingNode, HandlerRedoReplace, HandlerUndoReplace, isNested: true);

            Action <IWriteableOperation> HandlerRedoInsert = (IWriteableOperation operation) => RedoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerUndoInsert = (IWriteableOperation operation) => UndoInsertNewNode(operation);
            WriteableInsertNodeOperation InsertOperation   = CreateInsertNodeOperation(Inner.Owner.Node, Inner.PropertyName, -1, Index + 1, InsertedNode, HandlerRedoInsert, HandlerUndoInsert, isNested: true);

            ReplaceOperation.Redo();
            InsertOperation.Redo();

            Action <IWriteableOperation>     HandlerRedoRefresh = (IWriteableOperation operation) => RedoRefresh(operation);
            Action <IWriteableOperation>     HandlerUndoRefresh = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
            WriteableGenericRefreshOperation RefreshOperation   = CreateGenericRefreshOperation(RootState, HandlerRedoRefresh, HandlerUndoRefresh, isNested: false);

            RefreshOperation.Redo();

            WriteableOperationList OperationList = CreateOperationList();

            OperationList.Add(ReplaceOperation);
            OperationList.Add(InsertOperation);
            WriteableOperationReadOnlyList OperationReadOnlyList = OperationList.ToReadOnly();
            WriteableOperationGroup        OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

            SetLastOperation(OperationGroup);

            CheckInvariant();

            firstIndex = ReplaceOperation.NewBrowsingIndex as IWriteableBrowsingListNodeIndex;
            Debug.Assert(firstIndex != null);

            secondIndex = InsertOperation.BrowsingIndex as IWriteableBrowsingListNodeIndex;
            Debug.Assert(secondIndex != null);
        }
        /// <summary>
        /// Removes a range of blocks from a block list.
        /// </summary>
        /// <param name="inner">The inner for the block list from which blocks are removed.</param>
        /// <param name="firstBlockIndex">Index of the first block to remove.</param>
        /// <param name="lastBlockIndex">Index following the last block to remove.</param>
        public virtual void RemoveBlockRange(IWriteableBlockListInner inner, int firstBlockIndex, int lastBlockIndex)
        {
            Contract.RequireNotNull(inner, out IWriteableBlockListInner Inner);
            Debug.Assert(firstBlockIndex >= 0 && firstBlockIndex < Inner.BlockStateList.Count);
            Debug.Assert(lastBlockIndex >= 0 && lastBlockIndex <= Inner.BlockStateList.Count);
            Debug.Assert(firstBlockIndex <= lastBlockIndex);

            System.Action <IWriteableOperation> HandlerRedoNode  = (IWriteableOperation operation) => RedoRemoveNode(operation);
            System.Action <IWriteableOperation> HandlerUndoNode  = (IWriteableOperation operation) => UndoRemoveNode(operation);
            System.Action <IWriteableOperation> HandlerRedoBlock = (IWriteableOperation operation) => RedoRemoveBlock(operation);
            System.Action <IWriteableOperation> HandlerUndoBlock = (IWriteableOperation operation) => UndoRemoveBlock(operation);

            WriteableOperationList OperationList = CreateOperationList();

            for (int i = firstBlockIndex; i < lastBlockIndex; i++)
            {
                IWriteableBlockState BlockState = (IWriteableBlockState)Inner.BlockStateList[i];
                Debug.Assert(BlockState.StateList.Count >= 1);

                // Remove at firstBlockIndex since subsequent blocks are moved as the block at firstBlockIndex is deleted.
                // Same for nodes inside blokcks, delete them at 0.
                for (int j = 1; j < BlockState.StateList.Count; j++)
                {
                    WriteableRemoveNodeOperation OperationNode = CreateRemoveNodeOperation(Inner.Owner.Node, Inner.PropertyName, firstBlockIndex, 0, HandlerRedoNode, HandlerUndoNode, isNested: true);
                    OperationList.Add(OperationNode);
                }

                IWriteableRemoveBlockOperation OperationBlock = CreateRemoveBlockOperation(Inner.Owner.Node, Inner.PropertyName, firstBlockIndex, HandlerRedoBlock, HandlerUndoBlock, isNested: true);
                OperationList.Add(OperationBlock);
            }

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList      OperationReadOnlyList = OperationList.ToReadOnly();
                System.Action <IWriteableOperation> HandlerRedo           = (IWriteableOperation operation) => RedoRefresh(operation);
                System.Action <IWriteableOperation> HandlerUndo           = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation    RefreshOperation      = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);
                WriteableOperationGroup             OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                OperationGroup.Redo();
                SetLastOperation(OperationGroup);
                CheckInvariant();
            }
        }
Ejemplo n.º 10
0
        private protected virtual void Expand(IWriteableNodeIndex expandedIndex, WriteableOperationList operationList)
        {
            IWriteablePlaceholderNodeState State = StateTable[expandedIndex] as IWriteablePlaceholderNodeState;

            State = FindBestExpandReduceState(State);
            Debug.Assert(State != null);

            WriteableInnerReadOnlyDictionary <string> InnerTable = State.InnerTable;

            foreach (string Key in InnerTable.Keys)
            {
                IWriteableInner Value = (IWriteableInner)InnerTable[Key];

                if (Value is IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> AsOptionalInner)
                {
                    ExpandOptional(AsOptionalInner, operationList);
                }
                else if (Value is IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> AsBlockListInner)
                {
                    ExpandBlockList(AsBlockListInner, operationList);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="WriteableOperationGroup"/> class.
 /// </summary>
 /// <param name="operationList">List of operations belonging to this group.</param>
 /// <param name="refresh">Optional refresh operation to execute at the end of undo and redo.</param>
 protected WriteableOperationGroup(WriteableOperationList operationList, WriteableGenericRefreshOperation refresh)
 {
     OperationList = new WriteableOperationReadOnlyList(operationList);
     Refresh       = refresh;
 }
Ejemplo n.º 12
0
 /// <inheritdoc/>
 public WriteableOperationReadOnlyList(WriteableOperationList list)
     : base(list)
 {
 }
Ejemplo n.º 13
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);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Removes a range of blocks from a block list and replace them with other blocks.
        /// </summary>
        /// <param name="inner">The inner for the block list from which blocks are replaced.</param>
        /// <param name="firstBlockIndex">Index of the first block to remove.</param>
        /// <param name="lastBlockIndex">Index following the last block to remove.</param>
        /// <param name="indexList">List of nodes in blocks to insert.</param>
        public virtual void ReplaceBlockRange(IWriteableBlockListInner inner, int firstBlockIndex, int lastBlockIndex, IList <IWriteableInsertionBlockNodeIndex> indexList)
        {
            Contract.RequireNotNull(inner, out IWriteableBlockListInner Inner);
            Debug.Assert(firstBlockIndex >= 0 && firstBlockIndex < Inner.BlockStateList.Count);
            Debug.Assert(lastBlockIndex >= 0 && lastBlockIndex <= Inner.BlockStateList.Count);
            Debug.Assert(firstBlockIndex <= lastBlockIndex);
            Contract.RequireNotNull(indexList, out IList <IWriteableInsertionBlockNodeIndex> IndexList);

            int BlockIndex     = firstBlockIndex - 1;
            int BlockNodeIndex = 0;

            foreach (IWriteableInsertionBlockNodeIndex NodeIndex in IndexList)
            {
                bool IsHandled = false;

                if (NodeIndex is IWriteableInsertionNewBlockNodeIndex AsNewBlockNodeIndex)
                {
                    BlockIndex++;
                    BlockNodeIndex = 0;

                    Debug.Assert(AsNewBlockNodeIndex.BlockIndex == BlockIndex);

                    IsHandled = true;
                }
                else if (NodeIndex is IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex)
                {
                    BlockNodeIndex++;

                    Debug.Assert(AsExistingBlockNodeIndex.BlockIndex == BlockIndex);
                    Debug.Assert(AsExistingBlockNodeIndex.Index == BlockNodeIndex);

                    IsHandled = true;
                }

                Debug.Assert(IsHandled);
            }

            int FinalBlockIndex = BlockIndex + 1;

            Action <IWriteableOperation> HandlerRedoInsertNode  = (IWriteableOperation operation) => RedoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerUndoInsertNode  = (IWriteableOperation operation) => UndoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerRedoInsertBlock = (IWriteableOperation operation) => RedoInsertNewBlock(operation);
            Action <IWriteableOperation> HandlerUndoInsertBlock = (IWriteableOperation operation) => UndoInsertNewBlock(operation);
            Action <IWriteableOperation> HandlerRedoRemoveNode  = (IWriteableOperation operation) => RedoRemoveNode(operation);
            Action <IWriteableOperation> HandlerUndoRemoveNode  = (IWriteableOperation operation) => UndoRemoveNode(operation);
            Action <IWriteableOperation> HandlerRedoRemoveBlock = (IWriteableOperation operation) => RedoRemoveBlock(operation);
            Action <IWriteableOperation> HandlerUndoRemoveBlock = (IWriteableOperation operation) => UndoRemoveBlock(operation);

            WriteableOperationList OperationList = CreateOperationList();

            // Insert first to prevent empty block lists.
            foreach (IWriteableInsertionBlockNodeIndex NodeIndex in IndexList)
            {
                if (NodeIndex is IWriteableInsertionNewBlockNodeIndex AsNewBlockNodeIndex)
                {
                    IBlock NewBlock = NodeTreeHelperBlockList.CreateBlock(Inner.Owner.Node, Inner.PropertyName, ReplicationStatus.Normal, AsNewBlockNodeIndex.PatternNode, AsNewBlockNodeIndex.SourceNode);
                    IWriteableInsertBlockOperation OperationInsertBlock = CreateInsertBlockOperation(Inner.Owner.Node, Inner.PropertyName, AsNewBlockNodeIndex.BlockIndex, NewBlock, AsNewBlockNodeIndex.Node, HandlerRedoInsertBlock, HandlerUndoInsertBlock, isNested: true);
                    OperationList.Add(OperationInsertBlock);
                }
                else if (NodeIndex is IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex)
                {
                    IndexToPositionAndNode(AsExistingBlockNodeIndex, out BlockIndex, out int Index, out _, out Node Node);
                    WriteableInsertNodeOperation OperationInsertNode = CreateInsertNodeOperation(Inner.Owner.Node, Inner.PropertyName, BlockIndex, Index, Node, HandlerRedoInsertNode, HandlerUndoInsertNode, isNested: true);
                    OperationList.Add(OperationInsertNode);
                }
            }

            Debug.Assert(BlockIndex + 1 == FinalBlockIndex);

            for (int i = FinalBlockIndex; i < FinalBlockIndex + lastBlockIndex - firstBlockIndex; i++)
            {
                IWriteableBlockState BlockState = (IWriteableBlockState)Inner.BlockStateList[i + firstBlockIndex - FinalBlockIndex];
                Debug.Assert(BlockState.StateList.Count >= 1);

                // Remove at FinalBlockIndex since subsequent blocks are moved as the block at FinalBlockIndex is deleted.
                // Same for nodes inside blokcks, delete them at 0.
                for (int j = 1; j < BlockState.StateList.Count; j++)
                {
                    WriteableRemoveNodeOperation OperationNode = CreateRemoveNodeOperation(Inner.Owner.Node, Inner.PropertyName, FinalBlockIndex, 0, HandlerRedoRemoveNode, HandlerUndoRemoveNode, isNested: true);
                    OperationList.Add(OperationNode);
                }

                IWriteableRemoveBlockOperation OperationBlock = CreateRemoveBlockOperation(Inner.Owner.Node, Inner.PropertyName, FinalBlockIndex, HandlerRedoRemoveBlock, HandlerUndoRemoveBlock, isNested: true);
                OperationList.Add(OperationBlock);
            }

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList   OperationReadOnlyList = OperationList.ToReadOnly();
                Action <IWriteableOperation>     HandlerRedo           = (IWriteableOperation operation) => RedoRefresh(operation);
                Action <IWriteableOperation>     HandlerUndo           = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation RefreshOperation      = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);
                WriteableOperationGroup          OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                OperationGroup.Redo();
                SetLastOperation(OperationGroup);
                CheckInvariant();
            }
        }
Ejemplo n.º 15
0
        /// <summary></summary>
        public virtual void ReplaceNodeRange(IWriteableListInner inner, int firstNodeIndex, int lastNodeIndex, IList <IWriteableInsertionCollectionNodeIndex> indexList)
        {
            Contract.RequireNotNull(inner, out IWriteableListInner Inner);
            Debug.Assert(firstNodeIndex >= 0 && firstNodeIndex < Inner.StateList.Count);
            Debug.Assert(lastNodeIndex >= 0 && lastNodeIndex <= Inner.StateList.Count);
            Debug.Assert(firstNodeIndex <= lastNodeIndex);

            int BlockNodeIndex = firstNodeIndex;

            foreach (IWriteableInsertionCollectionNodeIndex NodeIndex in indexList)
            {
                bool IsHandled = false;

                if (NodeIndex is IWriteableInsertionListNodeIndex AsListNodeIndex)
                {
                    Debug.Assert(AsListNodeIndex.Index == BlockNodeIndex);

                    BlockNodeIndex++;
                    IsHandled = true;
                }

                Debug.Assert(IsHandled);
            }

            int FinalNodeIndex = BlockNodeIndex;

            Action <IWriteableOperation> HandlerRedoInsertNode = (IWriteableOperation operation) => RedoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerUndoInsertNode = (IWriteableOperation operation) => UndoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerRedoRemoveNode = (IWriteableOperation operation) => RedoRemoveNode(operation);
            Action <IWriteableOperation> HandlerUndoRemoveNode = (IWriteableOperation operation) => UndoRemoveNode(operation);

            WriteableOperationList OperationList = CreateOperationList();

            // Insert first to prevent empty block lists.
            foreach (IWriteableInsertionCollectionNodeIndex NodeIndex in indexList)
            {
                if (NodeIndex is IWriteableInsertionListNodeIndex AsListNodeIndex)
                {
                    IndexToPositionAndNode(AsListNodeIndex, out int BlockIndex, out int Index, out _, out Node Node);
                    WriteableInsertNodeOperation OperationInsertNode = CreateInsertNodeOperation(Inner.Owner.Node, Inner.PropertyName, BlockIndex, Index, Node, HandlerRedoInsertNode, HandlerUndoInsertNode, isNested: true);
                    OperationList.Add(OperationInsertNode);
                }
            }

            for (int i = FinalNodeIndex; i < FinalNodeIndex + lastNodeIndex - firstNodeIndex; i++)
            {
                WriteableRemoveNodeOperation OperationNode = CreateRemoveNodeOperation(Inner.Owner.Node, Inner.PropertyName, -1, FinalNodeIndex, HandlerRedoRemoveNode, HandlerUndoRemoveNode, isNested: true);
                OperationList.Add(OperationNode);
            }

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList   OperationReadOnlyList = OperationList.ToReadOnly();
                Action <IWriteableOperation>     HandlerRedo           = (IWriteableOperation operation) => RedoRefresh(operation);
                Action <IWriteableOperation>     HandlerUndo           = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation RefreshOperation      = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);
                WriteableOperationGroup          OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                OperationGroup.Redo();
                SetLastOperation(OperationGroup);
                CheckInvariant();
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Reduces the optional node.
        /// </summary>
        private protected virtual void ReduceOptional(IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> optionalInner, WriteableOperationList operationList, bool isNested)
        {
            if (optionalInner.IsAssigned && NodeHelper.IsOptionalAssignedToDefault(optionalInner.ChildState.Optional))
            {
                IWriteableBrowsingOptionalNodeIndex ParentIndex = optionalInner.ChildState.ParentIndex;

                Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoUnassign(operation);
                Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoUnassign(operation);
                WriteableAssignmentOperation Operation   = CreateAssignmentOperation(optionalInner.Owner.Node, optionalInner.PropertyName, HandlerRedo, HandlerUndo, isNested);

                Operation.Redo();

                operationList.Add(Operation);
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Inserts a range of blocks in a block list.
        /// </summary>
        /// <param name="inner">The inner for the block list in which blocks are inserted.</param>
        /// <param name="insertedIndex">Index where to insert the first block.</param>
        /// <param name="indexList">List of nodes in blocks to insert.</param>
        public virtual void InsertBlockRange(IWriteableBlockListInner inner, int insertedIndex, IList <IWriteableInsertionBlockNodeIndex> indexList)
        {
            Contract.RequireNotNull(inner, out IWriteableBlockListInner Inner);
            Debug.Assert(insertedIndex >= 0 && insertedIndex <= Inner.BlockStateList.Count);
            Contract.RequireNotNull(indexList, out IList <IWriteableInsertionBlockNodeIndex> IndexList);

            int BlockIndex     = insertedIndex - 1;
            int BlockNodeIndex = 0;

            foreach (IWriteableInsertionBlockNodeIndex NodeIndex in IndexList)
            {
                bool IsHandled = false;

                if (NodeIndex is IWriteableInsertionNewBlockNodeIndex AsNewBlockNodeIndex)
                {
                    BlockIndex++;
                    BlockNodeIndex = 0;

                    Debug.Assert(AsNewBlockNodeIndex.BlockIndex == BlockIndex);

                    IsHandled = true;
                }
                else if (NodeIndex is IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex)
                {
                    BlockNodeIndex++;

                    Debug.Assert(AsExistingBlockNodeIndex.BlockIndex == BlockIndex);
                    Debug.Assert(AsExistingBlockNodeIndex.Index == BlockNodeIndex);

                    IsHandled = true;
                }

                Debug.Assert(IsHandled);
            }

            int FinalBlockIndex = BlockIndex + 1;

            Action <IWriteableOperation> HandlerRedoInsertNode  = (IWriteableOperation operation) => RedoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerUndoInsertNode  = (IWriteableOperation operation) => UndoInsertNewNode(operation);
            Action <IWriteableOperation> HandlerRedoInsertBlock = (IWriteableOperation operation) => RedoInsertNewBlock(operation);
            Action <IWriteableOperation> HandlerUndoInsertBlock = (IWriteableOperation operation) => UndoInsertNewBlock(operation);

            WriteableOperationList OperationList = CreateOperationList();

            foreach (IWriteableInsertionBlockNodeIndex NodeIndex in IndexList)
            {
                if (NodeIndex is IWriteableInsertionNewBlockNodeIndex AsNewBlockNodeIndex)
                {
                    IBlock NewBlock = NodeTreeHelperBlockList.CreateBlock(Inner.Owner.Node, Inner.PropertyName, ReplicationStatus.Normal, AsNewBlockNodeIndex.PatternNode, AsNewBlockNodeIndex.SourceNode);
                    IWriteableInsertBlockOperation OperationInsertBlock = CreateInsertBlockOperation(Inner.Owner.Node, Inner.PropertyName, AsNewBlockNodeIndex.BlockIndex, NewBlock, AsNewBlockNodeIndex.Node, HandlerRedoInsertBlock, HandlerUndoInsertBlock, isNested: true);
                    OperationList.Add(OperationInsertBlock);
                }
                else if (NodeIndex is IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex)
                {
                    IndexToPositionAndNode(AsExistingBlockNodeIndex, out BlockIndex, out int Index, out _, out Node Node);
                    WriteableInsertNodeOperation OperationInsertNode = CreateInsertNodeOperation(Inner.Owner.Node, Inner.PropertyName, BlockIndex, Index, Node, HandlerRedoInsertNode, HandlerUndoInsertNode, isNested: true);
                    OperationList.Add(OperationInsertNode);
                }
            }

            Debug.Assert(BlockIndex + 1 == FinalBlockIndex);

            if (OperationList.Count > 0)
            {
                WriteableOperationReadOnlyList   OperationReadOnlyList = OperationList.ToReadOnly();
                Action <IWriteableOperation>     HandlerRedo           = (IWriteableOperation operation) => RedoRefresh(operation);
                Action <IWriteableOperation>     HandlerUndo           = (IWriteableOperation operation) => throw new NotImplementedException(); // Undo is not possible.
                WriteableGenericRefreshOperation RefreshOperation      = CreateGenericRefreshOperation(RootState, HandlerRedo, HandlerUndo, isNested: false);
                WriteableOperationGroup          OperationGroup        = CreateOperationGroup(OperationReadOnlyList, RefreshOperation);

                OperationGroup.Redo();
                SetLastOperation(OperationGroup);
                CheckInvariant();
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Reduces the block list.
        /// </summary>
        private protected virtual void ReduceBlockList(IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> blockListInner, WriteableOperationList operationList, bool isNested)
        {
            if (!blockListInner.IsSingle)
            {
                return;
            }

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

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

            Debug.Assert(blockListInner.BlockStateList.Count == 1);
            Debug.Assert(blockListInner.BlockStateList[0].StateList.Count == 1);
            IWriteableNodeState FirstState = (IWriteableNodeState)blockListInner.BlockStateList[0].StateList[0];

            if (!NodeHelper.IsDefaultNode(FirstState.Node))
            {
                return;
            }

            Action <IWriteableOperation>   HandlerRedo = (IWriteableOperation operation) => RedoRemoveBlock(operation);
            Action <IWriteableOperation>   HandlerUndo = (IWriteableOperation operation) => UndoRemoveBlock(operation);
            IWriteableRemoveBlockOperation Operation   = CreateRemoveBlockOperation(blockListInner.Owner.Node, blockListInner.PropertyName, 0, HandlerRedo, HandlerUndo, isNested);

            Operation.Redo();

            operationList.Add(Operation);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Expands the optional node.
        /// * If assigned, does nothing.
        /// * If it has an item, assign it.
        /// * Otherwise, assign the item to a default node.
        /// </summary>
        private protected virtual void ExpandOptional(IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> optionalInner, WriteableOperationList operationList)
        {
            if (optionalInner.IsAssigned)
            {
                return;
            }

            IWriteableBrowsingOptionalNodeIndex ParentIndex = optionalInner.ChildState.ParentIndex;

            Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoAssign(operation);
            Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoAssign(operation);
            WriteableAssignmentOperation Operation   = CreateAssignmentOperation(optionalInner.Owner.Node, optionalInner.PropertyName, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();

            operationList.Add(Operation);
        }
Ejemplo n.º 20
0
        private protected virtual void CanonicalizeChildren(IWriteableNodeState state, WriteableOperationList operationList)
        {
            List <IWriteableNodeState> ChildStateList = new List <IWriteableNodeState>();

            foreach (string Key in state.InnerTable.Keys)
            {
                IWriteableInner Value = (IWriteableInner)state.InnerTable[Key];

                switch (Value)
                {
                case IWriteablePlaceholderInner <IWriteableBrowsingPlaceholderNodeIndex> AsPlaceholderInner:
                    ChildStateList.Add(AsPlaceholderInner.ChildState);
                    break;

                case IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> AsOptionalInner:
                    if (AsOptionalInner.IsAssigned)
                    {
                        CanonicalizeChildren(AsOptionalInner.ChildState, operationList);
                    }
                    break;

                case IWriteableListInner <IWriteableBrowsingListNodeIndex> AsListlInner:
                    foreach (IWriteablePlaceholderNodeState ChildState in AsListlInner.StateList)
                    {
                        ChildStateList.Add(ChildState);
                    }
                    break;

                case IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> AsBlockListlInner:
                    foreach (IWriteableBlockState BlockState in AsBlockListlInner.BlockStateList)
                    {
                        foreach (IWriteablePlaceholderNodeState ChildState in BlockState.StateList)
                        {
                            ChildStateList.Add(ChildState);
                        }
                    }
                    break;
                }
            }

            foreach (IWriteableNodeState ChildState in ChildStateList)
            {
                Canonicalize(ChildState, operationList);
            }
        }