1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
5
using System.Collections.Generic;
9
using ICSharpCode.AvalonEdit.Document;
10
using ICSharpCode.AvalonEdit.Highlighting;
12
namespace ICSharpCode.AvalonEdit.Editing
15
/// Base class for selections.
17
public abstract class Selection
20
/// Gets the empty selection.
22
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification="Empty selection is immutable")]
23
public static readonly Selection Empty = new SimpleSelection(-1, -1);
26
/// Gets the selected text segments.
28
public abstract IEnumerable<ISegment> Segments { get; }
31
/// Gets the smallest segment that contains all segments in this selection.
32
/// May return null if the selection is empty.
34
public abstract ISegment SurroundingSegment { get; }
37
/// Replaces the selection with the specified text.
39
public abstract void ReplaceSelectionWithText(TextArea textArea, string newText);
42
/// Updates the selection when the document changes.
44
public abstract Selection UpdateOnDocumentChange(DocumentChangeEventArgs e);
47
/// Gets whether the selection is empty.
49
public virtual bool IsEmpty {
50
get { return Length == 0; }
54
/// Gets the selection length.
56
public abstract int Length { get; }
59
/// Returns a new selection with the changed end point.
61
/// <exception cref="NotSupportedException">Cannot set endpoint for empty selection</exception>
62
public abstract Selection SetEndpoint(int newEndOffset);
65
/// If this selection is empty, starts a new selection from <paramref name="startOffset"/> to
66
/// <paramref name="newEndOffset"/>, otherwise, changes the endpoint of this selection.
68
public virtual Selection StartSelectionOrSetEndpoint(int startOffset, int newEndOffset)
71
return new SimpleSelection(startOffset, newEndOffset);
73
return SetEndpoint(newEndOffset);
77
/// Gets whether the selection is multi-line.
79
public virtual bool IsMultiline(TextDocument document)
82
throw new ArgumentNullException("document");
83
ISegment surroundingSegment = this.SurroundingSegment;
84
if (surroundingSegment == null)
86
int start = surroundingSegment.Offset;
87
int end = start + surroundingSegment.Length;
88
return document.GetLineByOffset(start) != document.GetLineByOffset(end);
92
/// Gets the selected text.
94
public virtual string GetText(TextDocument document)
97
throw new ArgumentNullException("document");
98
StringBuilder b = null;
100
foreach (ISegment s in Segments) {
103
b = new StringBuilder(text);
107
text = document.GetText(s);
110
if (text != null) b.Append(text);
113
return text ?? string.Empty;
118
/// Creates a HTML fragment for the selected text.
120
public string CreateHtmlFragment(TextArea textArea, HtmlOptions options)
122
if (textArea == null)
123
throw new ArgumentNullException("textArea");
125
throw new ArgumentNullException("options");
126
IHighlighter highlighter = textArea.GetService(typeof(IHighlighter)) as IHighlighter;
127
StringBuilder html = new StringBuilder();
129
foreach (ISegment selectedSegment in this.Segments) {
133
html.AppendLine("<br>");
134
html.Append(HtmlClipboard.CreateHtmlFragment(textArea.Document, highlighter, selectedSegment, options));
136
return html.ToString();
140
public abstract override bool Equals(object obj);
143
public abstract override int GetHashCode();
146
/// Gets whether the specified offset is included in the selection.
148
/// <returns>True, if the selection contains the offset (selection borders inclusive);
149
/// otherwise, false.</returns>
150
public virtual bool Contains(int offset)
154
if (this.SurroundingSegment.Contains(offset)) {
155
foreach (ISegment s in this.Segments) {
156
if (s.Contains(offset)) {
165
/// Creates a data object containing the selection's text.
167
public virtual DataObject CreateDataObject(TextArea textArea)
169
string text = GetText(textArea.Document);
170
// Ensure we use the appropriate newline sequence for the OS
171
DataObject data = new DataObject(TextUtilities.NormalizeNewLines(text, Environment.NewLine));
172
// we cannot use DataObject.SetText - then we cannot drag to SciTe
173
// (but dragging to Word works in both cases)
175
// Also copy text in HTML format to clipboard - good for pasting text into Word
176
// or to the SharpDevelop forums.
177
HtmlClipboard.SetHtml(data, CreateHtmlFragment(textArea, new HtmlOptions(textArea.Options)));