/// <summary>
        /// Moves a node around in a block.
        /// </summary>
        /// <param name="nodeIndex">Index for the moved node.</param>
        /// <param name="index">Position of the moved node in the block.</param>
        /// <param name="direction">The change in position, relative to the current position.</param>
        public virtual void Move(IWriteableBrowsingCollectionNodeIndex nodeIndex, int index, int direction)
        {
            Debug.Assert(index >= 0 && index < StateList.Count);
            Debug.Assert(index + direction >= 0 && index + direction < StateList.Count);

            MoveState(index, direction);
        }
        /// <summary>
        /// Update the operation with details.
        /// </summary>
        /// <param name="browsingIndex">Index of the state after it's inserted.</param>
        /// <param name="childState">State inserted.</param>
        public virtual void Update(IWriteableBrowsingCollectionNodeIndex browsingIndex, IWriteablePlaceholderNodeState childState)
        {
            Debug.Assert(browsingIndex != null);
            Debug.Assert(childState != null);

            BrowsingIndex = browsingIndex;
            ChildState    = childState;
        }
        /// <summary>
        /// Update the operation with details.
        /// </summary>
        /// <param name="browsingIndex">Index of the state after it's inserted.</param>
        /// <param name="childState">State inserted.</param>
        public virtual void Update(IWriteableBrowsingCollectionNodeIndex browsingIndex, IWriteablePlaceholderNodeState childState)
        {
            Contract.RequireNotNull(browsingIndex, out IWriteableBrowsingCollectionNodeIndex BrowsingIndex);
            Contract.RequireNotNull(childState, out IWriteablePlaceholderNodeState ChildState);

            this.BrowsingIndex = BrowsingIndex;
            this.ChildState    = ChildState;
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
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);
        }
Exemple #6
0
        /// <summary>
        /// Checks whether a node can be moved in a list.
        /// </summary>
        /// <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(IWriteableBrowsingCollectionNodeIndex nodeIndex, int direction)
        {
            bool IsHandled = false;
            bool Result    = false;

            if (nodeIndex is IWriteableBrowsingListNodeIndex AsListIndex)
            {
                int NewPosition = AsListIndex.Index + direction;
                Result = NewPosition >= 0 && NewPosition < StateList.Count;

                IsHandled = true;
            }

            Debug.Assert(IsHandled);
            return(Result);
        }
Exemple #7
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();
        }
Exemple #8
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);
        }
        /// <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);
        }
        /// <summary>
        /// Checks whether a node can be moved in a block list.
        /// </summary>
        /// <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(IWriteableBrowsingCollectionNodeIndex nodeIndex, int direction)
        {
            bool IsHandled = false;
            bool Result    = false;

            if (nodeIndex is IWriteableBrowsingExistingBlockNodeIndex AsExistingBlockNodeIndex)
            {
                Debug.Assert(AsExistingBlockNodeIndex != null);

                int BlockIndex = AsExistingBlockNodeIndex.BlockIndex;
                Debug.Assert(BlockIndex >= 0 && BlockIndex < BlockStateList.Count);

                IWriteableBlockState BlockState = (IWriteableBlockState)BlockStateList[BlockIndex];
                WriteablePlaceholderNodeStateReadOnlyList StateList = BlockState.StateList;

                int NewPosition = AsExistingBlockNodeIndex.Index + direction;
                Result = NewPosition >= 0 && NewPosition < StateList.Count;

                IsHandled = true;
            }

            Debug.Assert(IsHandled);
            return(Result);
        }
Exemple #12
0
 /// <summary>
 /// Checks whether a node can be moved in a list or block list.
 /// </summary>
 /// <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 abstract bool IsMoveable(IWriteableBrowsingCollectionNodeIndex nodeIndex, int direction);
Exemple #13
0
        private protected virtual void InsertNewBlock(IWriteableBlockListInner <IWriteableBrowsingBlockNodeIndex> blockListInner, IWriteableInsertionNewBlockNodeIndex newBlockIndex, out IWriteableBrowsingCollectionNodeIndex nodeIndex)
        {
            IBlock NewBlock = NodeTreeHelperBlockList.CreateBlock(blockListInner.Owner.Node, blockListInner.PropertyName, ReplicationStatus.Normal, newBlockIndex.PatternNode, newBlockIndex.SourceNode);

            Action <IWriteableOperation>   HandlerRedo = (IWriteableOperation operation) => RedoInsertNewBlock(operation);
            Action <IWriteableOperation>   HandlerUndo = (IWriteableOperation operation) => UndoInsertNewBlock(operation);
            IWriteableInsertBlockOperation Operation   = CreateInsertBlockOperation(blockListInner.Owner.Node, blockListInner.PropertyName, newBlockIndex.BlockIndex, NewBlock, newBlockIndex.Node, HandlerRedo, HandlerUndo, isNested: false);

            Operation.Redo();
            SetLastOperation(Operation);
            CheckInvariant();

            nodeIndex = Operation.BrowsingIndex;
        }
Exemple #14
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);
        }
Exemple #15
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;
        }