Browse Source

fixed bugs in RectangleSelection and SimpleSelection

pull/23/head
Siegfried Pammer 14 years ago
parent
commit
12493b5b49
  1. 53
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs
  2. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs

53
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs

@ -23,7 +23,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -23,7 +23,7 @@ namespace ICSharpCode.AvalonEdit.Editing
TextDocument document;
readonly int startLine, endLine;
readonly double startXPos, endXPos;
readonly int startOffset, endOffset;
readonly int topLeftOffset, bottomRightOffset;
readonly List<SelectionSegment> segments = new List<SelectionSegment>();
@ -45,12 +45,12 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -45,12 +45,12 @@ namespace ICSharpCode.AvalonEdit.Editing
this.endLine = end.Line;
this.startXPos = GetXPos(textArea, start);
this.endXPos = GetXPos(textArea, end);
this.startOffset = document.GetOffset(start.Location);
this.endOffset = document.GetOffset(end.Location);
CalculateSegments();
this.topLeftOffset = this.segments.First().StartOffset;
this.bottomRightOffset = this.segments.Last().EndOffset;
}
private RectangleSelection(TextArea textArea, int startLine, double startXPos, int startOffset, TextViewPosition end)
private RectangleSelection(TextArea textArea, int startLine, double startXPos, TextViewPosition end)
: base(textArea)
{
InitDocument();
@ -58,12 +58,12 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -58,12 +58,12 @@ namespace ICSharpCode.AvalonEdit.Editing
this.endLine = end.Line;
this.startXPos = startXPos;
this.endXPos = GetXPos(textArea, end);
this.startOffset = startOffset;
this.endOffset = document.GetOffset(end.Location);
CalculateSegments();
this.topLeftOffset = this.segments.First().StartOffset;
this.bottomRightOffset = this.segments.Last().EndOffset;
}
private RectangleSelection(TextArea textArea, TextViewPosition start, int endLine, double endXPos, int endOffset)
private RectangleSelection(TextArea textArea, TextViewPosition start, int endLine, double endXPos)
: base(textArea)
{
InitDocument();
@ -71,9 +71,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -71,9 +71,9 @@ namespace ICSharpCode.AvalonEdit.Editing
this.endLine = endLine;
this.startXPos = GetXPos(textArea, start);
this.endXPos = endXPos;
this.startOffset = document.GetOffset(start.Location);
this.endOffset = endOffset;
CalculateSegments();
this.topLeftOffset = this.segments.First().StartOffset;
this.bottomRightOffset = this.segments.Last().EndOffset;
}
static double GetXPos(TextArea textArea, TextViewPosition pos)
@ -124,7 +124,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -124,7 +124,7 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <inheritdoc/>
public override ISegment SurroundingSegment {
get {
return new SimpleSegment(Math.Min(startOffset, endOffset), Math.Abs(endOffset - startOffset));
return new SimpleSegment(topLeftOffset, bottomRightOffset - topLeftOffset);
}
}
@ -156,7 +156,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -156,7 +156,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
RectangleSelection r = obj as RectangleSelection;
return r != null && r.textArea == this.textArea
&& r.startOffset == this.startOffset && r.endOffset == this.endOffset
&& r.topLeftOffset == this.topLeftOffset && r.bottomRightOffset == this.bottomRightOffset
&& r.startLine == this.startLine && r.endLine == this.endLine
&& r.startXPos == this.startXPos && r.endXPos == this.endXPos;
}
@ -164,21 +164,20 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -164,21 +164,20 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <inheritdoc/>
public override int GetHashCode()
{
return startOffset ^ endOffset;
return topLeftOffset ^ bottomRightOffset;
}
/// <inheritdoc/>
public override Selection SetEndpoint(TextViewPosition endPosition)
{
var r = new RectangleSelection(textArea, startLine, startXPos, startOffset, endPosition);
return r;
return new RectangleSelection(textArea, startLine, startXPos, endPosition);
}
/// <inheritdoc/>
public override Selection UpdateOnDocumentChange(DocumentChangeEventArgs e)
{
TextLocation newStartLocation = textArea.Document.GetLocation(e.GetNewOffset(startOffset, AnchorMovementType.AfterInsertion));
TextLocation newEndLocation = textArea.Document.GetLocation(e.GetNewOffset(endOffset, AnchorMovementType.BeforeInsertion));
TextLocation newStartLocation = textArea.Document.GetLocation(e.GetNewOffset(topLeftOffset, AnchorMovementType.AfterInsertion));
TextLocation newEndLocation = textArea.Document.GetLocation(e.GetNewOffset(bottomRightOffset, AnchorMovementType.BeforeInsertion));
return new RectangleSelection(textArea,
new TextViewPosition(newStartLocation, GetVisualColumnFromXPos(newStartLocation.Line, startXPos)),
@ -191,12 +190,13 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -191,12 +190,13 @@ namespace ICSharpCode.AvalonEdit.Editing
if (newText == null)
throw new ArgumentNullException("newText");
using (textArea.Document.RunUpdate()) {
TextViewPosition start = new TextViewPosition(document.GetLocation(startOffset), GetVisualColumnFromXPos(startLine, startXPos));
TextViewPosition end = new TextViewPosition(document.GetLocation(endOffset), GetVisualColumnFromXPos(endLine, endXPos));
TextViewPosition start = new TextViewPosition(document.GetLocation(topLeftOffset), GetVisualColumnFromXPos(startLine, startXPos));
TextViewPosition end = new TextViewPosition(document.GetLocation(bottomRightOffset), GetVisualColumnFromXPos(endLine, endXPos));
int insertionLength;
int totalInsertionLength = 0;
int firstInsertionLength = 0;
int editOffset = Math.Min(startOffset, endOffset);
int editOffset = Math.Min(topLeftOffset, bottomRightOffset);
TextViewPosition pos;
if (NewLineFinder.NextNewLine(newText, 0) == SimpleSegment.Invalid) {
// insert same text into every line
foreach (SelectionSegment lineSegment in this.Segments.Reverse()) {
@ -206,10 +206,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -206,10 +206,9 @@ namespace ICSharpCode.AvalonEdit.Editing
}
int newEndOffset = editOffset + totalInsertionLength;
TextViewPosition pos = new TextViewPosition(document.GetLocation(editOffset + firstInsertionLength));
pos = new TextViewPosition(document.GetLocation(editOffset + firstInsertionLength));
textArea.Selection = new RectangleSelection(textArea, pos, Math.Max(startLine, endLine), GetXPos(textArea, pos), newEndOffset);
textArea.Caret.Position = textArea.TextView.GetPosition(new Point(GetXPos(textArea, pos), textArea.TextView.GetVisualTopByDocumentLine(Math.Max(startLine, endLine)))).GetValueOrDefault();
textArea.Selection = new RectangleSelection(textArea, pos, Math.Max(startLine, endLine), GetXPos(textArea, pos));
} else {
string[] lines = newText.Split(new[] { "\r\n", "\r", "\n" }, segments.Count, StringSplitOptions.None);
int line = Math.Min(startLine, endLine);
@ -217,10 +216,10 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -217,10 +216,10 @@ namespace ICSharpCode.AvalonEdit.Editing
ReplaceSingleLineText(textArea, segments[i], lines[i], out insertionLength);
firstInsertionLength = insertionLength;
}
TextViewPosition pos = new TextViewPosition(document.GetLocation(editOffset + firstInsertionLength));
pos = new TextViewPosition(document.GetLocation(editOffset + firstInsertionLength));
textArea.ClearSelection();
textArea.Caret.Position = textArea.TextView.GetPosition(new Point(GetXPos(textArea, pos), textArea.TextView.GetVisualTopByDocumentLine(Math.Max(startLine, endLine)))).GetValueOrDefault();
}
textArea.Caret.Position = textArea.TextView.GetPosition(new Point(GetXPos(textArea, pos), textArea.TextView.GetVisualTopByDocumentLine(Math.Max(startLine, endLine)))).GetValueOrDefault();
}
}
@ -261,11 +260,11 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -261,11 +260,11 @@ namespace ICSharpCode.AvalonEdit.Editing
if (endLocation.Line <= textArea.Document.LineCount) {
int endOffset = textArea.Document.GetOffset(endLocation);
if (textArea.Selection.EnableVirtualSpace || textArea.Document.GetLocation(endOffset) == endLocation) {
RectangleSelection rsel = new RectangleSelection(textArea, startPosition, endLocation.Line, GetXPos(textArea, startPosition), endOffset);
RectangleSelection rsel = new RectangleSelection(textArea, startPosition, endLocation.Line, GetXPos(textArea, startPosition));
rsel.ReplaceSelectionWithText(text);
if (selectInsertedText && textArea.Selection is RectangleSelection) {
RectangleSelection sel = (RectangleSelection)textArea.Selection;
textArea.Selection = new RectangleSelection(textArea, startPosition, sel.endLine, sel.endXPos, sel.endOffset);
textArea.Selection = new RectangleSelection(textArea, startPosition, sel.endLine, sel.endXPos);
}
return true;
}
@ -294,7 +293,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -294,7 +293,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
// It's possible that ToString() gets called on old (invalid) selections, e.g. for "change from... to..." debug message
// make sure we don't crash even when the desired locations don't exist anymore.
return string.Format("[RectangleSelection {0} {1} {2} to {3} {4} {5}]", startLine, startOffset, startXPos, endLine, endOffset, endXPos);
return string.Format("[RectangleSelection {0} {1} {2} to {3} {4} {5}]", startLine, topLeftOffset, startXPos, endLine, bottomRightOffset, endXPos);
}
}
}

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs

@ -136,7 +136,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -136,7 +136,9 @@ namespace ICSharpCode.AvalonEdit.Editing
{
SimpleSelection other = obj as SimpleSelection;
if (other == null) return false;
return this.start.Equals(other.start) && this.end.Equals(other.end) && this.textArea == other.textArea;
return this.start.Equals(other.start) && this.end.Equals(other.end)
&& this.startOffset == other.startOffset && this.endOffset == other.endOffset
&& this.textArea == other.textArea;
}
/// <inheritdoc/>

Loading…
Cancel
Save