Beispiel #1
0
 internal void Delete(ref DeferredEventList deferredEventList)
 {
     // we cannot fire an event here because this method is called while the LineManager adjusts the
     // lineCollection, so an event handler could see inconsistent state
     _lineSegment = null;
     deferredEventList.AddDeletedAnchor(this);
 }
Beispiel #2
0
        /// <summary>
        /// Replaces the specified offset.
        /// </summary>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="text">The text.</param>
        public void Replace(int offset, int length, string text)
        {
            int lineStart        = GetLineNumberForOffset(offset);
            int oldNumberOfLines = TotalNumberOfLines;
            DeferredEventList deferredEventList = new DeferredEventList();

            RemoveInternal(ref deferredEventList, offset, length);
            int numberOfLinesAfterRemoving = TotalNumberOfLines;

            if (!string.IsNullOrEmpty(text))
            {
                InsertInternal(offset, text);
            }
            // Only fire events after RemoveInternal+InsertInternal finished completely:
            // Otherwise we would expose inconsistent state to the event handlers.
            RunHighlighter(lineStart, 1 + Math.Max(0, TotalNumberOfLines - numberOfLinesAfterRemoving));

            if (deferredEventList.RemovedLines != null)
            {
                foreach (LineSegment ls in deferredEventList.RemovedLines)
                {
                    OnLineDeleted(new LineEventArgs(_document, ls));
                }
            }
            deferredEventList.RaiseEvents();
            if (TotalNumberOfLines != oldNumberOfLines)
            {
                OnLineCountChanged(new LineCountChangedEventArgs(_document, lineStart, TotalNumberOfLines - oldNumberOfLines));
            }
        }
Beispiel #3
0
        void RemoveInternal(ref DeferredEventList deferredEventList, int offset, int length)
        {
            Debug.Assert(length >= 0);
            if (length == 0)
            {
                return;
            }
            LineSegmentTree.Enumerator it  = _lineSegments.GetEnumeratorForOffset(offset);
            LineSegment startSegment       = it.Current;
            int         startSegmentOffset = startSegment.Offset;

            if (offset + length < startSegmentOffset + startSegment.TotalLength)
            {
                // just removing a part of this line segment
                startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, length);
                SetSegmentLength(startSegment, startSegment.TotalLength - length);
                return;
            }
            // merge startSegment with another line segment because startSegment's delimiter was deleted
            // possibly remove lines in between if multiple delimiters were deleted
            int charactersRemovedInStartLine = startSegmentOffset + startSegment.TotalLength - offset;

            Debug.Assert(charactersRemovedInStartLine > 0);
            startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, charactersRemovedInStartLine);


            LineSegment endSegment = _lineSegments.GetByOffset(offset + length);

            if (endSegment == startSegment)
            {
                // special case: we are removing a part of the last line up to the
                // end of the document
                SetSegmentLength(startSegment, startSegment.TotalLength - length);
                return;
            }
            int endSegmentOffset        = endSegment.Offset;
            int charactersLeftInEndLine = endSegmentOffset + endSegment.TotalLength - (offset + length);

            endSegment.RemovedLinePart(ref deferredEventList, 0, endSegment.TotalLength - charactersLeftInEndLine);
            startSegment.MergedWith(endSegment, offset - startSegmentOffset);
            SetSegmentLength(startSegment, startSegment.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
            startSegment.DelimiterLength = endSegment.DelimiterLength;
            // remove all segments between startSegment (excl.) and endSegment (incl.)
            it.MoveNext();
            LineSegment segmentToRemove;

            do
            {
                segmentToRemove = it.Current;
                it.MoveNext();
                _lineSegments.RemoveSegment(segmentToRemove);
                segmentToRemove.Deleted(ref deferredEventList);
            } while (segmentToRemove != endSegment);
        }
 /// <summary>
 /// Is called when the <see cref="LineSegment"/> is deleted.
 /// </summary>
 /// <param name="deferredEventList">The deferred event list.</param>
 internal void Deleted(ref DeferredEventList deferredEventList)
 {
     //Console.WriteLine("Deleted");
     _treeEntry = LineSegmentTree.Enumerator.Invalid;
     if (_anchors != null)
     {
         foreach (TextAnchor anchor in _anchors)
         {
             anchor.Delete(ref deferredEventList);
         }
         _anchors = null;
     }
 }
        /// <summary>
        /// Is called when a part of the line is removed.
        /// </summary>
        internal void RemovedLinePart(ref DeferredEventList deferredEventList, int startColumn, int length)
        {
            if (length == 0)
            {
                return;
            }
            Debug.Assert(length > 0);

            if (_anchors != null)
            {
                List <TextAnchor> deletedAnchors = null;
                foreach (TextAnchor anchor in _anchors)
                {
                    if (anchor.ColumnNumber > startColumn)
                    {
                        if (anchor.ColumnNumber >= startColumn + length)
                        {
                            anchor.ColumnNumber -= length;
                        }
                        else
                        {
                            if (deletedAnchors == null)
                            {
                                deletedAnchors = new List <TextAnchor>();
                            }
                            anchor.Delete(ref deferredEventList);
                            deletedAnchors.Add(anchor);
                        }
                    }
                }
                if (deletedAnchors != null)
                {
                    foreach (TextAnchor anchor in deletedAnchors)
                    {
                        _anchors.Remove(anchor);
                    }
                }
            }
        }
        /// <summary>
        /// Is called when a part of the line is removed.
        /// </summary>
        internal void RemovedLinePart(ref DeferredEventList deferredEventList, int startColumn, int length)
        {
            if (length == 0)
            return;
              Debug.Assert(length > 0);

              if (_anchors != null)
              {
            List<TextAnchor> deletedAnchors = null;
            foreach (TextAnchor anchor in _anchors)
            {
              if (anchor.ColumnNumber > startColumn)
              {
            if (anchor.ColumnNumber >= startColumn + length)
            {
              anchor.ColumnNumber -= length;
            }
            else
            {
              if (deletedAnchors == null)
                deletedAnchors = new List<TextAnchor>();
              anchor.Delete(ref deferredEventList);
              deletedAnchors.Add(anchor);
            }
              }
            }
            if (deletedAnchors != null)
            {
              foreach (TextAnchor anchor in deletedAnchors)
              {
            _anchors.Remove(anchor);
              }
            }
              }
        }
 /// <summary>
 /// Is called when the <see cref="LineSegment"/> is deleted.
 /// </summary>
 /// <param name="deferredEventList">The deferred event list.</param>
 internal void Deleted(ref DeferredEventList deferredEventList)
 {
     //Console.WriteLine("Deleted");
       _treeEntry = LineSegmentTree.Enumerator.Invalid;
       if (_anchors != null)
       {
     foreach (TextAnchor anchor in _anchors)
     {
       anchor.Delete(ref deferredEventList);
     }
     _anchors = null;
       }
 }
 internal void Delete(ref DeferredEventList deferredEventList)
 {
     // we cannot fire an event here because this method is called while the LineManager adjusts the
       // lineCollection, so an event handler could see inconsistent state
       _lineSegment = null;
       deferredEventList.AddDeletedAnchor(this);
 }
    void RemoveInternal(ref DeferredEventList deferredEventList, int offset, int length)
    {
      Debug.Assert(length >= 0);
      if (length == 0) return;
      LineSegmentTree.Enumerator it = _lineSegments.GetEnumeratorForOffset(offset);
      LineSegment startSegment = it.Current;
      int startSegmentOffset = startSegment.Offset;
      if (offset + length < startSegmentOffset + startSegment.TotalLength)
      {
        // just removing a part of this line segment
        startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, length);
        SetSegmentLength(startSegment, startSegment.TotalLength - length);
        return;
      }
      // merge startSegment with another line segment because startSegment's delimiter was deleted
      // possibly remove lines in between if multiple delimiters were deleted
      int charactersRemovedInStartLine = startSegmentOffset + startSegment.TotalLength - offset;
      Debug.Assert(charactersRemovedInStartLine > 0);
      startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, charactersRemovedInStartLine);


      LineSegment endSegment = _lineSegments.GetByOffset(offset + length);
      if (endSegment == startSegment)
      {
        // special case: we are removing a part of the last line up to the
        // end of the document
        SetSegmentLength(startSegment, startSegment.TotalLength - length);
        return;
      }
      int endSegmentOffset = endSegment.Offset;
      int charactersLeftInEndLine = endSegmentOffset + endSegment.TotalLength - (offset + length);
      endSegment.RemovedLinePart(ref deferredEventList, 0, endSegment.TotalLength - charactersLeftInEndLine);
      startSegment.MergedWith(endSegment, offset - startSegmentOffset);
      SetSegmentLength(startSegment, startSegment.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
      startSegment.DelimiterLength = endSegment.DelimiterLength;
      // remove all segments between startSegment (excl.) and endSegment (incl.)
      it.MoveNext();
      LineSegment segmentToRemove;
      do
      {
        segmentToRemove = it.Current;
        it.MoveNext();
        _lineSegments.RemoveSegment(segmentToRemove);
        segmentToRemove.Deleted(ref deferredEventList);
      } while (segmentToRemove != endSegment);
    }
    /// <summary>
    /// Replaces the specified offset.
    /// </summary>
    /// <param name="offset">The offset.</param>
    /// <param name="length">The length.</param>
    /// <param name="text">The text.</param>
    public void Replace(int offset, int length, string text)
    {
      int lineStart = GetLineNumberForOffset(offset);
      int oldNumberOfLines = TotalNumberOfLines;
      DeferredEventList deferredEventList = new DeferredEventList();
      RemoveInternal(ref deferredEventList, offset, length);
      int numberOfLinesAfterRemoving = TotalNumberOfLines;
      if (!string.IsNullOrEmpty(text))
      {
        InsertInternal(offset, text);
      }
      // Only fire events after RemoveInternal+InsertInternal finished completely:
      // Otherwise we would expose inconsistent state to the event handlers.
      RunHighlighter(lineStart, 1 + Math.Max(0, TotalNumberOfLines - numberOfLinesAfterRemoving));

      if (deferredEventList.RemovedLines != null)
      {
        foreach (LineSegment ls in deferredEventList.RemovedLines)
          OnLineDeleted(new LineEventArgs(_document, ls));
      }
      deferredEventList.RaiseEvents();
      if (TotalNumberOfLines != oldNumberOfLines)
      {
        OnLineCountChanged(new LineCountChangedEventArgs(_document, lineStart, TotalNumberOfLines - oldNumberOfLines));
      }
    }