summaryrefslogtreecommitdiff
path: root/Juick/Controls
diff options
context:
space:
mode:
Diffstat (limited to 'Juick/Controls')
-rw-r--r--Juick/Controls/HyperLinkRichTextBox.cs80
1 files changed, 80 insertions, 0 deletions
diff --git a/Juick/Controls/HyperLinkRichTextBox.cs b/Juick/Controls/HyperLinkRichTextBox.cs
new file mode 100644
index 0000000..6ec6883
--- /dev/null
+++ b/Juick/Controls/HyperLinkRichTextBox.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Media;
+
+namespace Juick.Controls
+{
+ public class HyperLinkRichTextBox : RichTextBox
+ {
+ static readonly Regex UrlRegex = new Regex(@"http(s)?://([\w+?\.\w+])+([a-zA-Z0-9\~\!\@\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?", RegexOptions.Compiled);
+ // TODO: Add more entities
+ static readonly Regex JuickEntityRegex = new Regex(@"#(\d+)(/\d+)?", RegexOptions.Compiled);
+ public static readonly DependencyProperty TextProperty =
+ DependencyProperty.Register("Text", typeof(string), typeof(HyperLinkRichTextBox), new PropertyMetadata(default(string), TextPropertyChanged));
+
+ public string Text
+ {
+ get { return (string)GetValue(TextProperty); }
+ set { SetValue(TextProperty, value); }
+ }
+
+ private static void TextPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
+ {
+ var richTextBox = (HyperLinkRichTextBox)dependencyObject;
+ var stringValue = (string)dependencyPropertyChangedEventArgs.NewValue;
+ var paragraph = new Paragraph();
+
+ var index = 0;
+ foreach (var match in UrlRegex.Matches(stringValue).OfType<Match>().Union(JuickEntityRegex.Matches(stringValue).OfType<Match>()))
+ {
+ Uri uri = null;
+ if (!Uri.TryCreate(match.Value, UriKind.Absolute, out uri))
+ {
+ // Juick entity
+ uri = new Uri(string.Format("/ThreadView.xaml?mid={0}", JuickEntityRegex.Replace(match.Value, "$1")), UriKind.Relative);
+ }
+ if (match.Index > 0)
+ {
+ var length = match.Index - index;
+ if (length > 0)
+ {
+ paragraph.Inlines.Add(new Run { Text = stringValue.Substring(index, length) });
+ }
+ }
+
+ var hyperLink = new Hyperlink
+ {
+ NavigateUri = uri
+ };
+ if (uri.IsAbsoluteUri)
+ {
+ hyperLink.TargetName = "_blank";
+ hyperLink.Inlines.Add(uri.Host);
+ }
+ else
+ {
+ hyperLink.Inlines.Add(match.Value);
+ }
+ paragraph.Inlines.Add(hyperLink);
+
+ index = match.Index + match.Length;
+ }
+
+ if (index == 0 || index < stringValue.Length - 1)
+ {
+ var lastRunText = stringValue.Substring(index);
+ if (lastRunText.Length > 0)
+ {
+ paragraph.Inlines.Add(new Run { Text = lastRunText });
+ }
+ }
+ richTextBox.Blocks.Clear();
+ richTextBox.Blocks.Add(paragraph);
+ }
+ }
+}