Beispiel #1
0
        // Returns the character offset of a node.
        // In the worst case this takes log time.
        internal int GetIMECharOffset()
        {
            SplayTreeNode node;
            int           charOffset;

            charOffset = 0;
            node       = this;

            // Each iteration walks a sibling tree.
            while (true)
            {
                // Splay this node up to the root, we're referencing it.
                node.Splay();

                // Offset gets everything to the left of this node.
                charOffset += node.LeftCharCount;

                node = node.ParentNode;
                if (node == null)
                {
                    break;
                }

                // Add the parent start edge.
                TextTreeTextElementNode elementNode = node as TextTreeTextElementNode;
                if (elementNode != null)
                {
                    charOffset += elementNode.IMELeftEdgeCharCount;
                }
            }

            return(charOffset);
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        // Returns a shallow copy of this node.
        internal override TextTreeNode Clone()
        {
            TextTreeTextElementNode clone;

            clone = new TextTreeTextElementNode();
            clone._symbolCount  = _symbolCount;
            clone._imeCharCount = _imeCharCount;
            clone._textElement  = _textElement;

            return(clone);
        }
        //------------------------------------------------------ 
        // 
        //  Internal Methods
        // 
        //------------------------------------------------------

        #region Internal Methods
 
        // Returns a shallow copy of this node.
        internal override TextTreeNode Clone() 
        { 
            TextTreeTextElementNode clone;
 
            clone = new TextTreeTextElementNode();
            clone._symbolCount = _symbolCount;
            clone._imeCharCount = _imeCharCount;
            clone._textElement = _textElement; 

            return clone; 
        } 
Beispiel #4
0
 // Token: 0x06003D16 RID: 15638 RVA: 0x0011BC18 File Offset: 0x00119E18
 internal TextTreeExtractElementUndoUnit(TextContainer tree, TextTreeTextElementNode elementNode) : base(tree, elementNode.GetSymbolOffset(tree.Generation))
 {
     this._symbolCount = elementNode.SymbolCount;
     this._type        = elementNode.TextElement.GetType();
     this._localValues = TextTreeUndoUnit.GetPropertyRecordArray(elementNode.TextElement);
     this._resources   = elementNode.TextElement.Resources;
     if (elementNode.TextElement is Table)
     {
         this._columns = TextTreeDeleteContentUndoUnit.SaveColumns((Table)elementNode.TextElement);
     }
 }
 // Token: 0x06003D15 RID: 15637 RVA: 0x0011BB88 File Offset: 0x00119D88
 private TextTreeNode CopyElementNode(TextTreeTextElementNode elementNode, out TextTreeDeleteContentUndoUnit.ContentContainer container)
 {
     if (elementNode.TextElement is Table)
     {
         container = new TextTreeDeleteContentUndoUnit.TableElementContentContainer(elementNode.TextElement as Table, TextTreeUndoUnit.GetPropertyRecordArray(elementNode.TextElement), this.CopyContent((TextTreeNode)elementNode.GetFirstContainedNode(), null));
     }
     else
     {
         container = new TextTreeDeleteContentUndoUnit.ElementContentContainer(elementNode.TextElement.GetType(), TextTreeUndoUnit.GetPropertyRecordArray(elementNode.TextElement), elementNode.TextElement.Resources, this.CopyContent((TextTreeNode)elementNode.GetFirstContainedNode(), null));
     }
     return((TextTreeNode)elementNode.GetNextNode());
 }
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        // Creates a new undo unit instance.
        internal TextTreeExtractElementUndoUnit(TextContainer tree, TextTreeTextElementNode elementNode)
            : base(tree, elementNode.GetSymbolOffset(tree.Generation))
        {
            _symbolCount = elementNode.SymbolCount;
            _type = elementNode.TextElement.GetType();
            _localValues = GetPropertyRecordArray(elementNode.TextElement);
            _resources = elementNode.TextElement.Resources;

            // Table requires additional work for storing its Columns collection
            if (elementNode.TextElement is Table)
            {
                _columns = TextTreeDeleteContentUndoUnit.SaveColumns((Table)elementNode.TextElement);
            }
        }
Beispiel #7
0
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        // Creates a new undo unit instance.
        internal TextTreeExtractElementUndoUnit(TextContainer tree, TextTreeTextElementNode elementNode)
            : base(tree, elementNode.GetSymbolOffset(tree.Generation))
        {
            _symbolCount = elementNode.SymbolCount;
            _type        = elementNode.TextElement.GetType();
            _localValues = GetPropertyRecordArray(elementNode.TextElement);
            _resources   = elementNode.TextElement.Resources;

            // Table requires additional work for storing its Columns collection
            if (elementNode.TextElement is Table)
            {
                _columns = TextTreeDeleteContentUndoUnit.SaveColumns((Table)elementNode.TextElement);
            }
        }
        // Copies a TextElement and all its contained content into a ContentContainer.
        // Returns the next node to examine.
        private TextTreeNode CopyElementNode(TextTreeTextElementNode elementNode, out ContentContainer container)
        {
            if (elementNode.TextElement is Table)
            {
                container = new TableElementContentContainer(elementNode.TextElement as Table,
                                                             GetPropertyRecordArray(elementNode.TextElement),
                                                             CopyContent((TextTreeNode)elementNode.GetFirstContainedNode(), null));
            }
            else
            {
                container = new ElementContentContainer(elementNode.TextElement.GetType(),
                                                        GetPropertyRecordArray(elementNode.TextElement),
                                                        elementNode.TextElement.Resources,
                                                        CopyContent((TextTreeNode)elementNode.GetFirstContainedNode(), null));
            }

            return((TextTreeNode)elementNode.GetNextNode());
        }
        // Token: 0x060035C2 RID: 13762 RVA: 0x000F442C File Offset: 0x000F262C
        internal int GetIMECharOffset()
        {
            int           num           = 0;
            SplayTreeNode splayTreeNode = this;

            for (;;)
            {
                splayTreeNode.Splay();
                num          += splayTreeNode.LeftCharCount;
                splayTreeNode = splayTreeNode.ParentNode;
                if (splayTreeNode == null)
                {
                    break;
                }
                TextTreeTextElementNode textTreeTextElementNode = splayTreeNode as TextTreeTextElementNode;
                if (textTreeTextElementNode != null)
                {
                    num += textTreeTextElementNode.IMELeftEdgeCharCount;
                }
            }
            return(num);
        }
 // Token: 0x06003D12 RID: 15634 RVA: 0x0011BA44 File Offset: 0x00119C44
 private TextTreeDeleteContentUndoUnit.ContentContainer CopyContent(TextTreeNode node, TextTreeNode haltNode)
 {
     TextTreeDeleteContentUndoUnit.ContentContainer result           = null;
     TextTreeDeleteContentUndoUnit.ContentContainer contentContainer = null;
     while (node != haltNode && node != null)
     {
         TextTreeTextNode textTreeTextNode = node as TextTreeTextNode;
         TextTreeDeleteContentUndoUnit.ContentContainer contentContainer2;
         if (textTreeTextNode != null)
         {
             node = this.CopyTextNode(textTreeTextNode, haltNode, out contentContainer2);
         }
         else
         {
             TextTreeObjectNode textTreeObjectNode = node as TextTreeObjectNode;
             if (textTreeObjectNode != null)
             {
                 node = this.CopyObjectNode(textTreeObjectNode, out contentContainer2);
             }
             else
             {
                 Invariant.Assert(node is TextTreeTextElementNode, "Unexpected TextTreeNode type!");
                 TextTreeTextElementNode elementNode = (TextTreeTextElementNode)node;
                 node = this.CopyElementNode(elementNode, out contentContainer2);
             }
         }
         if (contentContainer == null)
         {
             result = contentContainer2;
         }
         else
         {
             contentContainer.NextContainer = contentContainer2;
         }
         contentContainer = contentContainer2;
     }
     return(result);
 }
        // Copies a TextElement and all its contained content into a ContentContainer.
        // Returns the next node to examine.
        private TextTreeNode CopyElementNode(TextTreeTextElementNode elementNode, out ContentContainer container)
        {
            if(elementNode.TextElement is Table)
            {
                container = new TableElementContentContainer(elementNode.TextElement as Table,
                                                        GetPropertyRecordArray(elementNode.TextElement),
                                                        CopyContent((TextTreeNode)elementNode.GetFirstContainedNode(), null));

            }
            else
            {
                container = new ElementContentContainer(elementNode.TextElement.GetType(),
                                                        GetPropertyRecordArray(elementNode.TextElement),
                                                        elementNode.TextElement.Resources,
                                                        CopyContent((TextTreeNode)elementNode.GetFirstContainedNode(), null));
            }

            return (TextTreeNode)elementNode.GetNextNode();
        }
Beispiel #12
0
        // Inserts an element node into a sibling tree.  The node is expected to cover existing content.
        // Returns the symbol count of all contained nodes the elementNode covers.
        private int InsertElementToSiblingTreeComplex(TextPointer startPosition, TextPointer endPosition, TextTreeTextElementNode elementNode, 
            out int childCharCount)
        { 
            SplayTreeNode containingNode; 
            SplayTreeNode leftSubTree;
            SplayTreeNode middleSubTree; 
            SplayTreeNode rightSubTree;
            int childSymbolCount;

            containingNode = startPosition.GetScopingNode(); 

            // Rip out all the nodes the new element node is going to contain. 
            childSymbolCount = CutContent(startPosition, endPosition, out childCharCount, out leftSubTree, out middleSubTree, out rightSubTree); 

            // Join left/right trees under elementNode. 
            TextTreeNode.Join(elementNode, leftSubTree, rightSubTree);

            // Reparent middle tree under elementNode.
            elementNode.ContainedNode = middleSubTree; 
            middleSubTree.ParentNode = elementNode;
 
            // Reparent the whole thing under the original container. 
            containingNode.ContainedNode = elementNode;
            elementNode.ParentNode = containingNode; 

            return childSymbolCount;
        }
Beispiel #13
0
        // Adds a TextTreeExtractElementUndoUnit to the open parent undo unit, if any.
        // Called by TextContainer.ExtractElement.
        internal static TextTreeExtractElementUndoUnit CreateExtractElementUndoUnit(TextContainer tree, TextTreeTextElementNode elementNode)
        {
            UndoManager undoManager;
            TextTreeExtractElementUndoUnit undoUnit;

            undoManager = GetOrClearUndoManager(tree);
            if (undoManager == null)
            {
                return(null);
            }

            undoUnit = new TextTreeExtractElementUndoUnit(tree, elementNode);

            undoManager.Add(undoUnit);

            return(undoUnit);
        }
Beispiel #14
0
        // Increments the position reference counts on nodes immediately 
        // preceding and following a delete operation on a single TextElementNode.
        // This is similar to AdjustRefCountsForContentDelete, except that 
        // in this case we deleting a single node, and positions at the
        // BeforeStart/AfterEnd edges may move into contained content, which
        // is still live in the tree.
        // 
        // Whenever we delete a span of content, we have to worry about any
        // positions still referencing the deleted content.  They have enough 
        // information to find their way back to the surrounding nodes, but 
        // we need to increment the ref count on those nodes now so that they'll
        // still be around when the positions need them. 
        //
        // Because incrementing a ref count on a text node edge may involve
        // splitting the text node, this method takes refs to nodes and will
        // update the refs if a node is split. 
        //
        // Called by ExtractElementFromSiblingTree. 
        private void AdjustRefCountsForShallowDelete(ref TextTreeNode previousNode, ElementEdge previousEdge, 
                                                     ref TextTreeNode nextNode,ElementEdge nextEdge,
                                                     ref TextTreeNode firstContainedNode, ref TextTreeNode lastContainedNode, 
                                                     TextTreeTextElementNode extractedElementNode)
        {
            previousNode = previousNode.IncrementReferenceCount(previousEdge, extractedElementNode.AfterStartReferenceCount);
 
            nextNode = nextNode.IncrementReferenceCount(nextEdge, extractedElementNode.BeforeEndReferenceCount);
 
            if (firstContainedNode != null) 
            {
                firstContainedNode = firstContainedNode.IncrementReferenceCount(ElementEdge.BeforeStart, extractedElementNode.BeforeStartReferenceCount); 
            }
            else
            {
                nextNode = nextNode.IncrementReferenceCount(nextEdge, extractedElementNode.BeforeStartReferenceCount); 
            }
 
            if (lastContainedNode != null) 
            {
                lastContainedNode = lastContainedNode.IncrementReferenceCount(ElementEdge.AfterEnd, extractedElementNode.AfterEndReferenceCount); 
            }
            else
            {
                previousNode = previousNode.IncrementReferenceCount(previousEdge, extractedElementNode.AfterEndReferenceCount); 
            }
        } 
Beispiel #15
0
        // Removes an element node from its sibling tree.
        //
        // If deep == true, then this method also removes any contained nodes
        // and returns a deep copy of them. 
        //
        // If deep == false, any contained nodes are inserted into the original 
        // node's sibling tree. 
        private void ExtractElementFromSiblingTree(SplayTreeNode containingNode, TextTreeTextElementNode elementNode, bool deep)
        { 
            TextTreeNode previousNode;
            ElementEdge previousEdge;
            TextTreeNode nextNode;
            ElementEdge nextEdge; 
            SplayTreeNode childNode;
            SplayTreeNode minChildNode; 
            SplayTreeNode maxChildNode; 
            SplayTreeNode localRootNode;
            TextTreeNode firstContainedNode; 
            TextTreeNode lastContainedNode;

            // Remember the nodes surrounding the one we're going to remove.
            previousNode = (TextTreeNode)elementNode.GetPreviousNode(); 
            previousEdge = ElementEdge.AfterEnd;
            if (previousNode == null) 
            { 
                previousNode = (TextTreeNode)containingNode;
                previousEdge = ElementEdge.AfterStart; 
            }
            nextNode = (TextTreeNode)elementNode.GetNextNode();
            nextEdge = ElementEdge.BeforeStart;
            if (nextNode == null) 
            {
                nextNode = (TextTreeNode)containingNode; 
                nextEdge = ElementEdge.BeforeEnd; 
            }
 
            // Remove the element node.
            elementNode.Remove();
            Invariant.Assert(elementNode.Role == SplayTreeNodeRole.LocalRoot);
 
            if (deep)
            { 
                // Increment previous/nextNode reference counts. This may involve 
                // splitting a text node, so we use refs.
                AdjustRefCountsForContentDelete(ref previousNode, previousEdge, ref nextNode, nextEdge, elementNode); 

                // Reparent the removed node with a FixupNode, so that any orphaned
                // positions can find their way back to the tree.
                // We have to do this after the AdjustRefCountsForContentDelete call, because the fixup 
                // node doesn't act like a regular node.
                elementNode.ParentNode = new TextTreeFixupNode(previousNode, previousEdge, nextNode, nextEdge); 
 
                DeepCopy(elementNode);
            } 
            else
            {
                // Reparent contained nodes to elementNode's parent.
                childNode = elementNode.ContainedNode; 
                elementNode.ContainedNode = null;
                if (childNode != null) 
                { 
                    childNode.ParentNode = null;
                    firstContainedNode = (TextTreeNode)childNode.GetMinSibling(); 
                    lastContainedNode = (TextTreeNode)childNode.GetMaxSibling();
                }
                else
                { 
                    firstContainedNode = null;
                    lastContainedNode = null; 
                } 

                // Increment previous/nextNode reference counts. This may involve 
                // splitting a text node, so we use refs.
                AdjustRefCountsForShallowDelete(ref previousNode, previousEdge, ref nextNode, nextEdge, ref firstContainedNode, ref lastContainedNode, elementNode);

                // Reparent the removed node with a FixupNode, so that any orphaned 
                // positions can find their way back to the tree.
                // We have to do this after the AdjustRefCountsForContentDelete call, because the fixup 
                // node doesn't act like a regular node. 
                elementNode.ParentNode = new TextTreeFixupNode(previousNode, previousEdge, nextNode, nextEdge, firstContainedNode, lastContainedNode);
 
                if (childNode != null)
                {
                    // Get previous/next nodes into roots of individual trees.
                    // Then merge them with the element's children. 

                    // We need to splay childNode because it may no longer be a local root. 
                    // The addrefs in AdjustRefCountsForShallowDelete may have created new nodes 
                    // and shuffled the tree.
                    childNode.Splay(); 
                    localRootNode = childNode;

                    if (previousNode != containingNode)
                    { 
                        previousNode.Split();
                        Invariant.Assert(previousNode.Role == SplayTreeNodeRole.LocalRoot); 
                        Invariant.Assert(previousNode.RightChildNode == null); 

                        minChildNode = childNode.GetMinSibling(); 
                        minChildNode.Splay();

                        previousNode.RightChildNode = minChildNode;
                        minChildNode.ParentNode = previousNode; 

                        localRootNode = previousNode; 
                    } 

                    if (nextNode != containingNode) 
                    {
                        nextNode.Splay();
                        Invariant.Assert(nextNode.Role == SplayTreeNodeRole.LocalRoot);
                        Invariant.Assert(nextNode.LeftChildNode == null); 

                        maxChildNode = childNode.GetMaxSibling(); 
                        maxChildNode.Splay(); 

                        nextNode.LeftChildNode = maxChildNode; 
                        nextNode.LeftSymbolCount += maxChildNode.LeftSymbolCount + maxChildNode.SymbolCount;
                        nextNode.LeftCharCount += maxChildNode.LeftCharCount + maxChildNode.IMECharCount;
                        maxChildNode.ParentNode = nextNode;
 
                        localRootNode = nextNode;
                    } 
 
                    containingNode.ContainedNode = localRootNode;
                    if (localRootNode != null) 
                    {
                        localRootNode.ParentNode = containingNode;
                    }
                } 
            }
        } 
Beispiel #16
0
        // Inserts an element node into a sibling tree. 
        // Returns the symbol count of any contained nodes the elementNode covers.
        private int InsertElementToSiblingTree(TextPointer startPosition, TextPointer endPosition, TextTreeTextElementNode elementNode) 
        { 
            int childSymbolCount = 0;
            int childCharCount = 0; 

            if (startPosition.CompareTo(endPosition) == 0)
            {
                // Simple insert, no children for elementNode. 

                // Calculate childCharCount now, before we change position. 
                // IMELeftEdgeCharCount depends on context. 
                int childIMECharCount = elementNode.IMECharCount - elementNode.IMELeftEdgeCharCount;
 
                elementNode.InsertAtPosition(startPosition);
                if (elementNode.ContainedNode != null)
                {
                    childSymbolCount = elementNode.SymbolCount - 2; 
                    childCharCount = childIMECharCount;
                } 
            } 
            else
            { 
                // Complex insert, elementNode is going to have children.
                childSymbolCount = InsertElementToSiblingTreeComplex(startPosition, endPosition, elementNode, out childCharCount);
            }
 
            elementNode.SymbolCount = childSymbolCount + 2;
            elementNode.IMECharCount = childCharCount + elementNode.IMELeftEdgeCharCount; 
 
            return childSymbolCount;
        } 
Beispiel #17
0
        // Returns a copy of elementNode and all its children.  The copy is
        // guaranteed to have no position references. 
        //
        // All TextElements referencing TextTreeTextElementNodes in the copy
        // are adjusted to point to the new copied nodes.
        private TextTreeTextElementNode DeepCopy(TextTreeTextElementNode elementNode) 
        {
            TextTreeTextElementNode clone; 
 
            clone = (TextTreeTextElementNode)elementNode.Clone();
            elementNode.TextElement.TextElementNode = clone; 

            if (elementNode.ContainedNode != null)
            {
                clone.ContainedNode = DeepCopyContainedNodes((TextTreeNode)elementNode.ContainedNode.GetMinSibling()); 
                clone.ContainedNode.ParentNode = clone;
            } 
 
            return clone;
        } 
Beispiel #18
0
        // InsertElement worker.  Adds a TextElement to the tree.
        // If element is already in a tree, we remove it, do a deep copy of its content, 
        // and insert that too.
        internal void InsertElementInternal(TextPointer startPosition, TextPointer endPosition, TextElement element) 
        { 
            TextTreeTextElementNode elementNode;
            int symbolOffset; 
            int childSymbolCount;
            TextPointer startEdgePosition;
            TextPointer endEdgePosition;
            char[] elementText; 
            ExtractChangeEventArgs extractChangeEventArgs;
            DependencyObject parentLogicalNode; 
            bool newElementNode; 
            int deltaCharCount;
 
            Invariant.Assert(!this.PlainTextOnly);
            Invariant.Assert(startPosition.TextContainer == this);
            Invariant.Assert(endPosition.TextContainer == this);
 
            DemandCreateText();
 
            startPosition.SyncToTreeGeneration(); 
            endPosition.SyncToTreeGeneration();
 
            bool scopesExistingContent = startPosition.CompareTo(endPosition) != 0;

            BeforeAddChange();
 
            // Remove element from any previous tree.
            // When called from a public method we already checked all the 
            // illegal cases in CanInsertElementInternal. 
            if (element.TextElementNode != null)
            { 
                // This element is already in a tree.  Remove it!

                bool sameTextContainer = (this == element.TextContainer);
 
                if (!sameTextContainer)
                { 
                    // This is a cross-tree extract. 
                    // We need to start a change block now, so that we can
                    // raise a Changing event inside ExtractElementInternal 
                    // before raising the LogicalTree events below.
                    // We'll make an EndChange call to wrap up below.
                    element.TextContainer.BeginChange();
                } 

                bool exceptionThrown = true; 
                try 
                {
                    // ExtractElementInternal will raise LogicalTree events which 
                    // could raise exceptions from external code.
                    elementText = element.TextContainer.ExtractElementInternal(element, true /* deep */, out extractChangeEventArgs);
                    exceptionThrown = false;
                } 
                finally
                { 
                    if (exceptionThrown && !sameTextContainer) 
                    {
                        // If an exception is thrown, make sure we close the 
                        // change block we opened above before unwinding.
                        element.TextContainer.EndChange();
                    }
                } 

                elementNode = element.TextElementNode; 
                deltaCharCount = extractChangeEventArgs.ChildIMECharCount; 

                if (sameTextContainer) 
                {
                    // Re-[....] the TextPointers in case we just extracted from this tree.
                    startPosition.SyncToTreeGeneration();
                    endPosition.SyncToTreeGeneration(); 

                    // We must add the extract change now, before we move on to the insert. 
                    // (When !sameTextContainer we want to delay the notification in the extract 
                    // tree until the insert tree is in an accessible state, ie at the end of this method.)
                    extractChangeEventArgs.AddChange(); 

                    // Don't re-raise the change below.
                    extractChangeEventArgs = null;
                } 

                newElementNode = false; 
            } 
            else
            { 
                // Allocate a node in the tree to hold the element.
                elementText = null;
                elementNode = new TextTreeTextElementNode();
                deltaCharCount = 0; 
                newElementNode = true;
                extractChangeEventArgs = null; 
            } 

            parentLogicalNode = startPosition.GetLogicalTreeNode(); 

            // Invalidate any TextElementCollection that depends on the parent.
            // Make sure we do that before raising any public events.
            TextElementCollectionHelper.MarkDirty(parentLogicalNode); 

            // Link the TextElement to the TextElementNode. 
            if (newElementNode) 
            {
                elementNode.TextElement = element; 
                element.TextElementNode = (TextTreeTextElementNode)elementNode;
            }

            // If the new element will become the parent of an old element, 
            // the old element may become a firstIMEVisibleSibling.
            TextTreeTextElementNode newFirstIMEVisibleNode = null; 
            int newFirstIMEVisibleNodeCharDelta = 0; 
            if (scopesExistingContent)
            { 
                newFirstIMEVisibleNode = startPosition.GetAdjacentTextElementNodeSibling(LogicalDirection.Forward);
                if (newFirstIMEVisibleNode != null)
                {
                    newFirstIMEVisibleNodeCharDelta = -newFirstIMEVisibleNode.IMELeftEdgeCharCount; 
                    newFirstIMEVisibleNode.IMECharCount += newFirstIMEVisibleNodeCharDelta;
                } 
            } 

            // Attach the element node. 
            childSymbolCount = InsertElementToSiblingTree(startPosition, endPosition, elementNode);

            // Add the edge char count to our delta.  We couldn't get this before
            // because it depends on the position of the element in the tree. 
            deltaCharCount += elementNode.IMELeftEdgeCharCount;
 
            TextTreeTextElementNode formerFirstIMEVisibleNode = null; 
            int formerFirstIMEVisibleNodeCharDelta = 0;
            if (element.IsFirstIMEVisibleSibling && !scopesExistingContent) 
            {
                formerFirstIMEVisibleNode = (TextTreeTextElementNode)elementNode.GetNextNode();
                if (formerFirstIMEVisibleNode != null)
                { 
                    // The following node was the former first ime visible sibling.
                    // It just moved, and gains an edge character. 
                    formerFirstIMEVisibleNodeCharDelta = formerFirstIMEVisibleNode.IMELeftEdgeCharCount; 
                    formerFirstIMEVisibleNode.IMECharCount += formerFirstIMEVisibleNodeCharDelta;
                } 
            }

            // Ancester nodes gain the two edge symbols.
            UpdateContainerSymbolCount(elementNode.GetContainingNode(), /* symbolCount */ elementText == null ? 2 : elementText.Length, deltaCharCount + formerFirstIMEVisibleNodeCharDelta + newFirstIMEVisibleNodeCharDelta); 

            symbolOffset = elementNode.GetSymbolOffset(this.Generation); 
 
            if (newElementNode)
            { 
                // Insert text to account for the element edges.
                TextTreeText.InsertElementEdges(_rootNode.RootTextBlock, symbolOffset, childSymbolCount);
            }
            else 
            {
                // element already has an existing child, just copy over the corresponding text. 
                TextTreeText.InsertText(_rootNode.RootTextBlock, symbolOffset, elementText); 
            }
 
            NextGeneration(false /* deletedContent */);

            // Handle undo.
            TextTreeUndo.CreateInsertElementUndoUnit(this, symbolOffset, elementText != null /* deep */); 

            // If we extracted the TextElement from another tree, raise that event now. 
            // We can't raise this event any earlier, because prior to now _this_ tree 
            // is in an invalid state and this tree could be referenced by a listener
            // to changes on the other tree. 
            if (extractChangeEventArgs != null)
            {
                // Announce the extract from the old tree.
                // NB: we already Removed the element from the original logical tree with LogicalTreeHelper, 
                // and did a BeginChange above.
                extractChangeEventArgs.AddChange(); 
                extractChangeEventArgs.TextContainer.EndChange(); 
            }
 
            // Raise the public event for the insert into this tree.
            // During document load we won't have listeners and we can save
            // an allocation on every insert.  This can easily save 1000's of allocations during boot.
            if (this.HasListeners) 
            {
                // 
                startEdgePosition = new TextPointer(this, elementNode, ElementEdge.BeforeStart); 

                if (childSymbolCount == 0 || elementText != null) 
                {
                    AddChange(startEdgePosition, elementText == null ? 2 : elementText.Length, deltaCharCount, PrecursorTextChangeType.ContentAdded);
                }
                else 
                {
                    endEdgePosition = new TextPointer(this, elementNode, ElementEdge.BeforeEnd); 
 
                    AddChange(startEdgePosition, endEdgePosition, elementNode.SymbolCount,
                              elementNode.IMELeftEdgeCharCount, elementNode.IMECharCount - elementNode.IMELeftEdgeCharCount, 
                              PrecursorTextChangeType.ElementAdded, null, false);
                }

                if (formerFirstIMEVisibleNodeCharDelta != 0) 
                {
                    RaiseEventForFormerFirstIMEVisibleNode(formerFirstIMEVisibleNode); 
                } 

                if (newFirstIMEVisibleNodeCharDelta != 0) 
                {
                    RaiseEventForNewFirstIMEVisibleNode(newFirstIMEVisibleNode);
                }
            } 

            // Insert the element into a Framework logical tree 
            element.BeforeLogicalTreeChange(); 
            try
            { 
                LogicalTreeHelper.AddLogicalChild(parentLogicalNode, element);
            }
            finally
            { 
                element.AfterLogicalTreeChange();
            } 
 
            // Reparent all children.
            // We only need to do this if we created a new element node. 
            if (newElementNode)
            {
                ReparentLogicalChildren(elementNode, elementNode.TextElement, parentLogicalNode /* oldParent */);
            } 

            // Notify the TextElement of a content change if it was moved to parent new content. This 
            // can happen when Runs get merged. 
            if (scopesExistingContent)
            { 
                element.OnTextUpdated();
            }
        }
Beispiel #19
0
            //------------------------------------------------------
            // 
            //  Constructors
            //
            //-----------------------------------------------------
 
            #region Constructors
 
            // Creates a new instance. 
            internal ExtractChangeEventArgs(TextContainer textTree, TextPointer startPosition, TextTreeTextElementNode node,
                TextTreeTextElementNode newFirstIMEVisibleNode, TextTreeTextElementNode formerFirstIMEVisibleNode, int charCount, int childCharCount) 
            {
                _textTree = textTree;
                _startPosition = startPosition;
                _symbolCount = node.SymbolCount; 
                _charCount = charCount;
                _childCharCount = childCharCount; 
                _newFirstIMEVisibleNode = newFirstIMEVisibleNode; 
                _formerFirstIMEVisibleNode = formerFirstIMEVisibleNode;
            } 
        // Adds a TextTreeExtractElementUndoUnit to the open parent undo unit, if any.
        // Called by TextContainer.ExtractElement.
        internal static TextTreeExtractElementUndoUnit CreateExtractElementUndoUnit(TextContainer tree, TextTreeTextElementNode elementNode)
        {
            UndoManager undoManager;
            TextTreeExtractElementUndoUnit undoUnit;

            undoManager = GetOrClearUndoManager(tree);
            if (undoManager == null)
                return null;

            undoUnit = new TextTreeExtractElementUndoUnit(tree, elementNode);

            undoManager.Add(undoUnit);

            return undoUnit;
        }
        // Token: 0x06003E2D RID: 15917 RVA: 0x0011D670 File Offset: 0x0011B870
        internal static TextTreeExtractElementUndoUnit CreateExtractElementUndoUnit(TextContainer tree, TextTreeTextElementNode elementNode)
        {
            UndoManager orClearUndoManager = TextTreeUndo.GetOrClearUndoManager(tree);

            if (orClearUndoManager == null)
            {
                return(null);
            }
            TextTreeExtractElementUndoUnit textTreeExtractElementUndoUnit = new TextTreeExtractElementUndoUnit(tree, elementNode);

            orClearUndoManager.Add(textTreeExtractElementUndoUnit);
            return(textTreeExtractElementUndoUnit);
        }