Browse Source

Build hyperlink support into AvalonEdit and enable it by default.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4908 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 16 years ago
parent
commit
317621c567
  1. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs
  2. 17
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
  3. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  4. 138
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/LinkElementGenerator.cs
  5. 12
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/NewLineElementGenerator.cs
  6. 33
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs
  7. 43
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
  8. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs
  9. 5
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineElementGenerator.cs
  10. 111
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineLinkText.cs
  11. 56
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs
  12. 1
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

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

@ -377,7 +377,7 @@ namespace ICSharpCode.AvalonEdit.Editing
TextArea textArea = GetTextArea(target); TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Document != null) { if (textArea != null && textArea.Document != null) {
DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line);
textArea.Selection = new SimpleSelection(currentLine.Offset, currentLine.EndOffset); textArea.Selection = new SimpleSelection(currentLine.Offset, currentLine.Offset + currentLine.TotalLength);
textArea.RemoveSelectedText(); textArea.RemoveSelectedText();
args.Handled = true; args.Handled = true;
} }

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

@ -756,6 +756,23 @@ namespace ICSharpCode.AvalonEdit.Editing
} }
#endregion #endregion
#region OnKeyDown/OnKeyUp
// Make life easier for text editor extensions that use a different cursor based on the pressed modifier keys.
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
TextView.InvalidateCursor();
}
/// <inheritdoc/>
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
TextView.InvalidateCursor();
}
#endregion
/// <summary> /// <summary>
/// Gets the requested service. /// Gets the requested service.
/// </summary> /// </summary>

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -239,6 +239,7 @@
<Compile Include="Rendering\LayerPosition.cs"> <Compile Include="Rendering\LayerPosition.cs">
<DependentUpon>TextView.cs</DependentUpon> <DependentUpon>TextView.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Rendering\LinkElementGenerator.cs" />
<Compile Include="Rendering\NewLineElementGenerator.cs" /> <Compile Include="Rendering\NewLineElementGenerator.cs" />
<Compile Include="Rendering\SingleCharacterElementGenerator.cs" /> <Compile Include="Rendering\SingleCharacterElementGenerator.cs" />
<Compile Include="Rendering\TextLayer.cs"> <Compile Include="Rendering\TextLayer.cs">
@ -254,6 +255,7 @@
<Compile Include="Rendering\VisualLineElementTextRunProperties.cs"> <Compile Include="Rendering\VisualLineElementTextRunProperties.cs">
<DependentUpon>VisualLine.cs</DependentUpon> <DependentUpon>VisualLine.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Rendering\VisualLineLinkText.cs" />
<Compile Include="Rendering\VisualLinesInvalidException.cs" /> <Compile Include="Rendering\VisualLinesInvalidException.cs" />
<Compile Include="Rendering\VisualLineText.cs" /> <Compile Include="Rendering\VisualLineText.cs" />
<Compile Include="Rendering\VisualLineTextParagraphProperties.cs"> <Compile Include="Rendering\VisualLineTextParagraphProperties.cs">

138
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/LinkElementGenerator.cs

@ -0,0 +1,138 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using ICSharpCode.AvalonEdit.Document;
using System.Windows.Navigation;
namespace ICSharpCode.AvalonEdit.Rendering
{
// This class is public because it can be used as a base class for custom links.
/// <summary>
/// Detects hyperlinks and makes them clickable.
/// </summary>
/// <remarks>
/// This element generator can be easily enabled and configured using the
/// <see cref="TextEditorOptions"/>.
/// </remarks>
public class LinkElementGenerator : VisualLineElementGenerator, IBuiltinElementGenerator
{
// a link starts with a protocol (or just with www), followed by 0 or more 'link characters', followed by a link end character
// (this allows accepting punctuation inside links but not at the end)
internal readonly static Regex defaultLinkRegex = new Regex(@"\b(https?://|ftp://|www\.)[\w\d\._/\-~%()+:?&=]*[\w\d/]");
// try to detect email addresses
internal readonly static Regex defaultMailRegex = new Regex(@"\b[\w\d\.\-]+\@[\w\d\.\-]+\.[a-z]{2,6}\b");
readonly Regex linkRegex;
/// <summary>
/// Gets/Sets whether the user needs to press Control to click the link.
/// The default value is true.
/// </summary>
public bool RequireControlModifierForClick { get; set; }
/// <summary>
/// Creates a new LinkElementGenerator.
/// </summary>
public LinkElementGenerator()
{
this.linkRegex = defaultLinkRegex;
this.RequireControlModifierForClick = true;
}
/// <summary>
/// Creates a new LinkElementGenerator using the specified regex.
/// </summary>
protected LinkElementGenerator(Regex regex) : this()
{
if (regex == null)
throw new ArgumentNullException("regex");
this.linkRegex = regex;
}
void IBuiltinElementGenerator.FetchOptions(TextEditorOptions options)
{
this.RequireControlModifierForClick = options.RequireControlModifierForHyperlinkClick;
}
Match GetMatch(int startOffset)
{
DocumentLine endLine = CurrentContext.VisualLine.LastDocumentLine;
int endOffset = endLine.Offset + endLine.Length;
string relevantText = CurrentContext.Document.GetText(startOffset, endOffset - startOffset);
return linkRegex.Match(relevantText);
}
/// <inheritdoc/>
public override int GetFirstInterestedOffset(int startOffset)
{
Match m = GetMatch(startOffset);
return m.Success ? startOffset + m.Index : -1;
}
/// <inheritdoc/>
public override VisualLineElement ConstructElement(int offset)
{
Match m = GetMatch(offset);
if (m.Success && m.Index == 0) {
VisualLineLinkText linkText = new VisualLineLinkText(CurrentContext.VisualLine, m.Length);
linkText.NavigateUri = GetUriFromMatch(m);
linkText.RequireControlModifierForClick = this.RequireControlModifierForClick;
return linkText;
} else {
return null;
}
}
/// <summary>
/// Fetches the URI from the regex match.
/// </summary>
protected virtual Uri GetUriFromMatch(Match match)
{
string targetUrl = match.Value;
if (targetUrl.StartsWith("www.", StringComparison.Ordinal))
targetUrl = "http://" + targetUrl;
return new Uri(targetUrl);
}
}
// This class is internal because it does not need to be accessed by the user - it can be configured using TextEditorOptions.
/// <summary>
/// Detects e-mail addresses and makes them clickable.
/// </summary>
/// <remarks>
/// This element generator can be easily enabled and configured using the
/// <see cref="TextEditorOptions"/>.
/// </remarks>
sealed class MailLinkElementGenerator : LinkElementGenerator
{
/// <summary>
/// Creates a new MailLinkElementGenerator.
/// </summary>
public MailLinkElementGenerator()
: base(defaultMailRegex)
{
}
/// <inheritdoc/>
protected override Uri GetUriFromMatch(Match match)
{
return new Uri("mailto:" + match.Value);
}
}
}

12
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/NewLineElementGenerator.cs

@ -14,11 +14,21 @@ using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.Rendering namespace ICSharpCode.AvalonEdit.Rendering
{ {
// This class is internal because it does not need to be accessed by the user - it can be configured using TextEditorOptions.
/// <summary> /// <summary>
/// Elements generator that displays "¶" at the end of lines. /// Elements generator that displays "¶" at the end of lines.
/// </summary> /// </summary>
public class NewLineElementGenerator : VisualLineElementGenerator /// <remarks>
/// This element generator can be easily enabled and configured using the
/// <see cref="TextEditorOptions"/>.
/// </remarks>
sealed class NewLineElementGenerator : VisualLineElementGenerator, IBuiltinElementGenerator
{ {
void IBuiltinElementGenerator.FetchOptions(TextEditorOptions options)
{
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetFirstInterestedOffset(int startOffset) public override int GetFirstInterestedOffset(int startOffset)
{ {

33
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/SingleCharacterElementGenerator.cs

@ -16,6 +16,8 @@ using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Rendering namespace ICSharpCode.AvalonEdit.Rendering
{ {
// This class is internal because it does not need to be accessed by the user - it can be configured using TextEditorOptions.
/// <summary> /// <summary>
/// Element generator that displays · for spaces and » for tabs and a box for control characters. /// Element generator that displays · for spaces and » for tabs and a box for control characters.
/// </summary> /// </summary>
@ -24,7 +26,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
/// <see cref="TextEditorOptions"/>. /// <see cref="TextEditorOptions"/>.
/// </remarks> /// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace")]
public class SingleCharacterElementGenerator : VisualLineElementGenerator, IWeakEventListener sealed class SingleCharacterElementGenerator : VisualLineElementGenerator, IBuiltinElementGenerator
{ {
/// <summary> /// <summary>
/// Gets/Sets whether to show · for spaces. /// Gets/Sets whether to show · for spaces.
@ -51,34 +53,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
this.ShowBoxForControlCharacters = true; this.ShowBoxForControlCharacters = true;
} }
/// <summary> void IBuiltinElementGenerator.FetchOptions(TextEditorOptions options)
/// Fetch options from the text editor and synchronize with future option changes.
/// </summary>
public void SynchronizeOptions(ITextEditorComponent textEditor)
{
if (textEditor == null)
throw new ArgumentNullException("textEditor");
FetchOptions(textEditor.Options);
TextEditorWeakEventManager.OptionChanged.AddListener(textEditor, this);
}
/// <inheritdoc/>
protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
if (managerType == typeof(TextEditorWeakEventManager.OptionChanged)) {
ITextEditorComponent component = (ITextEditorComponent)sender;
FetchOptions(component.Options);
return true;
}
return false;
}
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
return ReceiveWeakEvent(managerType, sender, e);
}
void FetchOptions(TextEditorOptions options)
{ {
this.ShowSpaces = options.ShowSpaces; this.ShowSpaces = options.ShowSpaces;
this.ShowTabs = options.ShowTabs; this.ShowTabs = options.ShowTabs;

43
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs

@ -50,15 +50,12 @@ namespace ICSharpCode.AvalonEdit.Rendering
public TextView() public TextView()
{ {
services.AddService(typeof(TextView), this); services.AddService(typeof(TextView), this);
this.Options = new TextEditorOptions();
textLayer = new TextLayer(this); textLayer = new TextLayer(this);
elementGenerators = new ObserveAddRemoveCollection<VisualLineElementGenerator>(ElementGenerator_Added, ElementGenerator_Removed); elementGenerators = new ObserveAddRemoveCollection<VisualLineElementGenerator>(ElementGenerator_Added, ElementGenerator_Removed);
lineTransformers = new ObserveAddRemoveCollection<IVisualLineTransformer>(LineTransformer_Added, LineTransformer_Removed); lineTransformers = new ObserveAddRemoveCollection<IVisualLineTransformer>(LineTransformer_Added, LineTransformer_Removed);
backgroundRenderers = new ObserveAddRemoveCollection<IBackgroundRenderer>(BackgroundRenderer_Added, BackgroundRenderer_Removed); backgroundRenderers = new ObserveAddRemoveCollection<IBackgroundRenderer>(BackgroundRenderer_Added, BackgroundRenderer_Removed);
this.Options = new TextEditorOptions();
SingleCharacterElementGenerator sceg = new SingleCharacterElementGenerator(); Debug.Assert(singleCharacterElementGenerator != null); // assert that the option change created the builtin element generators
sceg.SynchronizeOptions(this);
elementGenerators.Add(sceg);
layers = new UIElementCollection(this, this); layers = new UIElementCollection(this, this);
InsertLayer(textLayer, KnownLayer.Text, LayerInsertionPosition.Replace); InsertLayer(textLayer, KnownLayer.Text, LayerInsertionPosition.Replace);
@ -172,7 +169,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
if (OptionChanged != null) { if (OptionChanged != null) {
OptionChanged(this, e); OptionChanged(this, e);
} }
UpdateNewlineVisibilityFromOptions(); UpdateBuiltinElementGeneratorsFromOptions();
Redraw(); Redraw();
} }
@ -235,21 +232,39 @@ namespace ICSharpCode.AvalonEdit.Rendering
DisconnectFromTextView(lineTransformer); DisconnectFromTextView(lineTransformer);
Redraw(); Redraw();
} }
#endregion
#region Builtin ElementGenerators
NewLineElementGenerator newLineElementGenerator; NewLineElementGenerator newLineElementGenerator;
SingleCharacterElementGenerator singleCharacterElementGenerator;
LinkElementGenerator linkElementGenerator;
MailLinkElementGenerator mailLinkElementGenerator;
void UpdateBuiltinElementGeneratorsFromOptions()
{
TextEditorOptions options = this.Options;
AddRemoveDefaultElementGeneratorOnDemand(ref newLineElementGenerator, options.ShowEndOfLine);
AddRemoveDefaultElementGeneratorOnDemand(ref singleCharacterElementGenerator, options.ShowBoxForControlCharacters || options.ShowSpaces || options.ShowTabs);
AddRemoveDefaultElementGeneratorOnDemand(ref linkElementGenerator, options.EnableHyperlinks);
AddRemoveDefaultElementGeneratorOnDemand(ref mailLinkElementGenerator, options.EnableEmailHyperlinks);
}
void UpdateNewlineVisibilityFromOptions() void AddRemoveDefaultElementGeneratorOnDemand<T>(ref T generator, bool demand)
where T : VisualLineElementGenerator, IBuiltinElementGenerator, new()
{ {
bool hasNewlineGenerator = newLineElementGenerator != null; bool hasGenerator = generator != null;
if (hasNewlineGenerator != Options.ShowEndOfLine) { if (hasGenerator != demand) {
if (Options.ShowEndOfLine) { if (demand) {
newLineElementGenerator = new NewLineElementGenerator(); generator = new T();
this.ElementGenerators.Add(newLineElementGenerator); this.ElementGenerators.Add(generator);
} else { } else {
this.ElementGenerators.Remove(newLineElementGenerator); this.ElementGenerators.Remove(generator);
newLineElementGenerator = null; generator = null;
} }
} }
if (generator != null)
generator.FetchOptions(this.Options);
} }
#endregion #endregion

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs

@ -81,9 +81,6 @@ namespace ICSharpCode.AvalonEdit.Rendering
g.FinishGeneration(); g.FinishGeneration();
} }
// if (FirstDocumentLine.Length != 0)
// elements.Add(new VisualLineText(FirstDocumentLine.Text, FirstDocumentLine.Length));
// //elements.Add(new VisualNewLine(VisualNewLine.NewLineType.Lf));
this.Elements = elements.AsReadOnly(); this.Elements = elements.AsReadOnly();
CalculateOffsets(context.GlobalTextRunProperties); CalculateOffsets(context.GlobalTextRunProperties);
} }

5
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineElementGenerator.cs

@ -59,4 +59,9 @@ namespace ICSharpCode.AvalonEdit.Rendering
/// </remarks> /// </remarks>
public abstract VisualLineElement ConstructElement(int offset); public abstract VisualLineElement ConstructElement(int offset);
} }
internal interface IBuiltinElementGenerator
{
void FetchOptions(TextEditorOptions options);
}
} }

111
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineLinkText.cs

@ -0,0 +1,111 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
namespace ICSharpCode.AvalonEdit.Rendering
{
/// <summary>
/// VisualLineElement that represents a piece of text and is a clickable link.
/// </summary>
public class VisualLineLinkText : VisualLineText
{
/// <summary>
/// Gets/Sets the URL that is navigated to when the link is clicked.
/// </summary>
public Uri NavigateUri { get; set; }
/// <summary>
/// Gets/Sets the window name where the URL will be opened.
/// </summary>
public string TargetName { get; set; }
/// <summary>
/// Gets/Sets whether the user needs to press Control to click the link.
/// The default value is true.
/// </summary>
public bool RequireControlModifierForClick { get; set; }
/// <summary>
/// Creates a visual line text element with the specified length.
/// It uses the <see cref="ITextRunConstructionContext.VisualLine"/> and its
/// <see cref="VisualLineElement.RelativeTextOffset"/> to find the actual text string.
/// </summary>
public VisualLineLinkText(VisualLine parentVisualLine, int length) : base(parentVisualLine, length)
{
this.RequireControlModifierForClick = true;
}
/// <inheritdoc/>
public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
{
this.TextRunProperties.SetForegroundBrush(Brushes.Blue);
this.TextRunProperties.SetTextDecorations(TextDecorations.Underline);
return base.CreateTextRun(startVisualColumn, context);
}
bool LinkIsClickable()
{
if (NavigateUri == null)
return false;
if (RequireControlModifierForClick)
return (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
else
return true;
}
/// <inheritdoc/>
protected internal override void OnQueryCursor(QueryCursorEventArgs e)
{
if (LinkIsClickable()) {
e.Handled = true;
e.Cursor = Cursors.Hand;
}
}
/// <inheritdoc/>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "I've seen Process.Start throw undocumented exceptions when the mail client / web browser is installed incorrectly")]
protected internal override void OnMouseDown(MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left && !e.Handled && LinkIsClickable()) {
RequestNavigateEventArgs args = new RequestNavigateEventArgs(this.NavigateUri, this.TargetName);
args.RoutedEvent = Hyperlink.RequestNavigateEvent;
FrameworkElement element = e.Source as FrameworkElement;
if (element != null) {
// allow user code to handle the navigation request
element.RaiseEvent(args);
}
if (!args.Handled) {
try {
Process.Start(this.NavigateUri.ToString());
} catch {
// ignore all kinds of errors during web browser start
}
}
e.Handled = true;
}
}
/// <inheritdoc/>
protected override VisualLineText CreateInstance(int length)
{
return new VisualLineLinkText(ParentVisualLine, length) {
NavigateUri = this.NavigateUri,
TargetName = this.TargetName,
RequireControlModifierForClick = this.RequireControlModifierForClick
};
}
}
}

56
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs

@ -111,6 +111,60 @@ namespace ICSharpCode.AvalonEdit
} }
#endregion #endregion
#region EnableHyperlinks
bool enableHyperlinks = true;
/// <summary>
/// Gets/Sets whether to enable clickable hyperlinks in the editor.
/// </summary>
/// <remarks>The default value is <c>true</c>.</remarks>
[DefaultValue(true)]
public virtual bool EnableHyperlinks {
get { return enableHyperlinks; }
set {
if (enableHyperlinks != value) {
enableHyperlinks = value;
OnPropertyChanged("EnableHyperlinks");
}
}
}
bool enableEmailHyperlinks = true;
/// <summary>
/// Gets/Sets whether to enable clickable hyperlinks for e-mail addresses in the editor.
/// </summary>
/// <remarks>The default value is <c>true</c>.</remarks>
[DefaultValue(true)]
public virtual bool EnableEmailHyperlinks {
get { return enableEmailHyperlinks; }
set {
if (enableEmailHyperlinks != value) {
enableEmailHyperlinks = value;
OnPropertyChanged("EnableEMailHyperlinks");
}
}
}
bool requireControlModifierForHyperlinkClick = true;
/// <summary>
/// Gets/Sets whether the user needs to press Control to click hyperlinks.
/// The default value is true.
/// </summary>
/// <remarks>The default value is <c>true</c>.</remarks>
[DefaultValue(true)]
public virtual bool RequireControlModifierForHyperlinkClick {
get { return requireControlModifierForHyperlinkClick; }
set {
if (requireControlModifierForHyperlinkClick != value) {
requireControlModifierForHyperlinkClick = value;
OnPropertyChanged("RequireControlModifierForHyperlinkClick");
}
}
}
#endregion
#region TabSize / IndentationSize / ConvertTabsToSpaces / GetIndentationString #region TabSize / IndentationSize / ConvertTabsToSpaces / GetIndentationString
// I'm using '_' prefixes for the fields here to avoid confusion with the local variables // I'm using '_' prefixes for the fields here to avoid confusion with the local variables
// in the methods below. // in the methods below.
@ -157,6 +211,7 @@ namespace ICSharpCode.AvalonEdit
/// Gets the text used for indentation. /// Gets the text used for indentation.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
[Browsable(false)]
public string IndentationString { public string IndentationString {
get { return GetIndentationString(1); } get { return GetIndentationString(1); }
} }
@ -182,6 +237,7 @@ namespace ICSharpCode.AvalonEdit
/// <summary> /// <summary>
/// Gets/Sets whether copying without a selection copies the whole current line. /// Gets/Sets whether copying without a selection copies the whole current line.
/// </summary> /// </summary>
[DefaultValue(true)]
public virtual bool CutCopyWholeLine { public virtual bool CutCopyWholeLine {
get { return cutCopyWholeLine; } get { return cutCopyWholeLine; }
set { set {

1
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -123,6 +123,7 @@ namespace ICSharpCode.SharpDevelop.Gui
void OnRequestNavigate(object sender, RequestNavigateEventArgs e) void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{ {
e.Handled = true;
if (e.Uri.Scheme == "mailto") { if (e.Uri.Scheme == "mailto") {
try { try {
Process.Start(e.Uri.ToString()); Process.Start(e.Uri.ToString());

Loading…
Cancel
Save