Browse Source

Refactored the selection API; preparing for improving the rectangular selection.

pull/23/head
Daniel Grunwald 14 years ago committed by Siegfried Pammer
parent
commit
b2a774f77b
  1. 8
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretNavigationCommandHandler.cs
  2. 12
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs
  3. 75
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EmptySelection.cs
  4. 8
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/LineNumberMargin.cs
  5. 167
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs
  6. 86
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Selection.cs
  7. 15
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionColorizer.cs
  8. 32
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs
  9. 63
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionSegment.cs
  10. 73
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
  11. 20
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
  12. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  13. 11
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ColorizingTransformer.cs
  14. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/InsertionContext.cs
  15. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetInputHandler.cs
  16. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs
  17. 14
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextViewPosition.cs

8
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/CaretNavigationCommandHandler.cs

@ -81,7 +81,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -81,7 +81,7 @@ namespace ICSharpCode.AvalonEdit.Editing
if (textArea != null && textArea.Document != null) {
args.Handled = true;
textArea.Caret.Offset = textArea.Document.TextLength;
textArea.Selection = new SimpleSelection(0, textArea.Document.TextLength);
textArea.Selection = SimpleSelection.Create(textArea, 0, textArea.Document.TextLength);
}
}
@ -112,7 +112,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -112,7 +112,7 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
args.Handled = true;
textArea.Selection = Selection.Empty;
textArea.ClearSelection();
MoveCaret(textArea, direction);
textArea.Caret.BringCaretToView();
}
@ -125,9 +125,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -125,9 +125,9 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
args.Handled = true;
int oldOffset = textArea.Caret.Offset;
TextViewPosition oldPosition = textArea.Caret.Position;
MoveCaret(textArea, direction);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
textArea.Caret.BringCaretToView();
}
};

12
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs

@ -143,7 +143,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -143,7 +143,7 @@ namespace ICSharpCode.AvalonEdit.Editing
if (defaultSegmentType == DefaultSegmentType.CurrentLine) {
segments = new ISegment[] { textArea.Document.GetLineByNumber(textArea.Caret.Line) };
} else if (defaultSegmentType == DefaultSegmentType.WholeDocument) {
segments = textArea.Document.Lines.Cast<ISegment>();
segments = textArea.Document.Lines;
} else {
segments = null;
}
@ -181,7 +181,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -181,7 +181,7 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
using (textArea.Document.RunUpdate()) {
if (textArea.Selection.IsMultiline(textArea.Document)) {
if (textArea.Selection.IsMultiline) {
var segment = textArea.Selection.SurroundingSegment;
DocumentLine start = textArea.Document.GetLineByOffset(segment.Offset);
DocumentLine end = textArea.Document.GetLineByOffset(segment.EndOffset);
@ -246,7 +246,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -246,7 +246,7 @@ namespace ICSharpCode.AvalonEdit.Editing
// If nothing in the selection is deletable; then reset caret+selection
// to the previous value. This prevents the caret from moving through read-only sections.
textArea.Caret.Position = oldCaretPosition;
textArea.Selection = Selection.Empty;
textArea.ClearSelection();
}
}
textArea.RemoveSelectedText();
@ -325,7 +325,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -325,7 +325,7 @@ namespace ICSharpCode.AvalonEdit.Editing
return;
}
string text = textArea.Selection.GetText(textArea.Document);
string text = textArea.Selection.GetText();
text = TextUtilities.NormalizeNewLines(text, Environment.NewLine);
textArea.OnTextCopied(new TextEventArgs(text));
}
@ -399,7 +399,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -399,7 +399,7 @@ namespace ICSharpCode.AvalonEdit.Editing
textArea.Document.Insert(currentLine.Offset, text);
}
} else if (rectangular && textArea.Selection.IsEmpty) {
if (!RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Offset, text, false))
if (!RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, false))
textArea.ReplaceSelectionWithText(text);
} else {
textArea.ReplaceSelectionWithText(text);
@ -417,7 +417,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -417,7 +417,7 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) {
DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line);
textArea.Selection = new SimpleSelection(currentLine.Offset, currentLine.Offset + currentLine.TotalLength);
textArea.Selection = Selection.Create(textArea, currentLine.Offset, currentLine.Offset + currentLine.TotalLength);
textArea.RemoveSelectedText();
args.Handled = true;
}

75
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EmptySelection.cs

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
// 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 System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Editing
{
sealed class EmptySelection : Selection
{
public EmptySelection(TextArea textArea) : base(textArea)
{
}
public override Selection UpdateOnDocumentChange(DocumentChangeEventArgs e)
{
return this;
}
public override ISegment SurroundingSegment {
get { return null; }
}
public override Selection SetEndpoint(TextViewPosition endPosition)
{
throw new NotSupportedException();
}
public override Selection StartSelectionOrSetEndpoint(TextViewPosition startPosition, TextViewPosition endPosition)
{
var document = textArea.Document;
if (document == null)
throw ThrowUtil.NoDocumentAssigned();
return Create(textArea, document.GetOffset(startPosition), document.GetOffset(endPosition));
}
public override IEnumerable<SelectionSegment> Segments {
get { return Empty<SelectionSegment>.Array; }
}
public override string GetText()
{
return string.Empty;
}
public override void ReplaceSelectionWithText(string newText)
{
if (newText == null)
throw new ArgumentNullException("newText");
if (newText.Length > 0) {
if (textArea.ReadOnlySectionProvider.CanInsert(textArea.Caret.Offset)) {
textArea.Document.Insert(textArea.Caret.Offset, newText);
}
}
}
public override int Length {
get { return 0; }
}
// Use reference equality because there's only one EmptySelection per text area.
public override int GetHashCode()
{
return RuntimeHelpers.GetHashCode(this);
}
public override bool Equals(object obj)
{
return this == obj;
}
}
}

8
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/LineNumberMargin.cs

@ -158,9 +158,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -158,9 +158,9 @@ namespace ICSharpCode.AvalonEdit.Editing
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
SimpleSelection simpleSelection = textArea.Selection as SimpleSelection;
if (simpleSelection != null)
selectionStart = new AnchorSegment(Document, simpleSelection);
selectionStart = new AnchorSegment(Document, simpleSelection.SurroundingSegment);
}
textArea.Selection = new SimpleSelection(selectionStart);
textArea.Selection = Selection.Create(textArea, selectionStart);
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
ExtendSelection(currentSeg);
}
@ -191,10 +191,10 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -191,10 +191,10 @@ namespace ICSharpCode.AvalonEdit.Editing
{
if (currentSeg.Offset < selectionStart.Offset) {
textArea.Caret.Offset = currentSeg.Offset;
textArea.Selection = new SimpleSelection(currentSeg.Offset, selectionStart.Offset + selectionStart.Length);
textArea.Selection = Selection.Create(textArea, currentSeg.Offset, selectionStart.Offset + selectionStart.Length);
} else {
textArea.Caret.Offset = currentSeg.Offset + currentSeg.Length;
textArea.Selection = new SimpleSelection(selectionStart.Offset, currentSeg.Offset + currentSeg.Length);
textArea.Selection = Selection.Create(textArea, selectionStart.Offset, currentSeg.Offset + currentSeg.Length);
}
}

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

@ -6,8 +6,10 @@ using System.Collections.Generic; @@ -6,8 +6,10 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media.TextFormatting;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Editing
@ -18,52 +20,71 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -18,52 +20,71 @@ namespace ICSharpCode.AvalonEdit.Editing
public sealed class RectangleSelection : Selection
{
TextDocument document;
readonly int startLine, endLine;
readonly double startXPos, endXPos;
readonly int startOffset, endOffset;
/// <summary>
/// Gets the start position of the selection.
/// </summary>
public int StartOffset { get; private set; }
readonly List<SelectionSegment> segments = new List<SelectionSegment>();
/// <summary>
/// Gets the end position of the selection.
/// </summary>
public int EndOffset { get; private set; }
void InitDocument()
{
document = textArea.Document;
if (document == null)
throw ThrowUtil.NoDocumentAssigned();
}
/// <summary>
/// Creates a new rectangular selection.
/// </summary>
public RectangleSelection(TextDocument document, int start, int end)
public RectangleSelection(TextArea textArea, TextViewPosition start, TextViewPosition end)
: base(textArea)
{
if (document == null)
throw new ArgumentNullException("document");
this.document = document;
this.StartOffset = start;
this.EndOffset = end;
InitDocument();
this.startLine = start.Line;
this.endLine = end.Line;
this.startXPos = GetXPos(start);
this.endXPos = GetXPos(end);
this.startOffset = document.GetOffset(start);
this.endOffset = document.GetOffset(end);
CalculateSegments();
}
/// <inheritdoc/>
public override bool IsEmpty {
get {
TextLocation start = document.GetLocation(StartOffset);
TextLocation end = document.GetLocation(EndOffset);
return start.Column == end.Column;
}
private RectangleSelection(TextArea textArea, int startLine, double startXPos, int startOffset, TextViewPosition end)
: base(textArea)
{
InitDocument();
this.startLine = startLine;
this.endLine = end.Line;
this.startXPos = startXPos;
this.endXPos = GetXPos(end);
this.startOffset = startOffset;
this.endOffset = document.GetOffset(end);
CalculateSegments();
}
/// <inheritdoc/>
public override bool Contains(int offset)
private RectangleSelection(TextArea textArea, TextViewPosition start, int endLine, double endXPos, int endOffset)
: base(textArea)
{
if (Math.Min(StartOffset, EndOffset) <= offset && offset <= Math.Max(StartOffset, EndOffset)) {
foreach (ISegment s in this.Segments) {
if (s.Contains(offset))
return true;
}
}
return false;
InitDocument();
this.startLine = start.Line;
this.endLine = endLine;
this.startXPos = GetXPos(start);
this.endXPos = endXPos;
this.startOffset = document.GetOffset(start);
this.endOffset = endOffset;
CalculateSegments();
}
double GetXPos(TextViewPosition pos)
{
DocumentLine documentLine = document.GetLineByNumber(pos.Line);
VisualLine visualLine = textArea.TextView.GetOrConstructVisualLine(documentLine);
TextLine textLine = visualLine.GetTextLine(pos.VisualColumn);
return visualLine.GetTextLineVisualXPosition(textLine, pos.VisualColumn);
}
/// <inheritdoc/>
public override string GetText(TextDocument document)
public override string GetText()
{
StringBuilder b = new StringBuilder();
foreach (ISegment s in this.Segments) {
@ -75,9 +96,9 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -75,9 +96,9 @@ namespace ICSharpCode.AvalonEdit.Editing
}
/// <inheritdoc/>
public override Selection StartSelectionOrSetEndpoint(int startOffset, int newEndOffset)
public override Selection StartSelectionOrSetEndpoint(TextViewPosition startPosition, TextViewPosition endPosition)
{
return SetEndpoint(newEndOffset);
return SetEndpoint(endPosition);
}
/// <inheritdoc/>
@ -90,61 +111,67 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -90,61 +111,67 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <inheritdoc/>
public override ISegment SurroundingSegment {
get {
return new SimpleSegment(Math.Min(StartOffset, EndOffset), Math.Abs(EndOffset - StartOffset));
return new SimpleSegment(Math.Min(startOffset, endOffset), Math.Abs(endOffset - startOffset));
}
}
/// <inheritdoc/>
public override IEnumerable<ISegment> Segments {
get {
TextLocation start = document.GetLocation(StartOffset);
TextLocation end = document.GetLocation(EndOffset);
DocumentLine line = document.GetLineByNumber(Math.Min(start.Line, end.Line));
int numberOfLines = Math.Abs(start.Line - end.Line);
int startCol = Math.Min(start.Column, end.Column);
int endCol = Math.Max(start.Column, end.Column);
for (int i = 0; i <= numberOfLines; i++) {
if (line.Length + 1 >= startCol) {
int thisLineEndCol = Math.Min(endCol, line.Length + 1);
yield return new SimpleSegment(line.Offset + startCol - 1, thisLineEndCol - startCol);
}
line = line.NextLine;
}
}
public override IEnumerable<SelectionSegment> Segments {
get { return segments; }
}
void CalculateSegments()
{
DocumentLine nextLine = document.GetLineByNumber(Math.Min(startLine, endLine));
do {
VisualLine vl = textArea.TextView.GetOrConstructVisualLine(nextLine);
int startVC = vl.GetVisualColumn(new Point(startXPos, 0), true);
int endVC = vl.GetVisualColumn(new Point(endXPos, 0), true);
int baseOffset = vl.FirstDocumentLine.Offset;
int startOffset = baseOffset + vl.GetRelativeOffset(startVC);
int endOffset = baseOffset + vl.GetRelativeOffset(endVC);
segments.Add(new SelectionSegment(startOffset, startVC, endOffset, endVC));
nextLine = vl.LastDocumentLine.NextLine;
} while (nextLine.LineNumber <= Math.Max(startLine, endLine));
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
RectangleSelection r = obj as RectangleSelection;
return r != null && r.document == this.document && r.StartOffset == this.StartOffset && r.EndOffset == this.EndOffset;
return r != null && r.textArea == this.textArea
&& r.startOffset == this.startOffset && r.endOffset == this.endOffset
&& r.startLine == this.startLine && r.endLine == this.endLine
&& r.startXPos == this.startXPos && r.endXPos == this.endXPos;
}
/// <inheritdoc/>
public override int GetHashCode()
{
return StartOffset ^ EndOffset;
return startOffset ^ endOffset;
}
/// <inheritdoc/>
public override Selection SetEndpoint(int newEndOffset)
public override Selection SetEndpoint(TextViewPosition endPosition)
{
return new RectangleSelection(this.document, this.StartOffset, newEndOffset);
return new RectangleSelection(textArea, startLine, startXPos, startOffset, endPosition);
}
/// <inheritdoc/>
public override Selection UpdateOnDocumentChange(DocumentChangeEventArgs e)
{
return new RectangleSelection(document,
e.GetNewOffset(StartOffset, AnchorMovementType.AfterInsertion),
e.GetNewOffset(EndOffset, AnchorMovementType.BeforeInsertion));
throw new NotImplementedException();
// return new RectangleSelection(textArea,
// e.GetNewOffset(StartOffset, AnchorMovementType.AfterInsertion),
// e.GetNewOffset(EndOffset, AnchorMovementType.BeforeInsertion));
}
/// <inheritdoc/>
public override void ReplaceSelectionWithText(TextArea textArea, string newText)
public override void ReplaceSelectionWithText(string newText)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
throw new NotImplementedException(); /*
if (newText == null)
throw new ArgumentNullException("newText");
using (textArea.Document.RunUpdate()) {
@ -201,7 +228,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -201,7 +228,7 @@ namespace ICSharpCode.AvalonEdit.Editing
textArea.Selection = Selection.Empty;
}
}
}
}*/
}
static void ReplaceSingleLineText(TextArea textArea, ISegment lineSegment, string newText)
@ -225,23 +252,22 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -225,23 +252,22 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <summary>
/// Performs a rectangular paste operation.
/// </summary>
public static bool PerformRectangularPaste(TextArea textArea, int startOffset, string text, bool selectInsertedText)
public static bool PerformRectangularPaste(TextArea textArea, TextViewPosition startPosition, string text, bool selectInsertedText)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
if (text == null)
throw new ArgumentNullException("text");
int newLineCount = text.Count(c => c == '\n');
TextLocation startLocation = textArea.Document.GetLocation(startOffset);
TextLocation endLocation = new TextLocation(startLocation.Line + newLineCount, startLocation.Column);
TextLocation endLocation = new TextLocation(startPosition.Line + newLineCount, startPosition.Column);
if (endLocation.Line <= textArea.Document.LineCount) {
int endOffset = textArea.Document.GetOffset(endLocation);
if (textArea.Document.GetLocation(endOffset) == endLocation) {
RectangleSelection rsel = new RectangleSelection(textArea.Document, startOffset, endOffset);
rsel.ReplaceSelectionWithText(textArea, text);
RectangleSelection rsel = new RectangleSelection(textArea, startPosition, new TextViewPosition(endLocation));
rsel.ReplaceSelectionWithText(text);
if (selectInsertedText && textArea.Selection is RectangleSelection) {
RectangleSelection sel = (RectangleSelection)textArea.Selection;
textArea.Selection = new RectangleSelection(textArea.Document, startOffset, sel.EndOffset);
textArea.Selection = new RectangleSelection(textArea, startPosition, sel.endLine, sel.endXPos, sel.endOffset);
}
return true;
}
@ -270,10 +296,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -270,10 +296,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.
if (StartOffset < document.TextLength && EndOffset < document.TextLength)
return "[RectangleSelection " + document.GetLocation(StartOffset) + " to " + document.GetLocation(EndOffset) + "]";
else
return "[RectangleSelection " + StartOffset + " to " + EndOffset + "]";
return "[RectangleSelection " + startOffset + " to " + endOffset + "]";
}
}
}

86
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Selection.cs

@ -5,9 +5,9 @@ using System; @@ -5,9 +5,9 @@ using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Editing
{
@ -17,15 +17,44 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -17,15 +17,44 @@ namespace ICSharpCode.AvalonEdit.Editing
public abstract class Selection
{
/// <summary>
/// Gets the empty selection.
/// Creates a new simple selection that selects the text from startOffset to endOffset.
/// </summary>
public static Selection Create(TextArea textArea, int startOffset, int endOffset)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
if (startOffset == endOffset)
return textArea.emptySelection;
else
return new SimpleSelection(textArea, startOffset, endOffset);
}
/// <summary>
/// Creates a new simple selection that selects the text in the specified segment.
/// </summary>
public static Selection Create(TextArea textArea, ISegment segment)
{
if (segment == null)
throw new ArgumentNullException("segment");
return Create(textArea, segment.Offset, segment.EndOffset);
}
internal readonly TextArea textArea;
/// <summary>
/// Constructor for Selection.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification="Empty selection is immutable")]
public static readonly Selection Empty = new SimpleSelection(-1, -1);
protected Selection(TextArea textArea)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
this.textArea = textArea;
}
/// <summary>
/// Gets the selected text segments.
/// </summary>
public abstract IEnumerable<ISegment> Segments { get; }
public abstract IEnumerable<SelectionSegment> Segments { get; }
/// <summary>
/// Gets the smallest segment that contains all segments in this selection.
@ -36,7 +65,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -36,7 +65,7 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <summary>
/// Replaces the selection with the specified text.
/// </summary>
public abstract void ReplaceSelectionWithText(TextArea textArea, string newText);
public abstract void ReplaceSelectionWithText(string newText);
/// <summary>
/// Updates the selection when the document changes.
@ -59,42 +88,39 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -59,42 +88,39 @@ namespace ICSharpCode.AvalonEdit.Editing
/// Returns a new selection with the changed end point.
/// </summary>
/// <exception cref="NotSupportedException">Cannot set endpoint for empty selection</exception>
public abstract Selection SetEndpoint(int newEndOffset);
public abstract Selection SetEndpoint(TextViewPosition endPosition);
/// <summary>
/// If this selection is empty, starts a new selection from <paramref name="startOffset"/> to
/// <paramref name="newEndOffset"/>, otherwise, changes the endpoint of this selection.
/// </summary>
public virtual Selection StartSelectionOrSetEndpoint(int startOffset, int newEndOffset)
{
if (IsEmpty)
return new SimpleSelection(startOffset, newEndOffset);
else
return SetEndpoint(newEndOffset);
}
public abstract Selection StartSelectionOrSetEndpoint(TextViewPosition startPosition, TextViewPosition endPosition);
/// <summary>
/// Gets whether the selection is multi-line.
/// </summary>
public virtual bool IsMultiline(TextDocument document)
{
if (document == null)
throw new ArgumentNullException("document");
ISegment surroundingSegment = this.SurroundingSegment;
if (surroundingSegment == null)
return false;
int start = surroundingSegment.Offset;
int end = start + surroundingSegment.Length;
return document.GetLineByOffset(start) != document.GetLineByOffset(end);
public virtual bool IsMultiline {
get {
ISegment surroundingSegment = this.SurroundingSegment;
if (surroundingSegment == null)
return false;
int start = surroundingSegment.Offset;
int end = start + surroundingSegment.Length;
var document = textArea.Document;
if (document == null)
throw ThrowUtil.NoDocumentAssigned();
return document.GetLineByOffset(start) != document.GetLineByOffset(end);
}
}
/// <summary>
/// Gets the selected text.
/// </summary>
public virtual string GetText(TextDocument document)
public virtual string GetText()
{
var document = textArea.Document;
if (document == null)
throw new ArgumentNullException("document");
throw ThrowUtil.NoDocumentAssigned();
StringBuilder b = null;
string text = null;
foreach (ISegment s in Segments) {
@ -117,10 +143,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -117,10 +143,8 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <summary>
/// Creates a HTML fragment for the selected text.
/// </summary>
public string CreateHtmlFragment(TextArea textArea, HtmlOptions options)
public string CreateHtmlFragment(HtmlOptions options)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
if (options == null)
throw new ArgumentNullException("options");
IHighlighter highlighter = textArea.GetService(typeof(IHighlighter)) as IHighlighter;
@ -166,7 +190,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -166,7 +190,7 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
public virtual DataObject CreateDataObject(TextArea textArea)
{
string text = GetText(textArea.Document);
string text = GetText();
// Ensure we use the appropriate newline sequence for the OS
DataObject data = new DataObject(TextUtilities.NormalizeNewLines(text, Environment.NewLine));
// we cannot use DataObject.SetText - then we cannot drag to SciTe
@ -174,7 +198,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -174,7 +198,7 @@ namespace ICSharpCode.AvalonEdit.Editing
// Also copy text in HTML format to clipboard - good for pasting text into Word
// or to the SharpDevelop forums.
HtmlClipboard.SetHtml(data, CreateHtmlFragment(textArea, new HtmlOptions(textArea.Options)));
HtmlClipboard.SetHtml(data, CreateHtmlFragment(new HtmlOptions(textArea.Options)));
return data;
}
}

15
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionColorizer.cs

@ -28,15 +28,20 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -28,15 +28,20 @@ namespace ICSharpCode.AvalonEdit.Editing
int lineStartOffset = context.VisualLine.FirstDocumentLine.Offset;
int lineEndOffset = context.VisualLine.LastDocumentLine.Offset + context.VisualLine.LastDocumentLine.TotalLength;
foreach (ISegment segment in textArea.Selection.Segments) {
int segmentStart = segment.Offset;
int segmentEnd = segment.Offset + segment.Length;
foreach (var segment in textArea.Selection.Segments) {
int segmentStart = segment.StartOffset;
int segmentEnd = segment.EndOffset;
if (segmentEnd <= lineStartOffset)
continue;
if (segmentStart >= lineEndOffset)
continue;
int startColumn = context.VisualLine.GetVisualColumn(Math.Max(0, segmentStart - lineStartOffset));
int endColumn = context.VisualLine.GetVisualColumn(segmentEnd - lineStartOffset);
int startColumn = segment.StartVisualColumn;
int endColumn = segment.EndVisualColumn;
if (startColumn < 0)
startColumn = context.VisualLine.GetVisualColumn(Math.Max(0, segmentStart - lineStartOffset));
if (endColumn < 0)
endColumn = context.VisualLine.GetVisualColumn(segmentEnd - lineStartOffset);
ChangeVisualElements(
startColumn, endColumn,
element => {

32
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs

@ -222,11 +222,11 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -222,11 +222,11 @@ namespace ICSharpCode.AvalonEdit.Editing
// the undo groups when text is moved.
textArea.Document.UndoStack.StartUndoGroup(this.currentDragDescriptor);
try {
if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, start, text, true)) {
if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, true)) {
} else {
textArea.Document.Insert(start, text);
textArea.Selection = new SimpleSelection(start, start + text.Length);
textArea.Selection = Selection.Create(textArea, start, start + text.Length);
}
} finally {
textArea.Document.UndoStack.EndUndoGroup();
@ -391,23 +391,23 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -391,23 +391,23 @@ namespace ICSharpCode.AvalonEdit.Editing
}
}
int oldOffset = textArea.Caret.Offset;
var oldPosition = textArea.Caret.Position;
SetCaretOffsetToMousePosition(e);
if (!shift) {
textArea.Selection = Selection.Empty;
textArea.ClearSelection();
}
if (textArea.CaptureMouse()) {
if ((modifiers & ModifierKeys.Alt) == ModifierKeys.Alt && textArea.Options.EnableRectangularSelection) {
mode = SelectionMode.Rectangular;
if (shift && textArea.Selection is RectangleSelection) {
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
}
} else if (e.ClickCount == 1 && ((modifiers & ModifierKeys.Control) == 0)) {
mode = SelectionMode.Normal;
if (shift && !(textArea.Selection is RectangleSelection)) {
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
}
} else {
SimpleSegment startWord;
@ -425,13 +425,13 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -425,13 +425,13 @@ namespace ICSharpCode.AvalonEdit.Editing
}
if (shift && !textArea.Selection.IsEmpty) {
if (startWord.Offset < textArea.Selection.SurroundingSegment.Offset) {
textArea.Selection = textArea.Selection.SetEndpoint(startWord.Offset);
textArea.Selection = textArea.Selection.SetEndpoint(new TextViewPosition(textArea.Document.GetLocation(startWord.Offset)));
} else if (startWord.EndOffset > textArea.Selection.SurroundingSegment.EndOffset) {
textArea.Selection = textArea.Selection.SetEndpoint(startWord.EndOffset);
textArea.Selection = textArea.Selection.SetEndpoint(new TextViewPosition(textArea.Document.GetLocation(startWord.EndOffset)));
}
this.startWord = new AnchorSegment(textArea.Document, textArea.Selection.SurroundingSegment);
} else {
textArea.Selection = new SimpleSelection(startWord.Offset, startWord.EndOffset);
textArea.Selection = Selection.Create(textArea, startWord.Offset, startWord.EndOffset);
this.startWord = new AnchorSegment(textArea.Document, startWord.Offset, startWord.Length);
}
}
@ -561,19 +561,21 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -561,19 +561,21 @@ namespace ICSharpCode.AvalonEdit.Editing
void ExtendSelectionToMouse(MouseEventArgs e)
{
int oldOffset = textArea.Caret.Offset;
TextViewPosition oldPosition = textArea.Caret.Position;
if (mode == SelectionMode.Normal || mode == SelectionMode.Rectangular) {
SetCaretOffsetToMousePosition(e);
if (mode == SelectionMode.Normal && textArea.Selection is RectangleSelection)
textArea.Selection = new SimpleSelection(oldOffset, textArea.Caret.Offset);
textArea.Selection = Selection.Create(textArea, oldOffset, textArea.Caret.Offset);
else if (mode == SelectionMode.Rectangular && !(textArea.Selection is RectangleSelection))
textArea.Selection = new RectangleSelection(textArea.Document, oldOffset, textArea.Caret.Offset);
textArea.Selection = new RectangleSelection(textArea, oldPosition, textArea.Caret.Position);
else
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
} else if (mode == SelectionMode.WholeWord || mode == SelectionMode.WholeLine) {
var newWord = (mode == SelectionMode.WholeLine) ? GetLineAtMousePosition(e) : GetWordAtMousePosition(e);
if (newWord != SimpleSegment.Invalid) {
textArea.Selection = new SimpleSelection(Math.Min(newWord.Offset, startWord.Offset),
Math.Max(newWord.EndOffset, startWord.EndOffset));
textArea.Selection = Selection.Create(textArea,
Math.Min(newWord.Offset, startWord.Offset),
Math.Max(newWord.EndOffset, startWord.EndOffset));
// Set caret offset, but limit the caret to stay inside the selection.
// in whole-word selection, it's otherwise possible that we get the caret outside the
// selection - but the TextArea doesn't like that and will reset the selection, causing
@ -594,7 +596,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -594,7 +596,7 @@ namespace ICSharpCode.AvalonEdit.Editing
if (mode == SelectionMode.PossibleDragStart) {
// -> this was not a drag start (mouse didn't move after mousedown)
SetCaretOffsetToMousePosition(e);
textArea.Selection = Selection.Empty;
textArea.ClearSelection();
} else if (mode == SelectionMode.Normal || mode == SelectionMode.WholeWord || mode == SelectionMode.WholeLine || mode == SelectionMode.Rectangular) {
ExtendSelectionToMouse(e);
}

63
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionSegment.cs

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// 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 System;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.Editing
{
/// <summary>
/// Represents a selected segment.
/// </summary>
public class SelectionSegment : ISegment
{
int startOffset, endOffset;
int startVC, endVC;
public SelectionSegment(int startOffset, int endOffset)
{
this.startOffset = Math.Min(startOffset, endOffset);
this.endOffset = Math.Max(startOffset, endOffset);
}
public SelectionSegment(int startOffset, int startVC, int endOffset, int endVC)
{
if (startOffset <= endOffset) {
this.startOffset = startOffset;
this.startVC = startVC;
this.endOffset = endOffset;
this.endVC = endVC;
} else {
this.startOffset = endOffset;
this.startVC = endVC;
this.endOffset = startOffset;
this.endVC = startVC;
}
}
public int StartOffset {
get { return startOffset; }
}
public int EndOffset {
get { return endOffset; }
}
public int StartVisualColumn {
get { return startVC; }
}
public int EndVisualColumn {
get { return endVC; }
}
int ISegment.Offset {
get { return startOffset; }
}
/// <inheritdoc/>
public int Length {
get { return endOffset - startOffset; }
}
}
}

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

@ -13,56 +13,37 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -13,56 +13,37 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <summary>
/// A simple selection.
/// </summary>
public sealed class SimpleSelection : Selection, ISegment
sealed class SimpleSelection : Selection
{
readonly int startOffset, endOffset;
/// <summary>
/// Creates a new SimpleSelection instance.
/// </summary>
public SimpleSelection(int startOffset, int endOffset)
internal SimpleSelection(TextArea textArea, int startOffset, int endOffset)
: base(textArea)
{
this.startOffset = startOffset;
this.endOffset = endOffset;
}
/// <summary>
/// Creates a new SimpleSelection instance.
/// </summary>
public SimpleSelection(ISegment segment)
{
if (segment == null)
throw new ArgumentNullException("segment");
this.startOffset = segment.Offset;
this.endOffset = startOffset + segment.Length;
}
/// <inheritdoc/>
public override IEnumerable<ISegment> Segments {
public override IEnumerable<SelectionSegment> Segments {
get {
if (!IsEmpty) {
return ExtensionMethods.Sequence<ISegment>(this);
} else {
return Empty<ISegment>.Array;
}
return ExtensionMethods.Sequence<SelectionSegment>(new SelectionSegment(startOffset, endOffset));
}
}
/// <inheritdoc/>
public override ISegment SurroundingSegment {
get {
if (IsEmpty)
return null;
else
return this;
return new SelectionSegment(startOffset, endOffset);
}
}
/// <inheritdoc/>
public override void ReplaceSelectionWithText(TextArea textArea, string newText)
public override void ReplaceSelectionWithText(string newText)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
if (newText == null)
throw new ArgumentNullException("newText");
using (textArea.Document.RunUpdate()) {
@ -73,7 +54,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -73,7 +54,7 @@ namespace ICSharpCode.AvalonEdit.Editing
}
}
} else {
ISegment[] segmentsToDelete = textArea.GetDeletableSegments(this);
ISegment[] segmentsToDelete = textArea.GetDeletableSegments(this.SurroundingSegment);
for (int i = segmentsToDelete.Length - 1; i >= 0; i--) {
if (i == segmentsToDelete.Length - 1) {
textArea.Caret.Offset = segmentsToDelete[i].EndOffset;
@ -83,7 +64,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -83,7 +64,7 @@ namespace ICSharpCode.AvalonEdit.Editing
}
}
if (segmentsToDelete.Length != 0) {
textArea.Selection = Selection.Empty;
textArea.ClearSelection();
}
}
}
@ -108,7 +89,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -108,7 +89,8 @@ namespace ICSharpCode.AvalonEdit.Editing
{
if (e == null)
throw new ArgumentNullException("e");
return new SimpleSelection(
return Selection.Create(
textArea,
e.GetNewOffset(startOffset, AnchorMovementType.Default),
e.GetNewOffset(endOffset, AnchorMovementType.Default)
);
@ -119,16 +101,6 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -119,16 +101,6 @@ namespace ICSharpCode.AvalonEdit.Editing
get { return startOffset == endOffset; }
}
// For segments, Offset must be less than or equal to EndOffset;
// so we must use Min/Max.
int ISegment.Offset {
get { return Math.Min(startOffset, endOffset); }
}
int ISegment.EndOffset {
get { return Math.Max(startOffset, endOffset); }
}
/// <inheritdoc/>
public override int Length {
get {
@ -137,18 +109,25 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -137,18 +109,25 @@ namespace ICSharpCode.AvalonEdit.Editing
}
/// <inheritdoc/>
public override Selection SetEndpoint(int newEndOffset)
public override Selection SetEndpoint(TextViewPosition endPosition)
{
if (IsEmpty)
throw new NotSupportedException();
else
return new SimpleSelection(startOffset, newEndOffset);
return Create(textArea, startOffset, textArea.Document.GetOffset(endPosition));
}
public override Selection StartSelectionOrSetEndpoint(TextViewPosition startPosition, TextViewPosition endPosition)
{
var document = textArea.Document;
if (document == null)
throw ThrowUtil.NoDocumentAssigned();
return Create(textArea, startOffset, document.GetOffset(endPosition));
}
/// <inheritdoc/>
public override int GetHashCode()
{
return startOffset ^ endOffset;
unchecked {
return startOffset * 27811 + endOffset + textArea.GetHashCode();
}
}
/// <inheritdoc/>
@ -156,9 +135,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -156,9 +135,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
SimpleSelection other = obj as SimpleSelection;
if (other == null) return false;
if (IsEmpty && other.IsEmpty)
return true;
return this.startOffset == other.startOffset && this.endOffset == other.endOffset;
return this.startOffset == other.startOffset && this.endOffset == other.endOffset && this.textArea == other.textArea;
}
/// <inheritdoc/>

20
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs

@ -59,6 +59,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -59,6 +59,8 @@ namespace ICSharpCode.AvalonEdit.Editing
this.textView = textView;
this.Options = textView.Options;
selection = emptySelection = new EmptySelection(this);
textView.Services.AddService(typeof(TextArea), this);
textView.LineTransformers.Add(new SelectionColorizer(this));
@ -204,7 +206,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -204,7 +206,7 @@ namespace ICSharpCode.AvalonEdit.Editing
// Reset caret location and selection: this is necessary because the caret/selection might be invalid
// in the new document (e.g. if new document is shorter than the old document).
caret.Location = new TextLocation(1, 1);
this.Selection = Selection.Empty;
this.ClearSelection();
if (DocumentChanged != null)
DocumentChanged(this, EventArgs.Empty);
CommandManager.InvalidateRequerySuggested();
@ -365,7 +367,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -365,7 +367,8 @@ namespace ICSharpCode.AvalonEdit.Editing
#endregion
#region Selection property
Selection selection = Selection.Empty;
internal readonly Selection emptySelection;
Selection selection;
/// <summary>
/// Occurs when the selection has changed.
@ -380,6 +383,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -380,6 +383,8 @@ namespace ICSharpCode.AvalonEdit.Editing
set {
if (value == null)
throw new ArgumentNullException("value");
if (value.textArea != this)
throw new ArgumentException("Cannot use a Selection instance that belongs to another text area.");
if (!object.Equals(selection, value)) {
//Debug.WriteLine("Selection change from " + selection + " to " + value);
if (textView != null) {
@ -416,6 +421,11 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -416,6 +421,11 @@ namespace ICSharpCode.AvalonEdit.Editing
}
}
public void ClearSelection()
{
this.Selection = emptySelection;
}
/// <summary>
/// The <see cref="SelectionBrush"/> property.
/// </summary>
@ -504,7 +514,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -504,7 +514,7 @@ namespace ICSharpCode.AvalonEdit.Editing
if (allowCaretOutsideSelection == 0) {
if (!selection.IsEmpty && !selection.Contains(caret.Offset)) {
Debug.WriteLine("Resetting selection because caret is outside");
this.Selection = Selection.Empty;
this.ClearSelection();
}
}
}
@ -861,7 +871,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -861,7 +871,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
if (this.Document == null)
throw ThrowUtil.NoDocumentAssigned();
selection.ReplaceSelectionWithText(this, string.Empty);
selection.ReplaceSelectionWithText(string.Empty);
#if DEBUG
if (!selection.IsEmpty) {
foreach (ISegment s in selection.Segments) {
@ -877,7 +887,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -877,7 +887,7 @@ namespace ICSharpCode.AvalonEdit.Editing
throw new ArgumentNullException("newText");
if (this.Document == null)
throw ThrowUtil.NoDocumentAssigned();
selection.ReplaceSelectionWithText(this, newText);
selection.ReplaceSelectionWithText(newText);
}
internal ISegment[] GetDeletableSegments(ISegment segment)

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -144,6 +144,10 @@ @@ -144,6 +144,10 @@
<Compile Include="Editing\DottedLineMargin.cs" />
<Compile Include="Editing\DragDropException.cs" />
<Compile Include="Editing\EditingCommandHandler.cs" />
<Compile Include="Editing\EmptySelection.cs">
<DependentUpon>Selection.cs</DependentUpon>
</Compile>
<Compile Include="Editing\SelectionSegment.cs" />
<Compile Include="Folding\AbstractFoldingStrategy.cs" />
<Compile Include="Folding\FoldingElementGenerator.cs" />
<Compile Include="Folding\FoldingManager.cs" />

11
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ColorizingTransformer.cs

@ -24,9 +24,16 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -24,9 +24,16 @@ namespace ICSharpCode.AvalonEdit.Rendering
/// </summary>
public void Transform(ITextRunConstructionContext context, IList<VisualLineElement> elements)
{
if (elements == null)
throw new ArgumentNullException("elements");
if (this.CurrentElements != null)
throw new InvalidOperationException("Recursive Transform() call");
this.CurrentElements = elements;
Colorize(context);
this.CurrentElements = null;
try {
Colorize(context);
} finally {
this.CurrentElements = null;
}
}
/// <summary>

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/InsertionContext.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.AvalonEdit.Snippets @@ -37,7 +37,7 @@ namespace ICSharpCode.AvalonEdit.Snippets
throw new ArgumentNullException("textArea");
this.TextArea = textArea;
this.Document = textArea.Document;
this.SelectedText = textArea.Selection.GetText(textArea.Document);
this.SelectedText = textArea.Selection.GetText();
this.InsertionPosition = insertionPosition;
this.startPosition = insertionPosition;

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetInputHandler.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.AvalonEdit.Snippets @@ -54,7 +54,7 @@ namespace ICSharpCode.AvalonEdit.Snippets
void SelectElement(IActiveElement element)
{
if (element != null) {
TextArea.Selection = new SimpleSelection(element.Segment);
TextArea.Selection = Selection.Create(TextArea, element.Segment);
TextArea.Caret.Offset = element.Segment.EndOffset;
}
}

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs

@ -818,7 +818,7 @@ namespace ICSharpCode.AvalonEdit @@ -818,7 +818,7 @@ namespace ICSharpCode.AvalonEdit
int length = this.SelectionLength;
textArea.Document.Replace(offset, length, value);
// keep inserted text selected
textArea.Selection = new SimpleSelection(offset, offset + value.Length);
textArea.Selection = SimpleSelection.Create(textArea, offset, offset + value.Length);
}
}
}
@ -890,7 +890,7 @@ namespace ICSharpCode.AvalonEdit @@ -890,7 +890,7 @@ namespace ICSharpCode.AvalonEdit
throw new ArgumentOutOfRangeException("start", start, "Value must be between 0 and " + documentLength);
if (length < 0 || start + length > documentLength)
throw new ArgumentOutOfRangeException("length", length, "Value must be between 0 and " + (documentLength - length));
textArea.Selection = new SimpleSelection(start, start + length);
textArea.Selection = SimpleSelection.Create(textArea, start, start + length);
textArea.Caret.Offset = start + length;
}

14
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextViewPosition.cs

@ -14,6 +14,19 @@ namespace ICSharpCode.AvalonEdit @@ -14,6 +14,19 @@ namespace ICSharpCode.AvalonEdit
{
int line, column, visualColumn;
/// <summary>
/// Gets/Sets Location.
/// </summary>
public TextLocation Location {
get {
return new TextLocation(line, column);
}
set {
line = value.Line;
column = value.Column;
}
}
/// <summary>
/// Gets/Sets the line number.
/// </summary>
@ -86,6 +99,7 @@ namespace ICSharpCode.AvalonEdit @@ -86,6 +99,7 @@ namespace ICSharpCode.AvalonEdit
/// <summary>
/// Implicit conversion to <see cref="TextLocation"/>.
/// </summary>
[Obsolete("Avoid")]
public static implicit operator TextLocation(TextViewPosition position)
{
return new TextLocation(position.Line, position.Column);

Loading…
Cancel
Save