PageRenderTime 69ms CodeModel.GetById 50ms app.highlight 12ms RepoModel.GetById 2ms app.codeStats 0ms

/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLineLinkText.cs

http://github.com/icsharpcode/ILSpy
C# | 130 lines | 74 code | 10 blank | 46 comment | 13 complexity | a93f3d3534a3a24b8f982663558bae92 MD5 | raw file
  1// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2// 
  3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4// software and associated documentation files (the "Software"), to deal in the Software
  5// without restriction, including without limitation the rights to use, copy, modify, merge,
  6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7// to whom the Software is furnished to do so, subject to the following conditions:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 17// DEALINGS IN THE SOFTWARE.
 18
 19using System;
 20using System.Collections.Generic;
 21using System.Diagnostics;
 22using System.Windows;
 23using System.Windows.Documents;
 24using System.Windows.Input;
 25using System.Windows.Media;
 26using System.Windows.Media.TextFormatting;
 27using System.Windows.Navigation;
 28
 29namespace ICSharpCode.AvalonEdit.Rendering
 30{
 31	/// <summary>
 32	/// VisualLineElement that represents a piece of text and is a clickable link.
 33	/// </summary>
 34	public class VisualLineLinkText : VisualLineText
 35	{
 36		/// <summary>
 37		/// Gets/Sets the URL that is navigated to when the link is clicked.
 38		/// </summary>
 39		public Uri NavigateUri { get; set; }
 40		
 41		/// <summary>
 42		/// Gets/Sets the window name where the URL will be opened.
 43		/// </summary>
 44		public string TargetName { get; set; }
 45		
 46		/// <summary>
 47		/// Gets/Sets whether the user needs to press Control to click the link.
 48		/// The default value is true.
 49		/// </summary>
 50		public bool RequireControlModifierForClick { get; set; }
 51		
 52		/// <summary>
 53		/// Creates a visual line text element with the specified length.
 54		/// It uses the <see cref="ITextRunConstructionContext.VisualLine"/> and its
 55		/// <see cref="VisualLineElement.RelativeTextOffset"/> to find the actual text string.
 56		/// </summary>
 57		public VisualLineLinkText(VisualLine parentVisualLine, int length) : base(parentVisualLine, length)
 58		{
 59			this.RequireControlModifierForClick = true;
 60		}
 61		
 62		/// <inheritdoc/>
 63		public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
 64		{
 65			this.TextRunProperties.SetForegroundBrush(context.TextView.LinkTextForegroundBrush);
 66			this.TextRunProperties.SetBackgroundBrush(context.TextView.LinkTextBackgroundBrush);
 67			if (context.TextView.LinkTextUnderline)
 68				this.TextRunProperties.SetTextDecorations(TextDecorations.Underline);
 69			return base.CreateTextRun(startVisualColumn, context);
 70		}
 71		
 72		/// <summary>
 73		/// Gets whether the link is currently clickable.
 74		/// </summary>
 75		/// <remarks>Returns true when control is pressed; or when
 76		/// <see cref="RequireControlModifierForClick"/> is disabled.</remarks>
 77		protected bool LinkIsClickable()
 78		{
 79			if (NavigateUri == null)
 80				return false;
 81			if (RequireControlModifierForClick)
 82				return (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
 83			else
 84				return true;
 85		}
 86		
 87		/// <inheritdoc/>
 88		protected internal override void OnQueryCursor(QueryCursorEventArgs e)
 89		{
 90			if (LinkIsClickable()) {
 91				e.Handled = true;
 92				e.Cursor = Cursors.Hand;
 93			}
 94		}
 95		
 96		/// <inheritdoc/>
 97		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
 98		                                                 Justification = "I've seen Process.Start throw undocumented exceptions when the mail client / web browser is installed incorrectly")]
 99		protected internal override void OnMouseDown(MouseButtonEventArgs e)
100		{
101			if (e.ChangedButton == MouseButton.Left && !e.Handled && LinkIsClickable()) {
102				RequestNavigateEventArgs args = new RequestNavigateEventArgs(this.NavigateUri, this.TargetName);
103				args.RoutedEvent = Hyperlink.RequestNavigateEvent;
104				FrameworkElement element = e.Source as FrameworkElement;
105				if (element != null) {
106					// allow user code to handle the navigation request
107					element.RaiseEvent(args);
108				}
109				if (!args.Handled) {
110					try {
111						Process.Start(this.NavigateUri.ToString());
112					} catch {
113						// ignore all kinds of errors during web browser start
114					}
115				}
116				e.Handled = true;
117			}
118		}
119		
120		/// <inheritdoc/>
121		protected override VisualLineText CreateInstance(int length)
122		{
123			return new VisualLineLinkText(ParentVisualLine, length) {
124				NavigateUri = this.NavigateUri,
125				TargetName = this.TargetName,
126				RequireControlModifierForClick = this.RequireControlModifierForClick
127			};
128		}
129	}
130}