Browse Source

Change TextChangeEventArgs.InsertedText and RemovedText from string to ITextSource.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
2e63fcd5bf
  1. 18
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/DocumentChangeEventArgs.cs
  2. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/LineManager.cs
  3. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/RopeTextSource.cs
  4. 136
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs
  5. 32
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/IDocument.cs
  6. 15
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs
  7. 26
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs
  8. 7
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/StringTextSource.cs
  9. 30
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/TextChangeEventArgs.cs

18
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/DocumentChangeEventArgs.cs

@ -71,14 +71,24 @@ namespace ICSharpCode.AvalonEdit.Document @@ -71,14 +71,24 @@ namespace ICSharpCode.AvalonEdit.Document
public DocumentChangeEventArgs(int offset, string removedText, string insertedText, OffsetChangeMap offsetChangeMap)
: base(offset, removedText, insertedText)
{
ThrowUtil.CheckNotNegative(offset, "offset");
ThrowUtil.CheckNotNull(removedText, "removedText");
ThrowUtil.CheckNotNull(insertedText, "insertedText");
SetOffsetChangeMap(offsetChangeMap);
}
/// <summary>
/// Creates a new DocumentChangeEventArgs object.
/// </summary>
public DocumentChangeEventArgs(int offset, ITextSource removedText, ITextSource insertedText, OffsetChangeMap offsetChangeMap)
: base(offset, removedText, insertedText)
{
SetOffsetChangeMap(offsetChangeMap);
}
void SetOffsetChangeMap(OffsetChangeMap offsetChangeMap)
{
if (offsetChangeMap != null) {
if (!offsetChangeMap.IsFrozen)
throw new ArgumentException("The OffsetChangeMap must be frozen before it can be used in DocumentChangeEventArgs");
if (!offsetChangeMap.IsValidForDocumentChange(offset, removedText.Length, insertedText.Length))
if (!offsetChangeMap.IsValidForDocumentChange(this.Offset, this.RemovalLength, this.InsertionLength))
throw new ArgumentException("OffsetChangeMap is not valid for this document change", "offsetChangeMap");
this.offsetChangeMap = offsetChangeMap;
}

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/LineManager.cs

@ -6,6 +6,7 @@ using System; @@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.AvalonEdit.Document
{
@ -181,7 +182,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -181,7 +182,7 @@ namespace ICSharpCode.AvalonEdit.Document
#endregion
#region Insert
public void Insert(int offset, string text)
public void Insert(int offset, ITextSource text)
{
DocumentLine line = documentLineTree.GetByOffset(offset);
int lineOffset = line.Offset;
@ -202,7 +203,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -202,7 +203,7 @@ namespace ICSharpCode.AvalonEdit.Document
if (ds == SimpleSegment.Invalid) {
// no newline is being inserted, all text is inserted in a single line
//line.InsertedLinePart(offset - line.Offset, text.Length);
SetLineLength(line, line.TotalLength + text.Length);
SetLineLength(line, line.TotalLength + text.TextLength);
return;
}
//DocumentLine firstLine = line;
@ -224,9 +225,9 @@ namespace ICSharpCode.AvalonEdit.Document @@ -224,9 +225,9 @@ namespace ICSharpCode.AvalonEdit.Document
}
//firstLine.SplitTo(line);
// insert rest after last delimiter
if (lastDelimiterEnd != text.Length) {
if (lastDelimiterEnd != text.TextLength) {
//line.InsertedLinePart(0, text.Length - lastDelimiterEnd);
SetLineLength(line, line.TotalLength + text.Length - lastDelimiterEnd);
SetLineLength(line, line.TotalLength + text.TextLength - lastDelimiterEnd);
}
}

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/RopeTextSource.cs

@ -11,6 +11,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -11,6 +11,7 @@ namespace ICSharpCode.AvalonEdit.Document
/// <summary>
/// Implements the ITextSource interface using a rope.
/// </summary>
[Serializable]
public sealed class RopeTextSource : ITextSource
{
readonly Rope<char> rope;

136
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs

@ -524,6 +524,21 @@ namespace ICSharpCode.AvalonEdit.Document @@ -524,6 +524,21 @@ namespace ICSharpCode.AvalonEdit.Document
/// The caret will also move behind the inserted text.
/// </remarks>
public void Insert(int offset, string text)
{
Replace(offset, 0, new StringTextSource(text), null);
}
/// <summary>
/// Inserts text.
/// </summary>
/// <param name="offset">The offset at which the text is inserted.</param>
/// <param name="text">The new text.</param>
/// <remarks>
/// Anchors positioned exactly at the insertion offset will move according to their movement type.
/// For AnchorMovementType.Default, they will move behind the inserted text.
/// The caret will also move behind the inserted text.
/// </remarks>
public void Insert(int offset, ITextSource text)
{
Replace(offset, 0, text, null);
}
@ -539,6 +554,25 @@ namespace ICSharpCode.AvalonEdit.Document @@ -539,6 +554,25 @@ namespace ICSharpCode.AvalonEdit.Document
/// The caret will also move according to the <paramref name="defaultAnchorMovementType"/> parameter.
/// </param>
public void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
{
if (defaultAnchorMovementType == AnchorMovementType.BeforeInsertion) {
Replace(offset, 0, new StringTextSource(text), OffsetChangeMappingType.KeepAnchorBeforeInsertion);
} else {
Replace(offset, 0, new StringTextSource(text), null);
}
}
/// <summary>
/// Inserts text.
/// </summary>
/// <param name="offset">The offset at which the text is inserted.</param>
/// <param name="text">The new text.</param>
/// <param name="defaultAnchorMovementType">
/// Anchors positioned exactly at the insertion offset will move according to the anchor's movement type.
/// For AnchorMovementType.Default, they will move according to the movement type specified by this parameter.
/// The caret will also move according to the <paramref name="defaultAnchorMovementType"/> parameter.
/// </param>
public void Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
{
if (defaultAnchorMovementType == AnchorMovementType.BeforeInsertion) {
Replace(offset, 0, text, OffsetChangeMappingType.KeepAnchorBeforeInsertion);
@ -562,7 +596,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -562,7 +596,7 @@ namespace ICSharpCode.AvalonEdit.Document
/// <param name="length">Length of the text to be removed.</param>
public void Remove(int offset, int length)
{
Replace(offset, length, string.Empty);
Replace(offset, length, StringTextSource.Empty);
}
internal bool inDocumentChanging;
@ -571,6 +605,16 @@ namespace ICSharpCode.AvalonEdit.Document @@ -571,6 +605,16 @@ namespace ICSharpCode.AvalonEdit.Document
/// Replaces text.
/// </summary>
public void Replace(ISegment segment, string text)
{
if (segment == null)
throw new ArgumentNullException("segment");
Replace(segment.Offset, segment.Length, new StringTextSource(text), null);
}
/// <summary>
/// Replaces text.
/// </summary>
public void Replace(ISegment segment, ITextSource text)
{
if (segment == null)
throw new ArgumentNullException("segment");
@ -584,6 +628,17 @@ namespace ICSharpCode.AvalonEdit.Document @@ -584,6 +628,17 @@ namespace ICSharpCode.AvalonEdit.Document
/// <param name="length">The length of the text to be replaced.</param>
/// <param name="text">The new text.</param>
public void Replace(int offset, int length, string text)
{
Replace(offset, length, new StringTextSource(text), null);
}
/// <summary>
/// Replaces text.
/// </summary>
/// <param name="offset">The starting offset of the text to be replaced.</param>
/// <param name="length">The length of the text to be replaced.</param>
/// <param name="text">The new text.</param>
public void Replace(int offset, int length, ITextSource text)
{
Replace(offset, length, text, null);
}
@ -597,6 +652,19 @@ namespace ICSharpCode.AvalonEdit.Document @@ -597,6 +652,19 @@ namespace ICSharpCode.AvalonEdit.Document
/// <param name="offsetChangeMappingType">The offsetChangeMappingType determines how offsets inside the old text are mapped to the new text.
/// This affects how the anchors and segments inside the replaced region behave.</param>
public void Replace(int offset, int length, string text, OffsetChangeMappingType offsetChangeMappingType)
{
Replace(offset, length, new StringTextSource(text), offsetChangeMappingType);
}
/// <summary>
/// Replaces text.
/// </summary>
/// <param name="offset">The starting offset of the text to be replaced.</param>
/// <param name="length">The length of the text to be replaced.</param>
/// <param name="text">The new text.</param>
/// <param name="offsetChangeMappingType">The offsetChangeMappingType determines how offsets inside the old text are mapped to the new text.
/// This affects how the anchors and segments inside the replaced region behave.</param>
public void Replace(int offset, int length, ITextSource text, OffsetChangeMappingType offsetChangeMappingType)
{
if (text == null)
throw new ArgumentNullException("text");
@ -607,33 +675,33 @@ namespace ICSharpCode.AvalonEdit.Document @@ -607,33 +675,33 @@ namespace ICSharpCode.AvalonEdit.Document
break;
case OffsetChangeMappingType.KeepAnchorBeforeInsertion:
Replace(offset, length, text, OffsetChangeMap.FromSingleElement(
new OffsetChangeMapEntry(offset, length, text.Length, false, true)));
new OffsetChangeMapEntry(offset, length, text.TextLength, false, true)));
break;
case OffsetChangeMappingType.RemoveAndInsert:
if (length == 0 || text.Length == 0) {
if (length == 0 || text.TextLength == 0) {
// only insertion or only removal?
// OffsetChangeMappingType doesn't matter, just use Normal.
Replace(offset, length, text, null);
} else {
OffsetChangeMap map = new OffsetChangeMap(2);
map.Add(new OffsetChangeMapEntry(offset, length, 0));
map.Add(new OffsetChangeMapEntry(offset, 0, text.Length));
map.Add(new OffsetChangeMapEntry(offset, 0, text.TextLength));
map.Freeze();
Replace(offset, length, text, map);
}
break;
case OffsetChangeMappingType.CharacterReplace:
if (length == 0 || text.Length == 0) {
if (length == 0 || text.TextLength == 0) {
// only insertion or only removal?
// OffsetChangeMappingType doesn't matter, just use Normal.
Replace(offset, length, text, null);
} else if (text.Length > length) {
} else if (text.TextLength > length) {
// look at OffsetChangeMappingType.CharacterReplace XML comments on why we need to replace
// the last character
OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + length - 1, 1, 1 + text.Length - length);
OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + length - 1, 1, 1 + text.TextLength - length);
Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
} else if (text.Length < length) {
OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + text.Length, length - text.Length, 0, true, false);
} else if (text.TextLength < length) {
OffsetChangeMapEntry entry = new OffsetChangeMapEntry(offset + text.TextLength, length - text.TextLength, 0, true, false);
Replace(offset, length, text, OffsetChangeMap.FromSingleElement(entry));
} else {
Replace(offset, length, text, OffsetChangeMap.Empty);
@ -660,10 +728,30 @@ namespace ICSharpCode.AvalonEdit.Document @@ -660,10 +728,30 @@ namespace ICSharpCode.AvalonEdit.Document
/// DocumentChangeEventArgs instance.
/// </param>
public void Replace(int offset, int length, string text, OffsetChangeMap offsetChangeMap)
{
Replace(offset, length, new StringTextSource(text), offsetChangeMap);
}
/// <summary>
/// Replaces text.
/// </summary>
/// <param name="offset">The starting offset of the text to be replaced.</param>
/// <param name="length">The length of the text to be replaced.</param>
/// <param name="text">The new text.</param>
/// <param name="offsetChangeMap">The offsetChangeMap determines how offsets inside the old text are mapped to the new text.
/// This affects how the anchors and segments inside the replaced region behave.
/// If you pass null (the default when using one of the other overloads), the offsets are changed as
/// in OffsetChangeMappingType.Normal mode.
/// If you pass OffsetChangeMap.Empty, then everything will stay in its old place (OffsetChangeMappingType.CharacterReplace mode).
/// The offsetChangeMap must be a valid 'explanation' for the document change. See <see cref="OffsetChangeMap.IsValidForDocumentChange"/>.
/// Passing an OffsetChangeMap to the Replace method will automatically freeze it to ensure the thread safety of the resulting
/// DocumentChangeEventArgs instance.
/// </param>
public void Replace(int offset, int length, ITextSource text, OffsetChangeMap offsetChangeMap)
{
if (text == null)
throw new ArgumentNullException("text");
text = text.CreateSnapshot();
if (offsetChangeMap != null)
offsetChangeMap.Freeze();
@ -687,18 +775,26 @@ namespace ICSharpCode.AvalonEdit.Document @@ -687,18 +775,26 @@ namespace ICSharpCode.AvalonEdit.Document
}
}
void DoReplace(int offset, int length, string newText, OffsetChangeMap offsetChangeMap)
void DoReplace(int offset, int length, ITextSource newText, OffsetChangeMap offsetChangeMap)
{
if (length == 0 && newText.Length == 0)
if (length == 0 && newText.TextLength == 0)
return;
// trying to replace a single character in 'Normal' mode?
// for single characters, 'CharacterReplace' mode is equivalent, but more performant
// (we don't have to touch the anchorTree at all in 'CharacterReplace' mode)
if (length == 1 && newText.Length == 1 && offsetChangeMap == null)
if (length == 1 && newText.TextLength == 1 && offsetChangeMap == null)
offsetChangeMap = OffsetChangeMap.Empty;
string removedText = rope.ToString(offset, length);
ITextSource removedText;
if (length == 0) {
removedText = StringTextSource.Empty;
} else if (length < 100) {
removedText = new StringTextSource(rope.ToString(offset, length));
} else {
// use a rope if the removed string is long
removedText = new RopeTextSource(rope.GetRange(offset, length));
}
DocumentChangeEventArgs args = new DocumentChangeEventArgs(offset, removedText, newText, offsetChangeMap);
// fire DocumentChanging event
@ -721,7 +817,11 @@ namespace ICSharpCode.AvalonEdit.Document @@ -721,7 +817,11 @@ namespace ICSharpCode.AvalonEdit.Document
if (offset == 0 && length == rope.Length) {
// optimize replacing the whole document
rope.Clear();
rope.InsertText(0, newText);
var newRopeTextSource = newText as RopeTextSource;
if (newRopeTextSource != null)
rope.InsertRange(0, newRopeTextSource.GetRope());
else
rope.InsertText(0, newText.Text);
lineManager.Rebuild();
} else {
rope.RemoveRange(offset, length);
@ -729,7 +829,11 @@ namespace ICSharpCode.AvalonEdit.Document @@ -729,7 +829,11 @@ namespace ICSharpCode.AvalonEdit.Document
#if DEBUG
lineTree.CheckProperties();
#endif
rope.InsertText(offset, newText);
var newRopeTextSource = newText as RopeTextSource;
if (newRopeTextSource != null)
rope.InsertRange(offset, newRopeTextSource.GetRope());
else
rope.InsertText(offset, newText.Text);
lineManager.Insert(offset, newText);
#if DEBUG
lineTree.CheckProperties();

32
src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/IDocument.cs

@ -109,6 +109,18 @@ namespace ICSharpCode.NRefactory.Editor @@ -109,6 +109,18 @@ namespace ICSharpCode.NRefactory.Editor
/// </remarks>
void Insert(int offset, string text);
/// <summary>
/// Inserts text.
/// </summary>
/// <param name="offset">The offset at which the text is inserted.</param>
/// <param name="text">The new text.</param>
/// <remarks>
/// Anchors positioned exactly at the insertion offset will move according to their movement type.
/// For AnchorMovementType.Default, they will move behind the inserted text.
/// The caret will also move behind the inserted text.
/// </remarks>
void Insert(int offset, ITextSource text);
/// <summary>
/// Inserts text.
/// </summary>
@ -121,6 +133,18 @@ namespace ICSharpCode.NRefactory.Editor @@ -121,6 +133,18 @@ namespace ICSharpCode.NRefactory.Editor
/// </param>
void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType);
/// <summary>
/// Inserts text.
/// </summary>
/// <param name="offset">The offset at which the text is inserted.</param>
/// <param name="text">The new text.</param>
/// <param name="defaultAnchorMovementType">
/// Anchors positioned exactly at the insertion offset will move according to the anchor's movement type.
/// For AnchorMovementType.Default, they will move according to the movement type specified by this parameter.
/// The caret will also move according to the <paramref name="defaultAnchorMovementType"/> parameter.
/// </param>
void Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType);
/// <summary>
/// Removes text.
/// </summary>
@ -136,6 +160,14 @@ namespace ICSharpCode.NRefactory.Editor @@ -136,6 +160,14 @@ namespace ICSharpCode.NRefactory.Editor
/// <param name="newText">The new text.</param>
void Replace(int offset, int length, string newText);
/// <summary>
/// Replaces text.
/// </summary>
/// <param name="offset">The starting offset of the text to be replaced.</param>
/// <param name="length">The length of the text to be replaced.</param>
/// <param name="newText">The new text.</param>
void Replace(int offset, int length, ITextSource newText);
/// <summary>
/// Make the document combine the following actions into a single
/// action for undo purposes.

15
src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs

@ -257,6 +257,21 @@ namespace ICSharpCode.NRefactory.Editor @@ -257,6 +257,21 @@ namespace ICSharpCode.NRefactory.Editor
throw new NotSupportedException();
}
void IDocument.Insert(int offset, ITextSource text)
{
throw new NotImplementedException();
}
void IDocument.Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
{
throw new NotImplementedException();
}
void IDocument.Replace(int offset, int length, ITextSource newText)
{
throw new NotImplementedException();
}
void IDocument.StartUndoableAction()
{
}

26
src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs

@ -104,17 +104,35 @@ namespace ICSharpCode.NRefactory.Editor @@ -104,17 +104,35 @@ namespace ICSharpCode.NRefactory.Editor
Replace(offset, 0, text);
}
/// <inheritdoc/>
public void Insert(int offset, ITextSource text)
{
if (text == null)
throw new ArgumentNullException("text");
Replace(offset, 0, text.Text);
}
/// <inheritdoc/>
public void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
{
if (offset < 0 || offset > this.TextLength)
throw new ArgumentOutOfRangeException("offset");
if (text == null)
throw new ArgumentNullException("text");
if (defaultAnchorMovementType == AnchorMovementType.BeforeInsertion)
PerformChange(new InsertionWithMovementBefore(offset, text));
else
Replace(offset, 0, text);
}
/// <inheritdoc/>
public void Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
{
if (text == null)
throw new ArgumentNullException("text");
Insert(offset, text.Text, defaultAnchorMovementType);
}
[Serializable]
sealed class InsertionWithMovementBefore : TextChangeEventArgs
{
@ -149,6 +167,14 @@ namespace ICSharpCode.NRefactory.Editor @@ -149,6 +167,14 @@ namespace ICSharpCode.NRefactory.Editor
PerformChange(new TextChangeEventArgs(offset, b.ToString(offset, length), newText));
}
/// <inheritdoc/>
public void Replace(int offset, int length, ITextSource newText)
{
if (newText == null)
throw new ArgumentNullException("newText");
Replace(offset, length, newText.Text);
}
bool isInChange;
void PerformChange(TextChangeEventArgs change)

7
src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/StringTextSource.cs

@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.Editor @@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.Editor
[Serializable]
public class StringTextSource : ITextSource
{
/// <summary>
/// Gets a text source containing the empty string.
/// </summary>
public static readonly StringTextSource Empty = new StringTextSource(string.Empty);
readonly string text;
readonly ITextSourceVersion version;
@ -69,7 +74,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -69,7 +74,7 @@ namespace ICSharpCode.NRefactory.Editor
/// <inheritdoc/>
public ITextSource CreateSnapshot()
{
return this; // StringTextBuffer is immutable
return this; // StringTextSource is immutable
}
/// <inheritdoc/>

30
src/Libraries/NRefactory/ICSharpCode.NRefactory/Editor/TextChangeEventArgs.cs

@ -28,8 +28,8 @@ namespace ICSharpCode.NRefactory.Editor @@ -28,8 +28,8 @@ namespace ICSharpCode.NRefactory.Editor
public class TextChangeEventArgs : EventArgs
{
readonly int offset;
readonly string removedText;
readonly string insertedText;
readonly ITextSource removedText;
readonly ITextSource insertedText;
/// <summary>
/// The offset at which the change occurs.
@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.Editor
/// <summary>
/// The text that was removed.
/// </summary>
public string RemovedText {
public ITextSource RemovedText {
get { return removedText; }
}
@ -49,13 +49,13 @@ namespace ICSharpCode.NRefactory.Editor @@ -49,13 +49,13 @@ namespace ICSharpCode.NRefactory.Editor
/// The number of characters removed.
/// </summary>
public int RemovalLength {
get { return removedText.Length; }
get { return removedText.TextLength; }
}
/// <summary>
/// The text that was inserted.
/// </summary>
public string InsertedText {
public ITextSource InsertedText {
get { return insertedText; }
}
@ -63,7 +63,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -63,7 +63,7 @@ namespace ICSharpCode.NRefactory.Editor
/// The number of characters inserted.
/// </summary>
public int InsertionLength {
get { return insertedText.Length; }
get { return insertedText.TextLength; }
}
/// <summary>
@ -71,9 +71,23 @@ namespace ICSharpCode.NRefactory.Editor @@ -71,9 +71,23 @@ namespace ICSharpCode.NRefactory.Editor
/// </summary>
public TextChangeEventArgs(int offset, string removedText, string insertedText)
{
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", offset, "offset must not be negative");
this.offset = offset;
this.removedText = removedText ?? string.Empty;
this.insertedText = insertedText ?? string.Empty;
this.removedText = removedText != null ? new StringTextSource(removedText) : StringTextSource.Empty;
this.insertedText = insertedText != null ? new StringTextSource(insertedText) : StringTextSource.Empty;
}
/// <summary>
/// Creates a new TextChangeEventArgs object.
/// </summary>
public TextChangeEventArgs(int offset, ITextSource removedText, ITextSource insertedText)
{
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", offset, "offset must not be negative");
this.offset = offset;
this.removedText = removedText ?? StringTextSource.Empty;
this.insertedText = insertedText ?? StringTextSource.Empty;
}
/// <summary>

Loading…
Cancel
Save