Example #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);
		}
Example #2
0
		public void Replace(int offset, int length, string text)
		{
			Debug.WriteLine("Replace offset="+offset+" length="+length+" text.Length="+text.Length);
			int lineStart = GetLineNumberForOffset(offset);
			int oldNumberOfLines = this.TotalNumberOfLines;
			DeferredEventList deferredEventList = new DeferredEventList();
			RemoveInternal(ref deferredEventList, offset, length);
			int numberOfLinesAfterRemoving = this.TotalNumberOfLines;
			if (!string.IsNullOrEmpty(text)) {
				InsertInternal(offset, text);
			}
//			#if DEBUG
//			Console.WriteLine("New line collection:");
//			Console.WriteLine(lineCollection.GetTreeAsString());
//			Console.WriteLine("New text:");
//			Console.WriteLine("'" + document.TextContent + "'");
//			#endif
			// Only fire events after RemoveInternal+InsertInternal finished completely:
			// Otherwise we would expose inconsistent state to the event handlers.
			RunHighlighter(lineStart, 1 + Math.Max(0, this.TotalNumberOfLines - numberOfLinesAfterRemoving));
			
			if (deferredEventList.removedLines != null) {
				foreach (LineSegment ls in deferredEventList.removedLines)
					OnLineDeleted(new LineEventArgs(document, ls));
			}
			deferredEventList.RaiseEvents();
			if (this.TotalNumberOfLines != oldNumberOfLines) {
				OnLineCountChanged(new LineCountChangeEventArgs(document, lineStart, this.TotalNumberOfLines - oldNumberOfLines));
			}
		}
Example #3
0
		/// <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);
			
			//Console.WriteLine("RemovedLinePart " + startColumn + ", " + length);
			if (anchors != null) {
				List<TextAnchor> deletedAnchors = null;
				foreach (TextAnchor a in anchors) {
					if (a.ColumnNumber > startColumn) {
						if (a.ColumnNumber >= startColumn + length) {
							a.ColumnNumber -= length;
						} else {
							if (deletedAnchors == null)
								deletedAnchors = new List<TextAnchor>();
							a.Delete(ref deferredEventList);
							deletedAnchors.Add(a);
						}
					}
				}
				if (deletedAnchors != null) {
					foreach (TextAnchor a in deletedAnchors) {
						anchors.Remove(a);
					}
				}
			}
		}
Example #4
0
		/// <summary>
		/// Is called when the LineSegment is deleted.
		/// </summary>
		internal void Deleted(ref DeferredEventList deferredEventList)
		{
			//Console.WriteLine("Deleted");
			treeEntry = LineSegmentTree.Enumerator.Invalid;
			if (anchors != null) {
				foreach (TextAnchor a in anchors) {
					a.Delete(ref deferredEventList);
				}
				anchors = null;
			}
		}
Example #5
0
		void RemoveInternal(ref DeferredEventList deferredEventList, int offset, int length)
		{
			Debug.Assert(length >= 0);
			if (length == 0) return;
			LineSegmentTree.Enumerator it = lineCollection.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 = lineCollection.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();
				lineCollection.RemoveSegment(segmentToRemove);
				segmentToRemove.Deleted(ref deferredEventList);
			} while (segmentToRemove != endSegment);
		}