Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        private protected virtual void ExecuteMove(WriteableMoveNodeOperation operation)
        {
            Node   ParentNode   = operation.ParentNode;
            string PropertyName = operation.PropertyName;
            IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> Inner = GetInner(ParentNode, PropertyName) as IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex>;

            Inner.Move(operation);
            NotifyStateMoved(operation);
        }
        private protected virtual void RemoveNode(IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> inner, int blockIndex, int index)
        {
            System.Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoRemoveNode(operation);
            System.Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoRemoveNode(operation);
            WriteableRemoveNodeOperation        Operation   = CreateRemoveNodeOperation(inner.Owner.Node, inner.PropertyName, blockIndex, index, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();
            SetLastOperation(Operation);
            CheckInvariant();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Checks whether a node can be moved in a list.
        /// </summary>
        /// <param name="inner">The inner where the node is.</param>
        /// <param name="nodeIndex">Index of the node that would be moved.</param>
        /// <param name="direction">Direction of the move, relative to the current position of the item.</param>
        public virtual bool IsMoveable(IWriteableCollectionInner inner, IWriteableBrowsingCollectionNodeIndex nodeIndex, int direction)
        {
            Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner);
            Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingCollectionNodeIndex NodeIndex);

            IWriteableNodeState State = (IWriteableNodeState)StateTable[NodeIndex];

            Debug.Assert(State != null);

            bool Result = Inner.IsMoveable(NodeIndex, direction);

            return(Result);
        }
Ejemplo n.º 5
0
        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;
        }
        /// <summary>
        /// Checks whether a range of nodes can be removed from a list or block list.
        /// </summary>
        /// <param name="inner">The inner with nodes to remove.</param>
        /// <param name="blockIndex">Index of the block where to remove nodes, for a block list. -1 for a list.</param>
        /// <param name="firstNodeIndex">Index of the first node to remove.</param>
        /// <param name="lastNodeIndex">Index following the last node to remove.</param>
        public virtual bool IsNodeRangeRemoveable(IWriteableCollectionInner inner, int blockIndex, int firstNodeIndex, int lastNodeIndex)
        {
            Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner);

            bool IsHandled = false;
            bool Result    = false;

            if (Inner is IWriteableBlockListInner AsBlockListInner)
            {
                Result    = IsNodeRangeRemoveable(AsBlockListInner, blockIndex, firstNodeIndex, lastNodeIndex);
                IsHandled = true;
            }
            else if (Inner is IWriteableListInner AsListInner)
            {
                Debug.Assert(blockIndex == -1);
                Result    = IsNodeRangeRemoveable(AsListInner, firstNodeIndex, lastNodeIndex);
                IsHandled = true;
            }

            Debug.Assert(IsHandled);

            if (!Result)
            {
                Debug.Assert(Inner.Owner != null);

                Node   Node         = Inner.Owner.Node;
                string PropertyName = Inner.PropertyName;
                Debug.Assert(Node != null);

                Result = true;

                //Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(inner.Owner.Node.GetType());
                Type InterfaceType = Type.FromGetType(Inner.Owner.Node);

                IReadOnlyDictionary <Type, string[]> NeverEmptyCollectionTable = NodeHelper.NeverEmptyCollectionTable;
                if (NeverEmptyCollectionTable.ContainsKey(InterfaceType))
                {
                    foreach (string Item in NeverEmptyCollectionTable[InterfaceType])
                    {
                        if (Item == PropertyName)
                        {
                            Result = false;
                        }
                    }
                }
            }

            return(Result);
        }
        private protected virtual void ExecuteRemoveNode(WriteableRemoveNodeOperation operation)
        {
            Node   ParentNode   = operation.ParentNode;
            string PropertyName = operation.PropertyName;
            IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex> Inner = GetInner(ParentNode, PropertyName) as IWriteableCollectionInner <IWriteableBrowsingCollectionNodeIndex>;

            Inner.Remove(operation);

            IWriteableNodeState RemovedState = operation.RemovedState;

            PruneState(RemovedState);
            Stats.PlaceholderNodeCount--;

            NotifyStateRemoved(operation);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Moves a node around in a list or block list. In a block list, the node stays in same block.
        /// </summary>
        /// <param name="inner">The inner for the list or block list in which the node is moved.</param>
        /// <param name="nodeIndex">Index for the moved node.</param>
        /// <param name="direction">The change in position, relative to the current position.</param>
        public virtual void Move(IWriteableCollectionInner inner, IWriteableBrowsingCollectionNodeIndex nodeIndex, int direction)
        {
            Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner);
            Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingCollectionNodeIndex NodeIndex);

            IWriteableNodeState State = (IWriteableNodeState)StateTable[NodeIndex];

            Debug.Assert(State != null);

            IndexToPositionAndNode(NodeIndex, out int BlockIndex, out int Index, out _, out Node Node);

            Action <IWriteableOperation> HandlerRedo = (IWriteableOperation operation) => RedoMove(operation);
            Action <IWriteableOperation> HandlerUndo = (IWriteableOperation operation) => UndoMove(operation);
            WriteableMoveNodeOperation   Operation   = CreateMoveNodeOperation(Inner.Owner.Node, Inner.PropertyName, BlockIndex, Index, direction, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();
            SetLastOperation(Operation);
            CheckInvariant();
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Removes a range of nodes from a list or block list and replace them with other nodes.
        /// </summary>
        /// <param name="inner">The inner for the list or block list from which nodes are replaced.</param>
        /// <param name="blockIndex">Index of the block where to remove nodes, for a block list. -1 for a list.</param>
        /// <param name="firstNodeIndex">Index of the first node to remove.</param>
        /// <param name="lastNodeIndex">Index following the last node to remove.</param>
        /// <param name="indexList">List of nodes to insert.</param>
        public virtual void ReplaceNodeRange(IWriteableCollectionInner inner, int blockIndex, int firstNodeIndex, int lastNodeIndex, IList <IWriteableInsertionCollectionNodeIndex> indexList)
        {
            Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner);

            bool IsHandled = false;

            if (Inner is IWriteableBlockListInner AsBlockListInner)
            {
                ReplaceNodeRange(AsBlockListInner, blockIndex, firstNodeIndex, lastNodeIndex, indexList);
                IsHandled = true;
            }
            else if (Inner is IWriteableListInner AsListInner)
            {
                Debug.Assert(blockIndex == -1);
                ReplaceNodeRange(AsListInner, firstNodeIndex, lastNodeIndex, indexList);
                IsHandled = true;
            }

            Debug.Assert(IsHandled);
        }
        /// <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);
        }
        /// <summary>
        /// Checks whether a node can be removed from a list.
        /// </summary>
        /// <param name="inner">The inner where the node is.</param>
        /// <param name="nodeIndex">Index of the node that would be removed.</param>
        public bool IsRemoveable(IWriteableCollectionInner inner, IWriteableBrowsingCollectionNodeIndex nodeIndex)
        {
            Contract.RequireNotNull(inner, out IWriteableCollectionInner Inner);
            Contract.RequireNotNull(nodeIndex, out IWriteableBrowsingCollectionNodeIndex NodeIndex);

            if (Inner.Count > 1)
            {
                return(true);
            }

            Debug.Assert(Inner.Count == 1);
            Debug.Assert(Inner.Owner != null);

            Node   Node         = Inner.Owner.Node;
            string PropertyName = Inner.PropertyName;

            Debug.Assert(Node != null);

            bool Result = true;

            //Type InterfaceType = NodeTreeHelper.NodeTypeToInterfaceType(inner.Owner.Node.GetType());
            Type InterfaceType = Type.FromGetType(Inner.Owner.Node);

            IReadOnlyDictionary <Type, string[]> NeverEmptyCollectionTable = NodeHelper.NeverEmptyCollectionTable;

            if (NeverEmptyCollectionTable.ContainsKey(InterfaceType))
            {
                foreach (string Item in NeverEmptyCollectionTable[InterfaceType])
                {
                    if (Item == PropertyName)
                    {
                        Result = false;
                    }
                }
            }

            return(Result);
        }