/// <summary> /// Inserts a new node in a list. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Insert(WriteableInsertNodeOperation operation) { int InsertionIndex = operation.Index; Debug.Assert(InsertionIndex >= 0 && InsertionIndex <= StateList.Count); Node ParentNode = Owner.Node; Node Node = operation.Node; NodeTreeHelperList.InsertIntoList(ParentNode, PropertyName, InsertionIndex, Node); IWriteableBrowsingListNodeIndex BrowsingIndex = CreateBrowsingNodeIndex(Node, InsertionIndex); IWriteablePlaceholderNodeState ChildState = (IWriteablePlaceholderNodeState)CreateNodeState(BrowsingIndex); InsertInStateList(InsertionIndex, ChildState); operation.Update(BrowsingIndex, ChildState); while (++InsertionIndex < StateList.Count) { IWriteablePlaceholderNodeState State = (IWriteablePlaceholderNodeState)StateList[InsertionIndex]; IWriteableBrowsingListNodeIndex NodeIndex = State.ParentIndex as IWriteableBrowsingListNodeIndex; Debug.Assert(NodeIndex != null); Debug.Assert(NodeIndex.Index == InsertionIndex - 1); NodeIndex.MoveUp(); } }
private protected virtual void UndoInsertNewNode(IWriteableOperation operation) { WriteableInsertNodeOperation InsertNodeOperation = (WriteableInsertNodeOperation)operation; WriteableRemoveNodeOperation RemoveNodeOperation = InsertNodeOperation.ToRemoveNodeOperation(); ExecuteRemoveNode(RemoveNodeOperation); }
/// <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(); } }
/// <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> /// Handler called every time a state is inserted in the controller. /// </summary> /// <param name="operation">Details of the operation performed.</param> private protected virtual void OnStateInserted(WriteableInsertNodeOperation operation) { IWriteableNodeState ChildState = operation.ChildState; Debug.Assert(ChildState != null); Debug.Assert(StateViewTable.ContainsKey(ChildState)); IWriteableBrowsingCollectionNodeIndex BrowsingIndex = operation.BrowsingIndex; Debug.Assert(ChildState.ParentIndex == BrowsingIndex); }
private protected virtual void InsertNewNode(IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> inner, IWriteableInsertionCollectionNodeIndex insertedIndex, out IWriteableBrowsingCollectionNodeIndex nodeIndex) { IndexToPositionAndNode(insertedIndex, out int BlockIndex, out int Index, out _, out Node Node); Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoInsertNewNode(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoInsertNewNode(operation); WriteableInsertNodeOperation Operation = CreateInsertNodeOperation(inner.Owner.Node, inner.PropertyName, BlockIndex, Index, Node, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); nodeIndex = Operation.BrowsingIndex; }
private protected virtual void ExecuteInsertNewNode(WriteableInsertNodeOperation operation) { Node ParentNode = operation.ParentNode; string PropertyName = operation.PropertyName; IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> Inner = GetInner(ParentNode, PropertyName) as IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex>; Inner.Insert(operation); IWriteableBrowsingCollectionNodeIndex BrowsingIndex = operation.BrowsingIndex; IWriteablePlaceholderNodeState ChildState = operation.ChildState; AddState(BrowsingIndex, ChildState); Stats.PlaceholderNodeCount++; BuildStateTable(Inner, null, BrowsingIndex, ChildState); Debug.Assert(Contains(BrowsingIndex)); NotifyStateInserted(operation); }
/// <summary> /// Inserts a new node in a block list. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void Insert(WriteableInsertNodeOperation 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); Node ParentNode = Owner.Node; IBlock ChildBlock = BlockState.ChildBlock; Node Node = operation.Node; NodeTreeHelperBlockList.InsertIntoBlock(ChildBlock, Index, Node); IWriteableBrowsingBlockNodeIndex BrowsingBlockIndex = CreateBrowsingNodeIndex(Node, BlockIndex, Index); IWriteablePlaceholderNodeState ChildState = (IWriteablePlaceholderNodeState)CreateNodeState(BrowsingBlockIndex); BlockState.Insert(BrowsingBlockIndex, Index, ChildState); operation.Update(BrowsingBlockIndex, ChildState); while (++Index < BlockState.StateList.Count) { IWriteablePlaceholderNodeState State = (IWriteablePlaceholderNodeState)BlockState.StateList[Index]; IWriteableBrowsingExistingBlockNodeIndex NodeIndex = State.ParentIndex as IWriteableBrowsingExistingBlockNodeIndex; Debug.Assert(NodeIndex != null); Debug.Assert(NodeIndex.BlockIndex == BrowsingBlockIndex.BlockIndex); Debug.Assert(NodeIndex.Index == Index - 1); NodeIndex.MoveUp(); } }
/// <summary> /// Inserts a new node in a list or block list. /// </summary> /// <param name="operation">Details of the operation performed.</param> public abstract void Insert(WriteableInsertNodeOperation operation);
/// <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(); } }
/// <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(); } }
/// <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(); } }
private protected virtual void RedoInsertNewNode(IWriteableOperation operation) { WriteableInsertNodeOperation InsertNodeOperation = (WriteableInsertNodeOperation)operation; ExecuteInsertNewNode(InsertNodeOperation); }
private protected virtual void NotifyStateInserted(WriteableInsertNodeOperation operation) { StateInsertedHandler?.Invoke(operation); }