diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/ISegment.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/ISegment.cs
index f90540d15b..6cc26e8c8b 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/ISegment.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/ISegment.cs
@@ -5,6 +5,7 @@
// $Revision$
//
+using ICSharpCode.AvalonEdit.Utils;
using System;
using System.Diagnostics;
@@ -130,44 +131,74 @@ namespace ICSharpCode.AvalonEdit.Document
///
/// A segment using text anchors as start and end positions.
///
- sealed class AnchorSegment : ISegment
+ ///
+ /// For the constructors creating new anchors, the start position will be AfterInsertion and the end position will be BeforeInsertion.
+ /// Should the end position move before the start position, the segment will have length 0.
+ ///
+ public sealed class AnchorSegment : ISegment
{
readonly TextAnchor start, end;
+ ///
public int Offset {
get { return start.Offset; }
}
+ ///
public int Length {
- get { return end.Offset - start.Offset; }
+ get {
+ // Math.Max takes care of the fact that end.Offset might move before start.Offset.
+ return Math.Max(0, end.Offset - start.Offset);
+ }
}
+ ///
public int EndOffset {
- get { return end.Offset; }
+ get {
+ // Math.Max takes care of the fact that end.Offset might move before start.Offset.
+ return Math.Max(start.Offset, end.Offset);
+ }
}
+ ///
+ /// Creates a new AnchorSegment using the specified anchors.
+ /// The anchors must have set to true.
+ ///
public AnchorSegment(TextAnchor start, TextAnchor end)
{
- Debug.Assert(start != null);
- Debug.Assert(end != null);
- Debug.Assert(start.SurviveDeletion);
- Debug.Assert(end.SurviveDeletion);
+ if (start == null)
+ throw new ArgumentNullException("start");
+ if (end == null)
+ throw new ArgumentNullException("end");
+ if (!start.SurviveDeletion)
+ throw new ArgumentException("Anchors for AnchorSegment must use SurviveDeletion", "start");
+ if (!end.SurviveDeletion)
+ throw new ArgumentException("Anchors for AnchorSegment must use SurviveDeletion", "end");
this.start = start;
this.end = end;
}
+ ///
+ /// Creates a new AnchorSegment that creates new anchors.
+ ///
public AnchorSegment(TextDocument document, ISegment segment)
- : this(document, segment.Offset, segment.Length)
+ : this(document, ThrowUtil.CheckNotNull(segment, "segment").Offset, segment.Length)
{
}
+ ///
+ /// Creates a new AnchorSegment that creates new anchors.
+ ///
public AnchorSegment(TextDocument document, int offset, int length)
{
- Debug.Assert(document != null);
+ if (document == null)
+ throw new ArgumentNullException("document");
this.start = document.CreateAnchor(offset);
this.start.SurviveDeletion = true;
+ this.start.MovementType = AnchorMovementType.AfterInsertion;
this.end = document.CreateAnchor(offset + length);
this.end.SurviveDeletion = true;
+ this.start.MovementType = AnchorMovementType.BeforeInsertion;
}
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextSegment.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextSegment.cs
index cabc57fd6d..abdc0b1d42 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextSegment.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextSegment.cs
@@ -109,8 +109,11 @@ namespace ICSharpCode.AvalonEdit.Document
}
///
- /// Gets the end offset of the segment.
+ /// Gets/Sets the end offset of the segment.
///
+ ///
+ /// Setting the end offset will change the length, the start offset will stay constant.
+ ///
public int EndOffset {
get {
return StartOffset + Length;
@@ -126,6 +129,9 @@ namespace ICSharpCode.AvalonEdit.Document
///
/// Gets/Sets the length of the segment.
///
+ ///
+ /// Setting the length will change the end offset, the start offset will stay constant.
+ ///
public int Length {
get {
return segmentLength;
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs
index 5b36f898a8..49ab029bf7 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs
@@ -151,7 +151,7 @@ namespace ICSharpCode.AvalonEdit.Editing
}
if (segments != null) {
foreach (ISegment segment in segments.Reverse()) {
- foreach (ISegment writableSegment in textArea.ReadOnlySectionProvider.GetDeletableSegments(segment).Reverse()) {
+ foreach (ISegment writableSegment in textArea.GetDeletableSegments(segment).Reverse()) {
transformSegment(textArea, writableSegment);
}
}
@@ -208,7 +208,7 @@ namespace ICSharpCode.AvalonEdit.Editing
int offset = line.Offset;
ISegment s = TextUtilities.GetSingleIndentationSegment(line.Document, offset, textArea.Options.IndentationSize);
if (s.Length > 0) {
- s = textArea.ReadOnlySectionProvider.GetDeletableSegments(s).FirstOrDefault();
+ s = textArea.GetDeletableSegments(s).FirstOrDefault();
if (s != null && s.Length > 0) {
textArea.Document.Remove(s.Offset, s.Length);
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/IReadOnlySectionProvider.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/IReadOnlySectionProvider.cs
index 2bdcc0ab6e..bfb1390205 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/IReadOnlySectionProvider.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/IReadOnlySectionProvider.cs
@@ -24,6 +24,10 @@ namespace ICSharpCode.AvalonEdit.Editing
///
/// Gets the deletable segments inside the given segment.
///
+ ///
+ /// All segments in the result must be within the given segment, and they must be returned in order
+ /// (e.g. if two segments are returned, EndOffset of first segment must be less than StartOffset of second segment).
+ ///
IEnumerable GetDeletableSegments(ISegment segment);
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs
index 7a27877bb0..521a5a2178 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs
@@ -215,9 +215,9 @@ namespace ICSharpCode.AvalonEdit.Editing
textArea.Document.Insert(lineSegment.Offset, newText);
}
} else {
- var segmentsToDelete = textArea.ReadOnlySectionProvider.GetDeletableSegments(lineSegment).ToList();
- for (int i = segmentsToDelete.Count - 1; i >= 0; i--) {
- if (i == segmentsToDelete.Count - 1) {
+ ISegment[] segmentsToDelete = textArea.GetDeletableSegments(lineSegment);
+ for (int i = segmentsToDelete.Length - 1; i >= 0; i--) {
+ if (i == segmentsToDelete.Length - 1) {
textArea.Document.Replace(segmentsToDelete[i], newText);
} else {
textArea.Document.Remove(segmentsToDelete[i]);
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs
index fa668b5577..bc71d5938f 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs
@@ -270,7 +270,7 @@ namespace ICSharpCode.AvalonEdit.Editing
DragDropEffects allowedEffects = DragDropEffects.All;
var deleteOnMove = textArea.Selection.Segments.Select(s => new AnchorSegment(textArea.Document, s)).ToList();
foreach (ISegment s in deleteOnMove) {
- ISegment[] result = textArea.ReadOnlySectionProvider.GetDeletableSegments(s).ToArray();
+ ISegment[] result = textArea.GetDeletableSegments(s);
if (result.Length != 1 || result[0].Offset != s.Offset || result[0].EndOffset != s.EndOffset) {
allowedEffects &= ~DragDropEffects.Move;
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
index 0e7efec1c0..46f284019b 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
@@ -77,9 +77,9 @@ namespace ICSharpCode.AvalonEdit.Editing
}
}
} else {
- var segmentsToDelete = textArea.ReadOnlySectionProvider.GetDeletableSegments(this).ToList();
- for (int i = segmentsToDelete.Count - 1; i >= 0; i--) {
- if (i == segmentsToDelete.Count - 1) {
+ ISegment[] segmentsToDelete = textArea.GetDeletableSegments(this);
+ for (int i = segmentsToDelete.Length - 1; i >= 0; i--) {
+ if (i == segmentsToDelete.Length - 1) {
textArea.Caret.Offset = segmentsToDelete[i].EndOffset;
textArea.Document.Replace(segmentsToDelete[i], newText);
} else {
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
index 285c014ed0..87e79fa05f 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
@@ -700,7 +700,7 @@ namespace ICSharpCode.AvalonEdit.Editing
#if DEBUG
if (!selection.IsEmpty) {
foreach (ISegment s in selection.Segments) {
- Debug.Assert(ReadOnlySectionProvider.GetDeletableSegments(s).Count() == 0);
+ Debug.Assert(this.ReadOnlySectionProvider.GetDeletableSegments(s).Count() == 0);
}
}
#endif
@@ -714,6 +714,23 @@ namespace ICSharpCode.AvalonEdit.Editing
throw ThrowUtil.NoDocumentAssigned();
selection.ReplaceSelectionWithText(this, newText);
}
+
+ internal ISegment[] GetDeletableSegments(ISegment segment)
+ {
+ var deletableSegments = this.ReadOnlySectionProvider.GetDeletableSegments(segment);
+ if (deletableSegments == null)
+ throw new InvalidOperationException("ReadOnlySectionProvider.GetDeletableSegments returned null");
+ var array = deletableSegments.ToArray();
+ int lastIndex = segment.Offset;
+ for (int i = 0; i < array.Length; i++) {
+ if (array[i].Offset < lastIndex)
+ throw new InvalidOperationException("ReadOnlySectionProvider returned incorrect segments (outside of input segment / wrong order)");
+ lastIndex = array[i].EndOffset;
+ }
+ if (lastIndex > segment.EndOffset)
+ throw new InvalidOperationException("ReadOnlySectionProvider returned incorrect segments (outside of input segment / wrong order)");
+ return array;
+ }
#endregion
#region IndentationStrategy property
diff --git a/src/Main/Base/Project/Src/Gui/AbstractViewContent.cs b/src/Main/Base/Project/Src/Gui/AbstractViewContent.cs
index cfd39fe514..a271b8e35f 100644
--- a/src/Main/Base/Project/Src/Gui/AbstractViewContent.cs
+++ b/src/Main/Base/Project/Src/Gui/AbstractViewContent.cs
@@ -341,7 +341,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
string titleName;
- LanguageDependendExtension titleNameLocalizeExtension;
+ LanguageDependentExtension titleNameLocalizeExtension;
string IViewContent.TitleName {
get {
diff --git a/src/Main/ICSharpCode.Core.Presentation/LocalizeExtension.cs b/src/Main/ICSharpCode.Core.Presentation/LocalizeExtension.cs
index 4ce3a933c9..4702407b79 100644
--- a/src/Main/ICSharpCode.Core.Presentation/LocalizeExtension.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/LocalizeExtension.cs
@@ -17,7 +17,7 @@ namespace ICSharpCode.Core.Presentation
/// Markup extension that retrieves localized resource strings.
///
[MarkupExtensionReturnType(typeof(string))]
- public sealed class LocalizeExtension : LanguageDependendExtension
+ public sealed class LocalizeExtension : LanguageDependentExtension
{
public LocalizeExtension(string key)
{
@@ -48,9 +48,9 @@ namespace ICSharpCode.Core.Presentation
}
}
- public abstract class LanguageDependendExtension : MarkupExtension, INotifyPropertyChanged, IWeakEventListener
+ public abstract class LanguageDependentExtension : MarkupExtension, INotifyPropertyChanged, IWeakEventListener
{
- protected LanguageDependendExtension()
+ protected LanguageDependentExtension()
{
this.UpdateOnLanguageChange = true;
}
diff --git a/src/Main/ICSharpCode.Core.Presentation/StringParseExtension.cs b/src/Main/ICSharpCode.Core.Presentation/StringParseExtension.cs
index ddff553a29..a06a9d165f 100644
--- a/src/Main/ICSharpCode.Core.Presentation/StringParseExtension.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/StringParseExtension.cs
@@ -18,7 +18,7 @@ namespace ICSharpCode.Core.Presentation
/// Markup extension that works like StringParser.Parse
///
[MarkupExtensionReturnType(typeof(string))]
- public sealed class StringParseExtension : LanguageDependendExtension
+ public sealed class StringParseExtension : LanguageDependentExtension
{
string text;