Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        /// <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();
        }
Beispiel #9
0
        /// <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; }
 }
Beispiel #15
0
 IWriteableNodeState IReadOnlyDictionary <IWriteableIndex, IWriteableNodeState> .this[IWriteableIndex key] {
     get { return(this[(IFocusIndex)key]); }
 }
Beispiel #16
0
 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)
 {
 }
Beispiel #18
0
 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]); }
 }