132 lines
3.9 KiB
C#
132 lines
3.9 KiB
C#
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
using ICSharpCode.AvalonEdit.Utils;
|
|
using System;
|
|
|
|
namespace ICSharpCode.AvalonEdit.Document
|
|
{
|
|
/// <summary>
|
|
/// Describes a change of the document text.
|
|
/// This class is thread-safe.
|
|
/// </summary>
|
|
[Serializable]
|
|
public class DocumentChangeEventArgs : EventArgs
|
|
{
|
|
/// <summary>
|
|
/// The offset at which the change occurs.
|
|
/// </summary>
|
|
public int Offset { get; private set; }
|
|
|
|
/// <summary>
|
|
/// The text that was removed.
|
|
/// </summary>
|
|
public string RemovedText { get; private set; }
|
|
|
|
/// <summary>
|
|
/// The number of characters removed.
|
|
/// </summary>
|
|
public int RemovalLength {
|
|
get { return RemovedText.Length; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The text that was inserted.
|
|
/// </summary>
|
|
public string InsertedText { get; private set; }
|
|
|
|
/// <summary>
|
|
/// The number of characters inserted.
|
|
/// </summary>
|
|
public int InsertionLength {
|
|
get { return InsertedText.Length; }
|
|
}
|
|
|
|
volatile OffsetChangeMap offsetChangeMap;
|
|
|
|
/// <summary>
|
|
/// Gets the OffsetChangeMap associated with this document change.
|
|
/// </summary>
|
|
/// <remarks>The OffsetChangeMap instance is guaranteed to be frozen and thus thread-safe.</remarks>
|
|
public OffsetChangeMap OffsetChangeMap {
|
|
get {
|
|
OffsetChangeMap map = offsetChangeMap;
|
|
if (map == null) {
|
|
// create OffsetChangeMap on demand
|
|
map = OffsetChangeMap.FromSingleElement(CreateSingleChangeMapEntry());
|
|
offsetChangeMap = map;
|
|
}
|
|
return map;
|
|
}
|
|
}
|
|
|
|
internal OffsetChangeMapEntry CreateSingleChangeMapEntry()
|
|
{
|
|
return new OffsetChangeMapEntry(this.Offset, this.RemovalLength, this.InsertionLength);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the OffsetChangeMap, or null if the default offset map (=single replacement) is being used.
|
|
/// </summary>
|
|
internal OffsetChangeMap OffsetChangeMapOrNull {
|
|
get {
|
|
return offsetChangeMap;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the new offset where the specified offset moves after this document change.
|
|
/// </summary>
|
|
public int GetNewOffset(int offset, AnchorMovementType movementType)
|
|
{
|
|
if (offsetChangeMap != null)
|
|
return offsetChangeMap.GetNewOffset(offset, movementType);
|
|
else
|
|
return CreateSingleChangeMapEntry().GetNewOffset(offset, movementType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new DocumentChangeEventArgs object.
|
|
/// </summary>
|
|
public DocumentChangeEventArgs(int offset, string removedText, string insertedText)
|
|
: this(offset, removedText, insertedText, null)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new DocumentChangeEventArgs object.
|
|
/// </summary>
|
|
public DocumentChangeEventArgs(int offset, string removedText, string insertedText, OffsetChangeMap offsetChangeMap)
|
|
{
|
|
ThrowUtil.CheckNotNegative(offset, "offset");
|
|
ThrowUtil.CheckNotNull(removedText, "removedText");
|
|
ThrowUtil.CheckNotNull(insertedText, "insertedText");
|
|
|
|
this.Offset = offset;
|
|
this.RemovedText = removedText;
|
|
this.InsertedText = insertedText;
|
|
|
|
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))
|
|
throw new ArgumentException("OffsetChangeMap is not valid for this document change", "offsetChangeMap");
|
|
this.offsetChangeMap = offsetChangeMap;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates DocumentChangeEventArgs for the reverse change.
|
|
/// </summary>
|
|
public DocumentChangeEventArgs Invert()
|
|
{
|
|
OffsetChangeMap map = this.OffsetChangeMapOrNull;
|
|
if (map != null) {
|
|
map = map.Invert();
|
|
map.Freeze();
|
|
}
|
|
return new DocumentChangeEventArgs(this.Offset, this.InsertedText, this.RemovedText, map);
|
|
}
|
|
}
|
|
}
|