private protected virtual void UndoSplitBlock(IWriteableOperation operation) { WriteableSplitBlockOperation SplitBlockOperation = (WriteableSplitBlockOperation)operation; WriteableMergeBlocksOperation MergeBlocksOperation = SplitBlockOperation.ToMergeBlocksOperation(); ExecuteMergeBlocks(MergeBlocksOperation); }
private protected virtual void ExecuteMergeBlocks(WriteableMergeBlocksOperation operation) { Node ParentNode = operation.ParentNode; string PropertyName = operation.PropertyName; IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> Inner = GetInner(ParentNode, PropertyName) as IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex>; int BlockIndex = operation.BlockIndex; IWriteableBlockState FirstBlockState = (IWriteableBlockState)Inner.BlockStateList[BlockIndex - 1]; IWriteableBlockState SecondBlockState = (IWriteableBlockState)Inner.BlockStateList[BlockIndex]; IReadOnlyBrowsingSourceIndex SourceIndex = FirstBlockState.SourceIndex; RemoveState(SourceIndex); Stats.PlaceholderNodeCount--; IReadOnlyBrowsingPatternIndex PatternIndex = FirstBlockState.PatternIndex; RemoveState(PatternIndex); Stats.PlaceholderNodeCount--; int OldNodeCount = FirstBlockState.StateList.Count + SecondBlockState.StateList.Count; int FirstNodeIndex = FirstBlockState.StateList.Count; Inner.MergeBlocks(operation); Stats.BlockCount--; IWriteableBlockState BlockState = (IWriteableBlockState)Inner.BlockStateList[BlockIndex - 1]; Debug.Assert(BlockState.StateList.Count == OldNodeCount); Debug.Assert(FirstNodeIndex < BlockState.StateList.Count); NotifyBlocksMerged(operation); }
/// <summary> /// Handler called every time two blocks are merged. /// </summary> /// <param name="operation">Details of the operation performed.</param> private protected virtual void OnBlocksMerged(WriteableMergeBlocksOperation operation) { Debug.Assert(!operation.IsNested); IWriteableBlockState BlockState = operation.BlockState; Debug.Assert(BlockState != null); Debug.Assert(!BlockStateViewTable.ContainsKey(BlockState)); }
/// <summary> /// Merges two blocks at the given index. /// </summary> /// <param name="operation">Details of the operation performed.</param> public virtual void MergeBlocks(WriteableMergeBlocksOperation operation) { int MergeBlockIndex = operation.BlockIndex; Debug.Assert(MergeBlockIndex > 0 && MergeBlockIndex < BlockStateList.Count); IWriteableBlockState FirstBlockState = (IWriteableBlockState)BlockStateList[MergeBlockIndex - 1]; IWriteableBlockState SecondBlockState = (IWriteableBlockState)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 = (IWriteablePlaceholderNodeState)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 = (IWriteablePlaceholderNodeState)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(); } } }
/// <summary> /// Merges two blocks at the given index. /// </summary> /// <param name="inner">The inner where blocks are merged.</param> /// <param name="nodeIndex">Index of the first node in the block to merge.</param> public virtual void MergeBlocks(IWriteableBlockListInner inner, IWriteableBrowsingExistingBlockNodeIndex nodeIndex) { Contract.RequireNotNull(inner, out IWriteableBlockListInner Inner); Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingExistingBlockNodeIndex NodeIndex); Debug.Assert(Inner.IsMergeable(NodeIndex)); Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoMergeBlocks(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoMergeBlocks(operation); WriteableMergeBlocksOperation Operation = CreateMergeBlocksOperation(Inner.Owner.Node, Inner.PropertyName, NodeIndex.BlockIndex, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); }
private protected virtual void RedoMergeBlocks(IWriteableOperation operation) { WriteableMergeBlocksOperation MergeBlocksOperation = (WriteableMergeBlocksOperation)operation; ExecuteMergeBlocks(MergeBlocksOperation); }
private protected virtual void NotifyBlocksMerged(WriteableMergeBlocksOperation operation) { BlocksMergedHandler?.Invoke(operation); }