/// <summary> /// Replace an existing node with a new one. /// </summary> /// <param name="inner">The inner where the node is replaced.</param> /// <param name="replaceIndex">Index for the replace operation.</param> /// <param name="nodeIndex">Index of the replacing node upon return.</param> public void Replace(IWriteableInner inner, IWriteableInsertionChildIndex replaceIndex, out IWriteableBrowsingChildIndex nodeIndex) { Contract.RequireNotNull(inner, out IWriteableInner Inner); Contract.RequireNotNull(replaceIndex, out IWriteableInsertionChildIndex ReplaceIndex); 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); IndexToPositionAndNode(ReplaceIndex, out int BlockIndex, out int Index, out bool ClearNode, out Node NewNode); Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoReplace(operation); Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoReplace(operation); IWriteableReplaceOperation Operation = CreateReplaceOperation(Inner.Owner.Node, Inner.PropertyName, BlockIndex, Index, ClearNode, NewNode, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); nodeIndex = Operation.NewBrowsingIndex; }
/// <summary> /// Inserts a new node in a list or block list. /// </summary> /// <param name="inner">The inner for the list or block list where the node is inserted.</param> /// <param name="insertedIndex">Index for the insertion operation.</param> /// <param name="nodeIndex">Index of the inserted node upon return.</param> public virtual void Insert(IWriteableCollectionInner inner, IWriteableInsertionCollectionNodeIndex insertedIndex, out IWriteableBrowsingCollectionNodeIndex nodeIndex) { Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner); Contract.RequireNotNull(insertedIndex, out IWriteableInsertionCollectionNodeIndex InsertedIndex); 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); bool IsHandled = false; nodeIndex = null; if (Inner is IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> AsBlockListInner && InsertedIndex is IWriteableInsertionNewBlockNodeIndex AsNewBlockIndex) { InsertNewBlock(AsBlockListInner, AsNewBlockIndex, out nodeIndex); IsHandled = true; } else if (Inner is IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> AsCollectionInner && InsertedIndex is IWriteableInsertionCollectionNodeIndex AsCollectionIndex) { InsertNewNode(AsCollectionInner, AsCollectionIndex, out nodeIndex); IsHandled = true; } Debug.Assert(IsHandled); }
bool IReadOnlyDictionary <IWriteableIndex, IWriteableNodeState> .TryGetValue(IWriteableIndex key, out IWriteableNodeState value) { bool Result = TryGetValue((IFocusIndex)key, out IFocusNodeState Value); value = Value; return(Result); }
bool IDictionary <IWriteableIndex, IWriteableNodeState> .TryGetValue(IWriteableIndex key, out IWriteableNodeState value) { bool Result = TryGetValue((ILayoutIndex)key, out ILayoutNodeState Value); value = Value; return(Result); }
private protected virtual void IndexToPositionAndNode(IWriteableIndex nodeIndex, out int blockIndex, out int index, out bool clearNode, out Node node) { blockIndex = -1; index = -1; clearNode = false; node = null; bool IsHandled = false; switch (nodeIndex) { case IWriteableInsertionPlaceholderNodeIndex AsPlaceholderNodeIndex: node = AsPlaceholderNodeIndex.Node; IsHandled = true; break; case IWriteableInsertionOptionalNodeIndex AsOptionalNodeIndex: node = AsOptionalNodeIndex.Node; IsHandled = true; break; case IWriteableInsertionOptionalClearIndex AsOptionalClearIndex: //Type NodeType = NodeTreeHelperOptional.OptionalItemType(AsOptionalClearIndex.ParentNode, AsOptionalClearIndex.PropertyName); //Node Item = NodeHelper.CreateDefaultFromType(NodeType); //node = Item; clearNode = true; IsHandled = true; break; case IWriteableInsertionListNodeIndex AsListNodeIndex: index = AsListNodeIndex.Index; node = AsListNodeIndex.Node; IsHandled = true; break; case IWriteableInsertionExistingBlockNodeIndex AsExistingBlockNodeIndex: blockIndex = AsExistingBlockNodeIndex.BlockIndex; index = AsExistingBlockNodeIndex.Index; node = AsExistingBlockNodeIndex.Node; IsHandled = true; break; case IWriteableBrowsingListNodeIndex AsListNodeIndex: index = AsListNodeIndex.Index; node = AsListNodeIndex.Node; IsHandled = true; break; case IWriteableBrowsingExistingBlockNodeIndex AsExistingBlockNodeIndex: blockIndex = AsExistingBlockNodeIndex.BlockIndex; index = AsExistingBlockNodeIndex.Index; node = AsExistingBlockNodeIndex.Node; IsHandled = true; break; } Debug.Assert(IsHandled); }
/// <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); }
private protected virtual void ReplaceState(IWriteableReplaceOperation operation, IWriteableInner <IWriteableBrowsingChildIndex> inner) { Contract.RequireNotNull(inner, out IWriteableInner <IWriteableBrowsingChildIndex> Inner); 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); IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex> AsOptionalInner = Inner as IWriteableOptionalInner <IWriteableBrowsingOptionalNodeIndex>; if (AsOptionalInner != null) { IWriteableNodeState OldState = AsOptionalInner.ChildState; PruneStateChildren(OldState); if (AsOptionalInner.IsAssigned) { Stats.AssignedOptionalNodeCount--; } } Inner.Replace(operation); IWriteableBrowsingChildIndex OldBrowsingIndex = operation.OldBrowsingIndex; IWriteableBrowsingChildIndex NewBrowsingIndex = operation.NewBrowsingIndex; IWriteableNodeState ChildState = operation.NewChildState; if (AsOptionalInner != null) { if (AsOptionalInner.IsAssigned) { Stats.AssignedOptionalNodeCount++; } } else { Debug.Assert(Contains(OldBrowsingIndex)); IWriteableNodeState OldState = (IWriteableNodeState)StateTable[OldBrowsingIndex]; PruneStateChildren(OldState); } RemoveState(OldBrowsingIndex); AddState(NewBrowsingIndex, ChildState); BuildStateTable(Inner, null, NewBrowsingIndex, ChildState); }
/// <summary> /// Changes the value of a text. /// </summary> /// <param name="nodeIndex">Index of the state with the comment to change.</param> /// <param name="text">The new comment.</param> public virtual void ChangeComment(IWriteableIndex nodeIndex, string text) { Contract.RequireNotNull(nodeIndex, out IWriteableIndex NodeIndex); Debug.Assert(StateTable.ContainsKey(NodeIndex)); Contract.RequireNotNull(text, out string Text); System.Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoChangeComment(operation); System.Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoChangeComment(operation); IWriteableNodeState State = (IWriteableNodeState)StateTable[NodeIndex]; WriteableChangeCommentOperation Operation = CreateChangeCommentOperation(State.Node, Text, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); }
/// <summary> /// Changes the value of an enum or boolean. /// If the value exceeds allowed values, it is rounded to fit. /// </summary> /// <param name="nodeIndex">Index of the state with the enum to change.</param> /// <param name="propertyName">Name of the property to change.</param> /// <param name="value">The new value.</param> public virtual void ChangeDiscreteValue(IWriteableIndex nodeIndex, string propertyName, int value) { Contract.RequireNotNull(nodeIndex, out IWriteableIndex NodeIndex); Debug.Assert(StateTable.ContainsKey(NodeIndex)); Debug.Assert(value >= 0); System.Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoChangeDiscreteValue(operation); System.Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoChangeDiscreteValue(operation); IWriteableNodeState State = (IWriteableNodeState)StateTable[NodeIndex]; WriteableChangeDiscreteValueOperation Operation = CreateChangeDiscreteValueOperation(State.Node, propertyName, value, HandlerRedo, HandlerUndo, isNested: false); Operation.Redo(); SetLastOperation(Operation); CheckInvariant(); }
/// <summary> /// Removes a node from a list or block list. /// </summary> /// <param name="inner">The inner for the list or block list from which the node is removed.</param> /// <param name="nodeIndex">Index for the removed node.</param> public virtual void Remove(IWriteableCollectionInner inner, IWriteableBrowsingCollectionNodeIndex nodeIndex) { Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner); Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingCollectionNodeIndex NodeIndex); 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); IndexToPositionAndNode(NodeIndex, out int BlockIndex, out int Index, out _, out Node Node); bool IsHandled = false; if (Inner is IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> AsBlockListInner && NodeIndex is IWriteableBrowsingExistingBlockNodeIndex ExistingBlockIndex) { if (AsBlockListInner.BlockStateList[ExistingBlockIndex.BlockIndex].StateList.Count == 1) { RemoveBlock(AsBlockListInner, BlockIndex); } else { RemoveNode(AsBlockListInner, BlockIndex, Index); } IsHandled = true; } else if (Inner is IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> AsCollectionInner) { RemoveNode(AsCollectionInner, BlockIndex, Index); IsHandled = true; } Debug.Assert(IsHandled); }
bool IDictionary <IWriteableIndex, IWriteableNodeState> .Remove(IWriteableIndex key) { return(Remove((ILayoutIndex)key)); }
bool IDictionary <IWriteableIndex, IWriteableNodeState> .ContainsKey(IWriteableIndex key) { return(ContainsKey((ILayoutIndex)key)); }
void IDictionary <IWriteableIndex, IWriteableNodeState> .Add(IWriteableIndex key, IWriteableNodeState value) { Add((ILayoutIndex)key, (ILayoutNodeState)value); }
IWriteableNodeState IDictionary <IWriteableIndex, IWriteableNodeState> .this[IWriteableIndex key] { get { return(this[(ILayoutIndex)key]); } set { this[(ILayoutIndex)key] = (ILayoutNodeState)value; } }
IWriteableNodeState IReadOnlyDictionary <IWriteableIndex, IWriteableNodeState> .this[IWriteableIndex key] { get { return(this[(IFocusIndex)key]); } }
bool IReadOnlyDictionary <IWriteableIndex, IWriteableNodeState> .ContainsKey(IWriteableIndex key) { return(ContainsKey((IFocusIndex)key)); }
/// <summary> /// Initializes a new instance of the <see cref="WriteableNodeState{IInner}"/> class. /// </summary> /// <param name="parentIndex">The index used to create the state.</param> public WriteableNodeState(IWriteableIndex parentIndex) : base(parentIndex) { }
void IDictionary <IWriteableIndex, IWriteableNodeState> .Add(IWriteableIndex key, IWriteableNodeState value) { Add((IFocusIndex)key, (IFocusNodeState)value); }
bool IWriteableIndexNodeStateReadOnlyDictionary.ContainsKey(IWriteableIndex key) { return(ContainsKey((ILayoutIndex)key)); }
IWriteableNodeState IWriteableIndexNodeStateReadOnlyDictionary.this[IWriteableIndex key] { get { return(this[(ILayoutIndex)key]); } }