diff options
author | spingel | 2008-10-01 03:48:20 +0000 |
---|---|---|
committer | spingel | 2008-10-01 03:48:20 +0000 |
commit | 59077bed02259818b5b6cd096f89f86a3dcd9a01 (patch) | |
tree | 28142d58247b549c9d5ed0817b67a3cac58199b5 | |
parent | 97dab52d9f6087f3edfd44954f8b3729758c137c (diff) | |
download | org.eclipse.mylyn.tasks-59077bed02259818b5b6cd096f89f86a3dcd9a01.tar.gz org.eclipse.mylyn.tasks-59077bed02259818b5b6cd096f89f86a3dcd9a01.tar.xz org.eclipse.mylyn.tasks-59077bed02259818b5b6cd096f89f86a3dcd9a01.zip |
NEW - bug 244442: [api] TaskHyperlinkDetector does not detect hyperlinks correctly for regions of non-zero length
https://bugs.eclipse.org/bugs/show_bug.cgi?id=244442
10 files changed, 269 insertions, 110 deletions
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/tasklist/BugzillaConnectorUi.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/tasklist/BugzillaConnectorUi.java index c0f5837f0..a4583ea44 100644 --- a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/tasklist/BugzillaConnectorUi.java +++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/tasklist/BugzillaConnectorUi.java @@ -110,36 +110,13 @@ public class BugzillaConnectorUi extends AbstractRepositoryConnectorUi { } @Override - public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int lineOffset, int regionOffset) { - ArrayList<IHyperlink> hyperlinksFound = new ArrayList<IHyperlink>(); + public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int index, int textOffset) { + ArrayList<IHyperlink> hyperlinksFound = null; Matcher m = PATTERN.matcher(text); while (m.find()) { - if (lineOffset <= m.start() && lineOffset < m.end()) { - IHyperlink link = extractHyperlink(repository, regionOffset, m); - if (link != null) { - hyperlinksFound.add(link); - } - } - } - - if (hyperlinksFound.size() > 0) { - return hyperlinksFound.toArray(new IHyperlink[1]); - } - return null; - } - - @Override - public IHyperlink[] findHyperlinks(TaskRepository repository, String content, int contentOffset, IRegion region) { - List<IHyperlink> hyperlinksFound = null; - - final int start = region.getOffset(); - final int end = region.getOffset() + region.getLength(); - - Matcher m = PATTERN.matcher(content); - while (m.find()) { - if (start <= m.start() && end >= m.end()) { - IHyperlink link = extractHyperlink(repository, contentOffset, m); + if (index == -1 || (index >= m.start() && index <= m.end())) { + IHyperlink link = extractHyperlink(repository, textOffset, m); if (link != null) { if (hyperlinksFound == null) { hyperlinksFound = new ArrayList<IHyperlink>(); @@ -149,10 +126,7 @@ public class BugzillaConnectorUi extends AbstractRepositoryConnectorUi { } } - if (hyperlinksFound != null && !hyperlinksFound.isEmpty()) { - return hyperlinksFound.toArray(new IHyperlink[1]); - } - return null; + return (hyperlinksFound != null) ? hyperlinksFound.toArray(new IHyperlink[0]) : null; } @Override diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java index 8896584a5..bf5b1c4a1 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java @@ -15,6 +15,8 @@ import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.mylyn.tasks.tests.ui.MarkTaskHandlerTest; +import org.eclipse.mylyn.tasks.tests.ui.TaskHyperlinkDetectorTest; +import org.eclipse.mylyn.tasks.tests.ui.TaskRelationHyperlinkDetectorTest; /** * @author Mik Kersten @@ -68,6 +70,8 @@ public class AllTasksTests { suite.addTestSuite(StackTraceDuplicateDetectorTest.class); suite.addTestSuite(MarkTaskHandlerTest.class); suite.addTestSuite(RepositoryTemplateManagerTest.class); + suite.addTestSuite(TaskHyperlinkDetectorTest.class); + suite.addTestSuite(TaskRelationHyperlinkDetectorTest.class); // XXX long running tests, put back? //suite.addTestSuite(TaskDataImportTest.class); diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnectorUi.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnectorUi.java index 7b031571e..221d201a0 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnectorUi.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/connector/MockRepositoryConnectorUi.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2004, 2008 Tasktop Technologies and others. + * Copyright (c) 2004, 2008 Tasktop Technologies and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,18 +11,29 @@ package org.eclipse.mylyn.tasks.tests.connector; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.wizard.IWizard; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.ITaskMapping; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; +import org.eclipse.mylyn.tasks.ui.TaskHyperlink; import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage; /** * @author Mik Kersten + * @author Steffen Pingel */ public class MockRepositoryConnectorUi extends AbstractRepositoryConnectorUi { + private static Pattern HYPERLINK_PATTERN = Pattern.compile("(\\d+)"); + @Override public String getConnectorKind() { return "mock"; @@ -50,4 +61,14 @@ public class MockRepositoryConnectorUi extends AbstractRepositoryConnectorUi { // ignore return null; } + + @Override + public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int index, int textOffset) { + List<IHyperlink> links = new ArrayList<IHyperlink>(); + Matcher m = HYPERLINK_PATTERN.matcher(text); + while (m.find()) { + links.add(new TaskHyperlink(new Region(textOffset + m.start(), m.end() - m.start()), repository, m.group())); + } + return links.toArray(new IHyperlink[0]); + } } diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskHyperlinkDetectorTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskHyperlinkDetectorTest.java new file mode 100644 index 000000000..107a2b6c3 --- /dev/null +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskHyperlinkDetectorTest.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.tasks.tests.ui; + +import junit.framework.TestCase; + +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkDetector; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.tests.TaskTestUtil; +import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryConnectorUi; +import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; + +/** + * @author Steffen Pingel + */ +public class TaskHyperlinkDetectorTest extends TestCase { + + protected MockRepositoryConnectorUi connectorUi; + + protected TaskRepository repository; + + @Override + protected void setUp() throws Exception { + repository = TaskTestUtil.createMockRepository(); + connectorUi = new MockRepositoryConnectorUi(); + } + + protected IHyperlink[] detect(final String text, int start, int length) { + TaskHyperlinkDetector detector = createHyperlinkDetector(); + return detector.detectHyperlinks(new TextViewer() { + @Override + public IDocument getDocument() { + return new Document(text); + } + }, new Region(start, length), true); + } + + protected TaskHyperlinkDetector createHyperlinkDetector() { + TaskHyperlinkDetector detector = new TaskHyperlinkDetector() { + @Override + protected TaskRepository getTaskRepository(ITextViewer textViewer) { + return repository; + } + + @Override + protected AbstractRepositoryConnectorUi getConnectorUi(TaskRepository repository) { + return connectorUi; + } + }; + return detector; + } + + public void testMultiple() { + IHyperlink[] links = detect("123 456 789", 4, 5); + assertNotNull(links); + assertEquals(2, links.length); + assertEquals(new Region(4, 3), links[0].getHyperlinkRegion()); + assertEquals(new Region(8, 1), links[1].getHyperlinkRegion()); + } + + public void testMultipleFullRegion() { + IHyperlink[] links = detect("123 456 789", 0, 11); + assertEquals(3, links.length); + assertEquals(new Region(0, 3), links[0].getHyperlinkRegion()); + assertEquals(new Region(4, 3), links[1].getHyperlinkRegion()); + assertEquals(new Region(8, 3), links[2].getHyperlinkRegion()); + } + + public void testSingleZeroLenghtRegion() { + IHyperlink[] links = detect("123 456 789", 5, 0); + assertEquals(1, links.length); + } + + public void testSpaceZeroLengthRegion() { + IHyperlink[] links = detect("1234 789", 5, 0); + assertNull(links); + } + +} diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskRelationHyperlinkDetectorTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskRelationHyperlinkDetectorTest.java new file mode 100644 index 000000000..de2cc5f19 --- /dev/null +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/TaskRelationHyperlinkDetectorTest.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.tasks.tests.ui; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.mylyn.internal.tasks.ui.editors.TaskHyperlinkDetector; +import org.eclipse.mylyn.internal.tasks.ui.editors.TaskRelationHyperlinkDetector; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; + +/** + * @author Steffen Pingel + */ +public class TaskRelationHyperlinkDetectorTest extends TaskHyperlinkDetectorTest { + + @Override + protected TaskHyperlinkDetector createHyperlinkDetector() { + TaskRelationHyperlinkDetector detector = new TaskRelationHyperlinkDetector() { + @Override + protected TaskRepository getTaskRepository(ITextViewer textViewer) { + return repository; + } + + @Override + protected AbstractRepositoryConnectorUi getConnectorUi(TaskRepository repository) { + return connectorUi; + } + }; + return detector; + } + +} diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/RepositoryTextViewerConfiguration.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/RepositoryTextViewerConfiguration.java index dc9af7a2e..3c9d797c4 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/RepositoryTextViewerConfiguration.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/RepositoryTextViewerConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2004, 2008 Tasktop Technologies and others. + * Copyright (c) 2004, 2008 Tasktop Technologies and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -147,7 +147,7 @@ public class RepositoryTextViewerConfiguration extends TextSourceViewerConfigura @Override public IHyperlinkPresenter getHyperlinkPresenter(final ISourceViewer sourceViewer) { - return new TaskTextViewerHyperlinkPresenter(JFaceResources.getColorRegistry().get( + return new RepositoryTextViewerHyperlinkPresenter(JFaceResources.getColorRegistry().get( JFacePreferences.ACTIVE_HYPERLINK_COLOR), sourceViewer); } @@ -165,7 +165,8 @@ public class RepositoryTextViewerConfiguration extends TextSourceViewerConfigura } } - private final class TaskTextViewerHyperlinkPresenter extends DefaultHyperlinkPresenter { + private final class RepositoryTextViewerHyperlinkPresenter extends DefaultHyperlinkPresenter { + private final ISourceViewer sourceViewer; private IRegion activeRegion; @@ -176,7 +177,7 @@ public class RepositoryTextViewerConfiguration extends TextSourceViewerConfigura */ private ITask currentTaskHyperlink; - private TaskTextViewerHyperlinkPresenter(Color color, ISourceViewer sourceViewer) { + private RepositoryTextViewerHyperlinkPresenter(Color color, ISourceViewer sourceViewer) { super(color); this.sourceViewer = sourceViewer; } @@ -238,11 +239,6 @@ public class RepositoryTextViewerConfiguration extends TextSourceViewerConfigura super.hideHyperlinks(); } - @Override - public void uninstall() { - // ignore - super.uninstall(); - } } private static class RepositoryTextScanner extends RuleBasedScanner { diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkDetector.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkDetector.java index 818d3a3cd..105f9bfcd 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkDetector.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkDetector.java @@ -14,16 +14,18 @@ package org.eclipse.mylyn.internal.tasks.ui.editors; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.jface.text.BadLocationException; 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.util.SafeRunnable; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; @@ -43,9 +45,8 @@ import org.eclipse.ui.PlatformUI; */ public class TaskHyperlinkDetector extends AbstractHyperlinkDetector { - public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion matchRegion, - boolean canShowMultipleHyperlinks) { - if (matchRegion == null || textViewer == null) { + public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) { + if (region == null || textViewer == null) { return null; } @@ -56,7 +57,7 @@ public class TaskHyperlinkDetector extends AbstractHyperlinkDetector { String content; int contentOffset; - IRegion region = matchRegion; + int index; try { if (region.getLength() == 0) { // expand the region to include the whole line @@ -69,24 +70,24 @@ public class TaskHyperlinkDetector extends AbstractHyperlinkDetector { int regionLength = Math.max(regionEnd, lineEnd) - lineOffset; contentOffset = lineOffset; content = document.get(lineOffset, regionLength); - region = new Region(0, regionLength); + index = region.getOffset() - lineOffset; } else { + // the line starts after region, may never happen int regionLength = Math.max(regionEnd, lineEnd) - region.getOffset(); contentOffset = region.getOffset(); content = document.get(contentOffset, regionLength); - region = new Region(0, regionLength); + index = 0; } } else { content = document.get(region.getOffset(), region.getLength()); contentOffset = region.getOffset(); - region = new Region(0, region.getLength()); + index = -1; } } catch (BadLocationException ex) { return null; } List<TaskRepository> repositories = new ArrayList<TaskRepository>(); - TaskRepository selectedRepository = getTaskRepository(textViewer); if (selectedRepository != null) { repositories.add(selectedRepository); @@ -94,36 +95,59 @@ public class TaskHyperlinkDetector extends AbstractHyperlinkDetector { repositories.addAll(TasksUi.getRepositoryManager().getAllRepositories()); } - List<IHyperlink> hyperlinks = new ArrayList<IHyperlink>(); - detectHyperlinks(content, contentOffset, matchRegion, region, repositories, hyperlinks); + List<IHyperlink> hyperlinks = detectHyperlinks(content, index, contentOffset, repositories); + if (hyperlinks == null) { + return null; + } + + // filter hyperlinks that do not match original region + if (region.getLength() == 0) { + for (Iterator<IHyperlink> it = hyperlinks.iterator(); it.hasNext();) { + IHyperlink hyperlink = it.next(); + IRegion hyperlinkRegion = hyperlink.getHyperlinkRegion(); + if (!isInRegion(region, hyperlinkRegion)) { + it.remove(); + } + } + } if (hyperlinks.isEmpty()) { return null; } + return hyperlinks.toArray(new IHyperlink[hyperlinks.size()]); } - private void detectHyperlinks(String content, int contentOffset, IRegion matchRegion, IRegion region, - List<TaskRepository> repositories, List<IHyperlink> hyperlinks) { - for (TaskRepository repository : repositories) { - AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind()); + protected List<IHyperlink> detectHyperlinks(final String content, final int index, final int contentOffset, + List<TaskRepository> repositories) { + List<IHyperlink> result = null; + for (final TaskRepository repository : repositories) { + final AbstractRepositoryConnectorUi connectorUi = getConnectorUi(repository); if (connectorUi == null) { continue; } - IHyperlink[] links = connectorUi.findHyperlinks(repository, content, contentOffset, region); - if (links == null) { - continue; - } - if (matchRegion.getLength() == 0) { - for (IHyperlink link : links) { - IRegion hyperlinkRegion = link.getHyperlinkRegion(); - if (isInRegion(matchRegion, hyperlinkRegion)) { - hyperlinks.add(link); - } + final IHyperlink[][] links = new IHyperlink[1][]; + SafeRunnable.run(new ISafeRunnable() { + + public void handleException(Throwable exception) { } - } else { - hyperlinks.addAll(Arrays.asList(links)); + + public void run() throws Exception { + links[0] = connectorUi.findHyperlinks(repository, content, index, contentOffset); + } + + }); + if (links[0] != null && links[0].length > 0) { + if (result == null) { + result = new ArrayList<IHyperlink>(); + } + result.addAll(Arrays.asList(links[0])); } } + return result; + } + + protected AbstractRepositoryConnectorUi getConnectorUi(TaskRepository repository) { + return TasksUiPlugin.getConnectorUi(repository.getConnectorKind()); } private boolean isInRegion(IRegion matchRegion, IRegion hyperlinkRegion) { diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkTextPresentationManager.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkTextPresentationManager.java index 03d6ce33b..f7d0f13cf 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkTextPresentationManager.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskHyperlinkTextPresentationManager.java @@ -19,7 +19,6 @@ import java.util.List; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextPresentationListener; import org.eclipse.jface.text.ITextViewerExtension4; -import org.eclipse.jface.text.Region; import org.eclipse.jface.text.TextPresentation; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; @@ -73,19 +72,19 @@ public class TaskHyperlinkTextPresentationManager { private class Support implements ITextPresentationListener { public void applyTextPresentation(TextPresentation textPresentation) { - StyleRange[] styleRanges = computeStyleRanges(); + System.err.println(textPresentation.getExtent()); + StyleRange[] styleRanges = computeStyleRanges(textPresentation.getExtent()); if (styleRanges != null && styleRanges.length > 0) { textPresentation.mergeStyleRanges(styleRanges); } } } - private StyleRange[] computeStyleRanges() { + private StyleRange[] computeStyleRanges(IRegion extent) { if (viewer == null || hyperlinkDetector == null || viewer.getDocument() == null) { return null; } - IHyperlink[] hyperlinks = hyperlinkDetector.detectHyperlinks(viewer, new Region(0, viewer.getDocument() - .getLength()), true); + IHyperlink[] hyperlinks = hyperlinkDetector.detectHyperlinks(viewer, extent, true); if (hyperlinks != null && hyperlinks.length > 0) { List<IRegion> regions = null; diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskRelationHyperlinkDetector.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskRelationHyperlinkDetector.java index 50a605fc1..d7a7d0dec 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskRelationHyperlinkDetector.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskRelationHyperlinkDetector.java @@ -11,6 +11,11 @@ package org.eclipse.mylyn.internal.tasks.ui.editors; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; @@ -25,25 +30,48 @@ import org.eclipse.mylyn.tasks.ui.TaskHyperlink; */ public class TaskRelationHyperlinkDetector extends TaskHyperlinkDetector { + private static Pattern HYPERLINK_PATTERN = Pattern.compile("([^\\s,]+)"); + @Override public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { if (region == null || textViewer == null || textViewer.getDocument() == null) { return null; } - TaskRepository taskRepository = getTaskRepository(textViewer); - if (taskRepository != null) { - String prefix = extractPrefix(textViewer, region.getOffset()); - String postfix = extractPostfix(textViewer, region.getOffset()); - String taskKey = prefix + postfix; - if (taskKey != null) { - Region hyperlinkRegion = new Region(region.getOffset() - prefix.length(), taskKey.length()); - return new IHyperlink[] { new TaskHyperlink(hyperlinkRegion, taskRepository, taskKey) }; + if (region.getLength() > 0) { + return super.detectHyperlinks(textViewer, region, canShowMultipleHyperlinks); + } else { + TaskRepository taskRepository = getTaskRepository(textViewer); + if (taskRepository != null) { + String prefix = extractPrefix(textViewer, region.getOffset()); + String postfix = extractPostfix(textViewer, region.getOffset()); + String taskKey = prefix + postfix; + if (taskKey.length() > 0) { + Region hyperlinkRegion = new Region(region.getOffset() - prefix.length(), taskKey.length()); + return new IHyperlink[] { new TaskHyperlink(hyperlinkRegion, taskRepository, taskKey) }; + } } } return null; } + @Override + protected List<IHyperlink> detectHyperlinks(String content, int index, int contentOffset, + List<TaskRepository> repositories) { + List<IHyperlink> links = null; + for (TaskRepository repository : repositories) { + Matcher m = HYPERLINK_PATTERN.matcher(content); + while (m.find()) { + if (links == null) { + links = new ArrayList<IHyperlink>(); + } + Region region = new Region(contentOffset + m.start(), m.end() - m.start()); + links.add(new TaskHyperlink(region, repository, m.group())); + } + } + return links; + } + private String extractPrefix(ITextViewer viewer, int offset) { int i = offset; IDocument document = viewer.getDocument(); diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java index 0d98172bf..072f81e40 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java @@ -17,7 +17,6 @@ import java.util.Collections; import java.util.List; import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizard; @@ -208,47 +207,26 @@ public abstract class AbstractRepositoryConnectorUi { } /** - * Returns an array of hyperlinks that link to tasks within <code>text</code>. + * Returns an array of hyperlinks that link to tasks within <code>text</code>. If <code>index</code> is != -1 + * clients may limit the results to hyperlinks found at <code>index</code>. It is legal for clients to always return + * all results. * * @param repository * the task repository, never <code>null</code> * @param text * the line of text + * @param index + * the index within <code>text</code>, if -1 return all hyperlinks found in text * @param textOffset - * the offset within <code>text</code> - * @param lineOffset * the offset of <code>text</code> - * @return an array of hyperlinks + * @return an array of hyperlinks, or null if no hyperlinks were found * @since 2.0 - * - * @deprecated use {@link #findHyperlinks(TaskRepository, String, int, IRegion)} instead */ - @Deprecated - public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int textOffset, int lineOffset) { + public IHyperlink[] findHyperlinks(TaskRepository repository, String text, int index, int textOffset) { return null; } /** - * Returns an array of hyperlinks that link to tasks within <code>content</code>. - * - * @param repository - * the repository for which hyperlinks should be detected, never <code>null</code> - * @param content - * the text content in which to find hyperlinks - * @param contentOffset - * the offset into the original content at which the <code>content</code> starts. Returned hyperlinks - * should be offset by this factor - * @param region - * the region that specifies the subset of the content in which to find hyperlinks - * - * @return an array of hyperlinks, or null - * @since 3.1 - */ - public IHyperlink[] findHyperlinks(TaskRepository repository, String content, int contentOffset, IRegion region) { - return findHyperlinks(repository, content, region.getOffset(), contentOffset); - } - - /** * @since 3.0 */ public boolean hasCustomNotifications() { |