Exemplo n.º 1
0
 // Token: 0x06002BD1 RID: 11217 RVA: 0x000C7918 File Offset: 0x000C5B18
 private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange)
 {
     Invariant.Assert(!this._isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!");
     ((ITextContainer)this).BeginChange();
     try
     {
         if (this.Changing != null)
         {
             this.Changing(this, EventArgs.Empty);
         }
         if (this._changes == null)
         {
             this._changes = new TextContainerChangedEventArgs();
         }
         this._changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(this._start, startPosition), symbolCount, false);
         if (this.Change != null)
         {
             Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved);
             TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved;
             this._isReadOnly = true;
             try
             {
                 this.Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange));
             }
             finally
             {
                 this._isReadOnly = false;
             }
         }
     }
     finally
     {
         ((ITextContainer)this).EndChange();
     }
 }
 // Token: 0x060037B5 RID: 14261 RVA: 0x000F8C68 File Offset: 0x000F6E68
 internal void AddChange(PrecursorTextChangeType textChange, int offset, int length, bool collectTextChanges)
 {
     if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded || textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted)
     {
         this._hasContentAddedOrRemoved = true;
     }
     if (!collectTextChanges)
     {
         return;
     }
     if (textChange == PrecursorTextChangeType.ElementAdded)
     {
         this.AddChangeToList(textChange, offset, 1);
         this.AddChangeToList(textChange, offset + length - 1, 1);
         return;
     }
     if (textChange == PrecursorTextChangeType.ElementExtracted)
     {
         this.AddChangeToList(textChange, offset + length - 1, 1);
         this.AddChangeToList(textChange, offset, 1);
         return;
     }
     if (textChange == PrecursorTextChangeType.PropertyModified)
     {
         return;
     }
     this.AddChangeToList(textChange, offset, length);
 }
Exemplo n.º 3
0
 // Token: 0x0600539A RID: 21402 RVA: 0x00173170 File Offset: 0x00171370
 private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange)
 {
     Invariant.Assert(this._changeBlockLevel > 0, "All public APIs must call BeginChange!");
     Invariant.Assert(!this._isReadOnly, "Illegal to modify PasswordTextContainer inside Change event scope!");
     if (this.Changing != null)
     {
         this.Changing(this, EventArgs.Empty);
     }
     if (this._changes == null)
     {
         this._changes = new TextContainerChangedEventArgs();
     }
     this._changes.AddChange(precursorTextChange, startPosition.Offset, symbolCount, false);
     if (this.Change != null)
     {
         Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved);
         TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved;
         this._isReadOnly = true;
         try
         {
             this.Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, symbolCount, textChange));
         }
         finally
         {
             this._isReadOnly = false;
         }
     }
 }
        private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange)
        {
            Invariant.Assert(!_isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!");

            ITextContainer textContainer = (ITextContainer)this;

            textContainer.BeginChange();
            try
            {
                // Contact any listeners.
                if (this.Changing != null)
                {
                    Changing(this, EventArgs.Empty);
                }

                // Fire the ChangingEvent now if we haven't already.
                if (_changes == null)
                {
                    _changes = new TextContainerChangedEventArgs();
                }

                _changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(_start, startPosition), symbolCount, false /* collectTextChanges */);

                if (this.Change != null)
                {
                    Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved);
                    TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ?
                                                TextChangeType.ContentAdded : TextChangeType.ContentRemoved;

                    _isReadOnly = true;
                    try
                    {
                        // Pass in a -1 for charCount parameter.  DocumentSequenceTextContainer
                        // doesn't support this feature because it is only consumed by IMEs
                        // which never run on read-only documents.
                        Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange));
                    }
                    finally
                    {
                        _isReadOnly = false;
                    }
                }
            }
            finally
            {
                textContainer.EndChange();
            }
        }
        // Adds a new change to the Delta list.
        internal void AddChange(PrecursorTextChangeType textChange, int offset, int length, bool collectTextChanges)
        {
            if (textChange == PrecursorTextChangeType.ContentAdded || 
                textChange == PrecursorTextChangeType.ElementAdded ||
                textChange == PrecursorTextChangeType.ContentRemoved || 
                textChange == PrecursorTextChangeType.ElementExtracted) 
            {
                _hasContentAddedOrRemoved = true; 
            }

            if (!collectTextChanges)
            { 
                return;
            } 
 
            // We only want to add or remove the edges for empty elements (and ElementAdded /
            // ElementRemoved are only used with empty elements).  Note that since we're making 
            // two changes instead of one the order matters.  We have to treat the two cases differently.
            if (textChange == PrecursorTextChangeType.ElementAdded)
            {
                AddChangeToList(textChange, offset, 1); 
                AddChangeToList(textChange, offset + length - 1, 1);
            } 
            else if (textChange == PrecursorTextChangeType.ElementExtracted) 
            {
                AddChangeToList(textChange, offset + length - 1, 1); 
                AddChangeToList(textChange, offset, 1);
            }
            else if (textChange == PrecursorTextChangeType.PropertyModified)
            { 
                // ignore property changes
                return; 
            } 
            else
            { 
                AddChangeToList(textChange, offset, length);
            }
        }
        // Adds a new change to the Delta list.
        internal void AddChange(PrecursorTextChangeType textChange, int offset, int length, bool collectTextChanges)
        {
            if (textChange == PrecursorTextChangeType.ContentAdded ||
                textChange == PrecursorTextChangeType.ElementAdded ||
                textChange == PrecursorTextChangeType.ContentRemoved ||
                textChange == PrecursorTextChangeType.ElementExtracted)
            {
                _hasContentAddedOrRemoved = true;
            }

            if (!collectTextChanges)
            {
                return;
            }

            // We only want to add or remove the edges for empty elements (and ElementAdded /
            // ElementRemoved are only used with empty elements).  Note that since we're making
            // two changes instead of one the order matters.  We have to treat the two cases differently.
            if (textChange == PrecursorTextChangeType.ElementAdded)
            {
                AddChangeToList(textChange, offset, 1);
                AddChangeToList(textChange, offset + length - 1, 1);
            }
            else if (textChange == PrecursorTextChangeType.ElementExtracted)
            {
                AddChangeToList(textChange, offset + length - 1, 1);
                AddChangeToList(textChange, offset, 1);
            }
            else if (textChange == PrecursorTextChangeType.PropertyModified)
            {
                // ignore property changes
                return;
            }
            else
            {
                AddChangeToList(textChange, offset, length);
            }
        }
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange)
        {
            Invariant.Assert(_changeBlockLevel > 0, "All public APIs must call BeginChange!");
            Invariant.Assert(!_isReadOnly, "Illegal to modify PasswordTextContainer inside Change event scope!");

            // Contact any listeners.
            if (this.Changing != null)
            {
                Changing(this, EventArgs.Empty);
            }

            // Fire the ChangingEvent now if we haven't already.
            if (_changes == null)
            {
                _changes = new TextContainerChangedEventArgs();
            }

            _changes.AddChange(precursorTextChange, startPosition.Offset, symbolCount, false /* collectTextChanges */);

            if (this.Change != null)
            {
                Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved);
                TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ?
                                            TextChangeType.ContentAdded : TextChangeType.ContentRemoved;

                _isReadOnly = true;
                try
                {
                    Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, symbolCount, textChange));
                }
                finally
                {
                    _isReadOnly = false;
                }
            }
        }
        //-----------------------------------------------------
        // 
        //  Private Methods
        //
        //------------------------------------------------------
 
        //
        // First we discover where the new change goes in the sorted list.  If there's already 
        // a change there, merge the new one with the old one. 
        //
        // Next, if the new change is an insertion or deletion, see if the offset of the change 
        // is within a range covered by an insertion at a lower offset.  If so, merge the change at
        // the higher offset into the previous change and delete the change at the higher offset.
        //
        // Next, if the change is a deletion, see if we delete enough characters to run into a 
        // change at a higher offset.  If so, merge the change at the higher offset into this newer
        // change and delete the older, higher-offset change. 
        // 
        // Finally, update all offsets higher than the current change to reflect the number of
        // characters inserted or deleted. 
        //
        private void AddChangeToList(PrecursorTextChangeType textChange, int offset, int length)
        {
            int offsetDelta = 0; // Value by which to adjust other offsets in list 
            int curIndex;        // loop counter
            TextChange change = null; // initialize to satisfy compiler 
            bool isDeletion = false; 
#if PROPERTY_CHANGES
            bool shiftPropertyChanges = false; 
#endif

            //
            // Is there already a change at this offset in our list?  If so, use it 
            //
            int keyIndex = Changes.IndexOfKey(offset); 
            if (keyIndex != -1) 
            {
                change = Changes.Values[keyIndex]; 
            }
            else
            {
                change = new TextChange(); 
                change.Offset = offset;
                Changes.Add(offset, change); 
                keyIndex = Changes.IndexOfKey(offset); 
            }
 
            //
            // Merge values from new change into empty or pre-existing change
            //
            if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded) 
            {
                change.AddedLength += length; 
                offsetDelta = length; 
#if PROPERTY_CHANGES
                if (change.PropertyCount > 0) 
                {
                    shiftPropertyChanges = true;
                }
#endif 
            }
            else if (textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) 
            { 
                // Any deletions made after an addition just cancel out the earlier addition
                change.RemovedLength += Math.Max(0, length - change.AddedLength); 
                change.AddedLength = Math.Max(0, change.AddedLength - length);

#if PROPERTY_CHANGES
                // If an element was extracted, any property change made on that element should be removed as well 
                if (textChange == PrecursorTextChangeType.ElementExtracted)
                { 
                    change.SetPropertyCount(0); 
                }
                else 
                {
                    change.SetPropertyCount(Math.Max(0, change.PropertyCount - length));
                }
#endif 

                offsetDelta = -length; 
                isDeletion = true; 
            }
#if PROPERTY_CHANGES 
            else
            {
                // Property change
                if (change.PropertyCount < length) 
                {
                    change.SetPropertyCount(length); 
                } 
            }
#endif 

            //
            // Done with simple case.  Now look for changes that intersect.
            // There are two possible (non-exclusive) merge conditions: 
            //   1. A positionally preceding change spans this offset (this change is inserting
            //        into or deleting from the middle or right edge of previous inserted text) 
            //   2. On deletion, the change spans one or more positionally later changes 
            //
            if (keyIndex > 0 && textChange != PrecursorTextChangeType.PropertyModified) 
            {
                curIndex = keyIndex - 1;
                // Since we don't merge property changes, there could be an arbitrary number of
                // them between the new change and an overlapping insertion or overlapping property 
                // change.  In fact, there could be multiple property changes that overlap this
                // change.  We need to adjust ALL of them.  There can be only one overlapping 
                // insertion, but there's no way to leverage that fact. 
                TextChange mergedChange = null;
                while (curIndex >= 0) 
                {
                    TextChange prevChange = Changes.Values[curIndex];
#if PROPERTY_CHANGES
                    if (prevChange.Offset + prevChange.AddedLength >= offset || prevChange.Offset + prevChange.PropertyCount >= offset) 
#else
                    if (prevChange.Offset + prevChange.AddedLength >= offset) 
#endif 
                    {
                        if (MergeTextChangeLeft(prevChange, change, isDeletion, length)) 
                        {
                            mergedChange = prevChange;
                        }
                    } 
                    curIndex--;
                } 
                if (mergedChange != null) 
                {
                    // the change got merged.  Use the merged change as the basis for righthand merging. 
                    change = mergedChange;
                }
                // changes may have been deleted, so update the index of the change we're working with
                keyIndex = Changes.IndexOfKey(change.Offset); 
            }
 
            curIndex = keyIndex + 1; 
            if (isDeletion && curIndex < Changes.Count)
            { 
                while (curIndex < Changes.Count && Changes.Values[curIndex].Offset <= offset + length)
                {
                    // offset and length must be passed because if we've also merged left, we haven't yet adjusted indices.
                    // Note that MergeTextChangeRight() always removes Changes.Values[curIndex] from the list, so 
                    // we don't need to increment curIndex.
                    MergeTextChangeRight(Changes.Values[curIndex], change, offset, length); 
                } 
                // changes may have been deleted, so update the index of the change we're working with
                keyIndex = Changes.IndexOfKey(change.Offset); 
            }

            // Update all changes to reflect new offsets.
            // If offsetDelta is positive, go right to left; otherwise, go left to right. 
            // The order of the offsets will never change, so we can use an indexer safely.
            // To avoid nasty N-squared perf, create a new list instead of moving things within 
            // the old one. 
            //
            if (offsetDelta != 0) 
            {
                SortedList<int, TextChange> newChanges = new SortedList<int, TextChange>(Changes.Count);
                for (curIndex = 0; curIndex < Changes.Count; curIndex++)
                { 
                    TextChange curChange = Changes.Values[curIndex];
                    if (curIndex > keyIndex) 
                    { 
                        curChange.Offset += offsetDelta;
                    } 
                    newChanges.Add(curChange.Offset, curChange);
                }
                _changes = newChanges;
 
            }
 
            DeleteChangeIfEmpty(change); 

#if PROPERTY_CHANGES 
            // Finally, if the change was an insertion and there are property changes starting
            // at this location, the insertion is not part of the property changes.  Shift the
            // property changes forward by the length of the insertion.
            if (shiftPropertyChanges) 
            {
                int propertyCount = change.PropertyCount; 
                change.SetPropertyCount(0); 
                AddChangeToList(PrecursorTextChangeType.PropertyModified, offset + offsetDelta, propertyCount);
            } 
#endif
        }
Exemplo n.º 9
0
        //-----------------------------------------------------
        //
        //  Private Methods 
        //
        //----------------------------------------------------- 
 
        #region Private Methods
 
        private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange)
        {
            Invariant.Assert(_changeBlockLevel > 0, "All public APIs must call BeginChange!");
            Invariant.Assert(!_isReadOnly, "Illegal to modify PasswordTextContainer inside Change event scope!"); 

            // Contact any listeners. 
            if (this.Changing != null) 
            {
                Changing(this, EventArgs.Empty); 
            }

            // Fire the ChangingEvent now if we haven't already.
            if (_changes == null) 
            {
                _changes = new TextContainerChangedEventArgs(); 
            } 

            _changes.AddChange(precursorTextChange, startPosition.Offset, symbolCount, false /* collectTextChanges */); 

            if (this.Change != null)
            {
                Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); 
                TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ?
                    TextChangeType.ContentAdded : TextChangeType.ContentRemoved; 
 
                _isReadOnly = true;
                try 
                {
                    Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, symbolCount, textChange));
                }
                finally 
                {
                    _isReadOnly = false; 
                } 
            }
        } 
Exemplo n.º 10
0
 // Returns the TextChange matching an ContentAdded, ContentRemoved, 
 // or PropertyModified PrecursorTextChange.
 private TextChangeType ConvertSimplePrecursorChangeToTextChange(PrecursorTextChangeType precursorTextChange)
 {
     Invariant.Assert(precursorTextChange != PrecursorTextChangeType.ElementAdded && precursorTextChange != PrecursorTextChangeType.ElementExtracted); 
     return (TextChangeType)precursorTextChange;
 } 
        private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) 
        {
            Invariant.Assert(!_isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!");

            ITextContainer textContainer = (ITextContainer)this; 
            textContainer.BeginChange();
            try 
            { 
                // Contact any listeners.
                if (this.Changing != null) 
                {
                    Changing(this, EventArgs.Empty);
                }
 
                // Fire the ChangingEvent now if we haven't already.
                if (_changes == null) 
                { 
                    _changes = new TextContainerChangedEventArgs();
                } 

                _changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(_start, startPosition), symbolCount, false /* collectTextChanges */);

                if (this.Change != null) 
                {
                    Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); 
                    TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? 
                        TextChangeType.ContentAdded : TextChangeType.ContentRemoved;
 
                    _isReadOnly = true;
                    try
                    {
                        // Pass in a -1 for charCount parameter.  DocumentSequenceTextContainer 
                        // doesn't support this feature because it is only consumed by IMEs
                        // which never run on read-only documents. 
                        Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange)); 
                    }
                    finally 
                    {
                        _isReadOnly = false;
                    }
                } 
            }
            finally 
            { 
                textContainer.EndChange();
            } 
        }
Exemplo n.º 12
0
 // Adds a change to the current change block. 
 // This call must be preceeded by a matching BeforeAddChange. 
 internal void AddChange(TextPointer startPosition, int symbolCount, int charCount, PrecursorTextChangeType textChange)
 { 
     AddChange(startPosition, symbolCount, charCount, textChange, null, false);
 }
Exemplo n.º 13
0
        // Adds a change to the current change block. 
        // This call must be preceeded by a matching BeforeAddChange.
        internal void AddChange(TextPointer startPosition, int symbolCount, int charCount, PrecursorTextChangeType textChange, DependencyProperty property, bool affectsRenderOnly) 
        { 
            Invariant.Assert(textChange != PrecursorTextChangeType.ElementAdded &&
                             textChange != PrecursorTextChangeType.ElementExtracted, 
                             "Need second TextPointer for ElementAdded/Extracted operations!");

            AddChange(startPosition, null, symbolCount, /* leftEdgeCharCount */ 0, charCount, textChange, property, affectsRenderOnly);
        } 
Exemplo n.º 14
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        //
        // First we discover where the new change goes in the sorted list.  If there's already
        // a change there, merge the new one with the old one.
        //
        // Next, if the new change is an insertion or deletion, see if the offset of the change
        // is within a range covered by an insertion at a lower offset.  If so, merge the change at
        // the higher offset into the previous change and delete the change at the higher offset.
        //
        // Next, if the change is a deletion, see if we delete enough characters to run into a
        // change at a higher offset.  If so, merge the change at the higher offset into this newer
        // change and delete the older, higher-offset change.
        //
        // Finally, update all offsets higher than the current change to reflect the number of
        // characters inserted or deleted.
        //
        private void AddChangeToList(PrecursorTextChangeType textChange, int offset, int length)
        {
            int        offsetDelta = 0;   // Value by which to adjust other offsets in list
            int        curIndex;          // loop counter
            TextChange change     = null; // initialize to satisfy compiler
            bool       isDeletion = false;

#if PROPERTY_CHANGES
            bool shiftPropertyChanges = false;
#endif

            //
            // Is there already a change at this offset in our list?  If so, use it
            //
            int keyIndex = Changes.IndexOfKey(offset);
            if (keyIndex != -1)
            {
                change = Changes.Values[keyIndex];
            }
            else
            {
                change        = new TextChange();
                change.Offset = offset;
                Changes.Add(offset, change);
                keyIndex = Changes.IndexOfKey(offset);
            }

            //
            // Merge values from new change into empty or pre-existing change
            //
            if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded)
            {
                change.AddedLength += length;
                offsetDelta         = length;
#if PROPERTY_CHANGES
                if (change.PropertyCount > 0)
                {
                    shiftPropertyChanges = true;
                }
#endif
            }
            else if (textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted)
            {
                // Any deletions made after an addition just cancel out the earlier addition
                change.RemovedLength += Math.Max(0, length - change.AddedLength);
                change.AddedLength    = Math.Max(0, change.AddedLength - length);

#if PROPERTY_CHANGES
                // If an element was extracted, any property change made on that element should be removed as well
                if (textChange == PrecursorTextChangeType.ElementExtracted)
                {
                    change.SetPropertyCount(0);
                }
                else
                {
                    change.SetPropertyCount(Math.Max(0, change.PropertyCount - length));
                }
#endif

                offsetDelta = -length;
                isDeletion  = true;
            }
#if PROPERTY_CHANGES
            else
            {
                // Property change
                if (change.PropertyCount < length)
                {
                    change.SetPropertyCount(length);
                }
            }
#endif

            //
            // Done with simple case.  Now look for changes that intersect.
            // There are two possible (non-exclusive) merge conditions:
            //   1. A positionally preceding change spans this offset (this change is inserting
            //        into or deleting from the middle or right edge of previous inserted text)
            //   2. On deletion, the change spans one or more positionally later changes
            //
            if (keyIndex > 0 && textChange != PrecursorTextChangeType.PropertyModified)
            {
                curIndex = keyIndex - 1;
                // Since we don't merge property changes, there could be an arbitrary number of
                // them between the new change and an overlapping insertion or overlapping property
                // change.  In fact, there could be multiple property changes that overlap this
                // change.  We need to adjust ALL of them.  There can be only one overlapping
                // insertion, but there's no way to leverage that fact.
                TextChange mergedChange = null;
                while (curIndex >= 0)
                {
                    TextChange prevChange = Changes.Values[curIndex];
#if PROPERTY_CHANGES
                    if (prevChange.Offset + prevChange.AddedLength >= offset || prevChange.Offset + prevChange.PropertyCount >= offset)
#else
                    if (prevChange.Offset + prevChange.AddedLength >= offset)
#endif
                    {
                        if (MergeTextChangeLeft(prevChange, change, isDeletion, length))
                        {
                            mergedChange = prevChange;
                        }
                    }
                    curIndex--;
                }
                if (mergedChange != null)
                {
                    // the change got merged.  Use the merged change as the basis for righthand merging.
                    change = mergedChange;
                }
                // changes may have been deleted, so update the index of the change we're working with
                keyIndex = Changes.IndexOfKey(change.Offset);
            }

            curIndex = keyIndex + 1;
            if (isDeletion && curIndex < Changes.Count)
            {
                while (curIndex < Changes.Count && Changes.Values[curIndex].Offset <= offset + length)
                {
                    // offset and length must be passed because if we've also merged left, we haven't yet adjusted indices.
                    // Note that MergeTextChangeRight() always removes Changes.Values[curIndex] from the list, so
                    // we don't need to increment curIndex.
                    MergeTextChangeRight(Changes.Values[curIndex], change, offset, length);
                }
                // changes may have been deleted, so update the index of the change we're working with
                keyIndex = Changes.IndexOfKey(change.Offset);
            }

            // Update all changes to reflect new offsets.
            // If offsetDelta is positive, go right to left; otherwise, go left to right.
            // The order of the offsets will never change, so we can use an indexer safely.
            // To avoid nasty N-squared perf, create a new list instead of moving things within
            // the old one.
            // Change the implementation of Changes to a more efficient structure.
            if (offsetDelta != 0)
            {
                SortedList <int, TextChange> newChanges = new SortedList <int, TextChange>(Changes.Count);
                for (curIndex = 0; curIndex < Changes.Count; curIndex++)
                {
                    TextChange curChange = Changes.Values[curIndex];
                    if (curIndex > keyIndex)
                    {
                        curChange.Offset += offsetDelta;
                    }
                    newChanges.Add(curChange.Offset, curChange);
                }
                _changes = newChanges;
            }

            DeleteChangeIfEmpty(change);

#if PROPERTY_CHANGES
            // Finally, if the change was an insertion and there are property changes starting
            // at this location, the insertion is not part of the property changes.  Shift the
            // property changes forward by the length of the insertion.
            if (shiftPropertyChanges)
            {
                int propertyCount = change.PropertyCount;
                change.SetPropertyCount(0);
                AddChangeToList(PrecursorTextChangeType.PropertyModified, offset + offsetDelta, propertyCount);
            }
#endif
        }
Exemplo n.º 15
0
        // Adds a change to the current change block. 
        // This call must be preceeded by a matching BeforeAddChange. 
        internal void AddChange(TextPointer startPosition, TextPointer endPosition,
                                int symbolCount, int leftEdgeCharCount, int childCharCount, 
                                PrecursorTextChangeType textChange, DependencyProperty property, bool affectsRenderOnly)
        {
            Invariant.Assert(_changeBlockLevel > 0, "All public APIs must call BeginChange!");
            Invariant.Assert(!CheckFlags(Flags.ReadOnly) || 
                             textChange == PrecursorTextChangeType.PropertyModified,
                             "Illegal to modify TextContainer structure inside Change event scope!"); 
 
            if (this.HasListeners)
            { 
                // Lazy init _changes.  This looks redundant with the BeforeAddChange call
                // we already require -- strictly speaking that's true.  But in practice,
                // we want the Invariant in this method to remind callers to think about
                // when they must call BeforeAddChange ahead of logical tree events.  Then, 
                // in practice, there's a subtle bug where a listener might not initially
                // exist but is added during the logical tree events.  That we handle 
                // here with an additional BeforeAddChange call instead of requiring all 
                // our callers to remember to handle the more subtle case.
                if (_changes == null) 
                {
                    _changes = new TextContainerChangedEventArgs();
                }
 
                Invariant.Assert(_changes != null, "Missing call to BeforeAddChange!");
                _changes.AddChange(textChange, startPosition.Offset, symbolCount, this.CollectTextChanges); 
                if (this.ChangeHandler != null) 
                {
                    FireChangeEvent(startPosition, endPosition, symbolCount, leftEdgeCharCount, childCharCount, textChange, property, affectsRenderOnly); 
                }
            }
        }
Exemplo n.º 16
0
        // Worker for AddChange, fires a Change event. 
        private void FireChangeEvent(TextPointer startPosition, TextPointer endPosition, int symbolCount,
                                     int leftEdgeCharCount, int childCharCount, 
                                     PrecursorTextChangeType precursorTextChange, DependencyProperty property, bool affectsRenderOnly)
        {
            Invariant.Assert(this.ChangeHandler != null);
 
            // Set a flag to disallow reentrant edits.  We really can't support
            // that here, because any edits to the document would break the 
            // BeginChange/EndChange contract (no edits by listeners in a change 
            // block!).
            // (Note, we will allow re-entrant property changes only, because 
            // property change events are not exposed publicly on TextBox or RTB.)
            SetFlags(true, Flags.ReadOnly);

            try 
            {
                if (precursorTextChange == PrecursorTextChangeType.ElementAdded) 
                { 
                    Invariant.Assert(symbolCount > 2, "ElementAdded must span at least two element edges and one content symbol!");
 
                    TextContainerChangeEventArgs args1 = new TextContainerChangeEventArgs(startPosition, 1, leftEdgeCharCount, TextChangeType.ContentAdded);
                    TextContainerChangeEventArgs args2 = new TextContainerChangeEventArgs(endPosition, 1, 0, TextChangeType.ContentAdded);
                    ChangeHandler(this, args1);
                    ChangeHandler(this, args2); 
                }
                else if (precursorTextChange == PrecursorTextChangeType.ElementExtracted) 
                { 
                    Invariant.Assert(symbolCount > 2, "ElementExtracted must span at least two element edges and one content symbol!");
 
                    TextContainerChangeEventArgs args1 = new TextContainerChangeEventArgs(startPosition, 1, leftEdgeCharCount, TextChangeType.ContentRemoved);
                    TextContainerChangeEventArgs args2 = new TextContainerChangeEventArgs(endPosition, 1, 0, TextChangeType.ContentRemoved);
                    ChangeHandler(this, args1);
                    ChangeHandler(this, args2); 
                }
                else 
                { 
                    TextContainerChangeEventArgs args = new TextContainerChangeEventArgs(startPosition, symbolCount, leftEdgeCharCount + childCharCount, ConvertSimplePrecursorChangeToTextChange(precursorTextChange), property, affectsRenderOnly);
                    ChangeHandler(this, args); 
                }
            }
            finally
            { 
                SetFlags(false, Flags.ReadOnly);
            } 
        } 
        // Token: 0x060037B9 RID: 14265 RVA: 0x000F8CEC File Offset: 0x000F6EEC
        private void AddChangeToList(PrecursorTextChangeType textChange, int offset, int length)
        {
            int        num  = 0;
            bool       flag = false;
            int        num2 = this.Changes.IndexOfKey(offset);
            TextChange textChange2;

            if (num2 != -1)
            {
                textChange2 = this.Changes.Values[num2];
            }
            else
            {
                textChange2        = new TextChange();
                textChange2.Offset = offset;
                this.Changes.Add(offset, textChange2);
                num2 = this.Changes.IndexOfKey(offset);
            }
            if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded)
            {
                textChange2.AddedLength += length;
                num = length;
            }
            else if (textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted)
            {
                textChange2.RemovedLength += Math.Max(0, length - textChange2.AddedLength);
                textChange2.AddedLength    = Math.Max(0, textChange2.AddedLength - length);
                num  = -length;
                flag = true;
            }
            int i;

            if (num2 > 0 && textChange != PrecursorTextChangeType.PropertyModified)
            {
                i = num2 - 1;
                TextChange textChange3 = null;
                while (i >= 0)
                {
                    TextChange textChange4 = this.Changes.Values[i];
                    if (textChange4.Offset + textChange4.AddedLength >= offset && this.MergeTextChangeLeft(textChange4, textChange2, flag, length))
                    {
                        textChange3 = textChange4;
                    }
                    i--;
                }
                if (textChange3 != null)
                {
                    textChange2 = textChange3;
                }
                num2 = this.Changes.IndexOfKey(textChange2.Offset);
            }
            i = num2 + 1;
            if (flag && i < this.Changes.Count)
            {
                while (i < this.Changes.Count && this.Changes.Values[i].Offset <= offset + length)
                {
                    this.MergeTextChangeRight(this.Changes.Values[i], textChange2, offset, length);
                }
                num2 = this.Changes.IndexOfKey(textChange2.Offset);
            }
            if (num != 0)
            {
                SortedList <int, TextChange> sortedList = new SortedList <int, TextChange>(this.Changes.Count);
                for (i = 0; i < this.Changes.Count; i++)
                {
                    TextChange textChange5 = this.Changes.Values[i];
                    if (i > num2)
                    {
                        textChange5.Offset += num;
                    }
                    sortedList.Add(textChange5.Offset, textChange5);
                }
                this._changes = sortedList;
            }
            this.DeleteChangeIfEmpty(textChange2);
        }