package org.xmind.ui.richtext; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.text.hyperlink.URLHyperlink; public class RichTextHyperlinkDetector extends AbstractHyperlinkDetector { private static final String regex = "\\b(https?|ftp|mailto|svn|irc|gopher|telnet|nntp|worldwind|news):(?:/{1,3})([\\w-]+\\.)+[\\w-]+[\\w-._/\\~%-+&#?!=()@:]*";//$NON-NLS-1$ public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { if (region == null || textViewer == null) return null; IDocument document = textViewer.getDocument(); if (document == null || !(document instanceof IRichDocument)) return null; IHyperlink autoHyperlink = getAutoHyperlink(document, region); if (autoHyperlink != null) return new IHyperlink[] { autoHyperlink }; IRichDocument doc = (IRichDocument) document; List<Hyperlink> hyperlinks = getHyperlinksInRange(doc.getHyperlinks(), region); if (hyperlinks.isEmpty()) return null; return parseHyperlinks(textViewer, hyperlinks); } private IHyperlink getAutoHyperlink(IDocument document, IRegion region) { int offset = region.getOffset(); String content = document.get(); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(content); while (matcher.find()) { String group = matcher.group(); int start = matcher.start(); int end = matcher.end(); if (start <= offset && offset <= end) { return new URLHyperlink(new Region(start, group.length()), group); } } return null; } protected IHyperlink[] parseHyperlinks(ITextViewer viewer, List<Hyperlink> hyperlinks) { int size = hyperlinks.size(); IHyperlink[] list = new IHyperlink[size]; for (int i = 0; i < size; i++) { Hyperlink hyperlink = hyperlinks.get(i); list[i] = parseHyperlink(viewer, hyperlink); } return list; } protected IHyperlink parseHyperlink(ITextViewer viewer, Hyperlink hyperlink) { return new URLHyperlink(new Region(hyperlink.start, hyperlink.length), hyperlink.href); } protected List<Hyperlink> getHyperlinksInRange(Hyperlink[] hyperlinks, IRegion region) { int start = region.getOffset(); return RichTextUtils.getHyperlinksInRange(hyperlinks, start, start); // int end = start + region.getOffset(); // return RichTextUtils.getHyperlinksInRange(hyperlinks, start, end); } }